function GunStatAdjust(player, weapon)
    if not weapon or not instanceof(weapon, "HandWeapon") or not weapon:isRanged() then return end
    if not weapon:hasTag(Gun93Registries.guns93.Guns93) then return end
    local baseGunRef = instanceItem(weapon:getScriptItem())
    local recoilDelay = baseGunRef:getRecoilDelay()
    local hitChance = baseGunRef:getHitChance()
    local maxDMG = baseGunRef:getMaxDamage()
    local minDMG = baseGunRef:getMinDamage()
    maxDMG = maxDMG * SandboxVars.Guns93.Guns93DMGAdjust
    minDMG = minDMG * SandboxVars.Guns93.Guns93DMGAdjust
    hitChance = hitChance * SandboxVars.Guns93.Guns93HitAdjust
    recoilDelay = recoilDelay * SandboxVars.Guns93.Guns93RecoilAdjust
    if not SandboxVars.Guns93.Guns93Fouling and weapon:getModData().mod_fouling then
        local md = weapon:getModData()
        local howDirty = md.mod_fouling or 0
        if weapon:getBloodLevel() * 100 > howDirty then
            howDirty = weapon:getBloodLevel() * 100
        end
        local baseConChance = baseGunRef:getConditionLowerChance()
        local baseJamChance = baseGunRef:getJamGunChance()
        if howDirty > 80 then
            weapon:setConditionLowerChance(baseConChance * 0.5)
            weapon:setJamGunChance(baseJamChance * 1.5)
        elseif howDirty > 60 then
            weapon:setConditionLowerChance(baseConChance * 0.75)
            weapon:setJamGunChance(baseJamChance)
        elseif howDirty > 30 then
            weapon:setConditionLowerChance(baseConChance)
            weapon:setJamGunChance(baseJamChance * 0.75)
        else
            weapon:setConditionLowerChance(baseConChance * 1.5)
            weapon:setJamGunChance(baseJamChance * 0.5)
        end
    end
    local reqPart = true
    if weapon:hasTag(Gun93Registries.guns93.ReqTrigger) and not weapon:getWeaponPart("Trigger") then 
        reqPart = false
    elseif weapon:hasTag(Gun93Registries.guns93.ReqGrip) and not weapon:getWeaponPart("Grip") then 
        reqPart = false
    elseif weapon:hasTag(Gun93Registries.guns93.ReqStock) and not weapon:getWeaponPart("Stock") then 
        reqPart = false 
    end
    if not reqPart and weapon:getFireMode() ~= "Safe" then
        weapon:setFireMode("Safe")
    end
    local autoPart = weapon:getWeaponPart("AutoPart") or weapon:getWeaponPart("Trigger")
    local currentMode = weapon:getFireMode()
    if reqPart and autoPart then
        if currentMode == "Safe" then
            weapon:setFireMode("Single")
        elseif currentMode == "Auto" and not autoPart:hasTag(Gun93Registries.guns93.Fullauto) then
            weapon:setFireMode("Single")
        elseif currentMode == "Burst" and not autoPart:hasTag(Gun93Registries.guns93.Burst) then
            weapon:setFireMode("Single")
        elseif currentMode == "Single" and autoPart:hasTag(Gun93Registries.guns93.AutoOnly) then
            weapon:setFireMode("Auto")
        elseif currentMode == "Burst" and autoPart:hasTag(Gun93Registries.guns93.AutoOnly) then
            weapon:setFireMode("Auto")
        end
    end
    local sightMod = 10
    local sightHit = 0
    local irons = weapon:getWeaponPart("Irons")
    local scope = weapon:getWeaponPart("Scope")
    if irons or scope then
        sightMod = 0
        local sightPart = irons or scope
        if sightPart:getModData()["HitChanceModifier"] then
            sightHit = sightPart:getModData()["HitChanceModifier"]
        end
    end        
    weapon:setHitChance(hitChance - sightMod + sightHit)
    local canon = 0; local pad = 0; local stock = 0; local handguard = 0; local grip = 0
    local canonPart = weapon:getWeaponPart("Canon")
    if canonPart and canonPart:getRecoilDelay() then 
        canon = canonPart:getRecoilDelay() 
    end
    local padPart = weapon:getWeaponPart("Recoilpad")
    if padPart and padPart:getRecoilDelay() then 
        pad = padPart:getRecoilDelay() 
    end
    local stockPart = weapon:getWeaponPart("Stock")
    if stockPart and stockPart:getRecoilDelay() then 
        stock = stockPart:getRecoilDelay() 
    end
    local handguardPart = weapon:getWeaponPart("Handguard")
    if handguardPart and handguardPart:getRecoilDelay() then 
        handguard = handguardPart:getRecoilDelay() 
    end
    local gripPart = weapon:getWeaponPart("Grip")
    if gripPart and gripPart:getRecoilDelay() then 
        grip = gripPart:getRecoilDelay() 
    end
    local totalModifier = canon + pad + stock + handguard + grip
    recoilDelay = recoilDelay + totalModifier
    if weapon:getSwingAnim() == "Handgun" then
        local minRecoil = SandboxVars.Guns93.Guns93HandgunRecoilMin
        if recoilDelay < minRecoil then recoilDelay = minRecoil end
    elseif weapon:getSwingAnim() == "Rifle" then
        local minRecoil = SandboxVars.Guns93.Guns93LongGunRecoilMin
        if recoilDelay < minRecoil then recoilDelay = minRecoil end
    end
    if weapon:getFireMode() == "Auto" then
        weapon:setHitChance(hitChance - ((baseGunRef:getRecoilDelay() / 2) - sightMod) + sightHit)
    elseif weapon:getFireMode() == "Burst" then
        local burstCount = weapon:getModData()["modBurst_Num"] or 0
        weapon:setHitChance(hitChance - ((baseGunRef:getRecoilDelay() / 3) - sightMod) + sightHit)
        if burstCount == 2 then
            recoilDelay = recoilDelay + 5
            weapon:getModData()["modBurst_Num"] = 0
        else
            recoilDelay = 0
            weapon:getModData()["modBurst_Num"] = burstCount + 1
        end
    end
    weapon:setMaxDamage(maxDMG)
    weapon:setMinDamage(minDMG)
    weapon:setRecoilDelay(recoilDelay)
    if not isClient() then
        syncItemModData(player, weapon)
        syncHandWeaponFields(player, weapon)
    end
end


Events.OnWeaponSwing.Add(GunStatAdjust)
Events.OnEquipPrimary.Add(GunStatAdjust)
Events.OnGameStart.Add(function()
    local player = getPlayer()
    local weapon = player:getPrimaryHandItem()
    if player and weapon then
        if weapon:hasTag(Gun93Registries.guns93.Guns93) then 
            GunStatAdjust(player, weapon) 
        end
    end
end)