Issues With A Defense And Dodging Script

I’m Trying To Make A Script Where When the Player Takes Damage, The Script Checks To see if The Player Is Able To Either Dodge The attack, Nullifying the Damage Entirely at the Cost of Stamina, Or Use Defense, Reducing The Damage to 1, But Applying The Attacks Damage To The Defense Value.

The Issue So Far Is that, When The Player takes Damage, The Scripts For Dodging Or Defending Don’t activate, Meaning That The Player Takes The Damage Normally.

The Script Doesn’t Print Any Errors In The Console, So Its likely that the code is Just not Running.

I have tried encasing the whole function in a while true Loop, Which predictably Broke because it ran too many times, and a while Humanoid.HealthChanged() == true loop, Which I’m On now. I think It Could Be an issue With The Health changed == true, But I don’t Have any ideas on other ways to Make sure that the script Runs Every time The Player Takes Damage, So I’m Coming To you All for help.

Heres My Script In Its Entirety, Ive Added Comments To Help You Understand At a glance what each line was intended to do.

local settings = script.Settings --Grabs The Settings For the Dodge Script

local maxStamina = settings.maxStam.Value --Set The Players Max Stamina

local staminaRegen = settings.stamRegen.Value -- Set Players Stamina Regen

local stamtime = settings.stamtime.Value -- Sets the Time Needed for Stamina Recovery

local stamina = settings.stamina --Set the Player's Current Stamina (I dont Have .Value here because I need the script to Change the Values when Running The Scripts.)

local maxDefence = settings.Defence.Value --Sets the Player's Maximum Defence

local defence = settings.Defence --Set the Player's Current Defence

local folder = script.Parent --Find the Folder that the Script Is Housed In

local Humanoid = folder.Parent:WaitForChild("Humanoid") --Find Player Character That Parents That Folder

local maxHealth = settings.Health.Value --Sets maxHealth Variable to Health

local hasRun = false --Creates hasRun Boolean

