nebuluski Posted Sunday at 10:18 AM Posted Sunday at 10:18 AM (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 Sunday at 10:43 AM 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]
Nealius Posted Sunday at 11:36 AM Posted Sunday at 11:36 AM (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 Sunday at 11:37 AM by Nealius
nebuluski Posted Sunday at 12:29 PM Author Posted Sunday at 12:29 PM 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 nebuluski Posted Sunday at 01:02 PM Author Solution Posted Sunday at 01:02 PM 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) 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]
Recommended Posts