How to make key combination to do cool ability

Currently_In_Ability = false
local UserInputService = game:GetService("UserInputService")
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Anim = Instance.new("Animation")
Anim.AnimationId = "rbxassetid://9394210870"
local Anim = Humanoid:LoadAnimation(Anim)
local r_pressed = false
local t_pressed = false

UserInputService.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Z then 
		if Currently_In_Ability == false then
			Currently_In_Ability = true
			print("Inability")
			
			Anim:Play()
			
		else
			Anim:Stop()
			Currently_In_Ability = false
			print("Outability")
			
		end
	elseif Currently_In_Ability == true then
		--do the key combination
	end
end)

So, where it says "do combination, i wnat it so that they have to press R, then T, then T again, then T again, then R, then T, then G (R,T,T,T,R,T,G)once they are done pressing all those buttons in the exact order, then i want it to do something.

So you need a buffer and then something to parse the buffer.
I was nice to code up a possible working way to do it

local buffer = {}
buffer.max = 15
buffer.keys = {} ::{Enum.KeyCode} --new to old
function buffer:clear()
	self:trimTo(0)
end
function buffer:trimTo(size :number?)
	size = size or self.max
	for k,v in pairs(self.keys) do
		if k > size then
			self.keys[k] = nil
		end
	end
end
function buffer:add(key :Enum.KeyCode)
	if key == Enum.KeyCode.Unknown then return end
	table.insert(self.keys, 1, key)
	self:trimTo()
end

type combo = {name :string, keys :string, action :()->()}
local combos :{combo} = {
	{
		name = "TestCombo";
		keys = "RFC";
		action = function()
			print("POW")
		end;
	};
}
for k,v in pairs(combos) do
	if not type(v) == "table" then continue end
	combos[k].keys = v.keys:upper()
end

function combos:findComboInBuffer() :combo?
	for k,combo in pairs(self) do
		if not type(combo) == "table" then continue end
		local tofind = combo.keys:reverse():split("")
		for pos,char in ipairs(tofind) do
			if buffer.keys[pos] ~= Enum.KeyCode[char] then return nil end
		end
		return combo
	end
end

game:GetService("UserInputService").InputBegan:Connect(function(input, gameProcessedEvent)
	if gameProcessedEvent then return end
	buffer:add(input.KeyCode)
	local foundCombo = combos:findComboInBuffer()
	if foundCombo then
		print("found combo",foundCombo.name)
		foundCombo:action()
		buffer:clear()
	end
end)

Could you explain what a buffer is and how it is used in this example you provided?

Essentially the buffer table is there to keep track of keypresses to be used as reference for when you use it in userinputservice

2 Likes