VR-Forces 5.0.1 Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
VR-Forces Back-End Extension (displayStateData)

Table of Contents

The Display State Data example does the following

Retrieving State Data

This example shows how to create a VR-Forces Back End extension plugin and install your own console commands that can be issued to print out various data to the console associated with objects in the system. This example currently adds the following console commands:

Since this example is loaded as a plugin, it can be used in conjunction with the released VR-Forces application.

How to Run the Example

This example demonstrates how to install your own derived object manager.

Usage

In the Launcher, click the Plug-ins button to bring up the Plug-ins Selection dialog. Enable the plugin.

To view the new behavior:

  1. Launch VR-Forces GUI and SIM for HLA1516 Evolved only. This example, while it will build in multiple protocols, will only work in the 1516 Evolved protocol.
  2. Load the developer_toolkit_examples\displayStateData\displayStateData.scnx in order to use this example.
  3. The vrfSim console will print out information that the plugin is loaded and what commands are available.
  4. If the list with the commands is not printed - type the help-display command in the VRF SIM console window. The available commands will be printed out.
  5. Type a command from the list in the vrfSim console window and the corresponding state data will be printed out.

    print-airbase AB 1

  6. To witness the movement-mission and escort-mission you will need to run at 15X—takes time for the base to launch the assets. Open the air base's information/FlightStatus tab to see this.
  Note: In Linux - you should not use the Launcher to start the SIM and the GUI. 
  You need to start the vrfSim and vrfGui, manually - from two separate terminal windows.
  The necessary front-end and back-end command line arguments can be copied from the Launcher UI.

Plugin Entry Points

The plugin.cxx file contains all the code necessary to run this example

