--[[
Created April 2022
Originally created as a reference for VIPER to create our C++ external Autoplayer from
Only uses instances to autoplay
]]
local keys = {} -- MAKE THIS YOUR ROBEATS KEYBINDS FROM LEFT TO RIGHT (or let it auto grab)
local VirtualInputManager = Instance.new("VirtualInputManager")
local camera = workspace.CurrentCamera
local Autoplayer = {
noteY = 3879,
sliderY = 3878,
laneDistanceThreshold = 25,
distanceLowerBound = 0.2,
distanceUpperBound = 0.6,
delayLowerBound = 0.03,
delayUpperBound = 0.05,
sliderDebounce = 0.06,
random = Random.new(),
pressedLanes = {},
heldLanes = {},
currentLanePositionsIndex = nil,
lanePositions = {
{
Vector3.new(-309.00, 387.70, -181.09),
Vector3.new(-306.87, 387.70, -178.56),
Vector3.new(-304.53, 387.70, -176.21),
Vector3.new(-301.99, 387.70, -174.08)
},
{
Vector3.new(-301.99, 387.70, -235.64),
Vector3.new(-304.53, 387.70, -233.51),
Vector3.new(-306.87, 387.70, -231.16),
Vector3.new(-309.00, 387.70, -228.60)
},
{
Vector3.new(-247.44, 387.70, -228.63),
Vector3.new(-249.57, 387.70, -231.16),
Vector3.new(-251.92, 387.70, -233.51),
Vector3.new(-254.46, 387.70, -235.64)
},
{
Vector3.new(-254.46, 387.70, -174.08),
Vector3.new(-251.92, 387.70, -176.21),
Vector3.new(-249.57, 387.70, -178.56),
Vector3.new(-247.44, 387.70, -181.09)
}
}
}
local function UpdateLanePositions()
local nearestDistance = Autoplayer.laneDistanceThreshold
local nearestGroupIndex
for groupIndex, groupPositions in next, Autoplayer.lanePositions do
local distance = (groupPositions[1] - camera.CFrame.Position).Magnitude
if distance < nearestDistance then
nearestDistance = distance
nearestGroupIndex = groupIndex
end
end
Autoplayer.currentLanePositionsIndex = nearestGroupIndex
end
local function GetNearestLane(position)
UpdateLanePositions()
local nearestDistance = Autoplayer.laneDistanceThreshold
local nearestLane
for laneIndex, lanePosition in next, Autoplayer.lanePositions[Autoplayer.currentLanePositionsIndex] do
local distance = (lanePosition - position).Magnitude
if distance < nearestDistance then
nearestDistance = distance
nearestLane = { laneIndex, lanePosition}
end
end
if not nearestLane then
return
end
return nearestLane[1], nearestLane[2]
end
local function GrabKeys()
if #keys == 4 then
return
end
for _, child in next, workspace:GetChildren() do
if child:FindFirstChild("ControlPopup") then
for _, descendant in next, child:GetChildren() do
if descendant.Name == "ControlPopup" then
local popupLane = GetNearestLane(descendant.Position)
if popupLane then
keys[popupLane] = descendant.SurfaceGui.Frame.Letter.Text
end
end
end
end
end
end
for index, instance in next, workspace:GetDescendants() do
if instance.ClassName == "CylinderHandleAdornment" then
instance:GetPropertyChangedSignal("CFrame"):Connect(function()
GrabKeys()
if instance.Transparency == 0 and math.floor(instance.CFrame.Y * 10) == Autoplayer.noteY then
local noteLane, lanePosition = GetNearestLane(instance.CFrame.Position)
if noteLane then
local randomDistance = Autoplayer.random:NextNumber(Autoplayer.distanceLowerBound, Autoplayer.distanceUpperBound)
local distance = instance.CFrame.Position.X - lanePosition.X
if Autoplayer.currentLanePositionsIndex > 2 then
distance = math.abs(distance)
end
if not Autoplayer.pressedLanes[noteLane] and distance <= randomDistance then
Autoplayer.pressedLanes[noteLane] = true
VirtualInputManager:SendKeyEvent(true, keys[noteLane], false, game)
task.wait(Autoplayer.random:NextNumber(Autoplayer.delayLowerBound, Autoplayer.delayUpperBound))
VirtualInputManager:SendKeyEvent(false, keys[noteLane], false, game)
Autoplayer.pressedLanes[noteLane] = false
end
end
elseif instance.Transparency < 1 and instance.Height > 0.2 and math.floor(instance.CFrame.Y * 10) == Autoplayer.sliderY then
local noteLane, lanePosition = GetNearestLane(instance.CFrame.Position)
if noteLane then
local randomDistance = Autoplayer.random:NextNumber(Autoplayer.distanceLowerBound, Autoplayer.distanceUpperBound)
local distance = (instance.CFrame - instance.CFrame.LookVector * instance.Height / 2).X - lanePosition.X
if Autoplayer.currentLanePositionsIndex > 2 then
distance = math.abs(distance)
end
if not Autoplayer.heldLanes[noteLane] and distance <= randomDistance then
Autoplayer.heldLanes[noteLane] = true
VirtualInputManager:SendKeyEvent(true, keys[noteLane], false, game)
local noteDistance
repeat
noteDistance = (instance.CFrame + instance.CFrame.LookVector * instance.Height / 2).X - lanePosition.X
task.wait()
until (Autoplayer.currentLanePositionsIndex > 2 and math.abs(noteDistance) or noteDistance) <= randomDistance
VirtualInputManager:SendKeyEvent(false, keys[noteLane], false, game)
task.wait(Autoplayer.sliderDebounce)
Autoplayer.heldLanes[noteLane] = false
end
end
end
end)
end
end
Comments
No comments yet
Be the first to share your thoughts!