Quick time events code review

I want to improve this code for quick time events for my game. it works well, but is it possible to make it shorter or more secure for exploiters?

Local Script

local UIS = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local RS = game:GetService("RunService")
local done = false
wait(1) -- it sometimes doesn't load properly, so I give wait here

UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Q then
		done = true
	end
end)
game.ReplicatedStorage.SkillCheck.OnClientInvoke = function()
	script.Parent.Visible = true
	script.Parent.Time.Rotation = 0
	script.Parent.GoodSkillCheck.Rotation = math.random(60, 320)
	script.Parent.GreatSkillCheck.Rotation = script.Parent.GoodSkillCheck.Rotation - 4 -- it's always at start of good skill check
	wait(0.5)
	for i = 0, 360, 5 do
		script.Parent.Time.Rotation = i
		wait() -- I firstly used RenderStepped event, but I realized that with low FPS it spins slower, and with more FPS it's faster
		if done == true then
			done = false
			if script.Parent.Time.Rotation >= script.Parent.GoodSkillCheck.Rotation - 8 and script.Parent.Time.Rotation <= script.Parent.GoodSkillCheck.Rotation then -- here the problem starts, I needed to make returns in local script, which is not secure.
				script.Parent.Visible = false
				return "Great" --Great check gives +15 progress
			elseif script.Parent.Time.Rotation >= script.Parent.GoodSkillCheck.Rotation + 1 and script.Parent.Time.Rotation <= script.Parent.GoodSkillCheck.Rotation + 27 then
				script.Parent.Visible = false
				return "Good" --Good gives +3 progress
			else
				script.Parent.Visible = false
				return "Bad" --Bad reduces progress by 25 and makes power box smoke, so it can't be repaired for about 6 seconds
			end
		end
	end
end

Server Script

local RS = game:GetService("ReplicatedStorage")

local function skillCheck(player, object, playAnim) --main function
	local bar = player.PlayerGui.RepairingUI.EtoRepair.Progress.Bar
	local SkillCheckFunction = RS.SkillCheck:InvokeClient(player)
	if SkillCheckFunction == "Good" then
		print("Good Skill Check")
		object.Repair.Value = object.Repair.Value + 1
	elseif SkillCheckFunction == "Great" then
		print("Great Skill Check")
		object.Repair.Value = object.Repair.Value + 3
		bar.ImageColor3 = Color3.fromRGB(0,200,0)
		game:GetService("TweenService"):Create(bar, TweenInfo.new(0.6,Enum.EasingStyle.Linear), {ImageColor3 = Color3.fromRGB(241,241,241)}):Play()
        object.Parent.BoostTime.Value = object.Parent.BoostTime.Value + 3--boost increases repair speed by 25%
	else
		print("You Failed")
		playAnim:Stop()
		player.Character.Humanoid.AutoRotate = true
		player.Objectives.IsRepairingPowerBox.Value = false	
		player.Objectives.PowerBox.Value = nil
		object.Parent.CanRepair.Value = false
		object.Repair.Value = object.Repair.Value - 25
		object.Particles.Enabled = true
		wait(0.2)
		object.Particles.Enabled = false
		wait(0.5)
		object.Smoke.Enabled = true
		wait(5)
		object.Smoke.Enabled = false
		object.Parent.CanRepair.Value = true
	end
end

RS.Repair.OnServerEvent:Connect(function(player, object)
	local CancelRepair = false
	RS.CancelRepair.OnServerEvent:Connect(function()
		if player.Objectives.IsRepairingPowerBox.Value == true then
			CancelRepair = true
		end
	end)
	if object.Parent.CanRepair.Value == true then
		if player.Objectives.IsRepairingPowerBox.Value == false then
			if object.Parent.powerswitch.Power.Value == true then
				if player:DistanceFromCharacter(object.Position) <= 7 then
					if object.Name == "maincircuits" or object.Name == "smallcircuits" then
						player.Objectives.IsRepairingPowerBox.Value = true
						player.Objectives.PowerBox.Value = object
						player.Character.HumanoidRootPart.CFrame = object.Parent.PlayerPositionWhileRepairingPowerBox.CFrame
						player.Character.Humanoid.AutoRotate = false
						player.PlayerGui.RepairingUI.EtoRepair.Keybind.Visible = false
						local animation = Instance.new("Animation")
						animation.AnimationId = "rbxassetid://5894132367"
						animation.Name = "RepairingAnimation"
						animation.Parent = player
						local playAnim = player.Character.Humanoid.Animator:LoadAnimation(animation)
						playAnim:Play()
						repeat wait(0.12) -- loop for repairing
							object.Repair.Value = object.Repair.Value + 1
							if math.random(1, 60) == 1 or object.Repair.Value == object.MaxRepair.Value * 0.5 then 
                       
								skillCheck(player, object, playAnim)
							end
						until object.Repair.Value >= object.MaxRepair.Value or player:DistanceFromCharacter(object.Position) > 5 or player.Health.State.Value == "Dying" or CancelRepair == true or player.Objectives.IsRepairingPowerBox.Value == false or object.Parent.CanRepair.Value == false	
						CancelRepair = false
						player.PlayerGui.RepairingUI.EtoRepair.Keybind.Visible = true
						playAnim:Stop()
						animation:Destroy()
						player.Character.Humanoid.AutoRotate = true
						player.Objectives.IsRepairingPowerBox.Value = false	
						player.Objectives.PowerBox.Value = nil
					end
				end
3 Likes

Apologies for being late to this post. So far I am still reviewing this code, and will update this message if I find any other details that could be improved overall and for preventing exploited events.

For the if/then statements in this quoted code block, you could use β€˜or’ statements to shorten the code onto a single if/then statement, since inside of every statement there is only another if/then, so this would be the same, simply cleaner and easier to read.

1 Like