Jump to content

Is there an issue with scripting - controller:pushTask(fireTask) - specifically FireAtPoint


Go to solution Solved by nebuluski,

Recommended Posts

Posted (edited)

Having problems getting this to work on Germany map. It is just not working. Anybody else noticed this?

 

The code I was using is this below. Have also attached a stripped out miz file used to demonstrate, issue. It appears to pushTask but nothing happens.

 

Thanks

 

 

-- CONFIGURATION
local sovietGroupPrefix = "USSR"
local artilleryGroupPrefix = "USSR-ARTY-BTY-"
local timeDelaySeconds = 120
local minKillzoneRadius = 50
local maxKillzoneRadius = 200
local maxArtilleryRange = 30000

-- Fire parameters
local expendQty = 20
local expendQtyEnabled = true
local weaponType = 0 -- 0 = any
local alt_type = 0 -- 0 = BARO
local counterbatteryRadius = 0

-- INTERNAL VARIABLES
local attackedGroups = {}

-- EVENT HANDLER
local eventHandler = {}

function eventHandler:onEvent(event)
    if event.id == world.event.S_EVENT_HIT then
        if event.target and event.target:getCategory() == Object.Category.UNIT then
            local targetGroup = event.target:getGroup()
            if targetGroup and string.find(targetGroup:getName(), sovietGroupPrefix) == 1 then
                local groupName = targetGroup:getName()
                if not attackedGroups[groupName] then
                    attackedGroups[groupName] = { hitTime = timer.getTime(), enemyUnits = {} }
                end

                if event.initiator and event.initiator:getCategory() == Object.Category.UNIT then
                    table.insert(attackedGroups[groupName].enemyUnits, event.initiator)
                    env.info("Enemy unit " .. event.initiator:getName() .. " fired on " .. groupName)
                end
            end
        end
    end
end

world.addEventHandler(eventHandler)

-- FUNCTION TO FIND NEAREST ARTILLERY
local function findNearestArtillery(targetPos)
    local nearestGroup = nil
    local nearestDistance = math.huge

    for i = 1, 20 do
        local groupName = artilleryGroupPrefix .. tostring(i)
        local group = Group.getByName(groupName)

        if group and group:isExist() then
            local unit = group:getUnit(1)
            if unit and unit:isExist() then
                local pos = unit:getPoint()
                local dx = pos.x - targetPos.x
                local dz = pos.z - targetPos.z
                local distance = math.sqrt(dx * dx + dz * dz)

                if distance < nearestDistance then
                    nearestDistance = distance
                    nearestGroup = group
                end
            end
        end
    end

    return nearestGroup, nearestDistance
end

-- FUNCTION TO STOP ARTILLERY
local function stopArtillery(group)
    if group and group:isExist() then
        local controller = group:getController()
        if controller then
            controller:setTask({
                id = 'Hold',
                params = {}
            })
            env.info(" Ordered artillery group " .. group:getName() .. " to HOLD position before firing.")
        end
    end
end

-- FUNCTION TO ORDER ARTILLERY FIRE
local function fireArtillery(enemyUnits)
    if #enemyUnits == 0 then
        env.error("No enemy units to attack!")
        return
    end

    local validEnemy = nil
    for _, enemy in ipairs(enemyUnits) do
        if enemy:isExist() then
            validEnemy = enemy
            break
        end
    end

    if not validEnemy then
        env.error("No valid enemy units exist to target!")
        return
    end

    local enemyPos = validEnemy:getPoint()
    local nearestGroup, nearestDistance = findNearestArtillery(enemyPos)
    if not nearestGroup then
        env.error("No artillery groups found!")
        return
    end

    if nearestDistance > maxArtilleryRange then
        env.info("Nearest artillery group too far away (" .. math.floor(nearestDistance) .. "m), no fire mission.")
        return
    end

    -- STOP THEM FIRST!
    stopArtillery(nearestGroup)

    local randomAngle = math.random() * 2 * math.pi
    local randomDistance = math.random(0, 50)
    local targetX = enemyPos.x + math.cos(randomAngle) * randomDistance
    local targetZ = enemyPos.z + math.sin(randomAngle) * randomDistance
    local terrainHeight = land.getHeight({x = targetX, y = targetZ})
    local targetPos = { x = targetX, y = terrainHeight, z = targetZ }

    local radius = math.random(minKillzoneRadius, maxKillzoneRadius)

    local fireTask = {
        id = 'FireAtPoint',
        params = {
            point = { x = targetPos.x, y = targetPos.z },
            radius = radius,
            expendQty = expendQty,
            expendQtyEnabled = expendQtyEnabled,
            weaponType = weaponType,
            altitude = targetPos.y,
            alt_type = alt_type,
            counterbatteryRadius = counterbatteryRadius
        }
    }

    local controller = nearestGroup:getController()
    if controller then
        controller:pushTask(fireTask)
        env.info(string.format(" Artillery %s firing at (X:%.2f, Z:%.2f, Height:%.2f, Radius:%d)", nearestGroup:getName(), targetPos.x, targetPos.z, targetPos.y, radius))
    else
        env.error("No controller for group: " .. nearestGroup:getName())
    end