if hasRun == false then --If this code has not Been Run yet then (This Code Here is to make sure that the game setting the player's HP When Selecting a character Does NOT Trigger the Stamina Or Defence Scripts.)

	if Humanoid.MaxHealth ~= maxHealth then --If The Player's Max Health Does Not Equal the Max Health Variable

		Humanoid.MaxHealth = maxHealth --Set the Player's Max Health To The Max Health Variable

		Humanoid.Health = maxHealth --Set the Player's Health To the Max Health Variable

	end

	hasRun = true --Set hasRun to True.

	print("Health set!") --Debug Command To Let me know When Function Runs

end

while hasRun == true and Humanoid.HealthChanged == true do

	while Humanoid.HealthChanged == true do --When The Player's health Is changed

		if maxStamina > 0 then --Run Only If Max Stamina Is Greater than 0.

			print("Dodge Is Active!") 

			while stamina.Value > 0 do --If Stamina Is Greater than 0

				print("Dodging is Available!")

				local CurrentHp = Humanoid.Health --Check Player's Current health

				local NewHp = Humanoid.Health --Check Players health Again

				if NewHp < CurrentHp then --If The Player's Current Health Is Lower Than The last Time It was Checked.

					print("Player Has Taken Damage!")

					local Drain = CurrentHp - NewHp --Find The Damage Taken.

					Humanoid.Health = CurrentHp --Set Player's Health Back to What it was Before Taking Damage.

					stamina.Value = stamina.Value - Drain --Reduce Player's Stamina By The amount Of damage taken.

					print("Dodged!") --Debug Command To Let me know When Function Runs

				else 

					print("Player Has Taken Damage! Could Not Dodge!")

					return -- If Player's health is Not Lower than the Last time it was checked, Do Nothing

				end

			end 

		end

		while maxDefence > 0 do 

			print("Defence Is Active!")

			while defence.Value > 0 do --While Player Defence Is Greater than 0

				print("Defence Is Available!")

				local Humanoid = script.Parent:WaitForChild("Humanoid") --Get Player Character

				local CurrentHp = Humanoid.Health --Check Players Current Health

				wait()

				local NewHp = Humanoid.Health --Check Player Health Again And Compare To Original Value

				if NewHp < CurrentHp then --If Hp Has Decreased

					print("Player Has Taken Damage!")

					local Drain = CurrentHp - NewHp --Take The Difference Between The Old Hp and Current Hp

					Humanoid.Health = CurrentHp - 1 --Set Player Health To What It was Before the Damage was taken, Minus 1.

					defence.Value = defence.Value - Drain -- Reduce Defence By the Amount of Damage Taken.

					print("Damage Reduced!")

				end

			end

		end

	end
end

if stamina.Value < maxStamina then -- If The Player Has Lower Stamina Than Max Stamina

	repeat

		wait(stamtime) --Wait stamtime Seconds

		stamina.Value = stamina.Value + staminaRegen --Increase Stamina by staminaRegen Variable

		print("Stamina Recovered!")

	until stamina.Value == maxStamina --Repeat Until stamina is equal to The Max Stamina
end

if defence.Value <= 0 and hasRun == true then --If Defence is 0 Or Less

	wait(15) --Wait 15 seconds

	defence.Value = maxDefence --Set Defence Back to max Defence

	print("Defence Restored!")

end

while true do --Debug Script That Prints Stamina And Defence Values every 3 Seconds

	wait(5)

	print("Current Stamina: " .. stamina.Value)

	print("Current Defence: " .. defence.Value)

end
2 Likes

Just In Case Anyone Needs To Know What the Settings Folder For the Script Looks like, Here’s A screenshot:
image_2022-06-19_172907138

All Of the Items In the settings Folder Are NumberValues, I Have a settings Folder rather than put the values in the function because Im Trying to Pull these values for HUD, as well as Being Able to quickly and easily change the Values if needed.

Okay, I Managed To Fix the Issue, Turns Out It Was the Humanoid.HealthChanged() Part, I Also Split The Dodge and Defend into 2 Separate Functions To Make It Work Smoother.

If Anyone Wants to Look At The Reworked Code Incase they have a similar issue, Here it is.

local settings = script.Settings --Grabs The Settings For the Dodge Script

local maxStamina = settings.maxStam.Value --Set The Players Max Stamina

local staminaRegen = settings.stamRegen.Value -- Set Players Stamina Regen

local stamtime = settings.stamtime.Value -- Sets the Time Needed for Stamina Recovery

local stamina = settings.stamina --Set the Player's Current Stamina (I dont Have .Value here because I need the script to Change the Values when Running The Scripts.)

local maxDefence = settings.Defence.Value --Sets the Player's Maximum Defence

local defence = settings.Defence --Set the Player's Current Defence

local folder = script.Parent --Find the Folder that the Script Is Housed In

local Humanoid = folder.Parent:WaitForChild("Humanoid") --Find Player Character That Parents That Folder

local maxHealth = settings.Health.Value --Sets maxHealth Variable to Health

local cosHealth = settings["Cosmetic HP"]

local hasRun = false --Creates hasRun Boolean

if hasRun == false then --If this code has not Been Run yet then (This Code Here is to make sure that the game setting the player's HP When Selecting a character Does NOT Trigger the Stamina Or Defence Scripts.)

	if Humanoid.MaxHealth ~= maxHealth then --If The Player's Max Health Does Not Equal the Max Health Variable

		Humanoid.MaxHealth = maxHealth --Set the Player's Max Health To The Max Health Variable

		Humanoid.Health = maxHealth --Set the Player's Health To the Max Health Variable

	end

	hasRun = true --Set hasRun to True.

	print("Health set!") --Debug Command To Let me know When Function Runs

end

function Defend()
	if maxDefence > 0 then

		print("Defence Is Active!")

		while defence.Value > 0 do --While Player Defence Is Greater than 0

			print("Defence Is Available!")

			local Humanoid = script.Parent.Parent:WaitForChild("Humanoid") --Get Player Character

			local NewHp = Humanoid.Health --Check Player Health Again And Compare To Original Value

			if NewHp < cosHealth.Value then --If Hp Has Decreased

				print("Player Has Taken Damage!")

				local Drain = cosHealth.Value - NewHp --Take The Difference Between The Old Hp and Current Hp

				Humanoid.Health = cosHealth.Value - 1 --Set Player Health To What It was Before the Damage was taken, Minus 1.

				defence.Value = defence.Value - Drain -- Reduce Defence By the Amount of Damage Taken.

				cosHealth.Value = Humanoid.Health

				print("Damage Reduced!")

				return

			else 

				print("Player Has Taken Damage! Could Not Dodge!")

				return -- If Player's health is Not Lower than the Last time it was checked, Do Nothing

			end

		end

	end
end

function Dodge()

	if maxStamina > 0 then --Run Only If Max Stamina Is Greater than 0.

		print("Dodge Is Active!") 

		if stamina.Value > 0 then --If Stamina Is Greater than 0

			print("Dodging is Available!")

			local NewHp = Humanoid.Health --Check Players health Again

			if NewHp < cosHealth.Value then --If The Player's Current Health Is Lower Than The last Time It was Checked.

				print("Player Has Taken Damage!")

				local Drain = cosHealth.Value - NewHp --Find The Damage Taken.

				Humanoid.Health = cosHealth.Value --Set Player's Health Back to What it was Before Taking Damage.

				stamina.Value = stamina.Value - Drain --Reduce Player's Stamina By The amount Of damage taken.

				print("Dodged!") --Debug Command To Let me know When Function Runs

				return

			end
		else Defend()
		end 
	else Defend()
	end

end

Humanoid.HealthChanged:Connect(function()Dodge()
end)

while stamina.Value < maxStamina do -- If The Player Has Lower Stamina Than Max Stamina

	wait(stamtime) --Wait stamtime Seconds

	stamina.Value = stamina.Value + staminaRegen --Increase Stamina by staminaRegen Variable

	print("Stamina Recovered!")

end

while defence.Value <= 0 do --If Defence is 0 Or Less

	wait(15) --Wait 15 seconds

	defence.Value = maxDefence --Set Defence Back to max Defence

	print("Defence Restored!")

end