Jump to content

Recommended Posts

Posted (edited)

I have a mission I wrote and Pilots from both sides (red/blue) land on the runways at Al Dhafra at times.  When that happens the airport shuts down. And I mean FOREVER. never to work again !

I once removed a pilot by picking him up with the skids of a Uh-1  and dropping him down again from 1000 ft or so ... I once got rid of one by driving over him with my F18 Falcon. But now , I have another one from our side (blue) stuck on the runway . Tried mowing him down with a tank, and tried the Uh1 again . No luck !!! I would love to write some lua code to be able to perform a Rescue on team's pilots.  and just Squish enemy since you cant shoot at them .   otherwise a downed pilot STOPS the ENTIRE Airport at Al Dhafra ,which is a large part of the mission... 

Edited by Lineaxe
Posted
2 hours ago, Lineaxe said:

I have a mission I wrote and Pilots from both sides (red/blue) land on the runways at Al Dhafra at times.  When that happens the airport shuts down. And I mean FOREVER. never to work again !

I once removed a pilot by picking him up with the skids of a Uh-1  and dropping him down again from 1000 ft or so ... I once got rid of one by driving over him with my F18 Falcon. But now , I have another one from our side (blue) stuck on the runway . Tried mowing him down with a tank, and tried the Uh1 again . No luck !!! I would love to write some lua code to be able to perform a Rescue on team's pilots.  and just Squish enemy since you cant shoot at them .   otherwise a downed pilot STOPS the ENTIRE Airport at Al Dhafra ,which is a large part of the mission... 

 

 

If you need ejected pilots to be removed if landed on runway or taxiway it's simple to solve : (requires MIST to be loaded at mission start-doable without but I'm used to it)

Spoiler

function LandedPilot(event)
if event.id == world.event.S_EVENT_LANDING_AFTER_EJECTION then
PilotPos = event.initiator:getPosition().p
if land.getSurfaceType(mist.utils.makeVec2(PilotPos)) == 5 then
Unit.destroy(event.initiator)
end
end
end
LandedPilot = mist.addEventHandler(LandedPilot)

 

test-destroy-pilot-Rnw-Txw.miz

  • Like 1
Posted

I am using the moose engine and am wondering if adding in mist would slow up the running of the mission. Must admit I have wanted to use it. I am forced to use mission editor to get cockpit controls for example. So combining mist with moose, does it affect the performance ? If it's a little bit, that's not so bad.

Posted (edited)

If all you want it to remove all pilots that have parachuted without (the great) mist or moose libs, simply copy my tiny 'parashoo' script and paste it into a 'DOSCRIPT' action that you execute when mission starts. It's no frills - it doesn't check if the pilot has landed on a runway, or likes Shostakovich - it just removes them no questions asked. Then again, it's only 9 lines of code and two comments  🙂

 

I also attached a miz that demonstrates how to include the script with your own mission. Run the mission, hit eject three times, and watch as the pilots is removed immediately after standing up. 

 

parashoo = {}
-- remove parachuted pilots after landing
function parashoo:onEvent(event)
	if event.id == 31 then -- landing_after_eject
		if event.initiator then 
			Unit.destroy(event.initiator)
		end
	end
end
-- add event handler
world.addEventHandler(parashoo)

 

parashoo demo.miz

Edited by cfrag
  • Like 1
  • Thanks 3
Posted
12 hours ago, Lineaxe said:

I am using the moose engine and am wondering if adding in mist would slow up the running of the mission. Must admit I have wanted to use it. I am forced to use mission editor to get cockpit controls for example. So combining mist with moose, does it affect the performance ? If it's a little bit, that's not so bad.

 

As an example, "Through the infierno" missions run both MIST and MOOSE libraries.

Posted (edited)

Hey, I fit that into my code quite nicely and it seems to get rid of all downed pilots after they stand up. Now, here is a similar problem I was having with   shooting down helicopters.   Somehow , half of a helicopter would end up on the ground with a pilot standing beside it .(These choppers are late activated and respawn throughout the game . ) The Unit shows up as being alive , when I do tests on it ,but of course it can never move again. So I quickly wrote some code that after some  repetitions through a timer loop would destroy the unit. Alas, somehow , I think that it thinks it is moving (changing coordinates) . 

    But , I am hoping that this code you posted may actually take care of those kinds of problems as well.   Well the pilot stands besides the downed chopper , and maybe getting rid of him would do it ?

