multiplayer.model: more containers, more data, variable renaming,
temporarily catching error exceptions, colored missing-ac message ...
This commit is contained in:
parent
6feca1bda5
commit
540b9368fe
2 changed files with 53 additions and 37 deletions
|
@ -250,7 +250,7 @@ var dialog = {
|
||||||
var w = content.addChild("text");
|
var w = content.addChild("text");
|
||||||
w.node.setValues(column);
|
w.node.setValues(column);
|
||||||
var p = typeof(column.property) == "func" ? column.property() : column.property;
|
var p = typeof(column.property) == "func" ? column.property() : column.property;
|
||||||
w.node.setValues({row: row, col: col, live: 1, property: mp.path ~ "/" ~ p});
|
w.node.setValues({row: row, col: col, live: 1, property: mp.root ~ "/" ~ p});
|
||||||
w.setColor(me.fg[odd][0], me.fg[odd][1], me.fg[odd][2], me.fg[odd][3]);
|
w.setColor(me.fg[odd][0], me.fg[odd][1], me.fg[odd][2], me.fg[odd][3]);
|
||||||
col += 1;
|
col += 1;
|
||||||
}
|
}
|
||||||
|
@ -267,10 +267,13 @@ var dialog = {
|
||||||
foreach (var mp; model.list) {
|
foreach (var mp; model.list) {
|
||||||
var n = mp.node;
|
var n = mp.node;
|
||||||
var ac = geo.Coord.new().set_xyz(
|
var ac = geo.Coord.new().set_xyz(
|
||||||
n.getNode("position/global-x").getValue() or 0,
|
n.getNode("position/global-x").getValue(),
|
||||||
n.getNode("position/global-y").getValue() or 0,
|
n.getNode("position/global-y").getValue(),
|
||||||
n.getNode("position/global-z").getValue() or 0);
|
n.getNode("position/global-z").getValue());
|
||||||
var distance = self.distance_to(ac);
|
var distance = nil;
|
||||||
|
call(func distance = self.distance_to(ac), nil, var err = []);
|
||||||
|
if (size(err))
|
||||||
|
debug.dump(self, ac);
|
||||||
|
|
||||||
n.setValues({
|
n.setValues({
|
||||||
"model-short": mp.available ? mp.model : "??? " ~ mp.model,
|
"model-short": mp.available ? mp.model : "??? " ~ mp.model,
|
||||||
|
@ -334,23 +337,32 @@ var dialog = {
|
||||||
|
|
||||||
|
|
||||||
# Autonomous singleton class that monitors multiplayer aircraft,
|
# Autonomous singleton class that monitors multiplayer aircraft,
|
||||||
# maintains a data hash and a list (sorted by callsign), and raises
|
# maintains data in various structures, and raises signal
|
||||||
# signal "/sim/signals/multiplayer-updated" whenever an aircraft
|
# "/sim/signals/multiplayer-updated" whenever an aircraft
|
||||||
# joined or left. Both multiplayer.model.data and multiplayer.model.list
|
# joined or left. Available data containers are:
|
||||||
# contain hash entries of this form:
|
#
|
||||||
|
# multiplayer.model.data: hash, key := /ai/models/* path
|
||||||
|
# multiplayer.model.callsign hash, key := callsign
|
||||||
|
# multiplayer.model.list vector, sorted alphabetically (ASCII, case insensitive)
|
||||||
|
# multiplayer.model.available unsorted list of players with available models
|
||||||
|
# multiplayer.model.unavailable unsorted list of players with unavailable models
|
||||||
|
#
|
||||||
|
# All of them contain hash entries of this form:
|
||||||
#
|
#
|
||||||
# {
|
# {
|
||||||
# callsign: "bimaus",
|
# callsign: "BiMaus",
|
||||||
# model: "bo105", # model name without suffixes (xml, ac, -anim, -model)
|
# path: "Aircraft/bo105/Models/bo105.xml", # relative file path
|
||||||
# node: {...}, # node as props.Node hash
|
# root: "/ai/models/multiplayer[4]", # root property
|
||||||
# path: "/ai/models/multiplayer[4]",
|
# node: {...}, # root property as props.Node hash
|
||||||
|
# model: "bo105", # model name (extracted from path)
|
||||||
|
# available: 2, # whether the model is installed (0: not inst, 1: AI, 2: regular)
|
||||||
|
# sort: "bimaus", # callsign in lower case (for sorting)
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
#
|
|
||||||
var model = {
|
var model = {
|
||||||
init: func {
|
init: func {
|
||||||
me.L = [];
|
me.L = [];
|
||||||
me.list = [];
|
me.warned = {};
|
||||||
append(me.L, setlistener("ai/models/model-added", func(n) me.update(n.getValue())));
|
append(me.L, setlistener("ai/models/model-added", func(n) me.update(n.getValue())));
|
||||||
append(me.L, setlistener("ai/models/model-removed", func(n) me.update(n.getValue())));
|
append(me.L, setlistener("ai/models/model-removed", func(n) me.update(n.getValue())));
|
||||||
me.update();
|
me.update();
|
||||||
|
@ -361,7 +373,10 @@ var model = {
|
||||||
|
|
||||||
me.data = {};
|
me.data = {};
|
||||||
me.callsign = {};
|
me.callsign = {};
|
||||||
var root = string.normpath(getprop("/sim/fg-root")) ~ '/';
|
me.available = [];
|
||||||
|
me.unavailable = [];
|
||||||
|
|
||||||
|
var fg_root = string.normpath(getprop("/sim/fg-root")) ~ '/';
|
||||||
foreach (var n; props.globals.getNode("ai/models", 1).getChildren("multiplayer")) {
|
foreach (var n; props.globals.getNode("ai/models", 1).getChildren("multiplayer")) {
|
||||||
if (!n.getNode("valid", 1).getValue())
|
if (!n.getNode("valid", 1).getValue())
|
||||||
continue;
|
continue;
|
||||||
|
@ -369,25 +384,26 @@ var model = {
|
||||||
if ((var callsign = n.getNode("callsign")) == nil or !(callsign = callsign.getValue()))
|
if ((var callsign = n.getNode("callsign")) == nil or !(callsign = callsign.getValue()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var model = n.getNode("sim/model/path").getValue();
|
var path = n.getNode("sim/model/path").getValue();
|
||||||
var available = 0;
|
var available = 0;
|
||||||
if (io.stat(string.normpath(root ~ "AI/" ~ model)) != nil)
|
if (io.stat(string.normpath(fg_root ~ "AI/" ~ path)) != nil)
|
||||||
available = 1;
|
available = 1;
|
||||||
elsif (io.stat(string.normpath(root ~ model)) != nil)
|
elsif (io.stat(string.normpath(fg_root ~ path)) != nil)
|
||||||
available = 2;
|
available = 2;
|
||||||
else
|
elsif (!contains(me.warned, path))
|
||||||
print("Multiplayer model not available: ", model);
|
me.warned[path] = print(debug._error("=== MP model not installed: " ~ path));
|
||||||
|
|
||||||
model = split(".", split("/", model)[-1])[0];
|
var model = split(".", split("/", path)[-1])[0];
|
||||||
model = me.remove_suffix(model, "-model");
|
model = me.remove_suffix(model, "-model");
|
||||||
model = me.remove_suffix(model, "-anim");
|
model = me.remove_suffix(model, "-anim");
|
||||||
|
|
||||||
var path = n.getPath();
|
var root = n.getPath();
|
||||||
var data = { node: n, callsign: callsign, model: model, path: path,
|
var data = { node: n, callsign: callsign, model: model, root: root,
|
||||||
sort: string.lc(callsign), available: available };
|
sort: string.lc(callsign), available: available };
|
||||||
|
|
||||||
me.data[path] = data;
|
me.data[root] = data;
|
||||||
me.callsign[callsign] = data;
|
me.callsign[callsign] = data;
|
||||||
|
append(available ? me.available : me.unavailable, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
me.list = sort(keys(me.data), func(a, b) cmp(me.data[a].sort, me.data[b].sort));
|
me.list = sort(keys(me.data), func(a, b) cmp(me.data[a].sort, me.data[b].sort));
|
||||||
|
|
|
@ -360,13 +360,13 @@ var model_view_handler = {
|
||||||
},
|
},
|
||||||
_update_: func {
|
_update_: func {
|
||||||
var self = { callsign: getprop("/sim/multiplay/callsign"), model:,
|
var self = { callsign: getprop("/sim/multiplay/callsign"), model:,
|
||||||
node: props.globals, path: '/' };
|
node: props.globals, root: '/' };
|
||||||
me.list = [self] ~ multiplayer.model.list;
|
me.list = [self] ~ multiplayer.model.list;
|
||||||
if (!me.find(me.current))
|
if (!me.find(me.current))
|
||||||
me.select(0);
|
me.select(0);
|
||||||
},
|
},
|
||||||
setup: func(data) {
|
setup: func(data) {
|
||||||
if (data.path == '/') {
|
if (data.root == '/') {
|
||||||
var zoffset = getprop("/sim/chase-distance-m");
|
var zoffset = getprop("/sim/chase-distance-m");
|
||||||
var ident = '[' ~ data.callsign ~ ']';
|
var ident = '[' ~ data.callsign ~ ']';
|
||||||
} else {
|
} else {
|
||||||
|
@ -379,16 +379,16 @@ var model_view_handler = {
|
||||||
setprop("/sim/current-view/z-offset-m", zoffset);
|
setprop("/sim/current-view/z-offset-m", zoffset);
|
||||||
|
|
||||||
me.viewN.getNode("config").setValues({
|
me.viewN.getNode("config").setValues({
|
||||||
"eye-lat-deg-path": data.path ~ "/position/latitude-deg",
|
"eye-lat-deg-path": data.root ~ "/position/latitude-deg",
|
||||||
"eye-lon-deg-path": data.path ~ "/position/longitude-deg",
|
"eye-lon-deg-path": data.root ~ "/position/longitude-deg",
|
||||||
"eye-alt-ft-path": data.path ~ "/position/altitude-ft",
|
"eye-alt-ft-path": data.root ~ "/position/altitude-ft",
|
||||||
"eye-heading-deg-path": data.path ~ "/orientation/heading-deg",
|
"eye-heading-deg-path": data.root ~ "/orientation/heading-deg",
|
||||||
"target-lat-deg-path": data.path ~ "/position/latitude-deg",
|
"target-lat-deg-path": data.root ~ "/position/latitude-deg",
|
||||||
"target-lon-deg-path": data.path ~ "/position/longitude-deg",
|
"target-lon-deg-path": data.root ~ "/position/longitude-deg",
|
||||||
"target-alt-ft-path": data.path ~ "/position/altitude-ft",
|
"target-alt-ft-path": data.root ~ "/position/altitude-ft",
|
||||||
"target-heading-deg-path": data.path ~ "/orientation/heading-deg",
|
"target-heading-deg-path": data.root ~ "/orientation/heading-deg",
|
||||||
"target-pitch-deg-path": data.path ~ "/orientation/pitch-deg",
|
"target-pitch-deg-path": data.root ~ "/orientation/pitch-deg",
|
||||||
"target-roll-deg-path": data.path ~ "/orientation/roll-deg",
|
"target-roll-deg-path": data.root ~ "/orientation/roll-deg",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue