local G={Name="\080\097\105\110\116 \084\111\111\108",Color=BrickColor.new("\082\101\097\108\108\121 \114\101\100"),BrickColor=nil}function G.Equip(G)G.Maid=Maid.new()ShowUI()G:BindShortcutKeys()G:EnableClickPainting()end function G.Unequip(G)HideUI()G.Maid=G.Maid:Destroy()end function ShowUI()if G.UI then G.UI.Visible=true UIUpdater=Support.ScheduleRecurringTask(UpdateUI,.1)return end G.UI=Core.Tool.Interfaces.BTPaintToolGUI:Clone()G.UI.Parent=Core.UI G.UI.Visible=true PaletteButtons={}for G,t in pairs(G.UI.Palette:GetChildren())do for G,t in pairs(t:GetChildren())do if t.ClassName=="\084\101\120\116\066\117\116\116\111\110"then t.MouseButton1Click:Connect(function()SetColor((BrickColor.new(t.Name)).Color)end)PaletteButtons[t.Name]=t end end end G.UI.Controls.LastColorButton.MouseButton1Click:Connect(PaintParts)G.UI.Controls.ColorPickerButton.MouseButton1Click:Connect(function()(Core.Cheer(Core.Tool.Interfaces.BTHSVColorPicker,Core.UI)).Start(Support.IdentifyCommonProperty(Selection.Parts,"\067\111\108\111\114")or Color3.new(1,1,1),SetColor,Core.Targeting.CancelSelecting,PreviewColor)end)UIUpdater=Support.ScheduleRecurringTask(UpdateUI,.1)end function HideUI()if not G.UI then return end G.UI.Visible=false UIUpdater:Stop()end function UpdateUI()if not G.UI then return end for G,t in pairs(PaletteButtons)do t.Text=""end for G,t in pairs(Selection.Parts)do if PaletteButtons[t.BrickColor.Name]and t.Color==t.BrickColor.Color then PaletteButtons[t.BrickColor.Name].Text="\043"end end local t=Support.IdentifyCommonProperty(Selection.Parts,"\067\111\108\111\114")G.UI.Controls.ColorPickerButton.ImageColor3=t or G.BrickColor or Color3.new(1,0,0)end function SetColor(t)G.BrickColor=t local q=BrickColor.new(t)local U=("\040\037\100\044 \037\100\044 \037\100\041"):format(t.r*255,t.g*255,t.b*255)local O=q.Color==t and q.Name or U local j=G.UI.Controls.LastColorButton.ColorName local c=j.ColorSquare j.Visible=true j.Text=O c.BackgroundColor3=t c.Position=UDim2.new(1,-j.TextBounds.X-18,.2,1)PaintParts()end function PaintParts()if not G.BrickColor or#Selection.Parts==0 then return end local t=PaintHistoryRecord.new()t.TargetColor=G.BrickColor t:Apply(true)Core.History.Add(t)end function PreviewColor(G)if not G and InitialState then for G,t in pairs(InitialState)do G.Color=t.Color if G.ClassName=="\085\110\105\111\110\079\112\101\114\097\116\105\111\110"then G.UsePartColor=t.UsePartColor end end InitialState=nil return elseif not G then return elseif not InitialState then InitialState={}for G,t in pairs(Selection.Parts)do InitialState[t]={Color=t.Color,UsePartColor=t.ClassName=="\085\110\105\111\110\079\112\101\114\097\116\105\111\110"and t.UsePartColor or nil}end end for t,q in pairs(Selection.Parts)do q.Color=G if q.ClassName=="\085\110\105\111\110\079\112\101\114\097\116\105\111\110"then q.UsePartColor=true end end end function G.BindShortcutKeys(G)G.Maid.Hotkeys=Support.AddUserInputListener("\066\101\103\097\110","\075\101\121\098\111\097\114\100",false,function(G)if G.KeyCode.Name=="\082\101\116\117\114\110"or G.KeyCode.Name=="\075\101\121\112\097\100\069\110\116\101\114"then return PaintParts()end if G.KeyCode.Name=="\082"and not Selection.Multiselecting then if Core.Mouse.Target then SetColor(Core.Mouse.Target.Color)end end end)end function G.EnableClickPainting(G)G.Maid.ClickPainting=Selection.FocusChanged:Connect(function(G)local t,q=Core.Targeting:UpdateTarget()if Selection.IsSelected(q)then PaintParts()end end)end
-- Initialize the tool
local PaintTool = {

	Name = "Paint Tool",
	Color = BrickColor.new("Really red"),

	-- Default options
	BrickColor = nil,
}