Could be a different sort of problem ...

 

Edited by Lineaxe
Posted (edited)

You unfortunately did not post any code, track nor miz to illustrate the problem (nor did you, technically, ask a question 🙂 ). From your brief description it *sounds* as if the pilots that are milling about are the pilots that stand next to their vehicles after they completed their mission. It it possible that their unit gets (re-)activated (with the pilot spawned) after it is shot down? Then the pilot didn't parachute out, they got spawned on the ground and they do not trigger the "parashoo" script.  

 

Also, many helicopters do not have ejection seats, so what you are seeing may be pilots standing next to their downed rotorcraft after they successfully landed it and survived the landing.

 

Can you provide some more information and describe what it is you want to achieve?

Edited by cfrag
Posted (edited)
Quote

 It it possible that their unit gets (re-)activated (with the pilot spawned) after it is shot down? Then the pilot didn't parachute out, they got spawned on the ground and they do not trigger the "parashoo" script.  

Sure can add in detail. Your last scenario sounds very close to what seems to be happening , I guess. You see the 1/2 of their chopper that has been shot down is on the ground right behind its pilot. Now , it takes a while to shoot an enemy chopper down  like that & it takes flying the mission many times with several respawns of the group of choppers in each mission before that event occurs. Most of them just die in the air, or fly down with smoke. 

  So I did write some code which tests to see if the chopper unit IsAlive and continuously checked to see if it's coordinates vs it's last stored coordinates are equal ,that is, it has not moved since the last check. After X amount checks that are found equal, it then  Destroys the unit. I am part way through testing out this new code and have found that it seems to think it's moving under those conditions.

I have taken tanks & landed choppers right beside it so I can see that it aint moving 🙂 Anyhow, I am testing my code but I need to get the chopper shot down like that in order to turn on the diagnostics  (I set a switch on the F18 to trigger a Flag I can then monitor ). 

   Now , the whole thing is some kinda DCS bug , really.  I mean when a chopper is shot in half and on the ground and somehow magically can't be shot at , run over or killed off in any way. Well, that's gotta be a bug . I know, I have written several of 'em myself in the past  ?! 

 

 

 

Edited by Lineaxe
  • Like 1
Posted (edited)

 toutenglisse  , I will look into adding in mist . That should add even more action into my mission, Chop-U (a Helicopter/Jet based 2 player coop) . Also heard that they are releasing another chopper very soon & so I will be adding in missions for it 🙂  I have much artwork to add into the briefing -- some images for each sortie that I have in text in the briefing.

Edited by Lineaxe
Posted

 

Hi cfrag , I found that running the code does require another bit of code so that it would not send errors to the dcs log.   This is to (hopefully ) get rid of the bug --SCRIPTING: Error in SCHEDULER function:[string "C:\Users\xxxxx\AppData\Local\Temp\DCS.openbeta\/~mis00005FAD.lua"]:64617: attempt to index field '?' (a nil value)   ~~I put in a simple check on the Unit to see if it exists before destroying it. Since I put that into the code I have had no bugs in the dcs log show up , so far 🙂 

 parashoo = {}
-- remove parachuted pilots after landing
function parashoo:onEvent(event)
  if event.id == 31 then -- landing_after_eject
    if event.initiator then 
      if Unit~=nil then  Unit.destroy(event.initiator) end 
    end
  end
end
-- add event handler
world.addEventHandler(parashoo)
 

 

Posted (edited)

