flightgear-addon-aerotow-ev.../nasal/scenario.nas
2022-11-09 18:27:53 +01:00

184 lines
5.2 KiB
Plaintext

#
# Aerotow Everywhere - Add-on for FlightGear
#
# Written and developer by Roman Ludwicki (PlayeRom, SP-ROM)
#
# Copyright (C) 2022 Roman Ludwicki
#
# Aerotow Everywhere is an Open Source project and it is licensed
# under the GNU Public License v3 (GPLv3)
#
#
# Class Scenario for create AI scenario XML file and attach it to scenario property list for load it.
#
var Scenario = {
#
# Constants
#
SCENARIO_ID: "aerotow_addon",
SCENARIO_NAME: "Aerotow Add-on",
SCENARIO_DESC: "This scenario starts the towing plane at the airport where the pilot with the glider is located. Use Ctrl-o to hook the plane.",
FILENAME_SCENARIO: "aerotown-addon.xml",
#
# Constructor
#
# addon - Addon object
# message - Message object
#
new: func (addon, message) {
var obj = { parents: [Scenario] };
obj.addon = addon;
obj.message = message;
obj.addonNodePath = addon.node.getPath();
obj.listeners = [];
obj.routeDialog = RouteDialog.new(addon, message);
obj.flightPlan = FlightPlan.new(addon, message, obj.routeDialog);
obj.isScenarioLoaded = false;
obj.scenarioPath = addon.storagePath ~ "/" ~ Scenario.FILENAME_SCENARIO;
obj.flightPlan.initial();
append(obj.listeners, setlistener("/sim/presets/longitude-deg", func () {
# User change airport/runway
obj.flightPlan.initial();
}));
return obj;
},
#
# Destructor
#
del: func () {
me.routeDialog.del();
me.flightPlan.del();
foreach (var listener; me.listeners) {
removelistener(listener);
}
},
#
# Generate the XML file with the AI scenario.
# The file will be stored to $FG_HOME/Export/Addons/org.flightgear.addons.Aerotow/aerotown-addon.xml.
#
# Return true on successful, otherwise false
#
generateXml: func () {
if (!me.flightPlan.generateXml()) {
return false;
}
var scenarioXml = {
"PropertyList": {
"scenario": {
"name": Scenario.SCENARIO_NAME,
"description": Scenario.SCENARIO_DESC,
"entry": {
"callsign": "FG-TOW",
"type": "aircraft",
"class": "aerotow-dragger",
"model": Aircraft.getSelected(me.addon).modelPath,
"flightplan": FlightPlan.FILENAME_FLIGHTPLAN,
"repeat": true, # start again indefinitely, it will work if the aircraft stops on the ground
}
}
}
};
var node = props.Node.new(scenarioXml);
io.writexml(me.scenarioPath, node);
me.addScenarioToPropertyList();
return true;
},
#
# Add our new scenario to the "/sim/ai/scenarios" property list
# so that FlightGear will be able to load it by "load-scenario" command.
#
addScenarioToPropertyList: func () {
if (!me.isAlreadyAdded()) {
var scenarioData = {
"name": Scenario.SCENARIO_NAME,
"id": Scenario.SCENARIO_ID,
"description": Scenario.SCENARIO_DESC,
"path": me.scenarioPath,
};
props.globals.getNode("/sim/ai/scenarios").addChild("scenario").setValues(scenarioData);
}
},
#
# Return true if scenario is already added to "/sim/ai/scenarios" property list, otherwise return false.
#
isAlreadyAdded: func () {
foreach (var scenario; props.globals.getNode("/sim/ai/scenarios").getChildren("scenario")) {
var id = scenario.getChild("id");
if (id != nil and id.getValue() == Scenario.SCENARIO_ID) {
return true;
}
}
return false;
},
#
# Load scenario
#
# Return true on successful, otherwise false.
#
load: func () {
var args = props.Node.new({ "name": Scenario.SCENARIO_ID });
if (fgcommand("load-scenario", args)) {
me.isScenarioLoaded = true;
me.message.success("Let's fly!");
# Enable engine sound
setprop(me.addonNodePath ~ "/addon-devel/sound/enable", true);
return true;
}
me.message.error("Tow failed!");
return false;
},
#
# Unload scenario
#
# withMessages - Set true to display messages.
#
# Return true on successful, otherwise false.
#
unload: func (withMessages = 0) {
if (me.isScenarioLoaded) {
var args = props.Node.new({ "name": Scenario.SCENARIO_ID });
if (fgcommand("unload-scenario", args)) {
me.isScenarioLoaded = false;
if (withMessages) {
me.message.success("Aerotown disabled");
}
return true;
}
if (withMessages) {
me.message.error("Aerotown disable failed");
}
return false;
}
if (withMessages) {
me.message.success("Aerotown already disabled");
}
return true;
},
};