Jump to content

Recommended Posts

Posted

also bump, this is a critical issue.

  • Thanks 2

ChromiumDis.png

Author of DSMC, mod to enable scenario persistency and save updated miz file

Stable version & site: https://dsmcfordcs.wordpress.com/

Openbeta: https://github.com/Chromium18/DSMC

 

The thing is, helicopters are different from planes. An airplane by it's nature wants to fly, and if not interfered with too strongly by unusual events or by a deliberately incompetent pilot, it will fly. A helicopter does not want to fly. It is maintained in the air by a variety of forces in opposition to each other, and if there is any disturbance in this delicate balance the helicopter stops flying; immediately and disastrously.

Posted
On 3/20/2022 at 6:23 PM, Apple said:

Since the last BETA update, the event.dead isn't called, if a unit isn't immediately dead, see attached demo. The death is registered in the ME event log, but the API isn't called. Reported by dcs-online.de and [WP] Stingray in the Moose Discord.

event dead test.miz 8.62 kB · 13 downloads

Hi, I'm not completely sure that I don't miss something but : I did some tests tonight with both KILL and DEAD script events and I had no issue (player/client vs dynamically spawn or ME created targets.

I played the "event dead test.miz" and env.info does work for the damaged vehicle burning and then exploding (but info only wrote event ID - 8 - and initiator - Ground-1-1 - in DCS.txt/log, because there is no weapon or target for dead event). So is the issue solved since march ? Is the issue online/multiplayer specific ?

Personnaly the only problem I had with my script, for scoring based on KILL event, was that the target (I want to track units only) can be a unit or a static (directly destroyed target or burning target), so I changed code for : (Object.getCategory(event.target) == 3 or Object.getCategory(event.target) == 1) for script to work again in all cases. But no issues with event.

Posted (edited)
On 5/13/2022 at 7:28 AM, Dzsekeb said:

The problem comes when you try to identify whether the target was a ground unit or a ship for example.

Unit.Category has different values than StaticObject.Category. Once a dead unit starts reporting as static, you can no longer tell weather it was static or unit before death, and you wont know how to interpret its getDesc().category.

A getDesc().category value of 2 can be either a GROUND_UNIT if the target was a unit before death, or a WEAPON if it was a staticobject, and you have no way of telling which it is, because the Object.getCategory() has started reporting it as static after death, regardless of what it started out as.

On my side everything seems to be correctly identified, using event.target:getDesc()["category"]. (target for KILL event is initiator for DEAD event but it acts the same).

Edit : removed useless stuff

Edited by toutenglisse
Posted

The point is that the first shouldn't be a category 3 static, if it was a unit it should be category 1. From hoggit:

Object.Category
  UNIT    1
  WEAPON  2
  STATIC  3
  BASE    4
  SCENERY 5
  Cargo   6
  • Thanks 1

ChromiumDis.png

Author of DSMC, mod to enable scenario persistency and save updated miz file

Stable version & site: https://dsmcfordcs.wordpress.com/

Openbeta: https://github.com/Chromium18/DSMC

 

The thing is, helicopters are different from planes. An airplane by it's nature wants to fly, and if not interfered with too strongly by unusual events or by a deliberately incompetent pilot, it will fly. A helicopter does not want to fly. It is maintained in the air by a variety of forces in opposition to each other, and if there is any disturbance in this delicate balance the helicopter stops flying; immediately and disastrously.

Posted (edited)
27 minutes ago, Dzsekeb said:

I assume in your examples "target object category" is event.target:getCategory(), and "target category" is event.target:getDesc()['category']...

No, I just used Object.getCategory(event.target) for the first and event.target:getCategory() for the second, just to see if they return the same number, which they do.

event.target:getDesc()["category"] returns correctly 0 for plane, 1 for helo, 2 for ground (with an added difference between soldiers and vehicles using string.match), 3 for ships and 4 for structures, whatever the state of the target:getCategory (unit or static for initial unit, or static for initial static). EDIT : it is what gives me the points, relative to unit category.

At least it is what occurs on my script and in SP conditions.

@chromium yes, but while it is now a fact that an initially unit can be 1 (unit) or 3 (static), relative to destroyed on impact or battle damaged not yet destroyed, my concern is that I don't see an issue to correctly identifying the target category with getDesc, but I am 80% sure it is because I miss something - my case seems to work "perfectly" but it is just my case.

The thing is that the inital OP concern is event (dead or kill) not firing when target is not immediately destroyed on impact but BDA, which I don't see (it does fire on all cases on my side).

Edited by toutenglisse
in post
Posted (edited)

The point is the "fact", what we're asking for is a call on unit deaths to be able to make a distinction between  (for example) a static BTR-82A killed and a unit BTR-82A killed.

And for many script/mod this is a very important thing.

Edited by chromium

ChromiumDis.png

Author of DSMC, mod to enable scenario persistency and save updated miz file

Stable version & site: https://dsmcfordcs.wordpress.com/

Openbeta: https://github.com/Chromium18/DSMC

 

The thing is, helicopters are different from planes. An airplane by it's nature wants to fly, and if not interfered with too strongly by unusual events or by a deliberately incompetent pilot, it will fly. A helicopter does not want to fly. It is maintained in the air by a variety of forces in opposition to each other, and if there is any disturbance in this delicate balance the helicopter stops flying; immediately and disastrously.

Posted
12 minutes ago, chromium said:

The point is the "fact", what we're asking for is a call on unit deaths to be able to make a distinction between  (for example) a static BTR-82A killed and a unit BTR-82A killed.

And for many script/mod this is a very important thing.

 

Got it, effectively they act/return exactly the same when not destroyed/dead on impact, but after burning.

Posted (edited)

@chromium FWIW I added a small check in my KILL event, a BIRTH event that updates unit only nameTable, so when a KILL happens (would be same for death) a message tells if it was initially a Unit or a StaticObject.

Here the code I use for event (I put a comment before any external table/sound so it can run standalone - uses Mist) :

Spoiler
function KillEvent(event)

		if event.id == world.event.S_EVENT_BIRTH then
		MissionUnits = mist.makeUnitTable({'[all]'}, 'static')
		elseif event.id == world.event.S_EVENT_KILL then
		trigger.action.outText('target object category: ' .. event.target:getCategory(),10)
		local UnitTrue = 0
		if #MissionUnits > 0 then
		for k, name in pairs(MissionUnits) do
		if event.target:getName() == name then
		trigger.action.outText('Initially target object category was a Unit',10)
		UnitTrue = UnitTrue + 1
		end
		end
		if UnitTrue == 0 then
		trigger.action.outText('Initially target object category was a Static Object',10)
		end
		end
		for h = 1, 2 do
		local AllHumanUnits = coalition.getPlayers(h)
		if event.initiator ~= nil and event.target ~= nil and (Object.getCategory(event.target) == 3 or Object.getCategory(event.target) == 1) and event.target:getCoalition() == event.initiator:getCoalition() then
		for i = 1, #AllHumanUnits do
		if event.initiator == AllHumanUnits[i] then
		HumanId = AllHumanUnits[i]:getGroup():getID()
		trigger.action.outTextForGroup(HumanId, 'You killed a friendly unit. Reseting support points.',5)
		--trigger.action.outSoundForGroup(HumanId, 'l10n/DEFAULT/FRIENDLYKILL.ogg')
		--HumDataTable[HumanId][2] = 0
		end
		end
		elseif event.initiator ~= nil and event.target ~= nil and (Object.getCategory(event.target) == 3 or Object.getCategory(event.target) == 1) and event.target:getCoalition() ~= event.initiator:getCoalition() then
		for i = 1, #AllHumanUnits do
		if event.initiator == AllHumanUnits[i] then
		HumanId = AllHumanUnits[i]:getGroup():getID()
		if event.target:getDesc()["category"] == 0 then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 150 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 150
		elseif event.target:getDesc()["category"] == 1 then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 110 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 110
		elseif event.target:getDesc()["category"] == 2 then
		local typeName = string.lower(event.target:getTypeName().."")
		if string.match(typeName, "infantry") or string.match(typeName, "paratrooper")  or string.match(typeName, "comm")
		or string.match(typeName, "manpad") or string.match(typeName, "soldier") then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' killed. 20 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 20
		else
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 80 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 80
		end
		elseif event.target:getDesc()["category"] == 3 then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 220 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 220
		elseif event.target:getDesc()["category"] == 4 then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 180 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 180
		end
		end
		end
		end
		end
		end

end
mist.addEventHandler(KillEvent)

 

Edit : removed useless stuff

Edited by toutenglisse
in post
Posted
On 5/13/2022 at 3:05 PM, toutenglisse said:

The thing is that the inital OP concern is event (dead or kill) not firing when target is not immediately destroyed on impact but BDA, which I don't see (it does fire on all cases on my side).

I'm pretty sure that some of this is attributed to the way our code is structured. Since people tend to code the way they structure the world in their minds, I can easily imagine (because some of my code works the same way) that one of the first guards in the event processor is something like this:

if event.target:getCategory() ~= 1 then return end -- not a ground unit, ignore

So their particular implementation for a death event might fire, but since a core assumption (objects don't change category over their life cycle) no longer holds true, it fails. As a result, a lot of code has to be examined, and it makes us wonder what other central unit life cycle assumptions no longer hold true or may change without notice. 

  • Like 1
Posted
Il 13/5/2022 at 18:35, toutenglisse ha scritto:

@chromium FWIW I added a small check in my KILL event, a BIRTH event that updates unit only nameTable, so when a KILL happens (would be same for death) a message tells if it was initially a Unit or a StaticObject. Picture example with a dynamically spawned unit that gets BDA, then explodes as a static, but identified as initially Unit.

Here the code I use for event (I put a comment before any external table/sound so it can run standalone - uses Mist) :

  Mostra contenuto nascosto
function KillEvent(event)

		if event.id == world.event.S_EVENT_BIRTH then
		MissionUnits = mist.makeUnitTable({'[all]'}, 'static')
		elseif event.id == world.event.S_EVENT_KILL then
		trigger.action.outText('target object category: ' .. event.target:getCategory(),10)
		local UnitTrue = 0
		if #MissionUnits > 0 then
		for k, name in pairs(MissionUnits) do
		if event.target:getName() == name then
		trigger.action.outText('Initially target object category was a Unit',10)
		UnitTrue = UnitTrue + 1
		end
		end
		if UnitTrue == 0 then
		trigger.action.outText('Initially target object category was a Static Object',10)
		end
		end
		for h = 1, 2 do
		local AllHumanUnits = coalition.getPlayers(h)
		if event.initiator ~= nil and event.target ~= nil and (Object.getCategory(event.target) == 3 or Object.getCategory(event.target) == 1) and event.target:getCoalition() == event.initiator:getCoalition() then
		for i = 1, #AllHumanUnits do
		if event.initiator == AllHumanUnits[i] then
		HumanId = AllHumanUnits[i]:getGroup():getID()
		trigger.action.outTextForGroup(HumanId, 'You killed a friendly unit. Reseting support points.',5)
		--trigger.action.outSoundForGroup(HumanId, 'l10n/DEFAULT/FRIENDLYKILL.ogg')
		--HumDataTable[HumanId][2] = 0
		end
		end
		elseif event.initiator ~= nil and event.target ~= nil and (Object.getCategory(event.target) == 3 or Object.getCategory(event.target) == 1) and event.target:getCoalition() ~= event.initiator:getCoalition() then
		for i = 1, #AllHumanUnits do
		if event.initiator == AllHumanUnits[i] then
		HumanId = AllHumanUnits[i]:getGroup():getID()
		if event.target:getDesc()["category"] == 0 then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 150 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 150
		elseif event.target:getDesc()["category"] == 1 then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 110 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 110
		elseif event.target:getDesc()["category"] == 2 then
		local typeName = string.lower(event.target:getTypeName().."")
		if string.match(typeName, "infantry") or string.match(typeName, "paratrooper")  or string.match(typeName, "comm")
		or string.match(typeName, "manpad") or string.match(typeName, "soldier") then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' killed. 20 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 20
		else
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 80 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 80
		end
		elseif event.target:getDesc()["category"] == 3 then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 220 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 220
		elseif event.target:getDesc()["category"] == 4 then
		trigger.action.outTextForGroup(HumanId, event.target:getDesc()["displayName"] .. ' destroyed. 180 support points earned.',5)
		--HumDataTable[HumanId][2] = HumDataTable[HumanId][2] + 180
		end
		end
		end
		end
		end
		end

end
mist.addEventHandler(KillEvent)

 

BDA-then-Kill-DynSpwn-Unit.jpg

This should not going to work if the objects is not spawned, cause birth event don't fire on units already present in the mission file except for aircrafts.

ChromiumDis.png

Author of DSMC, mod to enable scenario persistency and save updated miz file

Stable version & site: https://dsmcfordcs.wordpress.com/

Openbeta: https://github.com/Chromium18/DSMC

 

The thing is, helicopters are different from planes. An airplane by it's nature wants to fly, and if not interfered with too strongly by unusual events or by a deliberately incompetent pilot, it will fly. A helicopter does not want to fly. It is maintained in the air by a variety of forces in opposition to each other, and if there is any disturbance in this delicate balance the helicopter stops flying; immediately and disastrously.

Posted (edited)
10 hours ago, chromium said:

This should not going to work if the objects is not spawned, cause birth event don't fire on units already present in the mission file except for aircrafts.

It does work with mission editor created units (I put a BTR82 unit and a BTR82 static and both were correctly identified when destroyed after burning).

EDIT : that said, I have dynamic units spawning at start of the mission where I tested it (even the player slots are client) so I have not verified that BIRTH event fires with ME units specifically. But you can still run a MissionUnits = mist.makeUnitTable({'[all]'}, 'static') at mission start if it doesn't, and check for initially static or unit at death/kill will work.

EDIT 2 : I've just verified in a new mission with only Mist and the "Killevent", 1 "player" F18 with AP rounds, 1 Unit and 1 Static BTR82, and effectively Birth event doesn't fire (script error because MissionUnits table doesn't exist) . But then I just added MissionUnits = mist.makeUnitTable({'[all]'}, 'static') before "Killevent" script and it worked.

Edit : removed useless stuff

 

Edited by toutenglisse
in post
Posted

to be honest, I'm not looking for a workaround. I'm going to wait for the fix. I have an entire mod (DSMC), that I won't run on other scripts as mist or else, of thousands lines of code... and it must be reliable as rock solid or else it won't work. I can't rework one of the core brick of the mod due to a reported bug... since it's reported, I assume this is a recognized bug and it will be fixed.

  • Thanks 1

ChromiumDis.png

Author of DSMC, mod to enable scenario persistency and save updated miz file

Stable version & site: https://dsmcfordcs.wordpress.com/

Openbeta: https://github.com/Chromium18/DSMC

 

The thing is, helicopters are different from planes. An airplane by it's nature wants to fly, and if not interfered with too strongly by unusual events or by a deliberately incompetent pilot, it will fly. A helicopter does not want to fly. It is maintained in the air by a variety of forces in opposition to each other, and if there is any disturbance in this delicate balance the helicopter stops flying; immediately and disastrously.

Posted
11 minutes ago, sorcer3r said:

any news ?

still not fixed

12900K | MSI Z690 | STRIX RTX3090 | 64GB DDR4 3600MHz | NVMe Storage gen3 | Custom Loop | Valve Index

  • 3 weeks later...
Posted

it worries me it has been 2 1/2 months since this bug was raised and ED still cannot work out how to fix it

No more pre-orders

Click here for tutorials for using Virpil Hardware and Software

 

Click here for Virpil Flight equipment dimensions and pictures.

.

  • ED Team
Posted
22.03.2022 в 00:48, Grimes сказал:

This was discovered and reported on Saturday. 

Jeff, please contact me in Discord regarding this issue.

Men may keep a sort of level of good, but no man has ever been able to keep on one level of evil. That road goes down and down.  
Можно держаться на одном уровне добра, но никому и никогда не удавалось удержаться на одном уровне зла. Эта дорога ведёт вниз и вниз.

G.K. Chesterton

DCS World 2.5: Часто задаваемые вопросы

  • 2 weeks later...
Posted (edited)

Would be nice to have this fix soon,.. I have many scripts failing..

Does this also involves infantry?  Having the same issue while calling the getGroup on a dead unit...  or this is not allowed anymore?

 

Edited by MarcosR
Posted
13 hours ago, MarcosR said:

Having the same issue while calling the getGroup on a dead unit.

This is one of the main stumbling blocks for many scripts: when the dead event occurs, many scripts access the unit's group via getGroup(). Static objects have (currently) no getGroup() method implemented, so the invocation fails and your mission breaks when the unit is replaced by a static object and that static object subsequently invokes a dead event. There currently is no remedy if your code depends on retrieving the group (to track if a specific group has been destroyed) - you'll have to resort to regularly iterate all interesting groups and determine if they are still alive. If you are accessing the group just for completeness, something similar to

local theGroup = nil
if theUnit.getGroup then 
	theGroup = theUnit:getGroup()
end

if theGroup then 
  -- do whatever you want with the group
else
  -- we probably have a static object 
end

should help in your code.

  • 4 weeks later...
  • 4 weeks later...
Posted (edited)

Bumping the thread for more visibility. It's kinda crazy that they broke such a crucial api functionality that many scripts use to create worthwhile missions and training environments, and then haven't fixed it for almost a year.  Please get this fixed so the scripting and multiplayer community can continue to prop up your game for you despite the lack of dynamic campaigns or many useful mission making features in the base game.

Edited by CarlosNO2
  • Like 1
  • Recently Browsing   0 members

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