I tweaked the code to check the position of a downed chopper (half of one anyhow) . It required me to multiply the Vec.x ,  Vec.y, and Height by 100,000 and then taking only the integer portion of the result. I found that I needed to modify the test for  Vec.xVec.y to test for small variances in the calculations coming in . So I test both against the previous results +/-  1  . If one of them is outside of this range, the chopper is moving about. If not , it is on the ground (probably broke up on impact after a safe landing?). Anyhow after looping thru the test X amount of times the counter counts down to 0 and at that point it Destroys the Chopper.  Thus Allowing me to reset the group of enemy aircraft to respawn another wave of attacks.   ~~I have designed it so that all units in the group need to be destroyed b4 a new wave of aircraft come in to attack.  (no code here , but you can check it inside of my mission   ~~ release 210811 or greater  ).

   I also use very similar code to handle a MOOSE EWR mission type of bug that  crops up. The Moose generated Aircraft seem to get stuck at times at Liwa Airport and won't move. So, now I can test their position and remove them if they don't move after a period of time. 

  It seems to me the airports repair themselves after they get damaged. I noticed this at Al Dhafra. So, just removing up those stuck Aircraft should help clear the flow of traffic going through it . 

Edited by Lineaxe
Posted (edited)
14 hours ago, Lineaxe said:

 

Hi cfrag , I found that running the code does require another bit of code so that it would not send errors to the dcs log.   This is to (hopefully ) get rid of the bug --SCRIPTING: Error in SCHEDULER function:[string "C:\Users\xxxxx\AppData\Local\Temp\DCS.openbeta\/~mis00005FAD.lua"]:64617: attempt to index field '?' (a nil value)   ~~I put in a simple check on the Unit to see if it exists before destroying it. Since I put that into the code I have had no bugs in the dcs log show up , so far 🙂 

 parashoo = {}
-- remove parachuted pilots after landing
function parashoo:onEvent(event)
  if event.id == 31 then -- landing_after_eject
    if event.initiator then 
      if Unit~=nil then  Unit.destroy(event.initiator) end 
    end
  end
end
-- add event handler
world.addEventHandler(parashoo)
 

 

 

"Unit" with capital "U" is the superclass of all Units in DCS: ground, aircraft, helicopters etc. If that is nil, you will have bigger problems. I recommend that you ensure that you did not accidentally re-define Unit in other code, or simply misspell Unit with a lower-case 'u' when invoking Unit.destroy().

 

-ch

 

Edited by cfrag
Posted (edited)
14 hours ago, Lineaxe said:

I tweaked the code to check the position of a downed chopper (half of one anyhow) . It required me to multiply the Vec.x ,  Vec.y, and Height by 100,000 and then taking only the integer portion of the result. I found that I needed to modify the test for  Vec.xVec.y to test for small variances in the calculations coming in . So I test both against the previous results +/-  1  . If one of them is outside of this range, the chopper is moving about.

 

 

I'm not entirely sure I understand what you are writing above or what you are doing. First, the position on the map is described by x and z (not y), with y being the absolute height above zero sea level (not height above ground), so you may be looking at the wrong coordinates. Also, it would help if you showed the code you are using - be advised that if you access a unit's location via Unit.getPosition(), the location you are looking for is in result.p, while when you use Unit.getPoint(), you can use the vec3 returned directly (with x,z being the map coordinates)

 

The easiest way to to find out how much a unit has moved in an interval is subtracting the two position vectors (then, now), and then get the magnitude of the resulting vector. That result tells you how far the unit has moved (in meters) between the two measurements. Simply check if that value is greater than you trigger value (1) and you are good to go (note that you need to factor in the time between the two measurements if you want to derive speed). Note also that when you invoke Unit.getVelocity(), getting the magnitude of the returned vector will easily tell you how fast that object is moving (in m/s) at that moment (without needing a previous location to compare to).  

 

Edited by cfrag
Posted (edited)
15 hours ago, Lineaxe said:

Anyhow after looping thru the test X amount of times the counter counts down to 0 and at that point it Destroys the Chopper.  Thus Allowing me to reset the group of enemy aircraft to respawn another wave of attacks.   

 

Perhaps this is more elegant and hopefully helpful for you. It uses velocity to detect if a unit isn't moving, and simply stores the time from the first time it detected that the unit didn't move to determine if the unit should be deleted. If the unit moves again, the detection is reset. All units that should be tested for stand-still should be added to the table movingTroops[]. The variable maxTime controls how many continuous seconds a unit may not move before it is deleted

 

