Jump to content

Detecting firing sucess with Triggers


Rudel_chw

Recommended Posts

Hello,

 

 

I'm editing an Intercept Mission, where my aircraft must shot down several enemy drones using IR missiles or gunfire.

 

 

I can use a UNIT DEAD condition to detect when a drone is destroyed and award the player with some Results Points :)

 

 

... however, if two drones collide by chance between themselves, the Trigger erroneously awards me with their destruction ... is there a way I can know, on a trigger, if a target was hit by myself?

 

 

Thanks a lot

 

 

Eduardo

 

For work: iMac mid-2010 of 27" - Core i7 870 - 6 GB DDR3 1333 MHz - ATI HD5670 - SSD 256 GB - HDD 2 TB - macOS High Sierra

For Gaming: 34" Monitor - Ryzen 3600X - 32 GB DDR4 2400 - nVidia GTX1070ti - SSD 1.25 TB - HDD 10 TB - Win10 Pro - TM HOTAS Cougar - Oculus Rift CV1

Mobile: iPad Pro 12.9" of 256 GB

Link to comment
Share on other sites

is there a way I can know, on a trigger, if a target was hit by myself?

 

I don't know if you can get that kind of info using ME triggers only.

 

In case you can't find a way, here's what I'd do instead (MOOSE script):

 

 

local MyPlane = UNIT:FindByName("Unit name of my plane in ME")

 

MyPlane:HandleEvent(EVENTS.Hit)

 

function MyPlane:OnEventHit(EventData)

 

local MyPlaneName = MyPlane:GetName() -- This will return the unit name of our plane

 

local InitiatorName = EventData.IniDCSUnitName -- This will return the unit name of the HIT event initiator

 

local TargetName = EventData.TgtDCSUnitName -- This will return the unit name of the HIT event target

 

if MyPlaneName == InitiatorName and TargetName == "Unit name of the drone in ME" then -- If the HIT event initiator is our plane and the target is the specified drone, then the logic will run

 

I hit the drone, time to get some juicy points!

end

end

 

 

This script will only work when you hit the specified drone, HIT events involving other units won't trigger the logic.


Edited by Hardcard
Link to comment
Share on other sites

I don't know if you can get that kind of info using ME triggers only.

 

It seems that I can not do it with just triggers. My workaround was to set the drones at slightly different altitudes, to minimize the chance of an accident, and also I reduced their fuel level to 70% as it seems to me that the virtual pilots dont handle well these crafts when fully loaded (I'm using the MQ-9 drone)

 

In case you can't find a way, here's what I'd do instead (MOOSE script):

 

...

This script will only work when you hit the specified drone, HIT events involving other units won't trigger the logic.

 

Thanks a lot, really :) .. I've started to learn more about how to connect the trigger logic, with the script logic, for example:

 

1) This script piece allows me to include Flag (Flag 101 on the sample) values on a message:

 

trigger.action.outText( 'Vertical Speed on touchdown: -' .. trigger.misc.getUserFlag ( '101' ), 30 )

 

2) On a script, I can get the value of a Trigger Flag (for example Flag 60) with this piece:

 

local temp = trigger.misc.getUserFlag('60')

 

3) And the reverse, I can alter the value of Flag 60 from within a script with:

 

trigger.action.setUserFlag('60', temp)

 

Will play with the script that you wrote, to understand better how it works :D

Cheers!

 

 

Eduardo

 

For work: iMac mid-2010 of 27" - Core i7 870 - 6 GB DDR3 1333 MHz - ATI HD5670 - SSD 256 GB - HDD 2 TB - macOS High Sierra

For Gaming: 34" Monitor - Ryzen 3600X - 32 GB DDR4 2400 - nVidia GTX1070ti - SSD 1.25 TB - HDD 10 TB - Win10 Pro - TM HOTAS Cougar - Oculus Rift CV1

Mobile: iPad Pro 12.9" of 256 GB

Link to comment
Share on other sites

I see that you're starting to understand what ME triggers actually do "under the hood" :thumbup:

 

As you pointed out, flags from ME can be modified via script quite easily.

 

Also, numerical values (or strings) can be added directly to messages, like this snippet shows:

 

trigger.action.outText( 'Vertical Speed on touchdown: -' .. trigger.misc.getUserFlag( '101' ), 30 ) -- Those two dots ".." are used in Lua for concatenation (ie putting different values together)

