Quick actions

cmd+k|ctrl+k

Navigation

Languages

peanut

Snippet info

Language

Lua

Visibility

public

Author

zen

Created

2023-12-30T00:36:43.170058Z

Updated

2024-01-08T17:49:52.187913Z

--https://github.com/Mokiros/roblox-FE-compatibility
if game:GetService("RunService"):IsClient() then error("Script must be server-side in order to work; use h/ and not hl/") end
local Player,game,owner = owner,game
local RealPlayer = Player
do
	local RealPlayer = RealPlayer
	script.Parent = RealPlayer.Character

	--Fake event to make stuff like Mouse.KeyDown work
	local Disconnect_Function = function(this)
		this[1].Functions[this[2]] = nil
	end
	local Disconnect_Metatable = {__index={disconnect=Disconnect_Function,Disconnect=Disconnect_Function}}
	local FakeEvent_Metatable = {__index={
		Connect = function(this,f)
			local i = tostring(math.random(0,10000))
			while this.Functions[i] do
				i = tostring(math.random(0,10000))
			end
			this.Functions[i] = f
			return setmetatable({this,i},Disconnect_Metatable)
		end
	}}
	FakeEvent_Metatable.__index.connect = FakeEvent_Metatable.__index.Connect
	local function fakeEvent()
		return setmetatable({Functions={}},FakeEvent_Metatable)
	end

	--Creating fake input objects with fake variables
	local FakeMouse = {Hit=CFrame.new(),KeyUp=fakeEvent(),KeyDown=fakeEvent(),Button1Up=fakeEvent(),Button1Down=fakeEvent(),Button2Up=fakeEvent(),Button2Down=fakeEvent()}
	FakeMouse.keyUp = FakeMouse.KeyUp
	FakeMouse.keyDown = FakeMouse.KeyDown
	local UIS = {InputBegan=fakeEvent(),InputEnded=fakeEvent()}
	local CAS = {Actions={},BindAction=function(self,name,fun,touch,...)
		CAS.Actions[name] = fun and {Name=name,Function=fun,Keys={...}} or nil
	end}
	--Merged 2 functions into one by checking amount of arguments
	CAS.UnbindAction = CAS.BindAction

	--This function will trigger the events that have been :Connect()'ed
	local function TriggerEvent(self,ev,...)
		for _,f in pairs(self[ev].Functions) do
			f(...)
		end
	end
	FakeMouse.TriggerEvent = TriggerEvent
	UIS.TriggerEvent = TriggerEvent

	--Client communication
	local Event = Instance.new("RemoteEvent")
	Event.Name = "UserInput_Event"
	Event.OnServerEvent:Connect(function(plr,io,rbxHandled)
		if plr~=RealPlayer then return end
		FakeMouse.Target = io.Target
		FakeMouse.Hit = io.Hit
		if not io.isMouse then
			local b = io.UserInputState == Enum.UserInputState.Begin
			UIS:TriggerEvent(b and "InputBegan" or "InputEnded",io,rbxHandled)
			if io.UserInputType == Enum.UserInputType.MouseButton1 then
				return FakeMouse:TriggerEvent(b and "Button1Down" or "Button1Up")
			end
			if io.UserInputType == Enum.UserInputType.MouseButton2 then
				return FakeMouse:TriggerEvent(b and "Button2Down" or "Button2Up")
			end
			for _,t in pairs(CAS.Actions) do
				for _,k in pairs(t.Keys) do
					if k==io.KeyCode then
						t.Function(t.Name,io.UserInputState,io)
					end
				end
			end
			FakeMouse:TriggerEvent(b and "KeyDown" or "KeyUp",io.KeyCode.Name:lower())
			--UIS:TriggerEvent(b and "InputBegan" or "InputEnded",io,rbxHandled)
		end
	end)
	Event.Parent = NLS([==[local Event = script:WaitForChild("UserInput_Event")
	local Mouse = owner:GetMouse()
	local UIS = game:GetService("UserInputService")
	local input = function(io,RobloxHandled)
		--Since InputObject is a client-side instance, we create and pass table instead
		Event:FireServer({KeyCode=io.KeyCode,UserInputType=io.UserInputType,UserInputState=io.UserInputState,Hit=Mouse.Hit,Target=Mouse.Target},RobloxHandled)
	end
	UIS.InputBegan:Connect(input)
	UIS.InputEnded:Connect(input)

	local h,t
	--Give the server mouse data every second frame, but only if the values changed
	--If player is not moving their mouse, client won't fire events
	local HB = game:GetService("RunService").Heartbeat
	while true do
		if h~=Mouse.Hit or t~=Mouse.Target then
			h,t=Mouse.Hit,Mouse.Target
			Event:FireServer({isMouse=true,Target=t,Hit=h})
		end
		--Wait 2 frames
		for i=1,2 do
			HB:Wait()
		end
	end]==],script)

	----Sandboxed game object that allows the usage of client-side methods and services
	--Real game object
	local RealGame = game

	--Metatable for fake service
	local FakeService_Metatable = {
		__index = function(self,k)
			local s = rawget(self,"_RealService")
			if s then
				return typeof(s[k])=="function"
					and function(_,...)return s[k](s,...)end or s[k]
			end
		end,
		__newindex = function(self,k,v)
			local s = rawget(self,"_RealService")
			if s then s[k]=v end
		end
	}
	local function FakeService(t,RealService)
		t._RealService = typeof(RealService)=="string" and RealGame:GetService(RealService) or RealService
		return setmetatable(t,FakeService_Metatable)
	end

	--Fake game object
	local FakeGame = {
		GetService = function(self,s)
			return rawget(self,s) or RealGame:GetService(s)
		end,
		Players = FakeService({
			LocalPlayer = FakeService({GetMouse=function(self)return FakeMouse end},Player)
		},"Players"),
		UserInputService = FakeService(UIS,"UserInputService"),
		ContextActionService = FakeService(CAS,"ContextActionService"),
		RunService = FakeService({
			_btrs = {},
			RenderStepped = RealGame:GetService("RunService").Heartbeat,
			BindToRenderStep = function(self,name,_,fun)
				self._btrs[name] = self.Heartbeat:Connect(fun)
			end,
			UnbindFromRenderStep = function(self,name)
				self._btrs[name]:Disconnect()
			end,
		},"RunService")
	}
	rawset(FakeGame.Players,"localPlayer",FakeGame.Players.LocalPlayer)
	FakeGame.service = FakeGame.GetService
	FakeService(FakeGame,game)
	--Changing owner to fake player object to support owner:GetMouse()
	game,owner = FakeGame,FakeGame.Players.LocalPlayer
