LUA Help, any help is greatly appreciated! - ED Forums
 


Notices

Reply
 
Thread Tools Display Modes
Old 09-15-2019, 05:06 PM   #1
shnicklefritz
Junior Member
 
Join Date: Feb 2018
Posts: 18
Default LUA Help, any help is greatly appreciated!

Trying to create a function that records on HIT. The script I am using is when any fired weapon hits within trigger zones defined in a table, then display message (going to change so that only artillery hits are recorded). However, since every hit is recorded, I would very much like to prevent a spam message on every hit. So when a hit occurs, the zone will be added into a separate table (recentTargetedZones) that will be "emptied" periodically. Here is what I have so far, no errors are occurring, but my outText is not displaying:

Any help is appreciated.

(Sorry for the sloppy code, still not great with writing)

myZoneTable = {
"FOB Alpha",
"FOB Bravo",
"FOB Charlie",
"FOB Delta",
"FOB Echo",
"FOB Foxtrot",
}

recentTargetedZones = {}
targetedZones = {}
function targetedZones:onEvent(event)

if world.event.S_EVENT_HIT == event.id and event.initiator:getPlayerName() == nil then
local grp = Unit.getGroup(event.initiator)
local groupName = grp:getName()
local groupCat = grp:getCategory()
local firedweapon = event.weapon
local weaponTarget = event.target
local tarPos = weaponTarget:getPoint()
for i = 1, #myZoneTable do --see if the hit occured from the zones listed
local zones = trigger.misc.getZone(myZoneTable[i]) --should zone be local or global?
if (((tarPos.x - zones.point.x)^2 + (tarPos.z - zones.point.z)^2)^0.5 <= zones.radius) then
if recentTargetedZones == nil then -- check to see if the table is empty
table.insert(recentTargetedZones, zones[i])
trigger.action.outText("Zone Added", 60)
else
for x = 1, #recentTargetedZones do -- is the zone already listed in the recently target zones?
local targeted_zones = trigger.misc.getZone(recentTargetedZones[i])
if targeted_zones ~= zones then
table.insert(recentTargetedZones, zones[i])
trigger.action.outText("Zone Added", 60) --finish the function

end
end
end
end
end
end
end
world.addEventHandler(targetedZones)
shnicklefritz is offline   Reply With Quote
Old 09-15-2019, 05:50 PM   #2
Richard Dastardly
Junior Member
 
Join Date: Jul 2019
Location: Europe
Posts: 93
Default

Formatted for easier reading:

Code:
myZoneTable = {
    "FOB Alpha",
    "FOB Bravo",
    "FOB Charlie",
    "FOB Delta",
    "FOB Echo",
    "FOB Foxtrot",
}

recentTargetedZones = {}
targetedZones = {}
function targetedZones:onEvent(event)
    
    if world.event.S_EVENT_HIT == event.id and event.initiator:getPlayerName() == nil then

        local grp = Unit.getGroup(event.initiator)
        local groupName = grp:getName()
        local groupCat = grp:getCategory()
        local firedweapon = event.weapon
        local weaponTarget = event.target
        local tarPos = weaponTarget:getPoint()

        for i = 1, #myZoneTable do --see if the hit occured from the zones listed
            local zones = trigger.misc.getZone(myZoneTable[i]) --should zone be local or global?
            if (((tarPos.x - zones.point.x) ^ 2 + (tarPos.z - zones.point.z) ^ 2) ^ 0.5 <= zones.radius) then
                if recentTargetedZones == nil then -- check to see if the table is empty
                    table.insert(recentTargetedZones, zones[i])
                    trigger.action.outText("Zone Added", 60)
                else
                    for x = 1, #recentTargetedZones do -- is the zone already listed in the recently target zones?
                        local targeted_zones = trigger.misc.getZone(recentTargetedZones[i])
                        if targeted_zones ~= zones then
                            table.insert(recentTargetedZones, zones[i])
                            trigger.action.outText("Zone Added", 60) --finish the function
                            
                        end
                    end
                end
            end
        end
    end
end

world.addEventHandler(targetedZones)
The obvious questions would be

* Are you getting an event at all?
* Are you getting an event anywhere from AI?
* Is your zone table iteration doing what you expect?
* is trigger.misc.getZone() returning anything useful?

Couple of general notes -

- Lua table iteration is a bit safer using foreach .. pairs() or ipairs()
- don't use global variables *ever* if you can help it - accessing local variables is much faster. The variable you questioned about is in scope for every if-else check below it, so that shouldn't be a problem

You can set variables local anywhere if you understand the scope - eg local myZoneTable will be seen in your entire file & not outside it, which is *probably* what you want anyway.
__________________
Most Wanted: the angry Naval Lynx | Buccaneer | Hawker Hunter | Hawker Tempest/Sea Fury | Su-17/22 | rough strip rearming / construction
Richard Dastardly is offline   Reply With Quote
Old 09-15-2019, 06:20 PM   #3
Hardcard
Member
 
Hardcard's Avatar
 
Join Date: May 2013
Posts: 649
Default

@shnicklefritz

Please, format your code properly next time.

I might take a deeper look later, but at first glance there might be an issue with the grp variable.

Code:
local grp = Unit.getGroup(event.initiator) -- This isn't how you get the group from the event initiator (it's not the typical way)

-- This is how I'd do it:
local grp = event.initiator:getGroup()
Regarding that for loop, I'd do what Richard Dastardly suggested, use either pairs or ipairs (ipairs only works with numeric indices, keep it in mind)