-- In this case, 'Vertical Speed on touchdown: -' is a string value and trigger.misc.getUserFlag( '101' ) is a function that returns the numerical value of flag 101.

-- This message will show the string value, followed by the numerical value of flag 101.

 

-- Btw, I don't see how the numerical value of flag 101 corresponds to the vertical speed of an aircraft on tochdown... :huh:

 

 

 

The snippets that you showed correspond to standard DCS scripting engine functions, though.

They will work with MOOSE just fine, but keep in mind that the MOOSE methods used to do this sort of stuff have a simpler syntax.

 

For instance, I'll give you the MOOSE version of each snippet:

 

Concatenation of string + numerical value from flag 101 in a message

 

-- DCS scripting engine version

 

trigger.action.outText( 'Vertical Speed on touchdown: -' .. trigger.misc.getUserFlag( '101' ), 30 )

 

-- MOOSE version

 

MESSAGE:New('Vertical Speed on touchdown: -'..USERFLAG:New('101'):Get(),30):ToAll() -- :ToAll() will send the message to everybody, spectators included

 

 

 

Get the numerical value from ME flag 60

 

-- DCS scripting engine version

 

local temp = trigger.misc.getUserFlag('60') -- 'local temp =' is just a local variable. It doesn't have to be called 'temp', you can give it any name you want, as long as it's in a valid format.

-- Variables are used to store functions, that way they can be run multiple times without the need to rewrite them. If you aren't planning on using it multiple times, there's no need to store this function in a variable

 

 

-- MOOSE version

 

local temp = USERFLAG:New('60'):Get() -- As I said, there's no need to store this function in a variable unless we want to run it multiple times. Also, we can give the variable any name we want, as long as it's in a valid format

 

 

 

Set the numerical value for ME flag 60

 

 

-- DCS scripting engine version

 

trigger.action.setUserFlag('60', temp)

 

-- The second parameter given ( 'temp' ) is the variable that we created earlier... this makes little sense to me. In any case, it needs to be included in the snippet as well:

 

local temp = trigger.misc.getUserFlag('60')

 

trigger.action.setUserFlag('60', temp) -- This is the same as writing -> trigger.action.setUserFlag('60', trigger.misc.getUserFlag('60')).

-- As you can see, variables allow us to run functions without the need to write them twice.

 

-- Btw, this line is actually setting flag 60 to the numerical value it already has (which makes no sense to me).

-- If you want to give it another value, do the following (I'll give it a value of 10):

trigger.action.setUserFlag('60', 10)

 

 

-- MOOSE version

 

local temp = USERFLAG:New('60'):Get()

 

USERFLAG:New('60'):Set(temp) -- As I said, this will set flag 60 to the value it already has, which is quite pointless

 

-- Let's set it to 10 instead:

 

USERFLAG:New('60'):Set(10)

 

 

 

 

I hope you understand these snippets better now.

 

Also, if you need help getting the script to work with your mission, feel free to ask :thumbup:

 

PS. Btw, perhaps you already know this, but I'll mention it anyway. The script I provided won't work without the presence of Moose.lua in your mission (it needs to be loaded first, at mission start).


Edited by Hardcard
Link to comment
Share on other sites

-- Btw, I don't see how the numerical value of flag 101 corresponds to the vertical speed of an aircraft on tochdown... :huh:

 

Well, I know that it is not an elegant solution, but keep in mind that I'm still learning my way around the ME triggers :)

 

What I do, is to make use of the Condition UNIT's VERTICAL SPEED IN LIMITS, to put on Flag 101 a running record of the players Vertical Speed each second when it's between -10 and -1 m/seg ... so when descending, the Flag goes 10, 8, 7, 5, 3 ... etc ... the triggers look like this:

 

YSbafil.jpg

 

I stop this running account, by setting Flag 97 to true, when the aircraft is just about to land ... as if I stopped it after landing it would be 0 or even positive if I bounced, so the tally is stopped when the unit is below 2 mts AGL ... this is the trigger that does that:

 

FNMuo7C.jpg

 

Here is a short video I made while I was developing this trigger sequence .. the last displayed value is the one that the Flag keeps as final Vert Speed on touchdown:

 

nbpWoMEE_UA

 

I know that probably using Scripts would be more elegant, but I'm moving within my limitations here :D

 

Thanks a lot for the mentoring.


Edited by Rudel_chw

 

For work: iMac mid-2010 of 27" - Core i7 870 - 6 GB DDR3 1333 MHz - ATI HD5670 - SSD 256 GB - HDD 2 TB - macOS High Sierra

For Gaming: 34" Monitor - Ryzen 3600X - 32 GB DDR4 2400 - nVidia GTX1070ti - SSD 1.25 TB - HDD 10 TB - Win10 Pro - TM HOTAS Cougar - Oculus Rift CV1

Mobile: iPad Pro 12.9" of 256 GB

Link to comment
Share on other sites

That's a pretty laborious solution ;)

 

I have good news for you (or not so good, depending on how you look at it).

 

The vertical speed of an aircraft can be obtained real time without going through all that trouble.

 

Here's the raw method (DCS scripting engine version, no MOOSE required):

 

 

local TestClient = Unit.getByName("Unit name of the aircraft in ME")

 

local VerticalVelocityMxS = TestClient:getVelocity().y -- This will return the unit's vertical velocity in meters per second

local VerticalVelocityFtxM = VerticalVelocityMxS * 196.85 -- Conversion from meters per second to feet per minute

 

 

 

 

Now, we can implement this in a mission, for instance:

 

 

local TestClient = Unit.getByName("Unit name of the aircraft in ME")

 

local function VerticalVelocityFunction(TestClient, time) -- This function is called by the scheduler at the very bottom of the script. It contains a loop, which depends on the aircraft's altitude from ground

 

-- The variables below are needed to calculate the unit's altitude from the ground (unit's center point from the ground, actually).

