Jump to content

Recommended Posts

Posted

Gents,

 

i kindly ask for your help again since i am banging my head against walls right now.

 

Here is the problem:


I am writing a script for my squadrons MP Server where we can "winch" some units with helicopters.

Everything is working as intended. I am able to "winch" the units with every "blue" helicopter. The unit to be winched itsef will generate a moving zone around itself.

As soon as one helicopter is inside that zone (and some other parameters for the helicopter are met) a counter starts. As long as the parameters are given (steady hover and so on) the counter will count up to 45 seconds. After that time, the unit shall be destroyed.

 

My big problem right now is, i can't assess that specific unit. After timer counts down, all units from the table will be destroyed. 

 

Is there any specific way to assess that exact unit and further use it (spawn smoke, destroy, etc...)?

Any slight help is highly appreciated!

 

I will attach the lua script (i know, for the lua pros it looks horrible):

 

function checkWinch()
    
    local blueHelos = mist.makeUnitTable({'[blue][helicopter]'}) --get all blue helicopters
          
        for i = 1, #blueHelos do
            if Unit.getByName(blueHelos[i]) then
                local u = Unit.getByName(blueHelos[i])
                if u:getLife() > 0 then
                       
                        mist.flagFunc.units_in_moving_zones     -- check, if some of blue helos are inside moving zone 'a' or 'b'
                            {
                            units           = {blueHelos[i]}, 
                            zone_units      = {'a', 'b'},
                            radius          = 150,
                            flag            = 1001
                            }
                
                        if trigger.misc.getUserFlag(1001) > 0 then
                            
                            -- check if helo is in air
                            hover = false     
                            local unit = Unit.getByName('' ..blueHelos[i])
                            local inAir = unit:inAir()
                            if inAir then hover = true
                                --trigger.action.outText('' .. blueHelos[i] .. ' is in air', 10)
                                else 
                                hover = false
                                --trigger.action.outText('' .. blueHelos[i] .. ' is not in air', 10)
                            end
                            
                            -- check if helos speed is suitable to winch
                            steady = false
                            local unit = UNIT:FindByName('' ..blueHelos[i])
                            local speed = unit:GetVelocityKNOTS()
                            if speed < 1.5 then steady = true
                                --trigger.action.outText('' .. blueHelos[i] .. ' speed zero', 10)
                                else
                                steady = false
                                --trigger.action.outText('' .. blueHelos[i] .. ' speed more than zero', 10)
                            end 
                            
                            -- check if helos height is not too high for the winch
                            height = false
                            local unit = UNIT:FindByName('' ..blueHelos[i])
                            local agl = unit:GetHeight()
                            if agl < 60 then height = true
                                --trigger.action.outText('' .. blueHelos[i] .. ' right height', 10)
                                else
                                height = false
                                --trigger.action.outText('' .. blueHelos[i] .. ' wrong height', 10) 
                            end
                        end
                end
            end
        end
        
        -- check if all 3 reqiurements are met
        if (hover or not hover) and steady and height then
                trigger.action.setUserFlag('1002', true)
                else
                trigger.action.setUserFlag('1002', false)
        end

end
checktimer = mist.scheduleFunction(checkWinch, {}, timer.getTime() + 1, 1)