If you aren't getting the messages, either the conditions aren't being met or there's a scripting error along the way (chances are that you won't see it in dcs.log) .

Last edited by Hardcard; 09-15-2019 at 06:33 PM.
Hardcard is offline   Reply With Quote
Old 09-15-2019, 09:28 PM   #4
shnicklefritz
Junior Member
 
Join Date: Feb 2018
Posts: 18
Default

Quote:
Originally Posted by Richard Dastardly View Post
The obvious questions would be

* Are you getting an event at all?
* Are you getting an event anywhere from AI?
* Is your zone table iteration doing what you expect?
* is trigger.misc.getZone() returning anything useful?

Couple of general notes -

- Lua table iteration is a bit safer using foreach .. pairs() or ipairs()
- don't use global variables *ever* if you can help it - accessing local variables is much faster. The variable you questioned about is in scope for every if-else check below it, so that shouldn't be a problem

You can set variables local anywhere if you understand the scope - eg local myZoneTable will be seen in your entire file & not outside it, which is *probably* what you want anyway.
Thank you for the reply. I should have mentioned that some of this script was taken from other sources, i.e., from Grimes as well as Smarter SAMs, and "reverse engineering" (for lack of better terminology) to suit my needs.

I am getting an event; in the ME, artillery are firing at a point within the one of the zones listed. Before I was using getPosition() instead of getPoint(). I will look into this more.

I suspect it has to do with the table iteration. As mentioned, I am new with lua and I do not have a wealth of knowledge in the topic. I will look into pairs or ipairs; thank you for the suggestion.

My apologies for the sloppy formatting of the code; I copied it in and it didn't keep the formatting that I had. Thank you again for looking at it.

Best,

Shnickle
shnicklefritz is offline   Reply With Quote
Old 09-15-2019, 09:38 PM   #5
shnicklefritz
Junior Member
 
Join Date: Feb 2018
Posts: 18
Default

Quote:
Originally Posted by Hardcard View Post
@shnicklefritz

Please, format your code properly next time.

I might take a deeper look later, but at first glance there might be an issue with the grp variable.

Code:
local grp = Unit.getGroup(event.initiator) -- This isn't how you get the group from the event initiator (it's not the typical way)

-- This is how I'd do it:
local grp = event.initiator:getGroup()
Regarding that for loop, I'd do what Richard Dastardly suggested, use either pairs or ipairs (ipairs only works with numeric indices, keep it in mind)

If you aren't getting the messages, either the conditions aren't being met or there's a scripting error along the way (chances are that you won't see it in dcs.log) .
Thank you for the reply. I suspect the conditions aren't being met, but I will look into "pairs." Sorry again for the sloppy code; it is formatted differently in my program and was lost when I pasted. I will make some changes and keep you posted. Thanks again.

Best,

Shnickle
shnicklefritz is offline   Reply With Quote
Old 09-15-2019, 11:33 PM   #6
Hardcard
Member
 
Hardcard's Avatar
 
Join Date: May 2013
Posts: 649
Default

Quote:
Originally Posted by shnicklefritz View Post
Sorry again for the sloppy code; it is formatted differently in my program and was lost when I pasted.
Your code isn't sloppy, it's just unformatted, which makes it a pita to read

Use the CODE wrap next time, it should keep the original format.


Like I said, I'll probably take a deeper look some other time, but so far here is my main suspect:
  • I don't think this is a valid way to check whether a table is empty

    Code:
    if recentTargetedZones == nil then -- check to see if the table is empty
    I don't see how recentTargetedZones would be nil, since it's a table (an empty table, sure, but a table nonetheless)

    If you run this simple test code in a lua environment, you'll see how table isn't nil (you'll get the second message):
    Code:
    local table = {}
    
    if table == nil then
       
       print("table is nil!")
    
    elseif table ~= nil then
       
       print("table isn't nil!")
    end
    I'd use a for loop with pairs, check all indices within the table, see if they are paired with a nil value (if they are, that means the table is effectively empty)

    If there are no indices in the table, that would also indicate it's empty, ofc. In that case, this should do the trick:
    Code:
    if next(recentTargetedZones) == nil then

Last edited by Hardcard; 09-16-2019 at 12:10 AM.
Hardcard is offline   Reply With Quote
Old 09-17-2019, 02:20 PM   #7
A101Wayz
Member
 
Join Date: Feb 2019
Posts: 114
Default

Table equality does not work.
Best way to check a table is to use an iterator loop, like Hardcard suggested.
Something like this:
Code:
for key, value in pairs(mytable) do
  ..code..
end
If 'value' is ever nil, the code will not execute for that key, value pair, so something like:
Code:
local mytable =
{
  value1 = 3,
  value2 = nil,
  value3 = "a string",
}

for key, value in pairs(mytable) do
  print(key.."  "..value)
end
Will produce the following results:
value1 3
value3 a string

If the table is empty, or all values in the table are nil, no code is executed.

Hope that helps.
__________________
Wayz Out


Intel Core i9 9900K | ASUS ROG Strix Z390E Gaming MB | G.Skill Ripjaws V 32gb DDR4-3200 | GeForce GTX 1070 Ti FTW2 | Samsung 970 EVO Plus NVMe
HTC Vive Pro VR | Logitech G x56 HOTAS | Logitech G PRO Pedals

Last edited by A101Wayz; 09-17-2019 at 02:22 PM.
A101Wayz is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT. The time now is 01:50 PM. vBulletin Skin by ForumMonkeys. Powered by vBulletin®.
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.