end

-- END

local SPEED = 110

local runService = game:GetService("RunService")
local userInput = game.UserInputService
local collectionService = game:GetService("CollectionService")

local character: Model = RealPlayer.Character or RealPlayer.CharacterAdded:Wait()
local mouse = owner:GetMouse()

local noKill = false
local shouldMove = true
local blink = false
local blinked = false
local willMove = false
local goFast = false

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {character}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude

local humanoid: Humanoid = character:WaitForChild("Humanoid")
local lastPosition = humanoid.RootPart.Position

for _,x in ipairs(character:GetDescendants()) do
	if x:IsA("Accessory") or x:IsA("Decal") or x:IsA("Sound") then
		x:Destroy()
	end

	if x:IsA("BasePart") and x ~= humanoid.RootPart and not x:FindFirstAncestorWhichIsA("Tool") then
		x.Transparency = 1
	end
end

for _,char in ipairs(workspace:GetChildren()) do
	if char:IsA("Model") and char:FindFirstChildWhichIsA("Humanoid") then
		raycastParams:AddToFilter(char)
	end
end

local teleporting = Instance.new("BoolValue")
teleporting.Name = "Teleporting"
teleporting.Parent = character

local looked = Instance.new("BoolValue")
looked.Name = "Looked"
looked.Parent = character

local canmove = Instance.new("BoolValue")
canmove.Name = "CanMove"
canmove.Parent = character

local moveSounds = {
	"rbxassetid://15869750783",
	"rbxassetid://15869752342",
	--"rbxassetid://15869754306"
}