end

-- SCHEDULED FUNCTION TO CHECK ARTILLERY TRIGGER
local function checkArtilleryTrigger()
    for groupName, data in pairs(attackedGroups) do
        if timer.getTime() >= data.hitTime + timeDelaySeconds then
            env.info(" Checking artillery fire for group: " .. groupName)
            fireArtillery(data.enemyUnits)
            attackedGroups[groupName] = nil
        end
    end

    return timer.getTime() + 5
end

-- INITIALIZATION
env.info(" Soviet Recce Artillery Final Script with Hold Before Fire v2 Started")
timer.scheduleFunction(checkArtilleryTrigger, {}, timer.getTime() + 5)

 

 

24 -=Shrek=- Meat Grinder-TEST.miz

Edited by nebuluski

Rig: MSI Mag X570 Tomahawk| AMD 5600 | 32 GB DDR3 | M2 NVME Gen4 1TB SSD | Samsung EVo 850 2TB, 500 & 256 GB SSD | Gigabyte AORUS GTX 1080Ti | Samsung 24" (1920x1200) |

2 x Iiyama 22" T2250MTS touch screen (1920x1080) | 2 x 6.4" LCD | Cougar MFDs | Thrustmaster Warthog | CH Pro Pedals | Windows 10

 

[sIGPIC][/sIGPIC]

Posted (edited)

Could you get fire at point working without scripting? I've found it extremely finicky as of late. If the fire at point objective isn't precisely on something the AI have LOS on they won't fire, and it's really dificult to make sure they have LOS when there's so many tiny depressions and ridges in terrain that don't show up well on the map.

Edited by Nealius
Posted
Just now, Nealius said:

Could you get fire at point working without scripting? I've found it extremely finicky as of late. If the fire at point objective isn't precisely on something the AI have LOS on they won't fire, and it's really dificult to make sure they have LOS when there's so many tiny depressions and ridges in terrain that don't show up well on the map.

Yes if setup as intial waypoint action it works fine. Unit is artillery so does not need LOS to target. Target in this case was 11Km away.

Rig: MSI Mag X570 Tomahawk| AMD 5600 | 32 GB DDR3 | M2 NVME Gen4 1TB SSD | Samsung EVo 850 2TB, 500 & 256 GB SSD | Gigabyte AORUS GTX 1080Ti | Samsung 24" (1920x1200) |

2 x Iiyama 22" T2250MTS touch screen (1920x1080) | 2 x 6.4" LCD | Cougar MFDs | Thrustmaster Warthog | CH Pro Pedals | Windows 10

 

[sIGPIC][/sIGPIC]

  • Solution
Posted

Have resolved the issue. It appears this was not working to the parameters to the firetask not being correct in some way! As soon as Ichanged these to just target x, y and radius it started working!

 

-- CONFIGURATION
local sovietGroupPrefix = "USSR"
local artilleryGroupPrefix = "USSR-ARTY-BTY-"
local timeDelaySeconds = 120
local minKillzoneRadius = 75
local maxKillzoneRadius = 300
local maxArtilleryRange = 30000 -- 30km

-- INTERNAL VARIABLES
local attackedGroups = {}

-- EVENT HANDLER
local eventHandler = {}

function eventHandler:onEvent(event)
    if event.id == world.event.S_EVENT_HIT then
        if event.target and event.target:getCategory() == Object.Category.UNIT then
            local targetGroup = event.target:getGroup()
            if targetGroup and string.find(targetGroup:getName(), sovietGroupPrefix) == 1 then
                local groupName = targetGroup:getName()
                if not attackedGroups[groupName] then
                    attackedGroups[groupName] = { hitTime = timer.getTime(), enemyUnits = {} }
                end

                if event.initiator and event.initiator:getCategory() == Object.Category.UNIT then
                    table.insert(attackedGroups[groupName].enemyUnits, event.initiator)
                    env.info(string.format("[ArtilleryScript] Enemy unit %s fired on %s", event.initiator:getName(), groupName))
                end
            end
        end
    end