-- code to check how long a unit hasn't moved
-- it uses the table slowUnits[] to store the time 
-- when it was first detected that the unit didn't 
-- move 
--
-- code checks all units in the table movingTroops[] if they
-- have moved, and removes them if they did not move for
-- longer than 60 seconds (maxTime)


function somemodule.mag(x, y, z) 
	if not x then x = 0 end
	if not y then y = 0 end 
	if not z then z = 0 end 
	
	return (x * x + y * y + z * z)^0.5
end

function somemodule.checkTroopMovement()
	local now = timer.getTime()
	-- call myself every 2 seconds 
	timer.scheduleFunction(somemodule.checkTroopMovement, {}, n + 2)
	
	local maxTime = 60 -- maximum 60 seconds

	for idx, theUnit in pairs(someModule.movingTroops) do 
	-- iterate through all troops that you want to check for 
	-- standing still

		local vel = theUnit:getVelocity()
		local speed = somemodule.mag(vel.x, vel.y, vel.z)
		if speed <= 0.01 then -- slower than 0.036 km/h?
			-- this unit is too slow to be called moving
			if somemodule.slowUnits[theUnit] ~= nil then 
				-- has been standing still for some time 
				if now - somemodule.slowUnits[theUnit] > maxTime then
					somemodule.slowUnits[theUnit] = nil
					theUnit:delete() -- remove unit
				end
			else 
				-- this is the first time. remember when it happened
				somemodule.slowUnits[theUnit] = now
			end
		else 
			-- unit is moving (again):
			-- simply erase this unit in our 'non-moving' table if it existed at all
			somemodule.slowUnits[theUnit] = nil
		end
	
	-- continue with iterating 
	end
end

 

Warning: I've typed this on the road, without access to DCS nor Lua IDE, and therefore did not test nor syntax-check. But the principle should be easily adaptable to your needs.

 

 

Edited by cfrag
Posted

I was working with 2d coordinates. and thus they are x and y.   Also was Testing out the various functions as well, in particular the GetHeight function for a unit which has worked quite well for me (sea or ground) . Of course the Vector differences also would work . Now, when I wrote up the code I had to get at the position data to find out what the downed choppers data even looks like and why it was behaving the way it did. Now that multiplying of the Vector X & Y data translates to some shift lefts and whatnot (in machine code) and so that part of the code runs quickly .   Most importantly, by looking over the raw data, I quickly  solved the positional error problem  without going over to a  Vector math solution 🙂  Seems  I would have to test the resultant vectors  OR the multiplied positional data that comes from Vec2.x and Vec2.y and the GetHeight function that I was using I guess.  

 

Now I will have to go over your new code for this . I am pretty sure that Vector and well, any maxtix math runs much quicker . After all the graphics card are designed to gobble matrices up 🙂

 

Posted (edited)
2 hours ago, Lineaxe said:

Now that multiplying of the Vector X & Y data translates to some shift lefts and whatnot (in machine code) and so that part of the code runs quickly .   Most importantly, by looking over the raw data, I quickly  solved the positional error problem  without going over to a  Vector math solution 🙂  Seems  I would have to test the resultant vectors  OR the multiplied positional data that comes from Vec2.x and Vec2.y and the GetHeight function that I was using I guess.  

 

Hmmm. I have to admit that I don't really understand much of what you wrote above, but as long as it works for you, everything is fine 🙂 .

Note that in LUA there is no machine code involved (Lua is interpreted byte code) and there is no direct bit-shifting involved with multiplications (that sounds very similar to how multiplication was done in the old days with machine language when there were no FPU available, and multiplying an integer by two was done by shifting the contents of a register once to the left) - a VM is much more likely to load the (floating point) values directly into the FPU, have it execute the math operation and return the result rather than doing the bit-manipulation itself. 

 

2 hours ago, Lineaxe said:

I am pretty sure that Vector and well, any maxtix math runs much quicker . After all the graphics card are designed to gobble matrices up 🙂

 