local moveSound = Instance.new("Sound")
moveSound.Parent = humanoid.RootPart or character:WaitForChild("HumanoidRootPart")
moveSound.Volume = 0.5
moveSound.SoundId = moveSounds[math.random(1,#moveSounds)]
moveSound.Looped = false
local blinkMoveSound = Instance.new("Sound")
blinkMoveSound.Parent = humanoid.RootPart or character:WaitForChild("HumanoidRootPart")
blinkMoveSound.Volume = 3
blinkMoveSound.SoundId = "rbxassetid://7785668624"

humanoid.MaxHealth = math.huge
humanoid.Health = humanoid.MaxHealth

humanoid.HealthDisplayType = Enum.HumanoidHealthDisplayType.AlwaysOn
humanoid.HealthDisplayDistance = math.huge
humanoid.WalkSpeed = SPEED
humanoid.RootPart.Transparency = 0

local mesh = Instance.new("SpecialMesh")
mesh.MeshId = "rbxassetid://7176615085"
mesh.TextureId = "rbxassetid://7176615317"
mesh.Scale = Vector3.new(0.02,0.02,0.02)
mesh.Offset = Vector3.new(0,0.6,0)
mesh.Parent = humanoid.RootPart



NLS([==[
local runService = game:GetService("RunService")
local userInput = game:GetService("UserInputService")
local mouse = owner:GetMouse()
local character = owner.Character or owner.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local teleporting = character:WaitForChild("Teleporting")
local looked = character:WaitForChild("Looked")
local canmove = character:WaitForChild("CanMove")

local part = Instance.new("Part")
part.Name = "Target"
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Anchored = true
part.Size = Vector3.new(2,2,1)
part.Parent = character

local mesh = Instance.new("SpecialMesh")
mesh.MeshId = "rbxassetid://7176615085"
mesh.TextureId = "rbxassetid://7176615317"
mesh.Scale = Vector3.new(0.02,0.02,0.02)
mesh.Offset = Vector3.new(0,0.6,0)
mesh.Parent = part

runService.RenderStepped:Connect(function()
	if workspace.CurrentCamera then
		workspace.CurrentCamera.FieldOfView = 90
	end
	
	if looked.Value then
		if canmove.Value then
			userInput.MouseIcon = "rbxassetid://15821955138"
		else
			userInput.MouseIcon = "rbxassetid://15821823896"
		end
	else
		userInput.MouseIcon = ""
	end
	
	part.LocalTransparencyModifier = 0
	if teleporting.Value and mouse.Target then
		local distance = (mouse.Hit.Position - humanoid.RootPart.Position).Magnitude
		if distance > 80 then
			mesh.VertexColor = Vector3.new(1,0,0)
		else
			mesh.VertexColor = Vector3.new(0,1,0)
		end
		part.Transparency = 0.5
		part.Position = mouse.Hit.Position + Vector3.new(0,3,0)
	else
		part.Transparency = 1
	end
end)

]==],character)

local function createFilth(position: Vector3)
	local part = Instance.new("Part")
	part.Name = "Filth"
	part.Size = Vector3.new(0.1,10,10)
	part.CFrame = CFrame.new(position) * CFrame.Angles(0,0,math.rad(90))
	part.Anchored = true
	part.CanCollide = false
	part.CanQuery = true
	part.CanTouch = true
	part.Shape = Enum.PartType.Cylinder
	part.Material = Enum.Material.CorrodedMetal
	part.BrickColor = BrickColor.new("Black")
	part.Parent = workspace
	local texture = part:Clone()
	texture.Size += Vector3.new(0.1,0.1,0.1)
	texture.BrickColor = BrickColor.new("Really black")
	texture.Material = Enum.Material.SmoothPlastic
	texture.Transparency = 0.4
	texture.Anchored = false
	texture.CanQuery = false
	texture.CanTouch = false
	texture.Massless = true
	texture.Parent = part
	local weld = Instance.new("Weld")
	weld.Name = "FilthTextureWeld"
	weld.Parent = part
	weld.Part0 = part
	weld.Part1 = texture
	
	collectionService:AddTag(part,"Filth")
end

local function kill()
    if noKill then return end
	local parts = workspace:GetPartBoundsInRadius(humanoid.RootPart.Position,2)
	for _,part in ipairs(parts) do
		if part:IsA("BasePart") then
			local model = part:FindFirstAncestorWhichIsA("Model")
			if model == character then continue end
			local vHumanoid = model:FindFirstChildWhichIsA("Humanoid")
			if not vHumanoid or vHumanoid.Health <= 0 then continue end
			vHumanoid.MaxHealth = 1
			vHumanoid.Health = 0.1
			vHumanoid:TakeDamage(math.huge)
			model:BreakJoints()
			
			local vRoot = vHumanoid.RootPart or model.PrimaryPart or model:FindFirstChild("HumanoidRootPart")
			
			if vRoot then
				local sound = Instance.new("Sound")
				sound.SoundId = "rbxassetid://8464330434"
				sound.Volume = 2
				sound.Parent = vRoot
				sound:Play()
				
				local c
				c = sound.Ended:Connect(function()
					sound:Destroy()
					c:Disconnect()
				end)
			end
			
			break
		end
	end
end

character.DescendantAdded:Connect(function(x)
	if x:IsA("Accessory") or x:IsA("Decal") then
		x:Destroy()
	end

	if x:IsA("BasePart") and x ~= humanoid.RootPart and not x:FindFirstAncestorWhichIsA("Tool") then
		x.Transparency = 1
	end
end)

workspace.ChildAdded:Connect(function(char)
	if char:IsA("Model") and char:FindFirstChildWhichIsA("Humanoid") then
		raycastParams:AddToFilter(char)
	end
end)

userInput.InputBegan:Connect(function(input,chatted)
	if chatted then return end
	if input.KeyCode == Enum.KeyCode.Y then
	   noKill = not noKill
	end
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		
		if willMove then
			local distance = (mouse.Hit.Position - humanoid.RootPart.Position).Magnitude
			if distance > 80 then
				return
			end
			blinkMoveSound:Play()
			humanoid.RootPart.Position = mouse.Hit.Position + Vector3.new(0,3,0)
			kill()
			blinked = false
			willMove = false
		else
			kill()
		end
	end
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		if not willMove and blinked then
			willMove = true
		end
	end
	if input.KeyCode == Enum.KeyCode.F then
		local raycast = workspace:Raycast(humanoid.RootPart.Position,Vector3.new(0,-100,0),raycastParams)
		
		if raycast then
			createFilth(raycast.Position)
		end
	end
	if input.KeyCode == Enum.KeyCode.LeftShift then
		goFast = not goFast
	end
end)

coroutine.wrap(function()
	while task.wait(1) do
		if not shouldMove then
			blinked = true
		end
		blink = true
		task.wait(0.1)
		blink = false
	end
end)()

runService.Stepped:Connect(function()
	
	humanoid.Health = humanoid.MaxHealth
	
	shouldMove = true

	for _,human in ipairs(workspace:GetChildren()) do
		local vHumanoid = human:FindFirstChildWhichIsA("Humanoid")
		if not vHumanoid or not vHumanoid.RootPart or vHumanoid.Health <= 0 then continue end
		
		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {character,human}
		raycastParams.FilterType = Enum.RaycastFilterType.Exclude
		
		local raycast = workspace:Raycast(
			humanoid.RootPart.Position,
			vHumanoid.RootPart.Position - humanoid.RootPart.Position,
			raycastParams
		)
		
		if raycast then continue end

		local distance_from_player = (humanoid.RootPart.Position - vHumanoid.RootPart.Position).Unit
		local look = vHumanoid.RootPart.CFrame.LookVector

		local dot = look:Dot(distance_from_player)

		local angle = math.deg(math.acos(dot))

		if angle < 100 / 2 then
			shouldMove = false
			break
		end
	end
	
	teleporting.Value = willMove
	looked.Value = not shouldMove
	canmove.Value = blinked

	if shouldMove then
		blinked = false
		if goFast then
			humanoid.WalkSpeed = SPEED * 2
		else
			humanoid.WalkSpeed = SPEED
		end
		if humanoid.MoveDirection.Magnitude > 0 then
			if not moveSound.IsPlaying then
				moveSound.SoundId = moveSounds[math.random(1,#moveSounds)]
				moveSound:Play()
			end
		else
			if moveSound.IsPlaying then
				moveSound:Pause()
			end
		end
	else
		humanoid.WalkSpeed = 0
		moveSound:Pause()
	end
end)

for _,x in ipairs(collectionService:GetTagged("Filth")) do
	if not x:IsA("BasePart") then continue end

	x.Touched:Connect(function(part)
		local hit = part:FindFirstAncestorWhichIsA("Model")
		if not hit then return end
		local humanoid = hit:FindFirstChildWhichIsA("Humanoid")
		if not humanoid then return end
		humanoid.WalkSpeed *= 0.7
	end)
end

collectionService:GetInstanceAddedSignal("Filth"):Connect(function(x: Instance)
	if not x:IsA("BasePart") then return end
	
	x.Touched:Connect(function(part)
		local hit = part:FindFirstAncestorWhichIsA("Model")
		if not hit then return end
		local humanoid = hit:FindFirstChildWhichIsA("Humanoid")
		if not humanoid then return end
		humanoid.WalkSpeed *= 0.7
	end)
end)
INFO