function stopWinch()

    if trigger.misc.getUserFlag(1002) > 0 then
        if time == nil then
            time = 0
            else
            time = time + 1
        end
        else time = 0
    end

    --trigger.action.outText('Timer counts ' .. tostring(time) .. ' seconds.', 1)

    local blueHelos = mist.makeUnitTable({'[blue][helicopter]'})          
        for i = 1, #blueHelos do
            if Unit.getByName(blueHelos[i]) then
                local u = Unit.getByName(blueHelos[i])
                if u:getLife() > 0 then
                        
                       mist.flagFunc.units_in_moving_zones 
                            {
                            units           = {'a', 'b'}, 
                            zone_units      = {blueHelos[i]},
                            radius          = 150,
                            flag            = 1003
                            }
                          

                                -- the textmsg are in german but basically they are giving information about the winching status
                                if (trigger.misc.getUserFlag(1003) > 0 and time == 1) then 
                                    local msg = {}
                                          msg.text = 'SEIL FÄHRT'
                                          msg.displayTime = 4
                                          msg.msgFor = { units = {'' ..blueHelos[i]}}
                                          mist.message.add(msg)
                                end
                            
                                if (trigger.misc.getUserFlag(1003) > 0 and time == 7) then 
                                    local msg = {}
                                          msg.text = 'SEIL NOCH 3 ZUM BODEN'
                                          msg.displayTime = 4
                                          msg.msgFor = { units = {'' ..blueHelos[i]}}
                                          mist.message.add(msg)
                                end
                            
                                if (trigger.misc.getUserFlag(1003) > 0 and time == 12) then 
                                    local msg = {}
                                          msg.text = 'SEIL IST AM BODEN, PERSON WIRD EINGEHÄNGT'
                                          msg.displayTime = 4
                                          msg.msgFor = { units = {'' ..blueHelos[i]}}
                                          mist.message.add(msg)
                                end
                            
                                if (trigger.misc.getUserFlag(1003) > 0 and time == 20) then 
                                    local msg = {}
                                          msg.text = 'SEIL WIRD EINGEHOLT'
                                          msg.displayTime = 4
                                          msg.msgFor = { units = {'' ..blueHelos[i]}}
                                          mist.message.add(msg)
                                end
                                
                                if (trigger.misc.getUserFlag(1003) > 0 and time == 25) then 
                                    local msg = {}
                                          msg.text = 'SEIL NOCH 3 ZUR ZELLE'
                                          msg.displayTime = 4
                                          msg.msgFor = { units = {'' ..blueHelos[i]}}
                                          mist.message.add(msg)
                                end
                                
                                if (trigger.misc.getUserFlag(1003) > 0 and time == 30) then 
                                    local msg = {}
                                          msg.text = 'PERSON WIRD EINGEHOLT'
                                          msg.displayTime = 4
                                          msg.msgFor = { units = {'' ..blueHelos[i]}}
                                          mist.message.add(msg)
                                end
                            
                                -- this is the big problem...i don't see a way to assess the specific unit wich is inside the zone where the helicopter is in right now to destroy it
                                if (trigger.misc.getUserFlag(1003) > 0 and time == 40) then 
                                    local blueinf = mist.makeUnitTable({'a', 'b'})            
                                    for i = 1, #blueinf do
                                        if Unit.getByName('' ..blueinf[i]) then
                                        local u = Unit.getByName('' ..blueinf[i])
                                            if u:getLife() > 0 then
                                                
                                                u:destroy()
                                         
                                                local msg = {}
                                                      msg.text = 'PERSON IM HUBSCHRAUBER, CABIN READY'
                                                      msg.displayTime = 4
                                                      msg.msgFor = { units = {'' ..blueHelos[i]}}
                                                mist.message.add(msg)
                                            end
                                        end
                                    end
                                end
                        
            end
         end
            
        end    

end
stoptimer = mist.scheduleFunction(stopWinch, {}, timer.getTime() + 1, 1)  

 

GeForce RTX 4090 Founders Edition - AMD Ryzen 7 5800X3D - 64Gb RAM - Win11 - HP Reverb G1 - Thrustmaster Warthog HOTAS (40cm extension) - VKB Sim T-Rudder MKIV Pedals

Posted (edited)

You would have to run a distance check for each unit you want it to be able to be moved and keep track of the winch time for each of them. 

 

However there are quite a few problems and optimizations you can make with your code.

 

For starters the function mist.flagFunc.units_in_moving_zones creates an automated self check each time it is run. It just needs to be run once and then whenever mist sees any of those units are in a zone it'll set flag 1001 to true. Flag 1001 also never gets set to false so it is always true. You are also running Unit.getByName() multiple times when you already have that unit. 

 