-- We'll use this to create a landing check later on, which will also handle the looping of VerticalVelocityFunction

 

local ClientPosition = TestClient:getPosition()

local ClientPointMSL = land.getHeight( { x = ClientPosition.p.x, y = ClientPosition.p.z } )

local ClientAltitudefromGround = ClientPosition.p.y - ClientPointMSL -- This will return the unit's center altitude from ground, expressed in meters

 

-- The variables below are needed to get the unit's vertical velocity

 

local VerticalVelocityMxS = TestClient:getVelocity().y -- This will return the unit's vertical velocity in meters per second

local VerticalVelocityFtxM = VerticalVelocityMxS * 196.85 -- Conversion from meters per second to feet per minute

 

-- Now we create a message to all, which will indicate the unit's center point altitude from ground and its vertical velocity (both in m/s and ft/min)

 

trigger.action.outText("Altitude (unit's center from ground): "..ClientAltitudefromGround.."\nVertical velocity (m/s): "..VerticalVelocityMxS.."\nVertical velocity (ft/min): "..VerticalVelocityFtxM, 1, true)

 

-- Finally, we set up the landing check, which also handles the looping of VerticalVelocityFunction. It will keep looping for as long as the unit's center is more than 2 meters above the ground

if ClientAltitudefromGround > 2 then

return time + 1

else

trigger.action.outText("Client has landed!\nScheduler stopped!", 5) -- We create a landing message, which will also tell us that the loop has ended

return nil

end

end

 

timer.scheduleFunction(VerticalVelocityFunction, TestClient, timer.getTime() + 1) -- This is the scheduler that will keep calling VerticalVelocityFunction until our aircraft lands

 

 

 

As you can see, scripting this is much more convenient and resource friendly.

We achieved the same result (or perhaps an even better one) with just ~20 lines of code and a single ME trigger, which only needs to run once.

 

That's why I tend to recommend people to stop using those ME trigger jungles and script stuff instead.

Scripting has a learning curve, of course, but once you have the basics down, it's all SO MUCH better :D

 

Demo mission + script attached

Vertical velocity test.miz

Vertical velocity test (Hoggit version).lua


Edited by Hardcard
Link to comment
Share on other sites

Thanks a lot for taking the time to teach me the basics .. I'm almost ashamed of my trigger mess :(

 

Will try out your mission sample, and report back soon ... thanks again :)

 

Eduardo

 

For work: iMac mid-2010 of 27" - Core i7 870 - 6 GB DDR3 1333 MHz - ATI HD5670 - SSD 256 GB - HDD 2 TB - macOS High Sierra

For Gaming: 34" Monitor - Ryzen 3600X - 32 GB DDR4 2400 - nVidia GTX1070ti - SSD 1.25 TB - HDD 10 TB - Win10 Pro - TM HOTAS Cougar - Oculus Rift CV1

