--кэш зомби pid
local trueID_module = {
    TrueID = {},
    HatFallen = {},
}
local ZombieHandler = {}
--непосредственно функция связывания
function ZombieHandler.Subdue(zombie)    
    zombie:setVariable("isSubdued", true) --иначе со временем переменная сбросится
    zombie:getEmitter():stopAll() -- работает но пробую новый метод
    --zombie:setUseless(true)    
    --zombie:changeState(BumpedState.instance()) -- c этим не работает анимация
    zombie:setBumpType("onback") -- работает но пробую новый метод
    zombie:getPathFindBehavior2():cancel()
    zombie:setPath2(nil)
    local modData = zombie:getModData()
    local globalData = ModData.getOrCreate("ZomboLewdFramework")
    modData.isSubdued = true
    id=GetZombieID(zombie)
    globalData.Subdued[id]=true
end
--не даёт вставить связанным зомби
local function _ZLOnZombieUpdate(zombie)
    if isServer() then return end
    local player = getPlayer()    
    if zombie:getVariableBoolean("AnimInProgress") then
        return
    end
    if not zombie:getVariableBoolean("isSubdued") then 
        local globalData = ModData.getOrCreate("ZomboLewdFramework")
        local modData = zombie:getModData()
        local id = GetZombieID(zombie)
        if modData.isSubdued then
            DebugLog.log(string.format("[Zombolewd] /_ZLOnZombieUpdate/ Found zombie, subdued in last session %d ...updating", zombie:getID()))
            ZombieHandler.Subdue(zombie)
        else
            for zlGid, zlGMD in pairs(globalData.Subdued) do
                if id == zlGid then
                    ZombieHandler.Subdue(zombie)
                end                
            end
        end
    elseif zombie:getVariableBoolean("MustDie") then    
        DebugLog.log(string.format("[Zombolewd] /_ZLOnZombieUpdate/ Found MustDie zombie %d ...killed", zombie:getID()))
        --zombie:setFakeDead(true) --не работает
        --zombie:Kill(player)
        zombie:becomeCorpse()        
    else
        ZombieHandler.Subdue(zombie)
        DebugLog.log(string.format("[Zombolewd] /_ZLOnZombieUpdate/ Found subdued zombie %d ...updating", zombie:getID()))
    end
end


function GetZombieID (zombie)
    -- retrieve zombie pID
    local pID = zombie:getPersistentOutfitID()

    -- if zombie is not yet initialized by the game, force it to be initialized so no issues can arise from unset zombies
    if pID == 0 then
        zombie:dressInRandomOutfit()
        pID = zombie:getPersistentOutfitID()
    end

    -- verify if trueID is cached
    local found = trueID_module.TrueID[pID] and pID or trueID_module.HatFallen[pID]
    if found then
        return found
    end

    -- transform the pID into bits
    local bits = string.split(string.reverse(Long.toUnsignedString(pID, 2)), "")
    while #bits < 16 do bits[#bits+1] = "0" end

    -- trueID
    bits[16] = "0"
    local trueID = Long.parseUnsignedLong(string.reverse(table.concat(bits, "")), 2)
    trueID_module.TrueID[trueID] = true

    -- hatFallenID
    bits[16] = "1"
    trueID_module.HatFallen[Long.parseUnsignedLong(string.reverse(table.concat(bits, "")), 2)] = trueID

    return trueID
end
--загрузка связанных зомби при старте игры
local function _ZLinitModData(isNewGame)
    local globalData = ModData.getOrCreate("ZomboLewdFramework")
    if not globalData.Subdued then 
        globalData.Subdued = {} 
    else
        for id, zlGMD in pairs(globalData.Subdued) do
            --ZombieHandler.Subdue(zombie)
        end
    end
end
--убирание зомби из общего массива после смерти
local function _ZLOnZombieDead(zombie)
    local id = GetZombieID(zombie)
    local globalData = ModData.getOrCreate("ZomboLewdFramework")
    if globalData.Subdued and globalData.Subdued[id] then
        globalData.Subdued[id] = nil
    end
end
Events.OnZombieUpdate.Add(_ZLOnZombieUpdate)
Events.OnInitGlobalModData.Add(_ZLinitModData)
Events.OnZombieDead.Add(_ZLOnZombieDead)

return ZombieHandler