In principle you are of course correct: GPU excel at massively parallel problems, of which vector/matrix operations are one good example, so GPU can be used to greatly accelerate these (and it is used that way when drawing the game's graphics). Unfortunately, that's not the case with Lua the way it is built into DCS today; there is no direct connection between the two: there is no API that allows a Lua script to directly interface with a GPU, nor has the VM direct access to it. That means that there is no automatic GPU-based acceleration of matrix/vector math in DCS Lua. The performance of any vector methods that you write depend entirely upon your (and the VM optimizer's) skills. Which, let's be honest, makes it more interesting 🙂

 

If you look at my implementation of mag() you'll see that I've done no performance optimization - the method can be tuned: by omitting the three guards, and if you really wanted to get max performance, you can omit taking the square root and always compare the result against the square of the target value. The jury is still out if x*x is faster than x^2 in Lua; I simply use that code snipped because it is more portable. Finally, you could inline the mag code entirely to avoid the invocation (the most costly of all operations). In total though, I doubt that it would have any noticeable impact even if you checked 1000 units every second. 

 

Then again, you should only start hand-tuning your Lua code if you have exhausted all other avenues, so I recommend you just leave that to the optimizer, and code any which way you like best. It's much more fun, performs almost identically, and you can still understand your code in 6 months, when you need to go in to correct a bug 🙂.

 

Edited by cfrag
Posted (edited)

Oh, heh on those left shifts  ,  I got carried away. At one point we were writing in Machine code for a 32k microcontroller. We hired in a new graduate from a local university and they had just started dabbling in the C language. (before that they ran Pascal,Fortran and others on the mainframe there) . So, we spent some time performance testing the Machine code that was generated from some  optimized C code.  (It was quite similar to what we were producing in a number of cases ) . So I always have that in back of mind when I write in C,C++ and others. 

 I have only coded in Lua about 18 months or so now, but I believe I have read that it is a language that gets converted into C code. That part I do like , since I can generally get an idea of what the C code will turn into. Now, if DCS is using Lua in a different way than churning the Lua into C code. Well, I have much to learn about the DCS engine.  Took me long enough to write up a decent mission with the MOOSE stuff 🙂 

  Oh, also I checked to see if my code had defined UNIT anywhere to conflict with the  eventhandlers Usage of it . It was the only place in the code that UNIT was used.  Anyhow a UNIT test for nil did stop the error in the dcs log & I read  recently (somewheres) , that a nil check for UNITS & GROUPS existence is probably a good idea.  

Edited by Lineaxe
Posted (edited)
15 hours ago, Lineaxe said:

Oh, heh on those left shifts  ,  I got carried away. At one point we were writing in Machine code for a 32k microcontroller. We hired in a new graduate from a local university and they had just started dabbling in the C language. (before that they ran Pascal,Fortran and others on the mainframe there) . So, we spent some time performance testing the Machine code that was generated from some  optimized C code.  (It was quite similar to what we were producing in a number of cases ) . So I always have that in back of mind when I write in C,C++ and others. 

 

Indeed, I remember comparing compiled code (TASC?) versus my own hand-written 6502 assemblies, and I wasn't impressed. Back then compilers (especially those written by MS) didn't optimize much and simply strung together machine code templates for each compiled instruction block. The result was faster than interpreted code, sure, but could not hold a candle against my hand-optimized assembler. Which made me feel great - until (at university) I first crossed path with optimizing compilers. That set me straight - und underscored nicely what my Prof said: "You do the design, and leave the tedious stuff to machines". Wise words indeed 🙂

 

15 hours ago, Lineaxe said:

I have only coded in Lua about 18 months or so now, but I believe I have read that it is a language that gets converted into C code.

 

You may be confusing that with the fact that Lua VM (the interpreter) is written in C. You may also have been misled by the fact that Lua - in principle - can call some C-compiled libraries, provided that they both utilize the same stack frame architecture and protocol.

 

 

15 hours ago, Lineaxe said:

Oh, also I checked to see if my code had defined UNIT anywhere to conflict with the  eventhandlers Usage of it . It was the only place in the code that UNIT was used.  

 

No. If <Unit> is nil, you have lost access to the base class for all DCS units. You may be confusing class and instance. Clearly

 

Unit.destroy(someobject)

 

directly invokes <destroy> on the DCS-defined global base class <Unit> itself, passing <someobject> as parameter. Now, if the base class is nil, it's either undefined (not likely), or "Unit" was redefined in the current scope.

 

You can simply change "Unit.destroy(someobject)" into the OOP-equivalent syntactic sugar

 

someobject:destroy()

 

to see that. <Unit> is called implicitly, and nil-checking <Unit> now shows that you are checking for the base class, not instance.

 

15 hours ago, Lineaxe said:

I read  recently (somewheres) , that a nil check for UNITS & GROUPS existence is probably a good idea.  

 

Yes it is. And after 18(!) months you should know that there is a difference between nil-checking for instances versus classes. The global name "Unit" in DCS Lua references a Class. Objects (ground, aircraft, ships, helicopters) in the game (and that you store in variables that can be named anything BUT 'Unit') are instances of that "Unit" class. You normally nil-check instances, not classes (except in Lua to check if they are defined; in machine-compiled code the Loader/Linker at latest would have thrown a hissy fit if you tried to access an undefined class).

 

Wrt your addition to the code: You are nil-checking if the base class 'Unit' is defined, not if the instance (the parachutist) exists. Verifying if the parachute guy instance is non-nil is not necessary because that was already done with the guard 'if event.initiator then ... end'. If the nil-check on "Unit" (spelled exactly like that) fails, it means that the current scope has no access to the globally DCS-defined class 'Unit'. I'm not doubting for a second that it happens in your code. I'm merely pointing out that if that happens, there's a lot more wrong than just a missing nil-check. Check each and every occurrence of the string "Unit" (uppercase "U", lowercase "nit") in your code. Unless your code executes before DCS gets to define "Unit", you are exceedingly likely to find an accidental (local?) assignment that redefines Unit for that scope.  Otherwise a nil-check on "Unit" can't fail.

 

Edited by cfrag
  • Like 1
Posted (edited)

Hi interesting script which version is the final version for parashoo?

Is it possible to do about the same for destroyed planes and ground fire for it disappears after a short time?

The aim should be to keep high FPS inspide of many plane destroyed

 

Best regards

Edited by Phil C6
Posted
9 hours ago, Phil C6 said:

Hi interesting script which version is the final version for parashoo?

Is it possible to do about the same for destroyed planes and ground fire for it disappears after a short time?

The aim should be to keep high FPS inspide of many plane destroyed

 

Best regards

 

 

Well, that is the final version, it took only a few seconds to write and I did not think of version-controlling it 🙂 

 

Removing wrecks may take some work (I was able to come up with parashoo so quickly simple because I did something similar shortly before). I'll look into it, and it depends if a plane crash returns the wreckage object that was placed on the ground. If so, the resulting script should be as simple as the one above. 

 

Ground fires are a different matter, though, as I don't know how they are currently controlled in DCS. May be worth a look into - mayge a DCS coding God like @Grimes knows.

 

  • 2 years later...
Posted

This script is working if loaded at start, is it possible to make a script that erase only the ejected pilots when executed, and that could be executed several times during a mission. For example to simulate a rescue, when the rescue  team is near the pilots, the unit is considered saved and removed from the map.

Thank you.

Posted
On 10/9/2023 at 11:27 AM, Flasher said:

This script is working if loaded at start, is it possible to make a script that erase only the ejected pilots when executed, and that could be executed several times during a mission. For example to simulate a rescue, when the rescue  team is near the pilots, the unit is considered saved and removed from the map.

Due to the way how DCS works right now, that would not work. At least not directly. What you can do (and what I'm doing for my CSAR missions), however, is when you remove the parachute guy, replace it with a normal (e.g. M4 Soldier) unit. Those you can work with, and remove at your leisure; you know where they are, and you know how long they have been milling around. You'll still need the script that always runs in the background, and that then allocates the M4 Soldiers for you. Then you can later remove those at your leisure. 

There are readily made scripts that you can use right now, so you don't even have to roll your own.  I personally like to use the scripts included with DML (for obvious reasons, there are others available). 

This may give you a step up:

 

  • Like 2
  • Recently Browsing   0 members

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