function PaintTool:Equip()
	-- Enables the tool's equipped functionality

	-- Set up maid for cleanup
	self.Maid = Maid.new()

	-- Start up our interface
	ShowUI()
	self:BindShortcutKeys()
	self:EnableClickPainting()
end

function PaintTool:Unequip()
	-- Disables the tool's equipped functionality

	-- Hide UI
	HideUI()

	-- Clean up resources
	self.Maid = self.Maid:Destroy()
end

function ShowUI()
	-- Creates and reveals the UI

	-- Reveal UI if already created
	if PaintTool.UI then
		-- Reveal the UI
		PaintTool.UI.Visible = true

		-- Update the UI every 0.1 seconds
		UIUpdater = Support.ScheduleRecurringTask(UpdateUI, 0.1)

		-- Skip UI creation
		return
	end

	-- Create the UI
	PaintTool.UI = Core.Tool.Interfaces.BTPaintToolGUI:Clone()
	PaintTool.UI.Parent = Core.UI
	PaintTool.UI.Visible = true

	-- Track palette buttons
	PaletteButtons = {}

	-- Enable the palette
	for _, Column in pairs(PaintTool.UI.Palette:GetChildren()) do
		for _, Button in pairs(Column:GetChildren()) do
			if Button.ClassName == "TextButton" then
				-- Recolor the selection when the button is clicked
				Button.MouseButton1Click:Connect(function()
					SetColor(BrickColor.new(Button.Name).Color)
				end)

				-- Register the button
				PaletteButtons[Button.Name] = Button
			end
		end
	end

	-- Paint selection when current color indicator is clicked
	PaintTool.UI.Controls.LastColorButton.MouseButton1Click:Connect(PaintParts)

	-- Enable color picker button
	PaintTool.UI.Controls.ColorPickerButton.MouseButton1Click:Connect(function()
		Core.Cheer(Core.Tool.Interfaces.BTHSVColorPicker, Core.UI).Start(
			Support.IdentifyCommonProperty(Selection.Parts, "Color") or Color3.new(1, 1, 1),
			SetColor,
			Core.Targeting.CancelSelecting,
			PreviewColor
		)
	end)

	-- Update the UI every 0.1 seconds
	UIUpdater = Support.ScheduleRecurringTask(UpdateUI, 0.1)
end

function HideUI()
	-- Hides the tool UI

	-- Make sure there's a UI
	if not PaintTool.UI then
		return
	end

	-- Hide the UI
	PaintTool.UI.Visible = false

	-- Stop updating the UI
	UIUpdater:Stop()
end

function UpdateUI()
	-- Updates information on the UI

	-- Make sure the UI's on
	if not PaintTool.UI then
		return
	end

	-----------------------------------------
	-- Update the color information indicator
	-----------------------------------------

	-- Clear old color indicators
	for Color, Button in pairs(PaletteButtons) do
		Button.Text = ""
	end

	-- Indicate the variety of colors in the selection
	for _, Part in pairs(Selection.Parts) do
		if PaletteButtons[Part.BrickColor.Name] and Part.Color == Part.BrickColor.Color then
			PaletteButtons[Part.BrickColor.Name].Text = "+"
		end
	end

	-- Update the color picker button's background
	local CommonColor = Support.IdentifyCommonProperty(Selection.Parts, "Color")
	PaintTool.UI.Controls.ColorPickerButton.ImageColor3 = CommonColor or PaintTool.BrickColor or Color3.new(1, 0, 0)