local blueHelos = mist.makeUnitTable({'[blue][helicopter]'}) --get all blue helicopters. This list wont change for client units so it only needs to be created once
local winchUnits = {'a', 'b'}
local winchStatus = {}
function checkWinch()
    local wPos = {}    -- for storing the position of the unit. Here so that it only gets the position once
    for i = 1, #blueHelos do
        local u = Unit.getByName(blueHelos[i])
        if u then    
            local inAir = u:inAir()
            local uPos = u:getPoint()
            if u:getLife() > 0 and inAir == true then
                for j = 1, #winchUnits do
                    local wName = winchUnits[j]
                    local w = Unit.getByName(wName)
                    if w then -- unit object only exists if returned
                        if not wPos[wName] then
                            wPos[wName] = w:getPoint()   -- updates the position of the unit within the shared folder
                        end
                        if mist.utils.get2DDist(uPos, wPos[wName]) < 150 then -- within range
                            if mist.vec.mag(u:getVelocity())*(3600/1852) < 1.5 and uPos.y -  wPos[wName].y < 60 then -- hovering and within 60 meters above the unit
                                if not winchStatus[wName] then -- creates the table
                                     winchStatus[wName] = {t = 0, heli = blueHelos[i]} -- stored as a table so you could add other information if you wanted to. 
                                     -- for example adding a entry for its current status. winchStatus[wName].s = "loaded"
                                end
                                winchStatus[wName].t = winchStatus[wName].t + 1 -- adds to the time associated with that unit
                
                                -- You can insert all of your code for displaying the status updates in this section
                                -- You can remove the checking of flag 1003 and just use if statements on winchStatus[wName].t == whatever
                                if  winchStatus[wName].t == 40 then -- unit has been winched
                                     w:destroy()
                                end 
                            elseif winchStatus[wName] then  -- renove the entry
                                winchStatus[wName] = nil
                            end
                        end
                    end
                end
             end
         end
     end
end

 

Edited by Grimes
  • Thanks 1

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

Posted

@GrimesYou really are a genius! I don't know how to thank you!

You didn't just take the time to give me a hint, you totally made it work! Wow! You just saved me a lot of time and nerves. 

 

I already changed the script and created an advanced fast rope script which was next on my list. It works like a charm! 

 

I only can't see what I can do with that line:

 

- for example adding a entry for its current status. winchStatus[wName].s = "loaded"

Is it basically a table where I can access that specific unit again(that unit that has completed the winch process and has a unit "on board"? For exaple:

 

if loaded then

    "Spawn a ground unit if the               specific heli is inside another             zone" 

end

 

Do I get that right? 

 

Again, thank you so much for your help! 

GeForce RTX 4090 Founders Edition - AMD Ryzen 7 5800X3D - 64Gb RAM - Win11 - HP Reverb G1 - Thrustmaster Warthog HOTAS (40cm extension) - VKB Sim T-Rudder MKIV Pedals

Posted
16 hours ago, Grimes said:

...

 

For starters the function mist.flagFunc.units_in_moving_zones creates an automated self check each time it is run. It just needs to be run once and then whenever mist sees any of those units are in a zone it'll set flag 1001 to true....

 

 

Hi Grimes, sorry OP for out-thread : I don't understand the self-check part of this function. It is supposed to self check with an interval of 1 sec by default when run once. but I've never seen that. If I run once it is checked at this moment and never after. I always schedule this function every 2 or 10 seconds relatively to interval I want.

(2 examples attached - a F18c do some flyby above a ground unit that triggers message. Ex 1 function is ran once, Ex 2 function is scheduled)

test-mist-UIMZ-schedulled.miz test-mist-UIMZ-selfcheck.miz

Posted
46 minutes ago, toutenglisse said:

It is supposed to self check with an interval of 1 sec by default when run once. but I've never seen that.

I noticed that too. I've read about that it schedules itself. But it never worked for me, that's the reason why I used a scheduler in the original script. 

GeForce RTX 4090 Founders Edition - AMD Ryzen 7 5800X3D - 64Gb RAM - Win11 - HP Reverb G1 - Thrustmaster Warthog HOTAS (40cm extension) - VKB Sim T-Rudder MKIV Pedals

Posted
3 hours ago, toutenglisse said:

 

Hi Grimes, sorry OP for out-thread : I don't understand the self-check part of this function. It is supposed to self check with an interval of 1 sec by default when run once. but I've never seen that. If I run once it is checked at this moment and never after. I always schedule this function every 2 or 10 seconds relatively to interval I want.

(2 examples attached - a F18c do some flyby above a ground unit that triggers message. Ex 1 function is ran once, Ex 2 function is scheduled)

 

 

 

function unitinzone1()
		mist.flagFunc.units_in_moving_zones({ 
			units = {'Aerial-1'}, 
			zone_units = {'Ground-1'}, 
			flag = "1", 
			radius = 3000,
			toggle = true,
			}) 
				
		if trigger.misc.getUserFlag("1") > 0 then
		trigger.action.outText('unit is in the moving zone', 5)
		end
		
end
unitinzone1()

You have the creation and evaluation of the flag in the same block. When you run it once it will create the flag function in mist, which it will check every second, but since you are only evaluating whether flag 1 is true that one time it'll never return true. Code like the following would be one way to change it. Generally speaking though the idea of the flagFuncs are to set a flag value. So just creating a do script with the flagFunc definition and another trigger where it is checking the value for that flag to do a given action is more in line with the design usage. Though you can certainly just check the flag value via code as exampled below. 

 

function unitinzone1() 
    if trigger.misc.getUserFlag("1") > 0 then
		trigger.action.outText('unit is in the moving zone', 5)
    end
    timer.scheduleFunction(unitinzone1, {}, timer.getTime() + 1)  -- reschedule the check
end

mist.flagFunc.units_in_moving_zones({  -- create flag func
    units = {'Aerial-1'}, 
    zone_units = {'Ground-1'}, 
    flag = "1", 
    radius = 3000,
    toggle = true,
    }) 
unitinzone1() -- run the check

The attached screenshot is a quick test of a simple outText statement added into the mist code that displays the time that flagFunc is run and what happens if you constantly keep calling the function. Since the functions automatically reschedule themselves until told to stop each time you manually call it again it is adding more and more checks. As you can see it runs once, then twice, then 3 times, 4, 5, 6, etc. 

 

3 hours ago, exil said:

I only can't see what I can do with that line:

 


- for example adding a entry for its current status. winchStatus[wName].s = "loaded"

Is it basically a table where I can access that specific unit again(that unit that has completed the winch process and has a unit "on board"? For exaple:

 

if loaded then

    "Spawn a ground unit if the               specific heli is inside another             zone" 

end

 

Do I get that right? 

 

Again, thank you so much for your help! 

Yeah kinda. Its keeping track of which units have been winched and where they are in a sense. So perhaps if you had command to unload those units then it could check to see who sent the command, use the name to get the unit's properties, modify the point values, and the respawn the group where it was dropped off. Honestly it is a little backwards because for something like that it might be better to index it by the helicopter rather than what is winched. 

flag_func_rerun.jpg

  • Thanks 1

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

Posted
14 minutes ago, Grimes said:

...You have the creation and evaluation of the flag in the same block. When you run it once it will create the flag function in mist, which it will check every second, but since you are only evaluating whether flag 1 is true that one time it'll never return true. Code like the following would be one way to change it. Generally speaking though the idea of the flagFuncs are to set a flag value. So just creating a do script with the flagFunc definition and another trigger where it is checking the value for that flag to do a given action is more in line with the design usage. Though you can certainly just check the flag value via code as exampled below. ...

 

Thanks, I get it now. The way I used it was dumb.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...