Page 1 of 1

LUA - Create RP relative to a unit from another side

Posted: Mon Feb 20, 2023 8:58 am
by blu3s
Why can't I assign relative reference points to a unit that is not on my side from lua, but from the game I can?

In the sample scen I have two sides BLUE and _BLUE, _BLUE is omniscient and wanna to create RP around the aircraft. Creating first the RP an then making relatives to the aircraft works as charms, but from Lua I can't.

Reading the docs it even says explicitly that the PR and the unit to which it is relative must be on the same side.
Test RP.zip
(6.88 KiB) Downloaded 23 times

Code: Select all

function getUnit()
	local unit =  ScenEdit_SelectedUnits().units[1]
	return ScenEdit_GetUnit({guid=unit.guid})
end
local unit = getUnit()
local distance = 20
local steps = 20

    for i=0,359,steps do
        local coordinates=World_GetPointFromBearing({latitude=unit.latitude, longitude=unit.longitude, bearing=i, distance=distance})
        local rp = ScenEdit_AddReferencePoint( {side='_BLUE', relativeTo=unit.guid, bearingType=0, latitude=coordinates.latitude, longitude=coordinates.longitude,highlighted=false})
        
    end

Trying to do it as from the game, creating first the area and then making them relative through SetReferencePoint doesn't work either.

Re: LUA - Create RP relative to a unit from another side

Posted: Mon Feb 20, 2023 7:45 pm
by KnightHawk75
I think you can do it in the GUI because, well once you could. Then you couldn't for a long while, then people brought it up and I think gui wise they brought it back. The actual "why" is the lua function code was never changed to add a parameter for what side to search for the unit, at present it uses the side specified in the SE_AddReferencePoint(), or SE_SetReference point() calls for it's RP search, it does not search all sides.

Either we need a relativeto_side parameter in both functions, or the lookup needs to do the own-side first (most common), followed by then searching all the rest of the sides for a guid match. Ideally it would would just accept an additional parameter and use that for the relative-to search for the unit.

In short I agree this does need some developer love. :)

btw if want for future (handles selected unit or selected contact)

Code: Select all

local function getSingleSelectedUnitsOrContactsUnit()
    local s,ug = ScenEdit_SelectedUnits(),nil
    if (s.units ~=nil) and s.units[1] ~=nil and #s.units <=1 then --try units first.
        ug=s.units[1].guid
    elseif (s.contacts ~=nil) and s.contacts[1] ~=nil and #s.contacts <=1 then --try contacts
        -- get contact's underling unit object.
        retval,ct = pcall(VP_GetContact,{guid=s.contacts[1].guid});
        if (retval) and ct ~=nil and ct.actualunitid ~=nil then
            ug = ct.actualunitid; --actual unitguid
        else
            print("failed to get the contact for guid: " .. s.contacts[1].guid .. " this could be known bug in Tiny if base\airbase.");
        end
    else
        print('Please select only one contact or only one unit.')
    end
    if ug ~=nil then
        retval, unit = pcall(ScenEdit_GetUnit,{guid=ug});
        if (retval) and unit ~=nil then return unit; end
    else
        print("selected unit or selected contact could not be obtained.")
    end
    return nil;
end

local function CreateRelativeRefPointsToUnit(rpside,unit,rpnameprefix,distance,stepping)
    if rpside ==nil then print("failed to specifiy a side, call aborted.") return false; end
    if (unit ==nil) or unit.guid ==nil then print("failed to supply a unit wrapper, call aborted.") return false; end
    if (distance==nil) or type(distance) ~="number" then distance = 20; end
    if (stepping ==nil) or type(stepping) ~="number" then stepping = 20; end
    local customname = false;
    if (rpnameprefix==nil) then customname=false; else customname=true;end
    for i=0,359, stepping do
        local coordinates=World_GetPointFromBearing({latitude=unit.latitude, longitude=unit.longitude, bearing=i, distance=distance})
        if customname then
            local retval,rp = pcall(ScenEdit_AddReferencePoint,{side=rpside, name=rpnameprefix .."-"..i, bearingType=0, latitude=coordinates.latitude, longitude=coordinates.longitude,highlighted=false})
            --future build local retval,rp = pcall(ScenEdit_AddReferencePoint,{side=rpside, relativeto=unit.guid,relativeto_side=unit.side,bearingType=0, latitude=coordinates.latitude, longitude=coordinates.longitude,highlighted=false})
        else
            local retval,rp = pcall(ScenEdit_AddReferencePoint,{side=rpside, bearingType=0, latitude=coordinates.latitude, longitude=coordinates.longitude,highlighted=false})
            --future build local retval,rp = pcall(ScenEdit_AddReferencePoint,{side=rpside, relativeto=unit.guid,relativeto_side=unit.side,bearingType=0, latitude=coordinates.latitude, longitude=coordinates.longitude,highlighted=false})
        end
        if not retval then
            print("Failed to create RP: "..  tostring(rp));
        end
    end
end
CreateRelativeRefPointsToUnit("Blue",getSingleSelectedUnitsOrContactsUnit(),"testing");

Re: LUA - Create RP relative to a unit from another side

Posted: Mon Feb 20, 2023 9:27 pm
by blu3s
Thanks KH, yeah it would be great if it will include in the LUA functionality, it could improve the AI by creating zones relative to unfriendly units and be able to play with them for missions, tracking, etc.

In fact my idea is to have a tracking of enemy threat zones on the AI side and based on that it can make decisions, set routes, attack vectors etc.

It is curious how something as simple for the human as to see what is the best position to attack a target by TLAM's and avoid interceptions of the SAMs, the implementation that I have tested to find the best route takes perhaps too long to be viable in LUA.

Re: LUA - Create RP relative to a unit from another side

Posted: Mon Feb 20, 2023 11:57 pm
by KnightHawk75
blu3s wrote: Mon Feb 20, 2023 9:27 pm Thanks KH, yeah it would be great if it will include in the LUA functionality, it could improve the AI by creating zones relative to unfriendly units and be able to play with them for missions, tracking, etc.

In fact my idea is to have a tracking of enemy threat zones on the AI side and based on that it can make decisions, set routes, attack vectors etc.

It is curious how something as simple for the human as to see what is the best position to attack a target by TLAM's and avoid interceptions of the SAMs, the implementation that I have tested to find the best route takes perhaps too long to be viable in LUA.
I know right! :lol:
Yeah sometimes things "you can technically do" ..turn out to not be that practical or introduce too much overhead.

That said if what you built takes too long per-second/minute whatever, you could in theory maybe break up the work or iterations using co-routines, they do work in CMO, or did in 1147.x and Lua 5.3, it's been a year or two since I touch them and haven't tried under "Tiny" or Lua 5.4 yet. I almost never bring that topic up or advise it, because shared lua environment between scenes in a exe session, and no way to know when someone is loading another scene, so that you can ensure proper stopping and cleaning up of your co-routine in such cases. But if you have a private scene where you know to just press a SA button to ensure stopping them before loading another scene etc, they can work well for iteratively doing long running tasks a little chunks per second\at a time. Which may fit pieces of what you may be doing for TLAM pathfinding, or... it may not at all. :shrugs:

Re: LUA - Create RP relative to a unit from another side

Posted: Tue Feb 21, 2023 7:52 am
by blu3s
KnightHawk75 wrote: Mon Feb 20, 2023 11:57 pm
That said if what you built takes too long per-second/minute whatever, you could in theory maybe break up the work or iterations using co-routines, they do work in CMO, or did in 1147.x and Lua 5.3, it's been a year or two since I touch them and haven't tried under "Tiny" or Lua 5.4 yet. I almost never bring that topic up or advise it, because shared lua environment between scenes in a exe session, and no way to know when someone is loading another scene, so that you can ensure proper stopping and cleaning up of your co-routine in such cases. But if you have a private scene where you know to just press a SA button to ensure stopping them before loading another scene etc, they can work well for iteratively doing long running tasks a little chunks per second\at a time. Which may fit pieces of what you may be doing for TLAM pathfinding, or... it may not at all. :shrugs:
Uuuh it sounds very interesting that of the co-routines, I will look for information about it.

An approach that I had thought was that for example in the first hour of the scen, have a regular time every 15 seconds completing, in a time that can be handled by lua, the most intensive tasks such as those that will define the tactics of the AI at the operational level, since the first phases are usually lighter in terms of CPU load.,

To the topic of keeping the same lua session open in different scenarios, I think that a way to avoid this would be to implement somehow a "cleanup" of the lua workspace. I don't really know how lua works internally and I don't know if it could be implemented, it seems that it should be the developers who would have to create a new session each time a scenario is started and I don't know to what extent it is feasible.

Re: LUA - Create RP relative to a unit from another side

Posted: Thu Feb 23, 2023 9:58 pm
by KnightHawk75
blu3s wrote: Tue Feb 21, 2023 7:52 am
Uuuh it sounds very interesting that of the co-routines, I will look for information about it.

An approach that I had thought was that for example in the first hour of the scen, have a regular time every 15 seconds completing, in a time that can be handled by lua, the most intensive tasks such as those that will define the tactics of the AI at the operational level, since the first phases are usually lighter in terms of CPU load.,

To the topic of keeping the same lua session open in different scenarios, I think that a way to avoid this would be to implement somehow a "cleanup" of the lua workspace. I don't really know how lua works internally and I don't know if it could be implemented, it seems that it should be the developers who would have to create a new session each time a scenario is started and I don't know to what extent it is feasible.
On the topic of lua environment, that's how it was way back in CMANO for awhile (wiped out upon each scene) but at some point it changed to shared, I forget the details, MichaelM might be able to shed light but I think it may have some how been causing more problems or leaks than it was deemed worth, and I would say things in lua did seem more stable after the change. A potentially easier thing might be to create a scene_unload event that really just hooks into "started loading another scene" under the hood. and folks could put their clean up code in actions it for it there. Ideally it would run that first...before truly starting to load the next scene (and any exceptions beyond logging them should just be ignored..and proceed with next scene - that way if our lua generates an error...oh well we don't break anything), but just bringing up the load dialogs - just when they actually loaded another. Then again the amount of people who would actually use it, it probably minuscule, or maybe not.

On co-routines an example might be you have something that say idk has to iterate over all units in a scene, or all units of particular types..whatever lets say they're are ~10k to do though. IF doing some expensive operations on any one game-second costs several real seconds for doing 10k, but you could actually live with all 10k only being completed every 10-15-game seconds. Say something like custom pathfinder logic. That's where it would come in handy cause you could still call it every seconds (via resume), but tell the routine to yield say after every 1000 units, and the iterator and state inside the routine can be maintained from call to call (and if needed passed new info from call to call). So instead of taking the hit all at once, you spread it out over time, costing say..idk 100ms per 1000units. Far less noticeable to the player (not that 100ms isn't noticeable..just example) than losing a full second, every game-second.
TLDR: It's basically Lua's version of threads.

http://www.lua.org/manual/5.4/manual.html#2.6
http://www.lua.org/manual/5.4/manual.html#6.2

Re: LUA - Create RP relative to a unit from another side

Posted: Sat Feb 25, 2023 8:12 am
by blu3s
KnightHawk75 wrote: Thu Feb 23, 2023 9:58 pm On co-routines an example might be you have something that say idk has to iterate over all units in a scene, or all units of particular types..whatever lets say they're are ~10k to do though. IF doing some expensive operations on any one game-second costs several real seconds for doing 10k, but you could actually live with all 10k only being completed every 10-15-game seconds. Say something like custom pathfinder logic. That's where it would come in handy cause you could still call it every seconds (via resume), but tell the routine to yield say after every 1000 units, and the iterator and state inside the routine can be maintained from call to call (and if needed passed new info from call to call). So instead of taking the hit all at once, you spread it out over time, costing say..idk 100ms per 1000units. Far less noticeable to the player (not that 100ms isn't noticeable..just example) than losing a full second, every game-second.
TLDR: It's basically Lua's version of threads.

http://www.lua.org/manual/5.4/manual.html#2.6
http://www.lua.org/manual/5.4/manual.html#6.2
Great, thank you very much, I have to look at it slowly because it looks like java threads but no haha.

In fact what takes me so long is a path finder implementation of finding the best position to attack a ground target. I still have to optimize the points that it is testing of an area beyond taking RandomPoints because surely there is a way to search more efficiently.

Have a nice weekend