45
49
#include "AIGroundVehicle.hxx"
46
50
#include "AIEscort.hxx"
52
class FGAIManager::Scenario
55
Scenario(FGAIManager* man, const std::string& nm, SGPropertyNode* scenarios) :
58
BOOST_FOREACH(SGPropertyNode* scEntry, scenarios->getChildren("entry")) {
59
FGAIBasePtr ai = man->addObject(scEntry);
61
_objects.push_back(ai);
63
} // of scenario entry iteration
65
SGPropertyNode* nasalScripts = scenarios->getChild("nasal");
70
_unloadScript = nasalScripts->getStringValue("unload");
71
std::string loadScript = nasalScripts->getStringValue("load");
72
if (!loadScript.empty()) {
73
FGNasalSys* nasalSys = (FGNasalSys*) globals->get_subsystem("nasal");
74
std::string moduleName = "scenario_" + _internalName;
75
nasalSys->createModule(moduleName.c_str(), moduleName.c_str(),
76
loadScript.c_str(), loadScript.size(),
83
BOOST_FOREACH(FGAIBasePtr ai, _objects) {
87
FGNasalSys* nasalSys = (FGNasalSys*) globals->get_subsystem("nasal");
91
std::string moduleName = "scenario_" + _internalName;
92
if (!_unloadScript.empty()) {
93
nasalSys->createModule(moduleName.c_str(), moduleName.c_str(),
94
_unloadScript.c_str(), _unloadScript.size(),
98
nasalSys->deleteModule(moduleName.c_str());
101
std::vector<FGAIBasePtr> _objects;
102
std::string _internalName;
103
std::string _unloadScript;
106
///////////////////////////////////////////////////////////////////////////////
48
108
FGAIManager::FGAIManager() :
49
109
cb_ai_bare(SGPropertyChangeCallback<FGAIManager>(this,&FGAIManager::updateLOD,
50
110
fgGetNode("/sim/rendering/static-lod/ai-bare", true))),
69
129
wind_from_east_node = fgGetNode("/environment/wind-from-east-fps",true);
70
130
wind_from_north_node = fgGetNode("/environment/wind-from-north-fps",true);
72
user_latitude_node = fgGetNode("/position/latitude-deg", true);
73
user_longitude_node = fgGetNode("/position/longitude-deg", true);
74
user_altitude_node = fgGetNode("/position/altitude-ft", true);
75
132
user_altitude_agl_node = fgGetNode("/position/altitude-agl-ft", true);
76
user_heading_node = fgGetNode("/orientation/heading-deg", true);
77
user_pitch_node = fgGetNode("/orientation/pitch-deg", true);
78
user_yaw_node = fgGetNode("/orientation/side-slip-deg", true);
79
user_roll_node = fgGetNode("/orientation/roll-deg", true);
80
133
user_speed_node = fgGetNode("/velocities/uBody-fps", true);
135
globals->get_commands()->addCommand("load-scenario", this, &FGAIManager::loadScenarioCommand);
136
globals->get_commands()->addCommand("unload-scenario", this, &FGAIManager::unloadScenarioCommand);
84
FGAIManager::postinit() {
140
FGAIManager::postinit()
85
142
// postinit, so that it can access the Nasal subsystem
87
if (!root->getBoolValue("scenarios-enabled", true))
90
144
// scenarios enabled, AI subsystem required
91
145
if (!enabled->getBoolValue())
92
146
enabled->setBoolValue(true);
94
148
// process all scenarios
95
std::map<string, bool> scenarios;
96
for (int i = 0 ; i < root->nChildren() ; i++) {
97
SGPropertyNode *n = root->getChild(i);
98
if (strcmp(n->getName(), "scenario"))
149
BOOST_FOREACH(SGPropertyNode* n, root->getChildren("scenario")) {
101
150
const string& name = n->getStringValue();
102
151
if (name.empty())
105
if (scenarios.find(name) != scenarios.end()) {
106
SG_LOG(SG_AI, SG_DEBUG, "won't load scenario '" << name << "' twice");
154
if (_scenarios.find(name) != _scenarios.end()) {
155
SG_LOG(SG_AI, SG_WARN, "won't load scenario '" << name << "' twice");
110
SG_LOG(SG_AI, SG_ALERT, "loading scenario '" << name << '\'');
111
processScenario(name);
112
scenarios[name] = true;
159
SG_LOG(SG_AI, SG_INFO, "loading scenario '" << name << '\'');
117
165
FGAIManager::reinit()
167
// shutdown scenarios
168
unloadAllScenarios();
120
171
std::for_each(ai_list.begin(), ai_list.end(), boost::mem_fn(&FGAIBase::reinit));
173
// (re-)load scenarios
178
FGAIManager::shutdown()
180
unloadAllScenarios();
182
BOOST_FOREACH(FGAIBase* ai, ai_list) {
188
globals->get_commands()->removeCommand("load-scenario");
189
globals->get_commands()->removeCommand("unload-scenario");
330
bool FGAIManager::loadScenarioCommand(const SGPropertyNode* args)
332
std::string name = args->getStringValue("name");
333
if (args->hasChild("load-property")) {
334
// slightly ugly, to simplify life in the dialogs, make load allow
335
// loading or unloading based on a bool property.
336
bool loadIt = fgGetBool(args->getStringValue("load-property"));
338
// user actually wants to unload, fine.
339
return unloadScenario(name);
343
if (_scenarios.find(name) != _scenarios.end()) {
344
SG_LOG(SG_AI, SG_WARN, "scenario '" << name << "' already loaded");
348
bool ok = loadScenario(name);
350
// create /sim/ai node for consistency
352
for (; root->hasChild("scenario", index); ++index) {}
354
SGPropertyNode* scenarioNode = root->getChild("scenario", index, true);
355
scenarioNode->setStringValue(name);
361
bool FGAIManager::unloadScenarioCommand(const SGPropertyNode* args)
363
std::string name = args->getStringValue("name");
364
return unloadScenario(name);
367
bool FGAIManager::addObjectCommand(const SGPropertyNode* definition)
369
addObject(definition);
373
FGAIBasePtr FGAIManager::addObject(const SGPropertyNode* definition)
375
const std::string& type = definition->getStringValue("type", "aircraft");
378
if (type == "tanker") { // refueling scenarios
380
} else if (type == "wingman") {
381
ai = new FGAIWingman;
382
} else if (type == "aircraft") {
383
ai = new FGAIAircraft;
384
} else if (type == "ship") {
386
} else if (type == "carrier") {
387
ai = new FGAICarrier;
388
} else if (type == "groundvehicle") {
389
ai = new FGAIGroundVehicle;
390
} else if (type == "escort") {
392
} else if (type == "thunderstorm") {
394
} else if (type == "thermal") {
395
ai = new FGAIThermal;
396
} else if (type == "ballistic") {
397
ai = new FGAIBallistic;
398
} else if (type == "static") {
402
ai->readFromScenario(const_cast<SGPropertyNode*>(definition));
407
bool FGAIManager::removeObject(const SGPropertyNode* args)
409
int id = args->getIntValue("id");
410
BOOST_FOREACH(FGAIBase* ai, get_ai_list()) {
411
if (ai->getID() == id) {
420
FGAIBasePtr FGAIManager::getObjectFromProperty(const SGPropertyNode* aProp) const
422
BOOST_FOREACH(FGAIBase* ai, get_ai_list()) {
423
if (ai->_getProps() == aProp) {
426
} // of AI objects iteration
432
FGAIManager::loadScenario( const string &filename )
434
SGPropertyNode_ptr file = loadScenarioFile(filename);
439
SGPropertyNode_ptr scNode = file->getChild("scenario");
444
_scenarios[filename] = new Scenario(this, filename, scNode);
450
FGAIManager::unloadScenario( const string &filename)
452
ScenarioDict::iterator it = _scenarios.find(filename);
453
if (it == _scenarios.end()) {
454
SG_LOG(SG_AI, SG_WARN, "unload scenario: not found:" << filename);
458
// remove /sim/ai node
459
unsigned int index = 0;
460
for (SGPropertyNode* n = NULL; (n = root->getChild("scenario", index)) != NULL; ++index) {
461
if (n->getStringValue() == filename) {
462
root->removeChild("scenario", index);
468
_scenarios.erase(it);
262
FGAIManager::processScenario( const string &filename ) {
264
SGPropertyNode_ptr scenarioTop = loadScenarioFile(filename);
269
SGPropertyNode* scenarios = scenarioTop->getChild("scenario");
274
for (int i = 0; i < scenarios->nChildren(); i++) {
275
SGPropertyNode* scEntry = scenarios->getChild(i);
277
if (strcmp(scEntry->getName(), "entry"))
279
const std::string& type = scEntry->getStringValue("type", "aircraft");
281
if (type == "tanker") { // refueling scenarios
282
FGAITanker* tanker = new FGAITanker;
283
tanker->readFromScenario(scEntry);
286
} else if (type == "wingman") {
287
FGAIWingman* wingman = new FGAIWingman;
288
wingman->readFromScenario(scEntry);
291
} else if (type == "aircraft") {
292
FGAIAircraft* aircraft = new FGAIAircraft;
293
aircraft->readFromScenario(scEntry);
296
} else if (type == "ship") {
297
FGAIShip* ship = new FGAIShip;
298
ship->readFromScenario(scEntry);
301
} else if (type == "carrier") {
302
FGAICarrier* carrier = new FGAICarrier;
303
carrier->readFromScenario(scEntry);
306
} else if (type == "groundvehicle") {
307
FGAIGroundVehicle* groundvehicle = new FGAIGroundVehicle;
308
groundvehicle->readFromScenario(scEntry);
309
attach(groundvehicle);
311
} else if (type == "escort") {
312
FGAIEscort* escort = new FGAIEscort;
313
escort->readFromScenario(scEntry);
316
} else if (type == "thunderstorm") {
317
FGAIStorm* storm = new FGAIStorm;
318
storm->readFromScenario(scEntry);
321
} else if (type == "thermal") {
322
FGAIThermal* thermal = new FGAIThermal;
323
thermal->readFromScenario(scEntry);
326
} else if (type == "ballistic") {
327
FGAIBallistic* ballistic = new FGAIBallistic;
328
ballistic->readFromScenario(scEntry);
331
} else if (type == "static") {
332
FGAIStatic* aistatic = new FGAIStatic;
333
aistatic->readFromScenario(scEntry);
473
FGAIManager::unloadAllScenarios()
475
ScenarioDict::iterator it = _scenarios.begin();
476
for (; it != _scenarios.end(); ++it) {
478
} // of scenarios iteration
481
// remove /sim/ai node
482
root->removeChildren("scenario");
341
487
SGPropertyNode_ptr
342
488
FGAIManager::loadScenarioFile(const std::string& filename)