/*******************************************************************************
** Copyright (c) 2018 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/
#include "vrfcgf/cgf.h"
extern "C" {
{
info.pluginName = "displayStateData";
info.pluginDescription = "Adds console commands to allow for the dislpay of state data. Type help-display to get a list of commands.";
info.pluginVersion = "1.00";
info.pluginCreator = "MAK Technologies";
info.pluginCreatorEmail = "sales@mak.com";
info.pluginContactWebPage = "www.mak.com";
info.pluginContactMailingAddress = "10 Fawcett Street, Suite 204, Cambridge, MA 02138 USA";
info.pluginContactPhone = "(617) 876 8085";
}
// When looking how to create a code task around a scripted task, you will need to know the scripted task script id you want to
// create the code around, and then inspect that script in the VR-Forces GUI to determine which variables are in that task to determine what
// reader writer variables need to be created and added to the scripted task. For example, in the script below, the launch_flight_mission
// scripted task is used. If you look at the Launch Flight Mission script, you can see the variables in the code mentioned below.
//
// The important parts to notice are the Variable Name and Type. The myVariableName is the reader/writer name you will use when creating your
// scripted task variable. The myType is the type of variable you will create. There are some common types you can see in the scripted tasks:
//
// string - DtRwString
// integer - DtRwInt
// double - DtRwReal
// simulationobject - DtRwObjectName
// datetime - DtRwReal
//
// When creating these reader/writer variables to add to the scripted task, you need to create the variable with the appropriate name and assign the value you want.
// For example, if you need to assign the AirBase, you would do:
//
// createFlightTask.setValue("Airbase", obj->uuid());
//
//
// The code saying you are adding an Airbase variable to the scripted task, and, for printing out on the screen in a plan, the variable type it is (this part is optional).
//
// For something like a double you would do:
//
// createFlightTask.setDateTime("LaunchTime", 0.);
//
// And so on, for the variables you want to add to the scripted task.
class DtStartMovementMissionCommand : public DtConsoleCommand
{
public:
DtStartMovementMissionCommand(DtCgf* c) : myCgf(c) {};
virtual ~DtStartMovementMissionCommand() {};
virtual bool execute(const DtString& parameters)
{
DtSimObjectReference obj = myCgf->simObjectManager()->lookup(DtUUID(parameters));
DtSimObjectReference waypoint = myCgf->simObjectManager()->lookup(DtUUID("Patrol Point"));
if (!obj.isValid())
{
DtWarn << "Could not find object named " << parameters << std::endl;
return true;
}
else if (!waypoint.isValid())
{
DtWarn << "Waypoint 1 does not exist. Please create a waypoint called Patrol Point as this example requires a waypoint to move to.";
return true;
}
else
{
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(obj);
// Look up the state data for runways in the state data parameters. If it does not exist then this is not an airbase
const DtRwPropertiesMap* runways = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(), "Runways");
if (!runways)
{
DtWarn << parameters << " is not an airbase.\n";
return true;
}
// Create the global plan. This will be used to add the tasks to for launching the mission from the airbase and
// then assigning that launched mission to move to the waypoint.
DtPlanBuilder globalPlanBuilder("Example Movement Mission Plan");
// Assign the mission to the airbase
DtScriptedTaskTask createFlightTask;
createFlightTask.setScriptId("launch_flight_mission"); // Script id to launch a mission flight
createFlightTask.setValue("Airbase", obj->uuid());
// Assign loadout
createFlightTask.setValue("Loadout", "Intercept");
// Assign the name to the aircraft unit
createFlightTask.setValue("CallSign", "MovementExample");
// Assign the aircraft unit type to create
createFlightTask.setValue("AircraftUnitType", DtEntityType(11, 2, 225, 35, 1, 3, 3));
// Wait for the launch to finish the task
createFlightTask.setValue("WaitForLaunch", true);
createFlightTask.setDateTime("LaunchTime", 0.);
globalPlanBuilder.addStatement(createFlightTask);
DtMoveToTask moveToWaypointTask;
moveToWaypointTask.setControlPoint(waypoint->uuid());
globalPlanBuilder.addTaskCommand(moveToWaypointTask, DtUUID("MovementExample", 0, true));
myCgf->globalPlanManager()->addOrUpdatePlan(globalPlanBuilder.planCopy());
DtWarn << "New movement mission plan assigned to " << obj->markingText() << std::endl;
}
return true;
}
protected:
DtCgf* myCgf;
};
// For this to work, you will need to click onto the AB 1 and add more aircraft to it to support the creation of an F16-C air aggregate
class DtStartEscortMissionCommand : public DtConsoleCommand
{
public:
DtStartEscortMissionCommand(DtCgf* c) : myCgf(c) {};
virtual ~DtStartEscortMissionCommand() {};
virtual void createAttackPlan(const DtSimObject* obj, const DtSimObject* waypoint)
{
// Create the global plan. This will be used to add the tasks to for launching the mission from the airbase and
// then assigning that launched mission to move to escort the attack mission
DtPlanBuilder globalPlanBuilder("Example Attack Mission Plan");
// Add a wait task to have tha attack be created a little after the escort
DtWaitDurationTask waitDuration;
waitDuration.setSecondsToWait(5);
globalPlanBuilder.addStatement(waitDuration);
// Assign the mission to the airbase
DtScriptedTaskTask createFlightTask;
createFlightTask.setScriptId("launch_flight_mission"); // Script id to launch a mission flight
// The name of the base to launch the mission
createFlightTask.setValue("Airbase", obj->uuid());
// Assign the necessary variables to create the launch script
// Assign loadout
createFlightTask.setValue("Loadout", "Attack");
// Assign the name to the aircraft unit
createFlightTask.setValue("CallSign", "AttackExample");
// Assign the aircraft unit type to create
createFlightTask.setValue("AircraftUnitType", DtEntityType(11, 2, 225, 35, 1, 3, 3));
// Wait for the launch to finish the task
createFlightTask.setValue("WaitForLaunch", true);
createFlightTask.setDateTime("LaunchTime", 0.);
globalPlanBuilder.addStatement(createFlightTask);
DtIssuePlanCommand issuePlan;
DtPlanBuilder attackPlan;
// Set the rule to hold fire
DtSetEngagementRulesRequest setEngagementRules;
setEngagementRules.setEngagementRules("hold-fire");
attackPlan.addStatement(setEngagementRules);
// Turn on IFF to avoid friendly fire
setIff.setModeSTcasI(true);
setIff.setModeSOn(true);
setIff.setMode5LevelSelection(true);
attackPlan.addStatement(setIff);
const DtLocalObject* targetPoint = myCgf->localObjectManager()->lookup(DtUUID("Attack Point"));
// Attack target point does not exist, so create it
if (!targetPoint)
{
if (ab2)
{
// First create the new psuedo aggregrate to carry out this plan
DtEntityType target(16, 0, 0, 2, 0, 0, 0);
DtVector initialPosition(ab2->worldPosition());
DtReal initialHeading = 0.0; //Heading in radians
// Create the aggregate above the air base
targetPoint = myCgf->localObjectManager()->createAndInitVrfObject(
DtObjectType(1, target),
true,
"Attack Point",
DtString::nullString(),
obj->forceType(),
initialPosition,
0,
false,
false,
DtAppearance::nullAppearance(),
"local-vrf-object");
}
}
// Add a task to wait for our escort to escort us
DtScriptedTaskTask waitForEscort;
waitForEscort.setScriptId("wait_for_escort");
// Where to meet
waitForEscort.setValue("WaitLocation", waypoint->uuid());
attackPlan.addStatement(waitForEscort);
DtSimObjectReference attackRoute = myCgf->simObjectManager()->lookup(DtUUID("Attack Route"));
if (targetPoint && attackRoute.isValid())
{
// And now, land back at the originating air base
DtScriptedTaskTask attackAirbase;
attackAirbase.setScriptId("Ground_Attack");
// Where to meet
attackAirbase.setValue("targetPoint", targetPoint->uuid());
attackAirbase.setValue("ingressRoute", attackRoute->uuid());
attackAirbase.setValue("egressRoute", attackRoute->uuid());
attackPlan.addStatement(attackAirbase);
}
// And now, land back at the originating air base
DtScriptedTaskTask landAtAirbase;
landAtAirbase.setScriptId("land_at_air_base");
// Where to meet
landAtAirbase.setValue("airBase", obj->uuid());
attackPlan.addStatement(landAtAirbase);
issuePlan.init();
issuePlan.setIssueTo(DtUUID("AttackExample", 0, true));
issuePlan.setPlan(attackPlan);
globalPlanBuilder.addStatement(issuePlan);
myCgf->globalPlanManager()->addOrUpdatePlan(globalPlanBuilder.planCopy());
}
virtual void createResourcePlan(const DtSimObject* obj)
{
// If this plan exists, then, don't create it again
if (myCgf->localObjectManager()->lookup(DtUUID("Example Resource Assignment Plan")))
{
return;
}
// Create the global plan. This will be used to add the sets for setting up the resources for the airbase
DtPlanBuilder globalPlanBuilder("Example Resource Assignment Plan");
// Assign the mission to the airbase
DtScriptedTaskSet setAssignAircraft;
setAssignAircraft.setScriptId("set_assign_aircraft");
std::map<DtString, int> aircraftMap;
aircraftMap["F-16C"] = 12;
setAssignAircraft.setValue("aircraft", aircraftMap);
setAssignAircraft.setValue("setAsCurrent", false);
globalPlanBuilder.addSetDataCommand(setAssignAircraft, obj->uuid());
DtSetStateProperties setPersonnel;
DtRwProperties modProps("modified-state-properties");
addProperty<DtRwPropertyInt>(modProps, "Initial-Ground-Crew-Size")->setValue(100);
addProperty<DtRwPropertyInt>(modProps, "Initial-Air-Crew-Size")->setValue(100);
setPersonnel.init();
setPersonnel.setStateProperties(modProps);
setPersonnel.setProperties("Initial-Ground-Crew-Size;Initial-Air-Crew-Size"); // Hint to the front-end so it know what dialog to bring up to edit properties
setPersonnel.setReplace(true);
setPersonnel.setValuesArePercentages(false);
globalPlanBuilder.addSetDataCommand(setPersonnel, obj->uuid());
DtSetStateProperties setSupplies;
modProps.clearVariables();
addProperty<DtRwPropertyInt>(modProps, "Munitions")->setValue(1000);
addProperty<DtRwPropertyReal>(modProps, "Aviation-Fuel")->setValue(1000000);
setSupplies.init();
setSupplies.setStateProperties(modProps);
setSupplies.setProperties("Munitions;Aviation-Fuel"); // Hint to the front-end so it know what dialog to bring up to edit properties
setSupplies.setReplace(true);
setSupplies.setValuesArePercentages(false);
globalPlanBuilder.addSetDataCommand(setSupplies, obj->uuid());
DtSetStateProperties setFacilities;
modProps.clearVariables();
addProperty<DtRwPropertyBoolean>(modProps, "Has-Night-Support")->setValue(true);
addProperty<DtRwPropertyInt>(modProps, "ORP-Aircraft-Capacity")->setValue(100);
addProperty<DtRwPropertyInt>(modProps, "Apron-Aircraft-Capacity")->setValue(100);
addProperty<DtRwPropertyInt>(modProps, "Repair-Hangar-Aircraft-Capacity")->setValue(10);
addProperty<DtRwPropertyReal>(modProps, "Aviation-Fuel-Capacity")->setValue(10000000);
addProperty<DtRwPropertyInt>(modProps, "Munition-Storage-Capacity")->setValue(10000);
addProperty<DtRwPropertyInt>(modProps, "Barracks-Capacity")->setValue(300);
DtRwPropertiesMap* runways = new DtRwPropertiesMap("Runways");
runways->setKeyType(DtRwStringType); // The map key is a string
// The prototype is a structure that has the Length, Width and Direction
DtRwPropertiesStructure prototype("Runway-Item");
addProperty<DtRwPropertyReal>(prototype, "Length");
addProperty<DtRwPropertyReal>(prototype, "Width");
addProperty<DtRwPropertyReal>(prototype, "Main-Direction");
addProperty<DtRwPropertyReal>(prototype, "Usable-Length");
// Set the prototype into the map -- it will be cloned
runways->setPrototype(&prototype);
// Now, create a map of the key of the runway name and the prototype value and assign it
std::map<DtRwString, DtRwPropertiesStructure> runwaysToAssign;
// Set the values into the prototype so that it can be reused for setting up the runways map
findAndSetPropertyValue(prototype, "Length", 1000.0);
findAndSetPropertyValue(prototype, "Usable-Length", 1000.0);
findAndSetPropertyValue(prototype, "Width", 55.0);
findAndSetPropertyValue(prototype, "Main-Direction", 45.0);
DtRwString key("Runway");
key = "Test Runway";
runwaysToAssign[key] = prototype;
setMapProperty(runways, runwaysToAssign);
addProperty(modProps, runways);
setFacilities.init();
setFacilities.setStateProperties(modProps);
setFacilities.setProperties("Runways;Has-Night-Support;ORP-Aircraft-Capacity;Apron-Aircraft-Capacity;Repair-Hangar-Aircraft-Capacity;Aviation-Fuel-Capacity;Munition-Storage-Capacity;Barracks-Capacity"); // Hint to the front-end so it know what dialog to bring up to edit properties
setFacilities.setReplace(true);
setFacilities.setValuesArePercentages(false);
globalPlanBuilder.addSetDataCommand(setFacilities, obj->uuid());
myCgf->globalPlanManager()->addOrUpdatePlan(globalPlanBuilder.planCopy());
}
virtual void createEscortPlan(const DtSimObject* obj, const DtSimObject* waypoint)
{
// Create the global plan. This will be used to add the tasks to for launching the mission from the airbase and
// then assigning that launched mission to move to escort the attack mission
DtPlanBuilder globalPlanBuilder("Example Escort Mission Plan");
// Assign the mission to the airbase
DtScriptedTaskTask createFlightTask;
createFlightTask.setScriptId("launch_flight_mission"); // Script id to launch a mission flight
// The name of the base to launch the mission
createFlightTask.setValue("Airbase", obj->uuid());
// Assign the necessary variables to create the launch script
// Assign loadout
createFlightTask.setValue("Loadout", "Intercept");
// Assign the name to the aircraft unit
createFlightTask.setValue("CallSign", "EscortExample");
// Assign the aircraft unit type to create
createFlightTask.setValue("AircraftUnitType", DtEntityType(11, 2, 225, 35, 1, 9, 10));
// Wait for the launch to finish the task
createFlightTask.setValue("WaitForLaunch", true);
createFlightTask.setDateTime("LaunchTime", 0.);
globalPlanBuilder.addStatement(createFlightTask);
DtIssuePlanCommand issuePlan;
DtPlanBuilder escortPlan;
// Set the rule to only fire when an enemy is in an engagement zone
DtSetEngagementRulesRequest setEngagementRules;
setEngagementRules.setEngagementRules("fire-when-in-engagement-zone");
escortPlan.addStatement(setEngagementRules);
// Set the engagement zone that the escort will be looking at
// Also check to see if the engagement zone is there. If not, do not add this statement
DtSimObjectReference zone = myCgf->simObjectManager()->lookup(DtUUID("Blue JEZ"));
if (zone.isValid())
{
DtScriptedTaskSet setEngagementZone;
setEngagementZone.setScriptId("set-engagement-zones"); // Script id to launch a mission flight
// The name of the base to launch the mission
std::vector<DtUUID> zones;
zones.push_back(zone->uuid());
setEngagementZone.setValue("engagementZones", zones);
escortPlan.addStatement(setEngagementZone);
}
// Turn on IFF to avoid friendly fire
setIff.setModeSTcasI(true);
setIff.setModeSOn(true);
setIff.setMode5LevelSelection(true);
escortPlan.addStatement(setIff);
// Wait until our escort is created to escort them
DtCeEntityCreated entityCreated;
entityCreated.setEntityName("AttackExample");
escortPlan.addWaitUntilCondition(entityCreated);
// Set up the escort task to escort the to be created attack flight
DtScriptedTaskTask escortFlightTask;
escortFlightTask.setScriptId("escort_air_unit"); // Script id to launch a mission flight
// Where to meet
escortFlightTask.setValue("LocationToMeet", waypoint->uuid());
escortFlightTask.setValue("UnitToEscort", DtUUID("AttackExample", 0, true));
escortPlan.addStatement(escortFlightTask);
// And now, land back at the originating air base
DtScriptedTaskTask landAtAirbase;
landAtAirbase.setScriptId("land_at_air_base");
// Where to meet
landAtAirbase.setValue("airBase", obj->uuid());
escortPlan.addStatement(landAtAirbase);
issuePlan.init();
issuePlan.setIssueTo(DtUUID("EscortExample", 0, true));
issuePlan.setPlan(escortPlan);
globalPlanBuilder.addStatement(issuePlan);
myCgf->globalPlanManager()->addOrUpdatePlan(globalPlanBuilder.planCopy());
}
virtual bool execute(const DtString& parameters)
{
DtSimObjectReference obj = myCgf->simObjectManager()->lookup(DtUUID(parameters));
DtSimObjectReference waypoint = myCgf->simObjectManager()->lookup(DtUUID("Patrol Point"));
if (!obj.isValid())
{
DtWarn << "Could not find object named " << parameters << std::endl;
return true;
}
else if (!waypoint.isValid())
{
DtWarn << "Waypoint 1 does not exist. Please create a waypoint called Patrol Point as this example requires a waypoint to move to.";
return true;
}
else
{
// Look up the state data for runways in the state data parameters. If it does not exist then this is not an airbase
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(obj);
const DtRwPropertiesMap* runways = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(), "Runways");
if (!runways)
{
DtWarn << parameters << " is not an airbase.\n";
return true;
}
createResourcePlan(obj);
createAttackPlan(obj, waypoint);
createEscortPlan(obj, waypoint);
DtWarn << "New escort mission plans assigned to " << obj->markingText() << std::endl;
}
return true;
}
protected:
DtCgf* myCgf;
};
class DtPrintAirbaseCommand : public DtConsoleCommand
{
public:
DtPrintAirbaseCommand(DtCgf* c) : myCgf(c) {};
virtual ~DtPrintAirbaseCommand() {};
virtual bool execute(const DtString& parameters)
{
DtSimObjectReference obj = myCgf->simObjectManager()->lookup(DtUUID(parameters));
if (!obj.isValid())
{
DtWarn << "Could not find object named " << parameters << std::endl;
return true;
}
else
{
// Look up the state data for runways in the state data parameters. If it does not exist then this is not an airbase
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(obj);
const DtRwPropertiesMap* runways = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(), "Runways");
if (!runways)
{
DtWarn << parameters << " is not an airbase.\n";
return true;
}
// Each runway item in the map is a structure that contains the following items:
// (DtRwStructure Runway-Item
// (DtRwReal Length)
// (DtRwReal Width)
// (DtRwReal Main-Direction) ; heading in degrees
// )
//
// To read each item you must iterate over all the reader/writer items in the map, dynamically casting them to a DtRwPropertiesStructure.
// Then, you can find each name within that structure to print out the actual value
std::vector<DtReaderWriterRegistryData *>::const_iterator iter =
runways->registry().registryData().begin();
std::vector<DtReaderWriterRegistryData *>::const_iterator endIter =
runways->registry().registryData().end();
DtWarn << "Runways:\n";
while (iter != endIter)
{
const DtRwPropertiesStructure* str = dynamic_cast<DtRwPropertiesStructure*>((*iter)->readerWriter());
if (str)
{
const DtRwReal* length = findProperty<DtRwReal>(*str, "Length");
const DtRwReal* width = findProperty<DtRwReal>(*str, "Width");
const DtRwReal* mainDirection = findProperty<DtRwReal>(*str, "Main-Direction");
DtWarn << " " << str->name().c_str() << " is " << *length << " meters in length, " << *width << " meters in width and a direction of " << *mainDirection << " degrees.\n";
}
++iter;
}
}
return true;
}
protected:
DtCgf* myCgf;
};
class DtPrintStatusCommand : public DtConsoleCommand
{
public:
DtPrintStatusCommand(DtCgf* c) : myCgf(c) {};
virtual ~DtPrintStatusCommand() {};
virtual void printFuelIfExists(const DtSimObject* obj, const DtString& val)
{
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(obj);
const DtRwPropertiesStructure* baseStructure = findProperty<DtRwPropertiesStructure>(vrfSimulatedSimObjectFacade.parameterProperties(), "Base-" + val);
const DtRwPropertiesStructure* currentStructure = findProperty<DtRwPropertiesStructure>(vrfSimulatedSimObjectFacade.stateProperties(), val);
if (baseStructure && currentStructure)
{
const DtRwReal* amount = findProperty<DtRwReal>(*baseStructure, "Amount");
if (amount && (amount->value() != 0))
{
const DtRwReal* current = findProperty<DtRwReal>(*currentStructure, "Amount");
if (current)
{
DtString title = DtReplaceAllSubstrings(val, "-", " ");
DtWarn << " " << title << ": " << *current << "/" << *amount << std::endl;
}
}
}
}
virtual void printAmmunition(const DtSimObject* obj)
{
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(obj);
const DtRwPropertiesMap* ammoRw = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(), "Ammunition");
if(ammoRw)
{
std::vector<DtReaderWriterRegistryData *>::const_iterator iter = ammoRw->registry().registryData().begin();
std::vector<DtReaderWriterRegistryData *>::const_iterator endIter = ammoRw->registry().registryData().end();
for (; iter != endIter; ++iter)
{
const DtReaderWriter* ammoItemRw = (*iter)->readerWriter();
const DtRwInt* count = findProperty<DtRwInt>(*ammoItemRw, "Count");
const DtRwString* type = findProperty<DtRwString>(*ammoItemRw, "Type");
if (count && type)
{
DtWarn << " Ammunition: " << *type << " has " << *count << " units remaining.\n";
}
}
}
}
virtual void printPrimaryEquipment(const DtSimObject* obj)
{
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(obj);
const DtRwPropertiesStructure* currentStructure = findProperty<DtRwPropertiesStructure>(vrfSimulatedSimObjectFacade.stateProperties(), "Primary-Equipment");
// Base-Primary-Equipment is a parameter property because it does not change at run time.
const DtRwPropertiesStructure* baseStructure = findProperty<DtRwPropertiesStructure>(obj->parameterProperties(), "Base-Primary-Equipment");
if (currentStructure && baseStructure)
{
const DtRwString* type = findProperty<DtRwString>(*currentStructure, "Type");
const DtRwInt* count = findProperty<DtRwInt>(*currentStructure, "Count");
const DtRwInt* baseCount = findProperty<DtRwInt>(*baseStructure, "Count");
if (type && count && baseCount && type->length())
{
DtWarn << " Primary Equipment: " << *type << " has " << *count << " units remaining out of " << *baseCount << "\n";
}
}
}
virtual void printEquipment(const DtSimObject* obj)
{
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(obj);
const DtRwPropertiesMap* equipment = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(), "Equipment");
// Base-Equipment is a parameter property because it does not change at run time.
const DtRwPropertiesMap* baseEquipment = findProperty<DtRwPropertiesMap>(obj->parameterProperties(), "Base-Equipment");
// Base-Loadout-Equipment, on the other hand, is a state property because it does change at run time when the loadout changes.
const DtRwPropertiesMap* baseLoadoutEquipment = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(), "Base-Loadout-Equipment");
DtWarn << " Equipment: " << std::endl;
if (equipment && baseEquipment && baseLoadoutEquipment)
{
std::vector<DtReaderWriterRegistryData *>::const_iterator iter = equipment->registry().registryData().begin();
std::vector<DtReaderWriterRegistryData *>::const_iterator end = equipment->registry().registryData().end();
while (iter != end)
{
const DtRwPropertiesStructure* currEquip =
static_cast<const DtRwPropertiesStructure*>((*iter)->readerWriter());
boost::optional<int> currCount = findPropertyValue<int>(*currEquip, "Count");
boost::optional<int> baseCount;
boost::optional<int> baseLoadoutCount;
if (currCount)
{
// See if this equipment type is part of the base equipment
const DtRwPropertiesStructure* baseEquip = findMapItem<DtRwPropertiesStructure>(*baseEquipment, currEquip->name().c_str());
if (baseEquip)
{
baseCount = findPropertyValue<int>(*baseEquip, "Count");
}
// See if this equipment type is part of the base loadout equipment
const DtRwPropertiesStructure* baseLoadoutEquip = findMapItem<DtRwPropertiesStructure>(*baseLoadoutEquipment, currEquip->name().c_str());
if (baseLoadoutEquip)
{
baseLoadoutCount = findPropertyValue<int>(*baseLoadoutEquip, "Count");
}
// Add up base count totals from base and loadout
int totalBaseCount = 0;
if (baseCount)
{
totalBaseCount += *baseCount;
}
if (baseLoadoutCount)
{
totalBaseCount += *baseLoadoutCount;
}
DtWarn << " " << currEquip->name() << ": " << *currCount << " out of " << totalBaseCount << std::endl;
}
++iter;
}
}
}
virtual void printEngagementHistory(const DtSimObject* obj)
{
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(obj);
const DtRwPropertiesMap* engagementHistory = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(), "Engagement-History");
if (engagementHistory)
{
std::vector<DtReaderWriterRegistryData *>::const_iterator iter = engagementHistory->registry().registryData().begin();
std::vector<DtReaderWriterRegistryData *>::const_iterator end = engagementHistory->registry().registryData().end();
DtWarn << " Engagement History: " << std::endl;
while (iter != end)
{
const DtRwPropertiesStructure* engagementEvent =
static_cast<const DtRwPropertiesStructure*>((*iter)->readerWriter());
boost::optional<bool> isAttack = findPropertyValue<bool>(*engagementEvent, "IsAttack");
boost::optional<DtString> enemy = findPropertyValue<DtString>(*engagementEvent, "Enemy");
boost::optional<DtString> weaponType = findPropertyValue<DtString>(*engagementEvent, "Type");
boost::optional<double> hitFactor = findPropertyValue<double>(*engagementEvent, "HitFactor");
boost::optional<double> defenseFactor = findPropertyValue<double>(*engagementEvent, "DefenseFactor");
boost::optional<double> timeStarted = findPropertyValue<double>(*engagementEvent, "TimeStarted");
boost::optional<double> timeCompleted = findPropertyValue<double>(*engagementEvent, "TimeComplete");
boost::optional<int> damageTaken = findPropertyValue<int>(*engagementEvent, "DamageTaken");
boost::optional<double> pHit = findPropertyValue<double>(*engagementEvent, "ProbabilityHit");
boost::optional<double> draw = findPropertyValue<double>(*engagementEvent, "RandomDraw");
if (enemy && weaponType && isAttack && hitFactor && defenseFactor && timeStarted &&
timeCompleted && damageTaken && pHit && draw)
{
DtSimObjectReference enemyObj = myCgf->simObjectManager()->lookup(DtUUID(*enemy));
DtString enemyName("Unknown");
if (enemyObj.isValid())
{
enemyName = enemyObj->markingText();
}
if (*isAttack)
{
DtWarn << " Fired at " << enemyName << " with " << *weaponType << "." << std::endl;
DtWarn << " Hit Factor: " << *hitFactor << std::endl;
}
else
{
DtWarn << " Shot at by " << enemyName << " with " << *weaponType << ". ";
// Check if this event hit us and caused damage
if (*damageTaken > 0)
{
DtWarn << "Hit! Took " << *damageTaken << " damage." << std::endl;
}
else
{
DtWarn << "Miss!" << std::endl;
}
DtWarn << " Hit Factor: " << *hitFactor << ", Defense Factor: "
<< *defenseFactor << ", P(hit): " << *pHit << ", Draw: " << *draw
<< std::endl;
}
DtWarn << " Time: " << *timeStarted << " to " << *timeCompleted << std::endl;
const DtRwPropertiesList* details = findProperty<DtRwPropertiesList>(*engagementEvent, "Details");
if (details)
{
DtWarn << " Details: " << std::endl;
std::vector<DtReaderWriterRegistryData *>::const_iterator iterDetails = details->registry().registryData().begin();
std::vector<DtReaderWriterRegistryData *>::const_iterator endDetails = details->registry().registryData().end();
for (; iterDetails != endDetails; ++iterDetails)
{
const DtReaderWriter* detailEvent = (*iterDetails)->readerWriter();
boost::optional<DtString> detailText = getPropertyValue<DtString>(detailEvent);
DtWarn << " " << *detailText << std::endl;
}
}
}
++iter;
}
}
}
virtual bool execute(const DtString& parameters)
{
if (parameters == "ALL")
{
DtManagedObjectList list(myCgf->simulationServices());
while (iter != end)
{
// Only print out objects that have health
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(*iter);
const DtRwInt* health = findProperty<DtRwInt>(vrfSimulatedSimObjectFacade.stateProperties(), "Health");
if (health)
{
printStatus(*iter);
DtWarn << std::endl;
}
++iter;
}
}
else
{
DtSimObjectReference obj = myCgf->simObjectManager()->lookup(DtUUID(parameters));
if (!obj.isValid())
{
DtWarn << "Could not find object named " << parameters << std::endl;
return true;
}
else
{
printStatus(obj);
}
}
return true;
}
virtual void printStatus(const DtSimObject* obj)
{
DtWarn << "Current status for " << obj->markingText() << std::endl;
// Look up the state data for runways in the state data parameters. If it does not exist then this is not an airbase
DtVrfSimulatedSimObjectFacade vrfSimulatedSimObjectFacade(obj);
const DtRwInt* health = findProperty<DtRwInt>(vrfSimulatedSimObjectFacade.stateProperties(), "Health");
const DtRwInt* baseHealth = findProperty<DtRwInt>(vrfSimulatedSimObjectFacade.parameterProperties(), "Base-Health");
if (health && baseHealth)
{
DtWarn << " Health: " << *health << "/" << *baseHealth << std::endl;
}
printFuelIfExists(obj, "Aviation-Fuel");
printFuelIfExists(obj, "Diesel-Fuel");
printPrimaryEquipment(obj);
printEquipment(obj);
printAmmunition(obj);
printEngagementHistory(obj);
}
protected:
DtCgf* myCgf;
};
class DtHelpDisplayCommand : public DtConsoleCommand
{
public:
virtual ~DtHelpDisplayCommand() {};
virtual bool execute(const DtString& parameters)
{
DtWarn << "print-airbase <name> - prints airbase specific data. If the object is not an airbase a warning will be issued.\n";
DtWarn << "start-movement-mission <name> - Starts a move to waypoint mission using F-16C aircraft at the supplied air base. If the object is not an airbase a warning will be issued.\n";
DtWarn << "start-escort-mission <name> - Starts an escort mission using F-16C aircraft at the supplied air base. If the object is not an airbase a warning will be issued. You will need to add more F16 aircraft to the airbase in order to use this feature.\n";
DtWarn << "print-status <name | ALL> - prints various status (health, fuel, equipment, weapon stores). If the object is not an airbase a warning will be issued. Use ALL to print out all aggregates.\n";
DtWarn << "help-display - prints this list.\n";
return true;
}
};
static DtHelpDisplayCommand* theHelpDisplayCommand = 0;
static DtPrintAirbaseCommand* thePrintAirbaseCommand = 0;
static DtPrintStatusCommand* thePrintStatusCommand = 0;
static DtStartMovementMissionCommand* theStartMovementMissionCommand = 0;
static DtStartEscortMissionCommand* theStartEscortMissionCommand = 0;
DT_VRF_DLL_PLUGIN void DtUnloadVrfPlugin()
{
delete theHelpDisplayCommand;
delete thePrintAirbaseCommand;
delete thePrintStatusCommand;
delete theStartMovementMissionCommand;
delete theStartEscortMissionCommand;
}
DT_VRF_DLL_PLUGIN bool DtInitializeVrfPlugin(DtCgf* cgf)
{
return true;
}
DT_VRF_DLL_PLUGIN void DtPostInitializeVrfPlugin(DtCgf* cgf)
{
theHelpDisplayCommand = new DtHelpDisplayCommand;
thePrintAirbaseCommand = new DtPrintAirbaseCommand(cgf);
thePrintStatusCommand = new DtPrintStatusCommand(cgf);
theStartMovementMissionCommand = new DtStartMovementMissionCommand(cgf);
theStartEscortMissionCommand = new DtStartEscortMissionCommand(cgf);
theHelpDisplayCommand);
thePrintAirbaseCommand);
thePrintStatusCommand);
theStartMovementMissionCommand);
theStartEscortMissionCommand);
}
}

Document ID: Generated on Mon Jun 20 00:38:30 EDT 2022 from SVN revision 244029
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)