Feedback on fall damage module

Hello! I made this module for managing fall damage in my game and I would like to hear some feedback! I tested the module and it works, but do you think I can improve something in it? Is the code readable enough? Let me know!

ā€“ adammada112

-- Made by adammada112. Feel free to use, no credits required.

local fall_damage = {}
local enabled = false


local PL = game:GetService("Players")
local activeCharacters = {}		 -- Table of characters that are affected by fall damage. KEY = player.UseId; Value = player.Character


local FALL_HEIGHT = 15   		  -- The minimal height that gives fall damage.
local DAMAGE_MULTIPLIER = 1    	  -- Fall damage = height * DAMAGE_MULTIPLIER
local SHIELD_PROTECTION = false   -- If this is true, you wont get damaged if you have a shield.


-- You can change these three values either manually or by the functions below.


function fall_damage:ChangeHeight(newHeight)

	if type(newHeight) == "number" then

		FALL_HEIGHT = newHeight
		print("Changed the height value to " .. tostring(newHeight))

	else
		warn("Wrong value type!")
	end
end


function fall_damage:ChangeDamage(newDamageMultiplier)

	if type(newDamageMultiplier) == "number" then

		DAMAGE_MULTIPLIER = newDamageMultiplier
		print("Changed the damage value to " .. tostring(newDamageMultiplier))

	else
		warn("Wrong value type!")
	end
end


function fall_damage:ChangeProtection(shieldProtection)

	if type(shieldProtection) == "boolean" then

		SHIELD_PROTECTION = shieldProtection
		print("Changed the shield value to " .. tostring(shieldProtection))

	else
		warn("Wrong value type!")
	end
end


function fall_damage:GetAffectedPlayers()
	return activeCharacters
end


local function GetPlayerAndHumanoid(char)

	local hum = char:FindFirstChild("Humanoid")
	local root = char:FindFirstChild("HumanoidRootPart")

	if hum and root then

		local player = PL:GetPlayerFromCharacter(char)

		if player then

			return player, hum, root
		else
			warn("There is no player that controls this character!")
		end
	else
		warn("Humanoid or root not found in the character!")
	end
end


local function CharacterFallDamage(char)

	local player, hum, root = GetPlayerAndHumanoid(char)

	if player and hum  and root then

		activeCharacters[player.UserId] = char
		print("Character added to the table!")

		local isFalling = false
		local startHeight = 0
		local stateConn, diedConn = nil, nil

		stateConn = hum.StateChanged:Connect(function(oldState, newState)

			print("State changed!")

			if activeCharacters[player.UserId] then


				if newState == Enum.HumanoidStateType.Freefall then

					if isFalling == false then

						isFalling = true
						startHeight = root.Position.Y + root.Size.Y / 2
					end

				else

					if isFalling == true then

						isFalling = false
						local difference = 0
						local endHeight = root.Position.Y - root.Size.Y / 2

						if startHeight >= 0 then

							difference = startHeight - endHeight

						else		
							difference = math.abs(endHeight) - math.abs(startHeight)
						end

						print(tostring(difference))


						if difference > FALL_HEIGHT then


							if SHIELD_PROTECTION == true then

								hum:TakeDamage(difference * DAMAGE_MULTIPLIER)

							elseif SHIELD_PROTECTION == false then

								hum.Health -= (difference * DAMAGE_MULTIPLIER)

							end
						end
					end
				end

			else
				print("Character not found in the active table!")
				stateConn:Disconnect()
				if diedConn then

					diedConn:Disconnect()
				end
			end
		end)

		diedConn = hum.Died:Connect(function()

			if activeCharacters[player.UserId] then

				table.remove(activeCharacters, player.UserId)
				print("Removed character from the table!")
				stateConn:Disconnect()
				diedConn:Disconnect()
			end
		end)

	else
		print("Player or humanoid or root not returned!")
	end
end


local function EnableForPlayer(player)

	local starterChar = player.Character or player.CharacterAdded:Wait()
	CharacterFallDamage(starterChar)


	player.CharacterAdded:Connect(function(char)

		CharacterFallDamage(char)

	end)
end


function fall_damage:Enable()

	enabled = true
	local playerConn = nil

	local playerTab = PL:GetPlayers()
	for each, player in pairs(playerTab) do

		EnableForPlayer(player)

	end

	playerConn = PL.PlayerAdded:Connect(function(newPlayer)

		if enabled == true then

			EnableForPlayer(newPlayer)

		else
			playerConn:Disconnect()
		end
	end)
end


function fall_damage:Disable()

	enabled = false
	table.clear(activeCharacters)
end


return fall_damage

Thanks for your time! :blue_heart:

7 Likes