local FlashTable = {}
local ExploseTable = {}

local function explose(playerObj, currentSq, ExplosionRange, ExplosionDamage, ExplosionType, ExplosionTime,
    ExplosionTick)
    if currentSq then
        local cx, cy, cz = currentSq:getX(), currentSq:getY(), currentSq:getZ()
        ExplosionDamage = ExplosionDamage * SandboxVars.AutoTurret.ZombieDamage

        for dx = -ExplosionRange, ExplosionRange do
            for dy = -ExplosionRange, ExplosionRange do
                local sq = getCell():getGridSquare(cx + dx, cy + dy, cz)
                if sq then
                    local Zombies = sq:getMovingObjects()
                    for i = 0, Zombies:size() - 1 do
                        local zombie = Zombies:get(i)
                        if instanceof(zombie, "IsoZombie") then
                            local distance = math.sqrt((dx * dx) + (dy * dy))
                            local scaledDamage = ExplosionDamage *
                                                     (math.abs((ExplosionRange - distance)) / ExplosionRange) * 2
                            local newHealth = zombie:getHealth() - scaledDamage
                            if newHealth < 0 then
                                newHealth = 0
                                zombie:Kill(playerObj)
                            end
                            zombie:setHealth(newHealth)
                        end
                    end
                end
            end
        end
        table.insert(ExploseTable, {currentSq, ExplosionType, ExplosionTime, ExplosionTick})
    end
end

function Turretfire(playerObj, vehicleUnit, zombie, ThisTurret)
    local Damege = ThisTurret.Damage * SandboxVars.AutoTurret.ZombieDamage
    local newHealth = zombie:getHealth() - Damege
    local zombieSq = zombie:getCurrentSquare()
    if newHealth < 0 then
        newHealth = 0
        zombie:Kill(playerObj)
    end
    zombie:setHealth(newHealth)
    if ThisTurret.TurretType == "GunTurret30mmFire" then
        zombie:SetOnFire()
    end
    local sound = ThisTurret.Sound
    local ScliencePart = vehicleUnit:getPartById("Silencer")
    if ScliencePart and ScliencePart:getInventoryItem() then
        vehicleUnit:playSound(ThisTurret.SclienceFireType)
        sound = sound / 4
    else
        vehicleUnit:playSound(ThisTurret.FireType)
    end
    local currentSq = vehicleUnit:getCurrentSquare()

    local newlight = IsoLightSource.new(currentSq:getX(), currentSq:getY(), 0, 0.8, 0.8, 0.6, 6)
    table.insert(FlashTable, {newlight, 5})
    getCell():addLamppost(newlight)
    getWorldSoundManager():addSound(playerObj, currentSq:getX(), currentSq:getY(), 1, sound, sound);
    if ThisTurret.Explosion then
        explose(playerObj, zombieSq, ThisTurret.ExplosionRange, ThisTurret.ExplosionDamage, ThisTurret.ExplosionType,
            ThisTurret.ExplosionTime, ThisTurret.ExplosionTick)
    end
end

local function RemoveFlash()
    for i = 1, #FlashTable do
        if FlashTable[i] then
            local light = FlashTable[i][1]
            local tick = FlashTable[i][2]
            FlashTable[i][2] = tick - 1
            if light and tick <= 0 then
                table.remove(FlashTable, i)
                i = i - 1
                getCell():removeLamppost(light)
            end
        end
    end
end

Events.OnTick.Add(RemoveFlash)

local function BoomUpdate()
    for i = 1, #ExploseTable do
        if ExploseTable[i] then
            local sq = ExploseTable[i][1]
            sq = getCell():getGridSquare(sq:getX(), sq:getY(), 0)
            local ExplosionType = ExploseTable[i][2]
            local ExplosionTime = ExploseTable[i][3]
            local ExplosionTick = ExploseTable[i][4]
            local FpsNow = getAverageFPS()
            local MoreTick = FpsNow / 60
            if sq and ExplosionType and ExplosionTime then
                if ExplosionTime > 0 then
                    ExplosionTime = ExplosionTime - 1
                else
                    sq:removeAllWorldObjects()
                    if ExplosionType == "ExplosionBig" then
                        local Script = ScriptManager.instance:getItem("AutoTurret.BigBoom")
                        Script:DoParam("Icon = BigBoom" .. tostring(ExplosionTick))
                        local item = sq:AddWorldInventoryItem("AutoTurret.BigBoom", 0.5, 0.5, 0)
                    end
                    if ExplosionType == "ExplosionSmall" then
                        local Script = ScriptManager.instance:getItem("AutoTurret.SmallBoom")
                        Script:DoParam("Icon = ExplosionSmall" .. tostring(ExplosionTick))
                        local item = sq:AddWorldInventoryItem("AutoTurret.SmallBoom", 0.5, 0.5, 0)
                    end
                    ExploseTable[i][3] = ExplosionTime + MoreTick
                    ExploseTable[i][4] = ExplosionTick - 1
                    if ExplosionTick <= 0 then
                        table.remove(ExploseTable, i)
                        i = i - 1
                        sq:removeAllWorldObjects()
                    end
                end
            end
        end

    end
end

Events.OnTick.Add(BoomUpdate)
