local p=require((game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")):WaitForChild("\078\101\118\101\114\109\111\114\101"))local N=game:GetService("\067\111\110\116\101\120\116\065\099\116\105\111\110\083\101\114\118\105\099\101")local q=p("\086\097\108\117\101\079\098\106\101\099\116")local k=p("\083\105\103\110\097\108")local a=p("\077\097\105\100")local Y=setmetatable({},{})Y.__index=Y Y.ClassName="\065\099\116\105\111\110\077\097\110\097\103\101\114"function Y.new()local p=setmetatable({},Y)p._maid=a.new()p._actions={}p.ActiveAction=q.new()p._maid:GiveTask(p.ActiveAction)p.ActionAdded=k.new()p._maid.ToolEquipped=N.LocalToolEquipped:Connect(function(N)p:StopCurrentAction()end)p._maid:GiveTask(p.ActiveAction.Changed:Connect(function(N,q)local k=a.new()if N then k:GiveTask(function()N:Deactivate()end)k:GiveTask(N.Deactivated:Connect(function()if p.ActiveAction==N then p.ActiveAction.Value=nil end end))end p._maid._activeActionMaid=k if N and not N.IsActivatedValue.Value then warn(("\091\065\099\116\105\111\110\077\097\110\097\103\101\114\046\065\099\116\105\118\101\065\099\116\105\111\110\046\067\104\097\110\103\101\100\093 - \073\109\109\101\100\105\097\116\101 \100\101\097\099\116\105\118\097\116\105\111\110 \111\102 \037\113"):format(tostring(N:GetName())))p.ActiveAction.Value=nil end end))return p end function Y.StopCurrentAction(p)p.ActiveAction.Value=nil end function Y.ActivateAction(N,p,...)local q=N:GetAction(p)if q then q:Activate(...)else error(("\091\065\099\116\105\111\110\077\097\110\097\103\101\114\093 - \078\111 \097\099\116\105\111\110 \119\105\116\104 \110\097\109\101 \'\037\115\'"):format(tostring(p)))end end function Y.GetAction(N,p)return N._actions[p]end function Y.GetActions(p)local N={}for p,q in pairs(p._actions)do table.insert(N,q)end return N end function Y.AddAction(N,p)local q=p:GetName()if N._actions[q]then error(("\091\065\099\116\105\111\110\077\097\110\097\103\101\114\093 - \097\099\116\105\111\110 \119\105\116\104 \110\097\109\101 \'\037\115\' \097\108\114\101\097\100\121 \101\120\105\115\116\115"):format(tostring(q)))return end N._actions[q]=p N._maid:GiveTask(p.Activated:Connect(function()N.ActiveAction.Value=p end))N._maid:GiveTask(p.Deactivated:Connect(function()if N.ActiveAction.Value==p then N.ActiveAction.Value=nil end end))N.ActionAdded:Fire(p)return N end return Y
--- Holds single toggleable actions (like a tool system)
-- @classmod ActionManager

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Nevermore"))

local ContextActionService = game:GetService("ContextActionService")

local ValueObject = require("ValueObject")
local Signal = require("Signal")
local Maid = require("Maid")

local ActionManager = setmetatable({}, {})
ActionManager.__index = ActionManager
ActionManager.ClassName = "ActionManager"

function ActionManager.new()
	local self = setmetatable({}, ActionManager)

	self._maid = Maid.new()
	self._actions = {}

	self.ActiveAction = ValueObject.new()
	self._maid:GiveTask(self.ActiveAction)

	self.ActionAdded = Signal.new() -- :Fire(action)

	-- Stop actions while tool is in play
	self._maid.ToolEquipped = ContextActionService.LocalToolEquipped:Connect(function(tool)
		self:StopCurrentAction()
	end)

	self._maid:GiveTask(self.ActiveAction.Changed:Connect(function(value, oldValue)
		local maid = Maid.new()
		if value then
			maid:GiveTask(function()
				value:Deactivate()
			end)
			maid:GiveTask(value.Deactivated:Connect(function()
				if self.ActiveAction == value then
					self.ActiveAction.Value = nil
				end
			end))
		end
		self._maid._activeActionMaid = maid

		-- Immediately deactivate
		if value and not value.IsActivatedValue.Value then
			warn(("[ActionManager.ActiveAction.Changed] - Immediate deactivation of %q"):format(tostring(value:GetName())))
			self.ActiveAction.Value = nil
		end
	end))

	return self
end

function ActionManager:StopCurrentAction()
	self.ActiveAction.Value = nil
end

function ActionManager:ActivateAction(name, ...)
	local action = self:GetAction(name)
	if action then
		action:Activate(...)
	else
		error(("[ActionManager] - No action with name '%s'"):format(tostring(name)))
	end
end

function ActionManager:GetAction(name)
	return self._actions[name]
end

function ActionManager:GetActions()
	local list = {}

	for _, action in pairs(self._actions) do
		table.insert(list, action)
	end

	return list
end

function ActionManager:AddAction(action)
	local name = action:GetName()

	if self._actions[name] then
		error(("[ActionManager] - action with name '%s' already exists"):format(tostring(name)))
		return
	end

	self._actions[name] = action

	self._maid:GiveTask(action.Activated:Connect(function()
		self.ActiveAction.Value = action
	end))

	self._maid:GiveTask(action.Deactivated:Connect(function()
		if self.ActiveAction.Value == action then
			self.ActiveAction.Value = nil
		end
	end))

	self.ActionAdded:Fire(action)

	return self
end

return ActionManager