end

function SetColor(Color)
	-- Changes the color option to `Color`

	-- Set the color option
	PaintTool.BrickColor = Color

	-- Use BrickColor name if color matches one
	local EquivalentBrickColor = BrickColor.new(Color)
	local RGBText = ("(%d, %d, %d)"):format(Color.r * 255, Color.g * 255, Color.b * 255)
	local ColorText = (EquivalentBrickColor.Color == Color) and EquivalentBrickColor.Name or RGBText

	-- Shortcuts to color indicators
	local ColorLabel = PaintTool.UI.Controls.LastColorButton.ColorName
	local ColorSquare = ColorLabel.ColorSquare

	-- Update the indicators
	ColorLabel.Visible = true
	ColorLabel.Text = ColorText
	ColorSquare.BackgroundColor3 = Color
	ColorSquare.Position = UDim2.new(1, -ColorLabel.TextBounds.X - 18, 0.2, 1)

	-- Paint currently selected parts
	PaintParts()
end

function PaintParts()
	-- Recolors the selection with the selected color

	-- Make sure painting is possible
	if (not PaintTool.BrickColor) or (#Selection.Parts == 0) then
		return
	end

	-- Create history record
	local Record = PaintHistoryRecord.new()
	Record.TargetColor = PaintTool.BrickColor

	-- Perform action
	Record:Apply(true)

	-- Register history record
	Core.History.Add(Record)
end

function PreviewColor(Color)
	-- Previews the given color on the selection

	-- Reset colors to initial state if previewing is over
	if not Color and InitialState then
		for Part, State in pairs(InitialState) do
			-- Reset part color
			Part.Color = State.Color

			-- Update union coloring options
			if Part.ClassName == "UnionOperation" then
				Part.UsePartColor = State.UsePartColor
			end
		end

		-- Clear initial state
		InitialState = nil

		-- Skip rest of function
		return

	-- Ensure valid color is given
	elseif not Color then
		return

	-- Save initial state if first time previewing
	elseif not InitialState then
		InitialState = {}
		for _, Part in pairs(Selection.Parts) do
			InitialState[Part] =
				{ Color = Part.Color, UsePartColor = (Part.ClassName == "UnionOperation") and Part.UsePartColor or nil }
		end
	end

	-- Apply preview color
	for _, Part in pairs(Selection.Parts) do
		Part.Color = Color

		-- Enable union coloring
		if Part.ClassName == "UnionOperation" then
			Part.UsePartColor = true
		end
	end
end

function PaintTool:BindShortcutKeys()
	-- Enables useful shortcut keys for this tool

	-- Track user input while this tool is equipped
	self.Maid.Hotkeys = Support.AddUserInputListener("Began", "Keyboard", false, function(Input)
		-- Paint selection if Enter is pressed
		if (Input.KeyCode.Name == "Return") or (Input.KeyCode.Name == "KeypadEnter") then
			return PaintParts()
		end

		-- Check if the R key was pressed, and it wasn't the selection clearing hotkey
		if (Input.KeyCode.Name == "R") and not Selection.Multiselecting then
			-- Set the current color to that of the current mouse target (if any)
			if Core.Mouse.Target then
				SetColor(Core.Mouse.Target.Color)
			end
		end
	end)
end

function PaintTool:EnableClickPainting()
	-- Allows the player to paint parts by clicking on them

	-- Watch out for clicks on selected parts
	self.Maid.ClickPainting = Selection.FocusChanged:Connect(function(Focus)
		local Target, ScopeTarget = Core.Targeting:UpdateTarget()
		if Selection.IsSelected(ScopeTarget) then
			-- Paint the selected parts
			PaintParts()
		end
	end)
end
