Hello, I have a vehicle lua extension (lua\vehicle\extensions) that counts the total driven distance for every spawned car: Spoiler: LUA Code: local function updateGFX(dt) distancem = electrics.values.wheelspeed * dt distanceTotalm = distancem + distanceTotalm Speed = electrics.values.wheelspeed * 3.6 if Speed > topSpeed then topSpeed = Speed end end local function getVar() state.fuelPercent = electrics.values['fuel'] state.fuelCap = electrics.values['fuelCapacity'] state.fuelVol = electrics.values['fuelVolume'] state.tSpeed = topSpeed state.carModel = v.config.model state.carConfig = v.config.partConfigFilename state.progress = distanceTotalm guihooks.trigger('sendState', state) end In my app.js, the distance is correctly be displayed for the current car (lua variable "distance" is send to app js) Spoiler: JS Code: scope.$on('sendState', function (event, data) { state = data; scope.vehicleModel = data.carModel; scope.vehicleConfig = data.carConfig; scope.tSpeed = Math.round(data.tSpeed * 10) / 10; scope.tSpeed2 = Math.round((data.tSpeed / 1.609344) * 10) / 10; scope.progress = Math.round((data.progress / 1000) * 100) / 100; scope.progress2 = Math.round((data.progress / 1609.3440057765) * 100) / 100; scope.progressEst = Math.round(((scope.fuelVol / scope.fuelLperKM) * 100) * 10) / 10; scope.progressEst2 = Math.round((scope.progressEst / 1.6093440057765) * 10) / 10; scope.fuelPercent = Math.round((data.fuelPercent * 100) * 10) / 10; scope.fuelCap = data.fuelCap; scope.fuelVol = Math.round(data.fuelVol * 100) / 100; scope.fuelLperKM = Math.round((((scope.fuelCap - scope.fuelVol) / scope.progress) * 100) * 10) / 10; scope.fuelMperG = Math.round((235.214583 / scope.fuelLperKM) * 10) / 10; scope.endurancePoints = formatter.format(data.progress / scope.fuelLperKM * (100 - scope.beams.deformed.percentage)); scope.$apply(); }); scope.$on('streamsUpdate', function (event, streams) { scope.$evalAsync(function () { bngApi.activeObjectLua('extensions.separatedistancecounter.getVar()'); if (streams.electrics && streams.engineInfo) { var wheelSpeed = streams.electrics.wheelspeed; prevTime = curTime; curTime = performance.now(); timer -= 0.001 * (curTime - prevTime); if (timer < 0) { totalDistance += ((1.0 - timer) * wheelSpeed); count++; timer = 1; } } }); }); However, I was wondering if there is a way to cycle/loop through all the spawned cars to read & update this value for all of them once, without needing to swap the current vehicle. Basically I'd like to display a ordered list or leaderboard of all the spawned cars. Anyone has a recomendation how to approach this? Write a separate game lua extension and/or can it be done right in the app.js?
So it looks like to me that you need to make a few adjustments. 1. Change Code: bngApi.activeObjectLua('extensions.separatedistancecounter.getVar()'); to Code: bngApi.queueAllObjectLua('extensions.separatedistancecounter.getVar()'); This will call the "separatedistancecounter.getVar()" function of all vehicles, which retrieves the values from all vehicles. 2. Now "scope.$on('sendState', function (event, data)" will be called by all vehicles. So store the values retrieved from this function in an array per vehicle. And note that "streams" data (e.g. streams.electrics.wheelspeed) only comes from the current vehicle, so you want to retrieve them from your Lua file in the "getVar()" function and send them off like you are doing now for other values.
Hey angelo 234, thank you very much, the queueAllObjectLua is exactly what I was looking for. Time to learn more about arrays now. Btw, the streams data is a leftover from trying a few different things last time I was working on my app.
@angelo234 Thanks again for your help, I managed to get an array working in JS and used the car-config as a (sort of) unique identifier/key, if a new car has to be added or just updated in the list. Also had to restructure the code a bit because getting all variables for all cars like fuel related parameters messed up the original HUD display. Now there are 2 separate LUA & JS functions for HUD/leaderboard in the same app. Here's the leaderboard in action:
Did the new update (0.23) change something regarding the queueAllObjectLua function? Seems it's behaving like before where I would only get the value of the currently viewed car and not all of them.
That's really strange, something else must be going on. The only thing I changed (to make it work with the new version) was Code: .directive('distanceDisplay', ['bngApi', 'StreamsManager', 'UiUnits', 'VehicleService', function (bngApi, StreamsManager, UiUnits, VehicleService) { to Code: .directive('distanceDisplay', ['VehicleService', function (VehicleService) { and Code: controller: ['$log', '$scope', 'bngApi', 'StreamsManager', function ($log, $scope, bngApi, StreamsManager) { to Code: controller: ['$log', '$scope', function ($log, $scope) { Once ingame the app sends out a bngApi.queueAllObjectLua('extensions.separatedistancecounter.getAllVar()'); which is Code: local function getAllVar() all.carConfig2 = v.config.partConfigFilename all.progress2 = distanceTotalm guihooks.trigger('sendAllState', all) end After that in the app scope.$on('sendAllState', function (event, data) { is triggered Code: all = data; console.log("State " + JSON.stringify(all)); //leaderboard code Here is where I'd get all the values of all the spawned vehicles before, but now it only passes the distance only for the currently viewed car.
Traffic/vehicle pooling (in gameplay options right?) was off and it doesn't seem to change the app behaviour when enabled. In my previous posted video (link) you can see the "debug" at the bottom and all values updating. Right now it only updates the value of the currently viewed car. For clarification, when I said "it behaves like before" I meant when using activeObjectLua rather than queueAllObjectLua.
Hm you're trying to send data from multiple vehicles to the UI? I don't think that's supported. I just checked queueAllObjectLua and that's working fine.
Yeah it seems like the update now makes it so Code: guihooks.trigger() only works with the current vehicle.
Ahh well, it was fun while it lasted Thanks again both of you for your time and help Triggering this for all vehicles on streamupdate was resource intensive anyway, that's why I had it call every 5 seconds in the end. One thing I also noticed is the saving function for a settings.json (explained here: https://documentation.beamng.com/modding/ui/app_creation/) not working since 0.23 but yeah I think this way is mostly outdated by now. Hopefully there will be more documentation on this topic later on.
Couldn't you just drop a little lua controller into each vehicle that queues distance information to the game engine every half second or so? Then game engine -> ui is easy. Q --- Post updated --- (So yeah full disclosure: I'm a noob and I'm just making this stuff up off the top of my head. I'm about to try doing exactly this tho once my infrastructural lua is set up correctly)
That's a great idea and below is a working solution which literally just makes the Game Engine Lua call the "guihooks.trigger" function Code: local json_data = jsonEncode(data) obj:queueGameEngineLua("guihooks.trigger('sendRadarInfo', '" .. json_data .. "')") The "data" variable is your Lua table/data you want to send to JS. I had to encode "data" into a JSON string in order for it to work. And in the JS, you need to decode the sent JSON string in the called function using: Code: var data = JSON.parse(json_data);