.damage absorbation/armour script isnt functioning properly

trying to make a script when the player takes damage and is wearing armour partial damage gets absorbed
setting OldHealth value at the start of HealthChanged will make the script not work, and doing the opposite fires HealthChanged several times before congestion

local char = script.Parent.Parent.Parent
local absorbation = .25 -- percentage, in decimal so the script wont need to mess around more

local humanoid = char:FindFirstChild("Humanoid")
if humanoid then
	local oldHealth = humanoid.Health
	humanoid.HealthChanged:Connect(function(newHealth)
		--oldHealth = newHealth
		if newHealth < oldHealth then
			local change = oldHealth - newHealth
			local cal = newHealth + (change * absorbation)
			humanoid.Health = cal
			oldHealth = humanoid.Health
			print("New Health = "..humanoid.Health..", old health = "..newHealth) -- prove that the change is implemented
			script.Parent.Parent.durability.Value -= 1
			if script.Parent.Parent.durability.Value <= 0 then
				script.Parent.Parent:Destroy()
			end
			oldHealth = cal
			newHealth = cal
		end
		oldHealth = cal or newHealth
		newHealth = cal or newHealth
	end)
end

note that I’m calculating via percentages