FDUtils = FDUtils or {}

FDUtils.PrependFunction = function(func,injectFunc) --adds code before a function
    local old = func
    func = function () injectFunc() old() end 
end

FDUtils.AppendFunction = function(func,injectFunc) --adds code after a function
    local old = func
    func = function () old() injectFunc() end
end

FDUtils.RandPer = function(percent) -- returns true a given percentage of calls
    assert(percent >= 0 and percent <= 100) -- sanity check
    local randomValue = ZombRand(0,100) -- Generates a random number between 0 and 100
    return percent >= randomValue
end

FDUtils.RandFloat = function(minf,maxf)
    local randomNumber = ZombRandFloat(minf,maxf)
    randomNumber = math.floor(randomNumber * 10 + 0.5) / 10 -- Round to one decimal place
    print(randomNumber)
end

FDUtils.Recur = function(funct,steps)
    for i=0,steps, 1 do
       funct()
    end
end

FDUtils.Log = function(text)
    local player = getSpecificPlayer(0)
    local color = player:getSpeakColour()
    player:addLineChatElement(text, color:getR(), color:getG(), color:getB())
end

FDUtils.DynamicMeleeHit = function(player,item) --dynamic solution to melee damage
    --give a slight chance to "miss" gotta give the players some mercy
    if(not FDUtils.RandPer(tonumber(BeyondOneWeek.hitChance))) then
        return
    end

    local bodyDamage = player:getBodyDamage()
    local health = bodyDamage:getOverallBodyHealth()
    local damageDealt 
    if(item:getFullType() == "Base.BareHands") then
        damageDealt = ZombRand(3,6) --botch fix for hands
    else
        damageDealt = (ZombRandFloat(item:getMinDamage(),item:getMaxDamage())*10)*tonumber(BeyondOneWeek.itemDmgMulti) --get the weapons stats and deal that as damage
    end
    -- SELECT BODY PART THAT WAS HIT
    local bodyParts = {}
    table.insert(bodyParts, {bname=BloodBodyPartType.Head, name=BodyPartType.Head, chance=1000})
    table.insert(bodyParts, {bname=BloodBodyPartType.Torso_Lower, name=BodyPartType.Torso_Lower, chance=600})
    table.insert(bodyParts, {bname=BloodBodyPartType.Torso_Upper, name=BodyPartType.Torso_Upper, chance=450})
    table.insert(bodyParts, {bname=BloodBodyPartType.Groin, name=BodyPartType.Groin, chance=300})
    table.insert(bodyParts, {bname=BloodBodyPartType.Neck, name=BodyPartType.Neck, chance=200})
    table.insert(bodyParts, {bname=BloodBodyPartType.UpperArm_R, name=BodyPartType.UpperArm_R, chance=100})
    table.insert(bodyParts, {bname=BloodBodyPartType.UpperArm_L, name=BodyPartType.UpperArm_L, chance=75})
    table.insert(bodyParts, {bname=BloodBodyPartType.ForeArm_R, name=BodyPartType.ForeArm_R, chance=50})
    table.insert(bodyParts, {bname=BloodBodyPartType.ForeArm_L, name=BodyPartType.ForeArm_L, chance=35})
    table.insert(bodyParts, {bname=BloodBodyPartType.Hand_R, name=BodyPartType.Hand_R, chance=20})
    table.insert(bodyParts, {bname=BloodBodyPartType.Hand_L, name=BodyPartType.Hand_L, chance=10})

    local r = 1 + ZombRand(1000)
    local bpi = 0
    for i, bp in pairs(bodyParts) do
        if bp.chance >= r then 
            bpi = i
        end
    end

    local sbp = bodyParts[bpi]
    local hitBodyPart = player:getBodyDamage():getBodyPart(sbp.name)
    print ("-- PLAYER HIT IN: " .. tostring(sbp.name))

    bodyDamage:ReduceGeneralHealth(damageDealt)

    player:addBlood(0.2)

    if sbp.name == BodyPartType.Head then
        player:helmetFall(true)
    end

    if ZombRand(4) == 1 then --its debuffing time
        --if it can make holes make holes
        if(item:isDamageMakeHole()) then
            -- CHECK PROTECTIVE CLOTHES
            local vest = player:getWornItem("TorsoExtraVest")
            local vestDef = 0
            local vestHoles = 0
            if vest then
                vestDef = vest:getBulletDefense()
                vestHoles = vest:getHolesNumber()
            end

            local hat = player:getWornItem("Hat")
            local hatDef = 0
            local hatHoles = 0
            if hat then
                hatDef = hat:getScratchDefense()
                hatHoles = hat:getHolesNumber()
            end
        end

        local DMGCat = item:getDamageCategory()
        if(DMGCat == "Slash") then --slashing weapons are more deadly should have varried chances to showcase this!!!
            if(FDUtils.RandPer(BeyondOneWeek.config.scratchChance)) then
                hitBodyPart:setScratched(true, true)
            end
            if(FDUtils.RandPer(BeyondOneWeek.config.deepWoundChance)) then
                hitBodyPart:setDeepWounded(true)
                return --return and ignore the rest because this is really really fatal
            end
            if(FDUtils.RandPer(BeyondOneWeek.config.cutChance)) then
                hitBodyPart:setCut(true,true)
            end
            if(FDUtils.RandPer(BeyondOneWeek.config.bleedingChance)) then
                hitBodyPart:setBleeding(true)
            end
            return
        end
        hitBodyPart:setScratched(true, true)
    end
end