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.
This example demonstrates how to install your own derived object manager.
In the Launcher, click the Plug-ins button to bring up the Plug-ins Selection dialog. Enable the plugin.
extern "C" {
{
info.
pluginDescription =
"Adds console commands to allow for the dislpay of state data. Type help-display to get a list of commands.";
}
{
public:
DtStartMovementMissionCommand(
DtCgf* c) : myCgf(c) {};
virtual ~DtStartMovementMissionCommand() {};
{
{
DtWarn << "Could not find object named " << parameters << std::endl;
return true;
}
{
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
{
const DtRwPropertiesMap* runways = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(),
"Runways");
if (!runways)
{
DtWarn << parameters << " is not an airbase.\n";
return true;
}
DtPlanBuilder globalPlanBuilder(
"Example Movement Mission Plan");
createFlightTask.
setValue(
"Loadout",
"Intercept");
createFlightTask.
setValue(
"CallSign",
"MovementExample");
createFlightTask.
setValue(
"AircraftUnitType", DtEntityType(11, 2, 225, 35, 1, 3, 3));
createFlightTask.
setValue(
"WaitForLaunch",
true);
globalPlanBuilder.addStatement(createFlightTask);
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:
};
{
public:
DtStartEscortMissionCommand(
DtCgf* c) : myCgf(c) {};
virtual ~DtStartEscortMissionCommand() {};
{
globalPlanBuilder.addStatement(waitDuration);
createFlightTask.
setValue(
"Loadout",
"Attack");
createFlightTask.
setValue(
"CallSign",
"AttackExample");
createFlightTask.
setValue(
"AircraftUnitType", DtEntityType(11, 2, 225, 35, 1, 3, 3));
createFlightTask.
setValue(
"WaitForLaunch",
true);
globalPlanBuilder.addStatement(createFlightTask);
const DtLocalObject* targetPoint = myCgf->localObjectManager()->lookup(
DtUUID(
"Attack Point"));
if (!targetPoint)
{
if (ab2)
{
DtEntityType target(16, 0, 0, 2, 0, 0, 0);
DtReal initialHeading = 0.0;
targetPoint = myCgf->localObjectManager()->createAndInitVrfObject(
true,
"Attack Point",
DtString::nullString(),
initialPosition,
0,
false,
false,
DtAppearance::nullAppearance(),
"local-vrf-object");
}
}
if (targetPoint && attackRoute.
isValid())
{
attackAirbase.
setValue(
"ingressRoute", attackRoute->
uuid());
}
globalPlanBuilder.addStatement(issuePlan);
myCgf->globalPlanManager()->addOrUpdatePlan(globalPlanBuilder.planCopy());
}
virtual void createResourcePlan(
const DtSimObject* obj)
{
if (myCgf->localObjectManager()->lookup(
DtUUID(
"Example Resource Assignment Plan")))
{
return;
}
std::map<DtString, int> aircraftMap;
aircraftMap["F-16C"] = 12;
setAssignAircraft.
setValue(
"aircraft", aircraftMap);
setAssignAircraft.
setValue(
"setAsCurrent",
false);
globalPlanBuilder.addSetDataCommand(setAssignAircraft, obj->
uuid());
addProperty<DtRwPropertyInt>(modProps, "Initial-Ground-Crew-Size")->setValue(100);
addProperty<DtRwPropertyInt>(modProps, "Initial-Air-Crew-Size")->setValue(100);
setPersonnel.
setProperties(
"Initial-Ground-Crew-Size;Initial-Air-Crew-Size");
globalPlanBuilder.addSetDataCommand(setPersonnel, obj->
uuid());
modProps.clearVariables();
addProperty<DtRwPropertyInt>(modProps, "Munitions")->setValue(1000);
addProperty<DtRwPropertyReal>(modProps, "Aviation-Fuel")->setValue(1000000);
globalPlanBuilder.addSetDataCommand(setSupplies, obj->
uuid());
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);
addProperty<DtRwPropertyReal>(prototype, "Length");
addProperty<DtRwPropertyReal>(prototype, "Width");
addProperty<DtRwPropertyReal>(prototype, "Main-Direction");
addProperty<DtRwPropertyReal>(prototype, "Usable-Length");
std::map<DtRwString, DtRwPropertiesStructure> runwaysToAssign;
key = "Test Runway";
runwaysToAssign[key] = prototype;
setFacilities.
setProperties(
"Runways;Has-Night-Support;ORP-Aircraft-Capacity;Apron-Aircraft-Capacity;Repair-Hangar-Aircraft-Capacity;Aviation-Fuel-Capacity;Munition-Storage-Capacity;Barracks-Capacity");
globalPlanBuilder.addSetDataCommand(setFacilities, obj->
uuid());
myCgf->globalPlanManager()->addOrUpdatePlan(globalPlanBuilder.planCopy());
}
{
createFlightTask.
setValue(
"Loadout",
"Intercept");
createFlightTask.
setValue(
"CallSign",
"EscortExample");
createFlightTask.
setValue(
"AircraftUnitType", DtEntityType(11, 2, 225, 35, 1, 9, 10));
createFlightTask.
setValue(
"WaitForLaunch",
true);
globalPlanBuilder.addStatement(createFlightTask);
{
std::vector<DtUUID> zones;
zones.push_back(zone->
uuid());
setEngagementZone.
setValue(
"engagementZones", zones);
}
escortFlightTask.
setValue(
"LocationToMeet", waypoint->
uuid());
escortFlightTask.
setValue(
"UnitToEscort",
DtUUID(
"AttackExample", 0,
true));
globalPlanBuilder.addStatement(issuePlan);
myCgf->globalPlanManager()->addOrUpdatePlan(globalPlanBuilder.planCopy());
}
{
{
DtWarn << "Could not find object named " << parameters << std::endl;
return true;
}
{
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
{
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:
};
{
public:
DtPrintAirbaseCommand(
DtCgf* c) : myCgf(c) {};
virtual ~DtPrintAirbaseCommand() {};
{
{
DtWarn << "Could not find object named " << parameters << std::endl;
return true;
}
else
{
const DtRwPropertiesMap* runways = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(),
"Runways");
if (!runways)
{
DtWarn << parameters << " is not an airbase.\n";
return true;
}
std::vector<DtReaderWriterRegistryData *>::const_iterator iter =
std::vector<DtReaderWriterRegistryData *>::const_iterator endIter =
DtWarn << "Runways:\n";
while (iter != endIter)
{
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:
};
{
public:
DtPrintStatusCommand(
DtCgf* c) : myCgf(c) {};
virtual ~DtPrintStatusCommand() {};
{
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;
}
}
}
else
{
DtWarn << " No " << val << "\n";
}
}
{
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 DtRwInt* count = findProperty<DtRwInt>(*ammoItemRw,
"Count");
const DtRwString* type = findProperty<DtRwString>(*ammoItemRw,
"Type");
if (count && type)
{
DtWarn << " Ammunition: " << *type << " has " << *count << " units remaining.\n";
}
}
}
else
{
DtWarn << " No Ammunition\n";
}
}
virtual void printPrimaryEquipment(
const DtSimObject* obj)
{
const DtRwPropertiesStructure* currentStructure = findProperty<DtRwPropertiesStructure>(vrfSimulatedSimObjectFacade.stateProperties(),
"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";
}
}
else
{
DtWarn << " No Primary Equipment\n";
}
}
{
const DtRwPropertiesMap* equipment = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(),
"Equipment");
const DtRwPropertiesMap* baseLoadoutEquipment = findProperty<DtRwPropertiesMap>(vrfSimulatedSimObjectFacade.stateProperties(),
"Base-Loadout-Equipment");
if (equipment && baseEquipment && baseLoadoutEquipment)
{
DtWarn << " Equipment: " << std::endl;
std::vector<DtReaderWriterRegistryData *>::const_iterator iter = equipment->
registry().
registryData().begin();
std::vector<DtReaderWriterRegistryData *>::const_iterator end = equipment->
registry().
registryData().end();
while (iter != end)
{
boost::optional<int> currCount = findPropertyValue<int>(*currEquip, "Count");
boost::optional<int> baseCount;
boost::optional<int> baseLoadoutCount;
if (currCount)
{
const DtRwPropertiesStructure* baseEquip = findMapItem<DtRwPropertiesStructure>(*baseEquipment, currEquip->name().c_str());
if (baseEquip)
{
baseCount = findPropertyValue<int>(*baseEquip, "Count");
}
const DtRwPropertiesStructure* baseLoadoutEquip = findMapItem<DtRwPropertiesStructure>(*baseLoadoutEquipment, currEquip->name().c_str());
if (baseLoadoutEquip)
{
baseLoadoutCount = findPropertyValue<int>(*baseLoadoutEquip, "Count");
}
int totalBaseCount = 0;
if (baseCount)
{
totalBaseCount += *baseCount;
}
if (baseLoadoutCount)
{
totalBaseCount += *baseLoadoutCount;
}
DtWarn << " " << currEquip->name() << ": " << *currCount << " out of " << totalBaseCount << std::endl;
}
++iter;
}
}
else
{
DtWarn << " No Equipment\n";
}
}
virtual void printEngagementHistory(
const DtSimObject* 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)
{
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)
{
{
}
if (*isAttack)
{
DtWarn << " Fired at " << enemyName << " with " << *weaponType << "." << std::endl;
DtWarn << " Hit Factor: " << *hitFactor << std::endl;
}
else
{
DtWarn << " Shot at by " << enemyName << " with " << *weaponType << ". ";
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)
{
boost::optional<DtString> detailText = getPropertyValue<DtString>(detailEvent);
DtWarn << " " << *detailText << std::endl;
}
}
}
++iter;
}
}
else
{
DtWarn << " No Engagement History\n";
}
}
{
if (parameters == "ALL")
{
while (iter != end)
{
const DtRwInt* health = findProperty<DtRwInt>(vrfSimulatedSimObjectFacade.stateProperties(),
"Health");
if (health)
{
printStatus(*iter);
DtWarn << std::endl;
}
++iter;
}
}
else
{
{
DtWarn << "Could not find object named " << parameters << std::endl;
return true;
}
else
{
printStatus(obj);
}
}
return true;
}
{
DtWarn <<
"Current status for " << obj->
markingText() << std::endl;
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:
};
{
public:
virtual ~DtHelpDisplayCommand() {};
{
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;
{
return true;
}
{
delete theHelpDisplayCommand;
theHelpDisplayCommand = nullptr;
delete thePrintAirbaseCommand;
thePrintAirbaseCommand = nullptr;
delete thePrintStatusCommand;
thePrintStatusCommand = nullptr;
delete theStartMovementMissionCommand;
theStartMovementMissionCommand = nullptr;
delete theStartEscortMissionCommand;
theStartEscortMissionCommand = nullptr;
}
{
theHelpDisplayCommand = new DtHelpDisplayCommand;
thePrintAirbaseCommand = new DtPrintAirbaseCommand(cgf);
thePrintStatusCommand = new DtPrintStatusCommand(cgf);
theStartMovementMissionCommand = new DtStartMovementMissionCommand(cgf);
theStartEscortMissionCommand = new DtStartEscortMissionCommand(cgf);
theHelpDisplayCommand);
thePrintAirbaseCommand);
thePrintStatusCommand);
theStartMovementMissionCommand);
theStartEscortMissionCommand);
}
}