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)