Why is this not working ?

All discussions & material related to Command's Lua interface

Moderators: angster, RoryAndersonCDT, michaelm75au, MOD_Command

Post Reply
User avatar
nukkxx5058
Posts: 3141
Joined: Thu Feb 03, 2005 2:57 pm
Location: France

Why is this not working ?

Post by nukkxx5058 »

Hi,
In my scoring function, I'd like to add the killer's weapon class in the log. And it's not working. Cannot figure out why. Help welcomed.

In the following code, if I add the code in bold (local killer and killer.classname in the setScore function), it won't work anymore, otherwise it works:

local side = "Tunisia"
local currentScore = ScenEdit_GetScore(side)
local points = 0
local unit = ScenEdit_UnitX()
local killer = ScenEdit_UnitY()

if unit.type == "Weapon" then
return
end

if -- scores by unit type
unit.type == "Aircraft" then points = 100
elseif
unit.type == "Ship" then points = 300
elseif
unit.type == "Submarine" then points = 500
elseif
unit.type == "Facility" then points = 30
end

currentScore = currentScore + points
ScenEdit_SetScore(side, currentScore, unit.name.. " ("..unit.classname.." Sub Type: "..unit.subtype.." ) Destroyed by ".. side .." "..killer.classname.. "/ Points: "..points)

Can't figure out why ?
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) :-)
Fido81
Posts: 176
Joined: Sat Jul 13, 2019 10:53 pm

RE: Why is this not working ?

Post by Fido81 »

The return statement in your first conditional expression doesn't look like it is returning anything. Is that intentional?
musurca
Posts: 168
Joined: Wed Jul 15, 2020 10:06 pm
Contact:

RE: Why is this not working ?

Post by musurca »

local killer = ScenEdit_UnitY()

One of the quirks of ScenEdit_UnitY() is that it doesn't return the actual unit, it returns a table containing the unit as a member variable. Here's how I access it:

local killer = ScenEdit_UnitY()
local killer_unit = nil
if killer then
if killer.unit then
killer_unit = killer.unit
end
end


After this you should be able to access killer_unit.classname and it will work.

See docs on the function here: https://commandlua.github.io/#ScenEdit_UnitY
The return statement in your first conditional expression doesn't look like it is returning anything. Is that intentional?

With that return statement, he's just terminating execution of the function if the 'killed' unit is a Weapon, as that wouldn't be useful for logging or scoring, I think.
User avatar
nukkxx5058
Posts: 3141
Joined: Thu Feb 03, 2005 2:57 pm
Location: France

RE: Why is this not working ?

Post by nukkxx5058 »

ORIGINAL: musurca
local killer = ScenEdit_UnitY()

One of the quirks of ScenEdit_UnitY() is that it doesn't return the actual unit, it returns a table containing the unit as a member variable. Here's how I access it:

local killer = ScenEdit_UnitY()
local killer_unit = nil
if killer then
if killer.unit then
killer_unit = killer.unit
end
end


After this you should be able to access killer_unit.classname and it will work.

See docs on the function here: https://commandlua.github.io/#ScenEdit_UnitY
The return statement in your first conditional expression doesn't look like it is returning anything. Is that intentional?

With that return statement, he's just terminating execution of the function if the 'killed' unit is a Weapon, as that wouldn't be useful for logging or scoring, I think.

Ah ! Thank you Musurca ! Would have never figured that alone ! Will try it. Was pulling my hair on this :-))
Many thanks.

PS: yes, Musurca's explanation about the "return" statement is the correct one.
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) :-)
User avatar
nukkxx5058
Posts: 3141
Joined: Thu Feb 03, 2005 2:57 pm
Location: France

RE: Why is this not working ?

Post by nukkxx5058 »

In fact, after playing with all these, it seems that the following (which I derived from above) is working:


local killer = ScenEdit_UnitY()
print(killer.unit.classname)


Not sure why but it does work ...

In fact this one works too: print(killer.unit).
It returns UnitY after transforming the ScenEdit_UnitY()table into a "unit" object.
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) :-)
musurca
Posts: 168
Joined: Wed Jul 15, 2020 10:06 pm
Contact:

RE: Why is this not working ?

Post by musurca »

ocal killer = ScenEdit_UnitY()
print(killer.unit.classname)

Not sure why but it does work ...

In fact this one works too: print(killer.unit).

You can do it that way—but I'd recommend first using a conditional to check if killer is valid as I posted in the code above. The reason is that under certain circumstances ScenEdit_UnitY() will return a nil value. If that happens, and if you try to access killer.unit when killer is nil, your code will fail silently at that point.
User avatar
nukkxx5058
Posts: 3141
Joined: Thu Feb 03, 2005 2:57 pm
Location: France

RE: Why is this not working ?

Post by nukkxx5058 »

Oh I see ! Ok :-) Thank you for clarifying. Will use the conditional algorithm then.
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) :-)
User avatar
nukkxx5058
Posts: 3141
Joined: Thu Feb 03, 2005 2:57 pm
Location: France

RE: Why is this not working ?

Post by nukkxx5058 »

ORIGINAL: musurca
ocal killer = ScenEdit_UnitY()
print(killer.unit.classname)