end

world.addEventHandler(eventHandler)

-- FUNCTION TO CALCULATE CENTER
local function calculateCenter(units)
    local sumX, sumZ = 0, 0
    local count = 0

    for _, unit in ipairs(units) do
        if unit:isExist() then
            local pos = unit:getPoint()
            sumX = sumX + pos.x
            sumZ = sumZ + pos.z
            count = count + 1
        end
    end

    if count == 0 then
        return nil
    end

    return { x = sumX / count, z = sumZ / count }
end

-- FUNCTION TO FIND NEAREST ARTILLERY
local function findNearestArtillery(centerPos)
    local nearestGroup = nil
    local nearestDistance = math.huge

    for i = 1, 20 do
        local groupName = artilleryGroupPrefix .. tostring(i)
        local group = Group.getByName(groupName)

        if group and group:isExist() then
            local unit = group:getUnit(1)
            if unit and unit:isExist() then
                local pos = unit:getPoint()
                local dx = pos.x - centerPos.x
                local dz = pos.z - centerPos.z
                local distance = math.sqrt(dx * dx + dz * dz)

                env.info(string.format("[ArtilleryScript] Checking artillery %s at (%.1f, %.1f), distance: %.1f", groupName, pos.x, pos.z, distance))

                if distance < nearestDistance then
                    nearestDistance = distance
                    nearestGroup = group
                end
            end
        else
            env.info("[ArtilleryScript] Artillery group not found: " .. groupName)
        end
    end

    return nearestGroup, nearestDistance
end

-- FUNCTION TO ORDER ARTILLERY FIRE
local function fireArtillery(enemyUnits)
    local centerPos = calculateCenter(enemyUnits)
    if not centerPos then
        env.error("[ArtilleryScript] No valid enemy units found to fire at!")
        return
    end

    local nearestGroup, nearestDistance = findNearestArtillery(centerPos)
    if not nearestGroup then
        env.error("[ArtilleryScript] No artillery groups found!")
        return
    end

    if nearestDistance > maxArtilleryRange then
        env.info(string.format("[ArtilleryScript] Nearest artillery group too far away (%.1f meters), no fire mission.", nearestDistance))
        return
    end

    local radius = math.random(minKillzoneRadius, maxKillzoneRadius)

    local fireTask = {
        id = 'FireAtPoint',
        params = {
            point = { x = centerPos.x, y = centerPos.z }, -- ✅ Correct mapping!
            radius = radius,
        }
    }

    nearestGroup:getController():pushTask(fireTask)

    env.info(string.format("[ArtilleryScript] Ordered %s to fire at (X=%.1f, Y=%.1f) with radius %d",
        nearestGroup:getName(), centerPos.x, centerPos.z, radius))
end

-- SCHEDULED FUNCTION TO CHECK TIME
local function checkArtilleryTrigger()
    for groupName, data in pairs(attackedGroups) do
        if timer.getTime() >= data.hitTime + timeDelaySeconds then
            env.info(string.format("[ArtilleryScript] Triggering artillery response for group %s", groupName))
            fireArtillery(data.enemyUnits)
            attackedGroups[groupName] = nil
        end
    end

    return timer.getTime() + 5
end

-- INITIALIZATION
env.info("[ArtilleryScript] Soviet Recce Artillery Response Script Started")
timer.scheduleFunction(checkArtilleryTrigger, {}, timer.getTime() + 5)

 

  • Like 1

Rig: MSI Mag X570 Tomahawk| AMD 5600 | 32 GB DDR3 | M2 NVME Gen4 1TB SSD | Samsung EVo 850 2TB, 500 & 256 GB SSD | Gigabyte AORUS GTX 1080Ti | Samsung 24" (1920x1200) |

2 x Iiyama 22" T2250MTS touch screen (1920x1080) | 2 x 6.4" LCD | Cougar MFDs | Thrustmaster Warthog | CH Pro Pedals | Windows 10

 

[sIGPIC][/sIGPIC]

  • Recently Browsing   0 members

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