diff --git a/Aircraft/Generic/Formations/formation_1.xml b/Aircraft/Generic/Formations/formation_1.xml
new file mode 100644
index 000000000..2f096a665
--- /dev/null
+++ b/Aircraft/Generic/Formations/formation_1.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ Echelon Stbd
+ 2
+
+ -75
+ 75
+ 0
+
+
+ -150
+ 150
+ 0
+
+
+ -75
+ 75
+ 0
+
+
+
+
+
diff --git a/Aircraft/Generic/Formations/formation_2.xml b/Aircraft/Generic/Formations/formation_2.xml
new file mode 100644
index 000000000..556dddb1a
--- /dev/null
+++ b/Aircraft/Generic/Formations/formation_2.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ Echelon Port
+ 3
+
+ -75
+ -75
+ 0
+
+
+ -150
+ -150
+ 0
+
+
+ -75
+ -75
+ 0
+
+
+
+
+
diff --git a/Aircraft/Generic/Formations/formation_3.xml b/Aircraft/Generic/Formations/formation_3.xml
new file mode 100644
index 000000000..889b6154a
--- /dev/null
+++ b/Aircraft/Generic/Formations/formation_3.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ Diamond
+ 4
+
+ -75
+ -75
+ 0
+
+
+ -75
+ 75
+ 0
+
+
+ -75
+ -75
+ 0
+
+
+
+
+
diff --git a/Aircraft/Generic/Formations/formation_4.xml b/Aircraft/Generic/Formations/formation_4.xml
new file mode 100644
index 000000000..533993a9e
--- /dev/null
+++ b/Aircraft/Generic/Formations/formation_4.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ Finger
+ 5
+
+ -100
+ -100
+ 0
+
+
+ -100
+ 100
+ 0
+
+
+ -100
+ 100
+ 0
+
+
+
+
+
diff --git a/Aircraft/Generic/Formations/formation_5.xml b/Aircraft/Generic/Formations/formation_5.xml
new file mode 100644
index 000000000..b3f50a0cc
--- /dev/null
+++ b/Aircraft/Generic/Formations/formation_5.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ Echelon Stbd Step Up
+ 6
+
+ -75
+ 75
+ 30
+
+
+ -150
+ 150
+ 60
+
+
+ -75
+ 75
+ 30
+
+
+
+
+
diff --git a/Aircraft/Generic/Formations/formation_6.xml b/Aircraft/Generic/Formations/formation_6.xml
new file mode 100644
index 000000000..79ccf949b
--- /dev/null
+++ b/Aircraft/Generic/Formations/formation_6.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ Take Off
+ 7
+
+ -50
+ -50
+ 0
+
+
+ -300
+ 0
+ 0
+
+
+ -50
+ -50
+ 0
+
+
+
+
+
diff --git a/Aircraft/Generic/Formations/formation_7.xml b/Aircraft/Generic/Formations/formation_7.xml
new file mode 100644
index 000000000..ca380bca4
--- /dev/null
+++ b/Aircraft/Generic/Formations/formation_7.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ Carrier Launch
+ 1
+
+ -15
+ -65
+ 0
+
+
+ -200
+ 0
+ 0
+
+
+ -15
+ -63
+ 0
+
+
+
+
+
diff --git a/Aircraft/Generic/Formations/formation_8.xml b/Aircraft/Generic/Formations/formation_8.xml
new file mode 100644
index 000000000..979facff8
--- /dev/null
+++ b/Aircraft/Generic/Formations/formation_8.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ Swan
+ 6
+
+ -225
+ -75
+ 0
+
+
+ -150
+
+ 0
+
+
+ -75
+ 75
+ 0
+
+
+
+
+
diff --git a/Aircraft/Generic/formation.nas b/Aircraft/Generic/formation.nas
new file mode 100644
index 000000000..cc84ebb1b
--- /dev/null
+++ b/Aircraft/Generic/formation.nas
@@ -0,0 +1,96 @@
+#####################################################################################
+# #
+# this script runs the foramation selection utility #
+# #
+#####################################################################################
+
+# ================================ Initalize ======================================
+# Make sure all needed properties are present and accounted
+# for, and that they have sane default values.
+
+
+for(var i = 0; i < 3; i = i + 1){
+ setprop("/sim/model/formation/position[" ~ i ~ "]/x-offset", 0);
+ setprop("/sim/model/formation/position[" ~ i ~ "]/y-offset", 0);
+ setprop("/sim/model/formation/position[" ~ i ~ "]/z-offset", 0);
+}
+
+formation_variant_Node = props.globals.getNode("sim/formation/variant", 1);
+formation_variant_Node.setIntValue(0);
+
+formation_index_Node = props.globals.getNode("sim/formation/index", 1);
+formation_index_Node.setIntValue(0);
+
+tgt_x_offset_Node = props.globals.getNode("ai/models/wingman/position/tgt-x-offset",1);
+tgt_y_offset_Node = props.globals.getNode("ai/models/wingman/position/tgt-y-offset",1);
+tgt_z_offset_Node = props.globals.getNode("ai/models/wingman/position/tgt-z-offset",1);
+tgt_x_offset_1_Node = props.globals.getNode("ai/models/wingman[1]/position/tgt-x-offset",1);
+tgt_y_offset_1_Node = props.globals.getNode("ai/models/wingman[1]/position/tgt-y-offset",1);
+tgt_z_offset_1_Node = props.globals.getNode("ai/models/wingman[1]/position/tgt-z-offset",1);
+tgt_x_offset_2_Node = props.globals.getNode("ai/models/wingman[2]/position/tgt-x-offset",1);
+tgt_y_offset_2_Node = props.globals.getNode("ai/models/wingman[2]/position/tgt-y-offset",1);
+tgt_z_offset_2_Node = props.globals.getNode("ai/models/wingman[2]/position/tgt-z-offset",1);
+
+props.globals.getNode("/sim/model/formation/position/x-offset",1);
+
+var formation_dialog = nil;
+
+initialize = func {
+
+ print("Initializing formation ...");
+
+ # initialise dialogs
+ aircraft.data.add("sim/model/formation/variant");
+ formation_dialog = gui.OverlaySelector.new("Select Formation",
+ "Aircraft/Generic/Formations",
+ "sim/model/formation/variant", nil, func(no) {
+ formation_variant_Node.setIntValue(no);
+ tgt_x_offset_Node.setDoubleValue(getprop("/sim/model/formation/position/x-offset"));
+ tgt_y_offset_Node.setDoubleValue(getprop("/sim/model/formation/position/y-offset"));
+ tgt_z_offset_Node.setDoubleValue(getprop("/sim/model/formation/position/z-offset"));
+ tgt_x_offset_1_Node.setDoubleValue(getprop("/sim/model/formation/position[1]/x-offset"));
+ tgt_y_offset_1_Node.setDoubleValue(getprop("/sim/model/formation/position[1]/y-offset"));
+ tgt_z_offset_1_Node.setDoubleValue(getprop("/sim/model/formation/position[1]/z-offset"));
+ tgt_x_offset_2_Node.setDoubleValue(getprop("/sim/model/formation/position[2]/x-offset"));
+ tgt_y_offset_2_Node.setDoubleValue(getprop("/sim/model/formation/position[2]/y-offset"));
+ tgt_z_offset_2_Node.setDoubleValue(getprop("/sim/model/formation/position[2]/z-offset"));
+ }
+ );
+
+
+ #set listeners
+
+ setlistener("/sim/model/formation/variant", func {
+ print("formation listener: ", getprop("/sim/model/formation/position/x-offset"));
+ if (tgt_x_offset_Node != nil){
+ print("formation listener getting", getprop("/sim/model/formation/position/x-offset"));
+ tgt_x_offset_Node.setDoubleValue(getprop("/sim/model/formation/position/x-offset"));
+ tgt_y_offset_Node.setDoubleValue(getprop("/sim/model/formation/position/y-offset"));
+ tgt_z_offset_Node.setDoubleValue(getprop("/sim/model/formation/position/z-offset"));
+ }
+ if (tgt_x_offset_1_Node != nil){
+ tgt_x_offset_1_Node.setDoubleValue(getprop("/sim/model/formation/position[1]/x-offset"));
+ tgt_y_offset_1_Node.setDoubleValue(getprop("/sim/model/formation/position[1]/y-offset"));
+ tgt_z_offset_1_Node.setDoubleValue(getprop("/sim/model/formation/position[1]/z-offset"));
+ }
+ if (tgt_x_offset_2_Node != nil){
+ tgt_x_offset_2_Node.setDoubleValue(getprop("/sim/model/formation/position[2]/x-offset"));
+ tgt_y_offset_2_Node.setDoubleValue(getprop("/sim/model/formation/position[2]/y-offset"));
+ tgt_z_offset_2_Node.setDoubleValue(getprop("/sim/model/formation/position[2]/z-offset"));
+ }
+ },
+ 0,
+ 1);
+
+} # end func
+
+###
+# ====================== end Initialization ========================================
+###
+
+
+# Fire it up
+
+setlistener("sim/signals/fdm-initialized", initialize);
+
+# end
diff --git a/Effects/water.eff b/Effects/water.eff
index 248950cb6..94a6cff6c 100644
--- a/Effects/water.eff
+++ b/Effects/water.eff
@@ -10,13 +10,6 @@
repeat
normalized
-
- Textures/Water/water-refraction.png
- linear-mipmap-linear
- repeat
- repeat
- normalized
-
Textures/Water/water-normalmap.png
linear-mipmap-linear
@@ -84,16 +77,6 @@
-
- 1
-
-
-
-
-
-
-
-
2
@@ -124,11 +107,6 @@
0
- water_refraction
- sampler-2d
- 1
-
-
water_normalmap
sampler-2d
2
diff --git a/Nasal/contrail.nas b/Nasal/contrail.nas
index 167759324..c9e93572c 100644
--- a/Nasal/contrail.nas
+++ b/Nasal/contrail.nas
@@ -26,8 +26,8 @@ updateContrail = func{
### Contrail
-print ("init contrail");
_setlistener("/sim/signals/nasal-dir-initialized", func {
+ printlog ("debug", "init contrail");
props.globals.initNode("environment/pressure-inhg", 1, "DOUBLE");
props.globals.initNode("environment/temperature-degc", 1, "DOUBLE");
props.globals.initNode("environment/contrail", 1, "BOOL");
diff --git a/Nasal/multiplayer.nas b/Nasal/multiplayer.nas
index f2843b0c6..a47838225 100644
--- a/Nasal/multiplayer.nas
+++ b/Nasal/multiplayer.nas
@@ -178,6 +178,7 @@ var dialog = {
{ type: "checkbox", property: "controls/invisible", callback: "multiplayer.dialog.toggle_ignore",
argprop: "callsign", label: "---------", halign: "right", font: font },
];
+ me.cs_warnings = {};
me.name = "who-is-online";
me.dialog = nil;
me.loopid = 0;
@@ -275,20 +276,29 @@ var dialog = {
var ac = geo.Coord.new().set_xyz(x, y, z);
var distance = nil;
call(func distance = self.distance_to(ac), nil, var err = []);
- if (size(err)) {
- # debug.printerror(err);
- # debug.dump(self, ac, mp);
- # debug.tree(mp.node);
+ if ((size(err))or(distance==nil)) {
+ # Oops, have errors. Bogus position data (and distance==nil).
+ if (me.cs_warnings[mp.callsign]!=1) {
+ # report each callsign once only (avoid cluttering)
+ me.cs_warnings[mp.callsign] = 1;
+ print("Received invalid position data: " ~ debug._error(mp.callsign));
+ }
+ # debug.printerror(err);
+ # debug.dump(self, ac, mp);
+ # debug.tree(mp.node);
+ }
+ else
+ {
+ # Node with valid position data (and "distance!=nil").
+ n.setValues({
+ "model-short": mp.available ? mp.model : "[" ~ mp.model ~ "]",
+ "bearing-to": self.course_to(ac),
+ "distance-to-km": distance / 1000.0,
+ "distance-to-nm": distance * M2NM,
+ "position/altitude-m": n.getNode("position/altitude-ft").getValue() * FT2M,
+ "controls/invisible": contains(ignore, mp.callsign),
+ });
}
-
- n.setValues({
- "model-short": mp.available ? mp.model : "[" ~ mp.model ~ "]",
- "bearing-to": self.course_to(ac),
- "distance-to-km": distance / 1000.0,
- "distance-to-nm": distance * M2NM,
- "position/altitude-m": n.getNode("position/altitude-ft").getValue() * FT2M,
- "controls/invisible": contains(ignore, mp.callsign),
- });
}
if (PILOTSDLG_RUNNING)
settimer(func me.update(id), 1, 1);
diff --git a/Nasal/seaport.nas b/Nasal/seaport.nas
index 5d9cb7fdb..81786fd55 100644
--- a/Nasal/seaport.nas
+++ b/Nasal/seaport.nas
@@ -1,11 +1,13 @@
-_setlistener("/sim/presets/latitude-deg", func {
- print("*** NEW LOCATION ***");
- settimer(func {
- var typ = getprop("/sim/type");
- var lat = getprop("/position/latitude-deg");
- var lon = getprop("/position/longitude-deg");
- var g = geodinfo(lat, lon);
- if ((g != nil and g[1] != nil and g[1].solid) and (typ == "seaplane") )
- fgcommand("dialog-show", props.Node.new({ "dialog-name": "seaport" }));
- }, 8);
-}, 1);
+_setlistener("/sim/signals/nasal-dir-initialized", func {
+ _setlistener("/sim/presets/latitude-deg", func {
+ printlog("info", "*** NEW LOCATION ***");
+ settimer(func {
+ var typ = getprop("/sim/type");
+ var lat = getprop("/position/latitude-deg");
+ var lon = getprop("/position/longitude-deg");
+ var g = geodinfo(lat, lon);
+ if ((g != nil and g[1] != nil and g[1].solid) and (typ == "seaplane") )
+ fgcommand("dialog-show", props.Node.new({ "dialog-name": "seaport" }));
+ }, 8);
+ }, 1);
+});
diff --git a/gui/dialogs/formation.xml b/gui/dialogs/formation.xml
index 6171a11a0..4cf76a276 100644
--- a/gui/dialogs/formation.xml
+++ b/gui/dialogs/formation.xml
@@ -119,32 +119,32 @@
left
-
- 75
- 25
- -180
- 180
- /ai/models/wingman/controls/break-deg-rel
-
- dialog-apply
-
-
- nasal
-
-
-
+
+ 75
+ 25
+ -180
+ 180
+ /ai/models/wingman/controls/break-deg-rel
+
+ dialog-apply
+
+
+ nasal
+
+
+
left
-
+
-
+
@@ -156,15 +156,8 @@
-
-
-
-
-
-
-
hbox
@@ -182,6 +175,26 @@
+
+ hbox
+
+
+ left
+
+
+
+
+
+
+
true
diff --git a/gui/dialogs/location-in-air.xml b/gui/dialogs/location-in-air.xml
index 63e104414..4e2fa953a 100644
--- a/gui/dialogs/location-in-air.xml
+++ b/gui/dialogs/location-in-air.xml
@@ -260,6 +260,8 @@
nasal
+
+
+
+
+
+
+ 6
+
+
+
+ 0
+ 1
+ /sim/current-view/model-cockpit-view
+
+ 1
+ 1
+ 1
+ 1
+
+
+ HELVETICA_14
+
+
+
+
+
diff --git a/gui/dialogs/route-manager.xml b/gui/dialogs/route-manager.xml
index f5449f121..f0ad2d1ca 100644
--- a/gui/dialogs/route-manager.xml
+++ b/gui/dialogs/route-manager.xml
@@ -30,6 +30,8 @@ command interface /autopilot/route-manager/input:
var list = cmdarg().getNode("list");
var cmd = routem.getNode("input", 1);
var route = routem.getNode("route", 1);
+ var dep = routem.getNode("departure", 1);
+ var dest = routem.getNode("destination", 1);
var sel_index = func {
return int(selection.getValue());
@@ -59,8 +61,8 @@ command interface /autopilot/route-manager/input:
cmd.setValue("@delete" ~ sel_index());
}
- var auto_route = func {
- cmd.setValue();
+ var route = func {
+ cmd.setValue("@route" ~ sel_index());
}
var jump_to = func {
@@ -88,10 +90,15 @@ command interface /autopilot/route-manager/input:
var departureRunways = dlg.getNode("departure-runways", 1);
var destRunways = dlg.getNode("destination-runways", 1);
-
+ var sids = dlg.getNode("sids", 1);
+ var stars = dlg.getNode("stars", 1);
+
var updateRunways = func {
- var depIcao = routem.getNode("departure").getNode("airport").getValue();
+ var depIcao = dep.getNode("airport").getValue();
departureRunways.removeChildren("value");
+
+ var currentRunway = dep.getNode("runway").getValue();
+ var foundCurrent = 0;
var apt = airportinfo(depIcao);
if (apt != nil) {
@@ -99,11 +106,20 @@ command interface /autopilot/route-manager/input:
foreach (var rwy; keys(apt.runways)) {
departureRunways.getNode("value[" ~ i ~ "]", 1).setValue(rwy);
i += 1;
+ if (rwy == currentRunway) {
+ foundCurrent = 1;
+ }
}
}
- var destIcao = routem.getNode("destination").getNode("airport").getValue();
+ if (!foundCurrent) {
+ dep.getNode("runway").clearValue();
+ }
+
+ var destIcao = dest.getNode("airport").getValue();
destRunways.removeChildren("value");
+ currentRunway = dest.getNode("runway").getValue();
+ foundCurrent = 0;
var apt = airportinfo(destIcao);
if (apt != nil) {
@@ -111,11 +127,68 @@ command interface /autopilot/route-manager/input:
foreach (var rwy; keys(apt.runways)) {
destRunways.getNode("value[" ~ i ~ "]", 1).setValue(rwy);
i += 1;
+ if (rwy == currentRunway) {
+ foundCurrent = 1;
+ }
}
}
+ if (!foundCurrent) {
+ dest.getNode("runway").clearValue();
+ }
+
+ print("updated runways");
gui.dialog_update("route-manager");
}
+
+ var updateSIDs = func {
+ sids.removeChildren("value");
+ var depIcao = dep.getNode("airport").getValue();
+ var rwy = dep.getNode("runway").getValue();
+ var apt = airportinfo(depIcao);
+ if (apt == nil or apt.runways[rwy] == nil) {
+ dep.getNode("sid").clearValue();
+ gui.dialog_update("route-manager", "sid");
+ return;
+ }
+
+ sids.getNode("value[0]", 1).setValue("(none)");
+ var i=1;
+ foreach (var s; apt.runways[rwy].sids) {
+ sids.getNode("value[" ~ i ~ "]", 1).setValue(s);
+ i += 1;
+ }
+
+ gui.dialog_update("route-manager", "sid");
+ }
+
+ var updateSTARs = func {
+ stars.removeChildren("value");
+ var icao = dest.getNode("airport").getValue();
+ var rwy = dest.getNode("runway").getValue();
+ var apt = airportinfo(icao);
+ if (apt == nil or apt.runways[rwy] == nil) {
+ dest.getNode("star").clearValue();
+ gui.dialog_update("route-manager", "star");
+ return;
+ }
+
+ var i=1;
+ stars.getNode("value[0]", 1).setValue("(none)");
+ foreach (var s; apt.runways[rwy].stars) {
+ stars.getNode("value[" ~ i ~ "]", 1).setValue(s);
+ i += 1;
+ }
+
+ gui.dialog_update("route-manager", "star");
+ }
+
+ # initialise departure values based on current position
+ cmd.setValue("@posinit");
+
+ updateRunways();
+ updateSIDs();
+ updateSTARs();
@@ -189,6 +262,31 @@ command interface /autopilot/route-manager/input:
/autopilot/route-manager/departure/runway
false
/sim/gui/dialogs/route-manager/departure-runways
+
+
+ dialog-apply
+ departure-runway
+
+
+ nasal
+
+
+
+
+
+
+
+
+ sid
+ 100
+ /autopilot/route-manager/departure/sid
+ false
+ /sim/gui/dialogs/route-manager/sids
+
+
+ dialog-apply
+ sid
+
@@ -229,6 +327,32 @@ command interface /autopilot/route-manager/input:
/autopilot/route-manager/destination/runway
false
/sim/gui/dialogs/route-manager/destination-runways
+
+
+ dialog-apply
+ destination-runway
+
+
+
+ nasal
+
+
+
+
+
+
+
+
+ star
+ 100
+ /autopilot/route-manager/destination/star
+ false
+ /sim/gui/dialogs/route-manager/stars
+
+
+ dialog-apply
+ star
+