Mobile: iPad Pro 12.9" of 256 GB

Link to comment
Share on other sites

Not at all! Your ME solution is quite inventive! :thumbup:

 

:) thanks .. it was the best I could do within the trigger things

 

I was studying your scripts and it really works perfectly, here is a sample landing:

 

DYMEZGg.jpg

 

The first value is the V/S as calculated on the script, the second is the rounded value that I put on the trigger flag .. pity that Flags can only have integer values.

 

This is my version of the script, my only change is the interfacing with the trigger parts of the mission:

 

fLQoxht.jpg

 

I was curious about performance differences between the two approaches, so I disabled the Vsync on DCS graphics options and ran the two versions of my mission: with triggers only and with the script ... turns out that the difference was minimal, just a couple of fps on a frame rate around 70 fps ... but still the trigger is a neater approach.

 

I will make use of your Script snippet on my future Missions :)

 

Best regards

 

For work: iMac mid-2010 of 27" - Core i7 870 - 6 GB DDR3 1333 MHz - ATI HD5670 - SSD 256 GB - HDD 2 TB - macOS High Sierra

For Gaming: 34" Monitor - Ryzen 3600X - 32 GB DDR4 2400 - nVidia GTX1070ti - SSD 1.25 TB - HDD 10 TB - Win10 Pro - TM HOTAS Cougar - Oculus Rift CV1

Mobile: iPad Pro 12.9" of 256 GB

Link to comment
Share on other sites

turns out that the difference was minimal, just a couple of fps on a frame rate around 70 fps

 

FPS aren't a good indicator of DCS scripting engine performance / load.

You can run DCS at 200 FPS and still get DCS scripting engine errors (or "trigger lag") due to high load.

 

At any rate, replacing a few continuous triggers with a script won't make much difference.

However, replacing hundreds of continuous and switched condition triggers with one script (or a few) can make a considerable difference (as long as the scripts are written with efficiency in mind).

 

...but still the trigger is a neater approach.

 

Let's agree to disagree :D

 

I stop this running account, by setting Flag 97 to true, when the aircraft is just about to land

 

Ok, just to make sure that we're on the same page...

You know that all continuous (and switched condition) triggers in ME will keep running throughout the mission, right?

 

For instance, in your case, when flag 97 is true you won't get the messages anymore, but those continuous triggers will keep checking for each condition every second, regardless.

 

This is another perk of scripting, it gives you control over continuous functions/checks.

For instance, in the script I posted, all checks stop running when the plane lands (the scheduled function that contains them won't be called anymore), which makes DCS scripting resources available for other stuff. :thumbup:

 

As I said, if you only have a bunch of continuous / switched condition triggers in your mission, this doesn't matter... but if you have hundreds of them (which is the case in complex missions), it does matter.


Edited by Hardcard
Link to comment
Share on other sites

  • 3 weeks later...

Ok, just to make sure that we're on the same page...

You know that all continuous (and switched condition) triggers in ME will keep running throughout the mission, right?

 

Yes, I realized that .. I've replaced those continuous triggers with your script .. I did a small modification to it in order to get a better integration with the triggers I already had, so its easier for me to update my old missions to make use of this script, and I'm now really happy with it.

 

For instance, in the script I posted, all checks stop running when the plane lands (the scheduled function that contains them won't be called anymore) ..

 

About this, can you teach me how can I stop the scheduled function using a script sequence that I can use from a trigger condition? I need to do this to cover the case when a Mission has two (or more) player slots, for example cold-start and on the runway, or cold start and already on the air.

 

Currently the script starts running for the first unit the player selects, but if he changes unit on mid game, the newly selected unit wont be tracked for vertical speed anymore.

 

Thanks a lot :)

 

For work: iMac mid-2010 of 27" - Core i7 870 - 6 GB DDR3 1333 MHz - ATI HD5670 - SSD 256 GB - HDD 2 TB - macOS High Sierra

For Gaming: 34" Monitor - Ryzen 3600X - 32 GB DDR4 2400 - nVidia GTX1070ti - SSD 1.25 TB - HDD 10 TB - Win10 Pro - TM HOTAS Cougar - Oculus Rift CV1

Mobile: iPad Pro 12.9" of 256 GB

Link to comment
Share on other sites

  • Recently Browsing   0 members

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