Not sure why but it does work ...

In fact this one works too: print(killer.unit).

You can do it that way—but I'd recommend first using a conditional to check if killer is valid as I posted in the code above. The reason is that under certain circumstances ScenEdit_UnitY() will return a nil value. If that happens, and if you try to access killer.unit when killer is nil, your code will fail silently at that point.

I just had the problem of UnitY() returning a nil value. I can't understand why this is happening.
Fortunately, with the IF statement I'm able to bypass this but it's quite weird and I'm obliged to flag the killer's weapon as unknown in the log each time UnitY() return a nil value.
Any idea why this is happening ?
07/04/2013 05:02: Score changed from 0 to 100. Reason: France Ship D 644 Primauguet [Type F70] (D 644 Primauguet [Type F70] Subtype: 3203 ) Killed by UK / Weapon: unknown / Points: 100

07/04/2013 05:02: Score changed from 100 to 110. Reason: France Aircraft Hercules #1 (Lynx HAS.4(FN) Subtype: 6001 ) Killed by UK / Weapon: unknown / Points: 10

07/04/2013 05:08: Score changed from 110 to 10. Reason: UK Submarine S 20 Astute (S 119 Astute Subtype: 2010 ) Killed by France / Weapon: MU-90 Impact / Points: -100


And I'm obliged to insert my code in the IF THEN ELSE condition and have to force the weapon to "unknown" when this occurs.
local killer = ScenEdit_UnitY() --killer identification
local killer_unit = nil

if killer then --check if killer is not nil
if killer.unit then
killer_unit = killer.unit
ScenEdit_SetScore(side, currentScore, sideB.." "..unit.type.." "..unit.name.. " ("..unit.classname.." Subtype: "..unit.subtype.." ) Killed by ".. side .." / Weapon: "..killer_unit.classname.." / Points: "..points)
ScenEdit_SetScore(sideB, currentScoreB, sideB.." "..unit.type.." "..unit.name.. " ("..unit.classname.." Subtype: "..unit.subtype.." ) Killed by ".. side .." / Weapon: "..killer_unit.classname.." / Points: " ..-points)
end

else

ScenEdit_SetScore(side, currentScore, sideB.." "..unit.type.." "..unit.name.. " ("..unit.classname.." Subtype: "..unit.subtype.." ) Killed by ".. side .." / Weapon: unknown".." / Points: "..points)
ScenEdit_SetScore(sideB, currentScoreB, sideB.." "..unit.type.." "..unit.name.. " ("..unit.classname.." Subtype: "..unit.subtype.." ) Killed by ".. side .." / Weapon: unknown".." / Points: " ..-points)

end

Would have preferred if UnitY() always returned a value.
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) :-)
musurca
Posts: 168
Joined: Wed Jul 15, 2020 10:06 pm
Contact:

RE: Why is this not working ?

Post by musurca »

I think Michael is still fixing the ScenEdit_UnitY() return in the 'UnitDestroyed' trigger per the last report about this: https://www.matrixgames.com/forums/tm.asp?m=5104622. (I haven't noticed anything about it in the latest update notes so I assume it's still in the works.)

In the meantime, there's a workaround which I use in the PBEM mod. I also capture the 'UnitDamaged' trigger, which more reliably returns a value for UnitY(), and store information about the last weapon to damage the unit. If UnitY() returns nil on the 'UnitDestroyed' trigger, I fall back to the previous weapon recorded via 'UnitDamaged.' You'll want to use ScenEdit_Set/GetKeyValue(...) for this.

In the UnitDamaged trigger:
-----------------------
local damaged = ScenEdit_UnitX()
local damager = ScenEdit_UnitY()

if damager then
if damager.unit then
-- store the weapon classname that just damaged the unit
ScenEdit_SetKeyValue("_LASTHIT_"..damaged.guid, damager.unit.classname)
end
end
------------------------

In the UnitDestroyed trigger:
-----------------------
local damaged = ScenEdit_UnitX()
local damager = ScenEdit_UnitY()
local damager_classname = "unknown weapon"

if damager then
if damager.unit then
damager_classname = damager.unit.classname
end
end

-- if no valid weapon returned, use the last weapon to damage the unit
if damager_classname == "unknown weapon" then
local d_class = ScenEdit_GetKeyValue("_LASTHIT_"..damaged.guid)
if d_class ~= "" then -- if the value has been set
damager_classname = d_class
end
end

-- clear the persistent dictionary entry
ScenEdit_SetKeyValue("_LASTHIT_"..damaged.guid, "")
------------------------

You can find a similar example in the IKE source code here: https://github.com/musurca/IKE/blob/mai ... m_msgs.lua (search for 'PBEM_RegisterUnitDamaged' and 'PBEM_RegisterUnitKilled')
User avatar
nukkxx5058
Posts: 3141
Joined: Thu Feb 03, 2005 2:57 pm
Location: France

RE: Why is this not working ?

Post by nukkxx5058 »

Ah yes, this works, good to know ! It however forces to add the damaged trigger.

But it's a good thing if UnitY() is going to be fixed in the future.
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) :-)
Post Reply

Return to “Lua Legion”