That's awesome, thanks!
I think I am checking for source_effects correctly but maybe I'm missing something.
local new_source_effects = {}
if not delivery.source_effects then goto continue end
for _, effect in ipairs(extract_source_effects(delivery)) do
table.insert(new_source_effects, effect)
end
::continue::
Loop over the ammo actions and their action_delivery, initialise an empty array as to not assume any source effects will be found, check for delivery source effects, add any found to the array and then inject them into the new projectile ammo type. Same as I do for the target effects. If none are found it simply uses the empty array.
I'm probably missing checks for other things. Type safety especially. The API lists a lot of stuff as possible that I've never run into while other stuff is not listed as possible but is supported and does work... Right now I'm happy enough tackling individual instances as they come up until I gain a bit more experience with the engine or get much more free time.