-
HttpService
true
-
Lighting
0.5699999928474426
0.5699999928474426
0.5699999928474426
0.8899999856948853
true
0.07999999821186066
3
11:30:00
-
ReplicatedStorage
-
CharacterComponents
-
BaseStateMachineRef
-
ClientCharacterComponents
-
ClientAnimate
animTable[animName][idx].weight) do
roll = roll - animTable[animName][idx].weight
idx = idx + 1
end
return idx
end
-----------------------------------------------------------------------------------------------------------------------
function AnimateComponent:ConfigureAnimationSet(name, fileList)
if self.AnimTable[name] ~= nil then
for _, connection in pairs(self.AnimTable[name].connections) do
connection:disconnect()
end
end
self.AnimTable[name] = {}
self.AnimTable[name].count = 0
self.AnimTable[name].totalWeight = 0
self.AnimTable[name].connections = {}
local allowCustomAnimations = true
local success, _ = pcall(function()
allowCustomAnimations = game:GetService("StarterPlayer").AllowCustomAnimations
end)
if not success then
allowCustomAnimations = true
end
-- check for config values
-- local config = script:FindFirstChild(name)
if allowCustomAnimations and self.ConfigObject then
local config = self.ConfigObject:FindFirstChild(name)
if config ~= nil then
table.insert(self.AnimTable[name].connections,
config.ChildAdded:connect(function(_) self:ConfigureAnimationSet(name, fileList) end))
table.insert(self.AnimTable[name].connections,
config.ChildRemoved:connect(function(_) self:ConfigureAnimationSet(name, fileList) end))
local idx
for _, childPart in pairs(config:GetChildren()) do
if childPart:IsA("Animation") then
local newWeight = 1
local weightObject = childPart:FindFirstChild("Weight")
if weightObject ~= nil then
newWeight = weightObject.Value
end
self.AnimTable[name].count = self.AnimTable[name].count + 1
idx = self.AnimTable[name].count
self.AnimTable[name][idx] = {}
self.AnimTable[name][idx].anim = childPart
self.AnimTable[name][idx].weight = newWeight
self.AnimTable[name].totalWeight = self.AnimTable[name].totalWeight +
self.AnimTable[name][idx].weight
table.insert(self.AnimTable[name].connections,
childPart.Changed:connect(function(_) self:ConfigureAnimationSet(name, fileList) end))
table.insert(self.AnimTable[name].connections,
childPart.ChildAdded:connect(function(_) self:ConfigureAnimationSet(name, fileList) end))
table.insert(self.AnimTable[name].connections,
childPart.ChildRemoved:connect(function(_) self:ConfigureAnimationSet(name, fileList) end))
end
end
end
end
-- fallback to defaults
if self.AnimTable[name].count <= 0 then
for idx, anim in pairs(fileList) do
self.AnimTable[name][idx] = {}
self.AnimTable[name][idx].anim = Instance.new("Animation")
self.AnimTable[name][idx].anim.Name = name
self.AnimTable[name][idx].anim.AnimationId = anim.id
self.AnimTable[name][idx].weight = anim.weight
self.AnimTable[name].count = self.AnimTable[name].count + 1
self.AnimTable[name].totalWeight = self.AnimTable[name].totalWeight + anim.weight
end
end
-- preload anims
for _, animType in pairs(self.AnimTable) do
for idx = 1, animType.count, 1 do
if self.PreloadedAnims[animType[idx].anim.AnimationId] == nil then
self.AnimationController:LoadAnimation(animType[idx].anim)
self.PreloadedAnims[animType[idx].anim.AnimationId] = true
end
end
end
end
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
-- ANIMATION CONTROL FUNCTIONS
function AnimateComponent:StopAllAnimations()
local oldAnim = self.CurrentAnim
-- return to idle if finishing an emote
if emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false then
oldAnim = "idle"
end
self.CurrentAnim = ""
self.CurrentAnimInstance = nil
if self.CurrentAnimKeyframeHandler ~= nil then
self.CurrentAnimKeyframeHandler:disconnect()
end
if self.CurrentAnimTrack ~= nil then
self.CurrentAnimTrack:Stop()
self.CurrentAnimTrack:Destroy()
self.CurrentAnimTrack = nil
end
-- clean up walk if there is one
if self.RunAnimKeyframeHandler ~= nil then
self.RunAnimKeyframeHandler:disconnect()
end
if self.RunAnimTrack ~= nil then
self.RunAnimTrack:Stop()
self.RunAnimTrack:Destroy()
self.RunAnimTrack = nil
end
return oldAnim
end
function AnimateComponent:GetHeightScale()
if self.AnimationController then
local hipHeight = self.CharacterComponentInterface.Configurations["StepHeight"].Value
local scale = hipHeight / humanoidHipHeight
if self.AnimationSpeedDampeningObject == nil then
self.AnimationSpeedDampeningObject = script:FindFirstChild("ScaleDampeningPercent")
end
if self.AnimationSpeedDampeningObject ~= nil then
scale = 1 + (hipHeight - humanoidHipHeight) * self.AnimationSpeedDampeningObject.Value / humanoidHipHeight
end
return scale
end
return 1
end
local smallButNotZero = 0.0001
function AnimateComponent:SetRunSpeed(speed)
local speedScaled = speed * 1.25
local heightScale = self:GetHeightScale()
local runSpeed = speedScaled / heightScale
if runSpeed ~= self.CurrentAnimSpeed then
if runSpeed < 0.33 then
self.CurrentAnimTrack:AdjustWeight(1.0)
self.RunAnimTrack:AdjustWeight(smallButNotZero)
elseif runSpeed < 0.66 then
local weight = ((runSpeed - 0.33) / 0.33)
self.CurrentAnimTrack:AdjustWeight(1.0 - weight + smallButNotZero)
self.RunAnimTrack:AdjustWeight(weight + smallButNotZero)
else
self.CurrentAnimTrack:AdjustWeight(smallButNotZero)
self.RunAnimTrack:AdjustWeight(1.0)
end
self.CurrentAnimSpeed = runSpeed
self.RunAnimTrack:AdjustSpeed(runSpeed)
self.CurrentAnimTrack:AdjustSpeed(runSpeed)
end
end
function AnimateComponent:SetAnimationSpeed(speed)
if self.CurrentAnim == "walk" then
self:SetRunSpeed(speed)
else
if speed ~= self.CurrentAnimSpeed then
self.CurrentAnimSpeed = speed
self.CurrentAnimTrack:AdjustSpeed(self.CurrentAnimSpeed)
end
end
end
function AnimateComponent:KeyFrameReachedFunc(frameName)
if frameName == "End" then
if self.CurrentAnim == "walk" then
if self.RunAnimTrack.Looped ~= true then
self.RunAnimTrack.TimePosition = 0.0
end
if self.CurrentAnimTrack.Looped ~= true then
self.CurrentAnimTrack.TimePosition = 0.0
end
else
local repeatAnim = self.CurrentAnim
-- return to idle if finishing an emote
if emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false then
repeatAnim = "idle"
end
local animSpeed = self.CurrentAnimSpeed
self:PlayAnimation(repeatAnim, 0.15, self.AnimationController, true)
self:SetAnimationSpeed(animSpeed)
end
end
end
function AnimateComponent:PlayAnimation(animName, transitionTime, animationController, forceReroll)
local idx = RollAnimation(animName, self.AnimTable)
local anim = self.AnimTable[animName][idx].anim
-- switch animation
if (anim ~= self.CurrentAnimInstance) and ((animName ~= self.CurrentAnim) or forceReroll) then
if self.CurrentAnimTrack ~= nil then
self.CurrentAnimTrack:Stop(transitionTime)
self.CurrentAnimTrack:Destroy()
end
if self.RunAnimTrack ~= nil then
self.RunAnimTrack:Stop(transitionTime)
self.RunAnimTrack:Destroy()
self.RunAnimTrack = nil
end
self.CurrentAnimSpeed = 1.0
-- load it to the animationController; get AnimationTrack
self.CurrentAnimTrack = animationController:LoadAnimation(anim)
self.CurrentAnimTrack.Priority = Enum.AnimationPriority.Core
-- play the animation
self.CurrentAnimTrack:Play(transitionTime)
self.CurrentAnim = animName
self.CurrentAnimInstance = anim
-- set up keyframe name triggers
if self.CurrentAnimKeyframeHandler ~= nil then
self.CurrentAnimKeyframeHandler:disconnect()
end
self.CurrentAnimKeyframeHandler = self.CurrentAnimTrack.KeyframeReached:connect(
function(keyframeName)
self:KeyFrameReachedFunc(keyframeName)
end)
-- check to see if we need to blend a walk/run animation
if animName == "walk" then
local runAnimName = "run"
local runIdx = RollAnimation(runAnimName, self.AnimTable)
self.RunAnimTrack = animationController:LoadAnimation(self.AnimTable[runAnimName][runIdx].anim)
self.RunAnimTrack.Priority = Enum.AnimationPriority.Core
self.RunAnimTrack:Play(transitionTime)
if self.RunAnimKeyframeHandler ~= nil then
self.RunAnimKeyframeHandler:disconnect()
end
self.RunAnimKeyframeHandler = self.RunAnimTrack.KeyframeReached:connect(
function(keyframeName)
self:KeyFrameReachedFunc(keyframeName)
end)
end
end
end
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
-- STATE CHANGE HANDLERS
function AnimateComponent:OnRunning(speed)
if speed > 0.5 then
local scale = 16.0
self:PlayAnimation("walk", 0.2, self.AnimationController)
self:SetAnimationSpeed(speed / scale)
self.Pose = "Running"
else
if emoteNames[self.CurrentAnim] == nil then
self:PlayAnimation("idle", 0.2, self.AnimationController)
self.Pose = "Standing"
end
end
end
function AnimateComponent:OnJumping()
self:PlayAnimation("jump", 0.1, self.AnimationController)
self.JumpAnimTime = jumpAnimDuration
self.Pose = "Jumping"
end
function AnimateComponent:OnClimbing(speed)
local scale = 5.0
self:PlayAnimation("climb", 0.1, self.AnimationController)
self:SetAnimationSpeed(speed / scale)
self.Pose = "Climbing"
end
function AnimateComponent:OnGettingUp()
self.Pose = "GettingUp"
end
function AnimateComponent:OnFreeFall()
if self.JumpAnimTime <= 0 then
self:PlayAnimation("fall", fallTransitionTime, self.AnimationController)
end
self.Pose = "FreeFall"
end
function AnimateComponent:OnFallingDown()
self.Pose = "FallingDown"
end
function AnimateComponent:OnSeated()
self.Pose = "Seated"
end
function AnimateComponent:OnPlatformStanding()
self.Pose = "PlatformStanding"
end
function AnimateComponent:OnSwimming(speed)
if speed > 1.00 then
local scale = 10.0
self:PlayAnimation("swim", 0.4, self.AnimationController)
self:SetAnimationSpeed(speed / scale)
self.Pose = "Swimming"
else
self:PlayAnimation("swimidle", 0.4, self.AnimationController)
self.Pose = "Standing"
end
end
-- connect events
function AnimateComponent:OnStateChanged(NewStateName)
if NewStateName then
if NewStateName == "GroundState" then
self.Pose = "Running"
elseif NewStateName == "JumpState" then
self:OnJumping()
elseif NewStateName == "AirState" then
self:OnFreeFall()
elseif NewStateName == "LadderState" then
self.Pose = "Climbing"
end
-- print(NewStateName)
end
end
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
local function getToolAnim(tool)
for _, c in ipairs(tool:GetChildren()) do
if c.Name == "toolanim" and c.className == "StringValue" then
return c
end
end
return nil
end
function AnimateComponent:ToolKeyFrameReachedFunc(frameName)
if frameName == "End" then
self:PlayToolAnimation(self.ToolAnimName, 0.0, self.AnimationController)
end
end
function AnimateComponent:PlayToolAnimation(animName, transitionTime, animationController, priority)
local idx = RollAnimation(animName, self.AnimTable)
local anim = self.AnimTable[animName][idx].anim
if self.ToolAnimInstance ~= anim then
if self.ToolAnimTrack ~= nil then
self.ToolAnimTrack:Stop()
self.ToolAnimTrack:Destroy()
transitionTime = 0
end
-- load it to the animationController; get AnimationTrack
self.ToolAnimTrack = animationController:LoadAnimation(anim)
if priority then
self.ToolAnimTrack.Priority = priority
end
-- play the animation
self.ToolAnimTrack:Play(transitionTime)
self.ToolAnimName = animName
self.ToolAnimInstance = anim
self.CurrentToolAnimKeyframeHandler = self.ToolAnimTrack.KeyframeReached:connect(
function(keyframeName)
self:ToolKeyFrameReachedFunc(keyframeName)
end)
end
end
function AnimateComponent:StopToolAnimations()
local oldAnim = self.ToolAnimName
if self.CurrentToolAnimKeyframeHandler ~= nil then
self.CurrentToolAnimKeyframeHandler:disconnect()
end
self.ToolAnimName = ""
self.ToolAnimInstance = nil
if self.ToolAnimTrack ~= nil then
self.ToolAnimTrack:Stop()
self.ToolAnimTrack:Destroy()
self.ToolAnimTrack = nil
end
return oldAnim
end
function AnimateComponent:AnimateTool()
if self.ToolAnim == "None" then
self:PlayToolAnimation("toolnone", toolTransitionTime, self.AnimationController,
Enum.AnimationPriority.Idle)
return
end
if self.ToolAnim == "Slash" then
self:PlayToolAnimation("toolslash", 0, self.AnimationController, Enum.AnimationPriority.Action)
return
end
if self.ToolAnim == "Lunge" then
self:PlayToolAnimation("toollunge", 0, self.AnimationController, Enum.AnimationPriority.Action)
return
end
end
-----------------------------------------------------------------------------------------------------------------------
function AnimateComponent:StepAnimate(deltaTime)
if self.JumpAnimTime > 0 then
self.JumpAnimTime = self.JumpAnimTime - deltaTime
end
if self.Pose == "FreeFall" and self.JumpAnimTime <= 0 then
self:PlayAnimation("fall", fallTransitionTime, self.AnimationController)
elseif self.Pose == "Seated" then
self:PlayAnimation("sit", 0.5, self.AnimationController)
return
elseif self.Pose == "Climbing" then
local velocity = self.CharacterComponentInterface:GetVariable("WorldVelocity")
local speed = velocity.Magnitude
self:OnClimbing(speed)
elseif self.Pose == "Running" or self.Pose == "Standing" then
local velocity = self.CharacterComponentInterface:GetVariable("WorldVelocity")
local speed = velocity.Magnitude
self:OnRunning(speed)
elseif self.Pose == "Dead" or self.Pose == "GettingUp" or self.Pose == "FallingDown" or
self.Pose == "Seated" or self.Pose == "PlatformStanding" then
self:StopAllAnimations()
end
-- Tool Animation handling
local tool = self.characterModel:FindFirstChildOfClass("Tool")
if tool and tool:FindFirstChild("Handle") then
local animStringValueObject = getToolAnim(tool)
if animStringValueObject then
self.ToolAnim = animStringValueObject.Value
-- message recieved, delete StringValue
animStringValueObject.Parent = nil
self.ToolAnimTime = self.ToolAnimTime + deltaTime
end
if self.ToolAnimTime > toolAnimDuration then
self.ToolAnimTime = 0
self.ToolAnim = "None"
end
self:AnimateTool()
else
self:StopToolAnimations()
self.ToolAnim = "None"
self.ToolAnimInstance = nil
self.ToolAnimTime = 0
end
end
-----------------------------------------------------------------------------------------------------------------------
-- Setup animation objects
function AnimateComponent:ScriptChildModified(child)
local fileList = animNames[child.Name]
if fileList ~= nil then
self:ConfigureAnimationSet(child.Name, fileList)
end
end
-----------------------------------------------------------------------------------------------------------------------
function AnimateComponent.new(CharacterComponentInterface)
math.randomseed(tick())
local self = {
name = "AnimateComponent",
CharacterComponentInterface = CharacterComponentInterface,
characterModel = CharacterComponentInterface.characterModel,
AnimationController = CharacterComponentInterface.characterModel:WaitForChild("AnimationController"),
Pose = "Standing",
CurrentAnim = "",
CurrentAnimInstance = nil,
CurrentAnimTrack = nil,
CurrentAnimKeyframeHandler = nil,
CurrentAnimSpeed = 1.0,
RunAnimTrack = nil,
RunAnimKeyframeHandler = nil,
JumpAnimTime = 0,
ToolAnim = "None",
ToolAnimTime = 0,
ToolAnimName = "",
ToolAnimTrack = nil,
ToolAnimInstance = nil,
CurrentToolAnimKeyframeHandler = nil,
OnStateChangedEvent = nil,
PreloadedAnims = {},
AnimTable = {},
ChildAddedConnection = nil,
ChildRemovedConnection = nil
}
setmetatable(self, AnimateComponent)
-- set up configuration object
self.ConfigObject = CharacterComponentInterface.ConfigurationsObject:FindFirstChild("Animate")
if self.ConfigObject ~= nil then
self.AnimationSpeedDampeningObject = self.ConfigObject:FindFirstChild("ScaleDampeningPercent")
self.ChildAddedConnection = self.ConfigObject.ChildAdded:Connect(
function(child)
self:ScriptChildModified(child)
end)
self.ChildRemovedConnection = self.ConfigObject.ChildRemoved:Connect(
function(child)
self:ScriptChildModified(child)
end)
end
for name, fileList in pairs(animNames) do
self:ConfigureAnimationSet(name, fileList)
end
local OnStateChangedEventObject = nil
while not OnStateChangedEventObject do
OnStateChangedEventObject = CharacterComponentInterface:GetVariable("OnStateChanged")
wait()
end
self.OnStateChangedEvent = OnStateChangedEventObject.Event:Connect(
function(NewStateName)
self:OnStateChanged(NewStateName)
end)
-- setup emote chat hook
local localPlayer = Players.LocalPlayer
if localPlayer then
Players.LocalPlayer.Chatted:Connect(function(msg)
local emote = ""
if string.sub(msg, 1, 3) == "/e " then
emote = string.sub(msg, 4)
elseif string.sub(msg, 1, 7) == "/emote " then
emote = string.sub(msg, 8)
end
if self.Pose == "Standing" and emoteNames[emote] ~= nil then
self:PlayAnimation(emote, 0.1, self.AnimationController)
end
end)
end
-- initialize to idle
self:PlayAnimation("idle", 0.1, self.AnimationController)
self.Pose = "Standing"
CharacterComponentInterface:CallFunction("AddHeartbeatCallback",
function(s, dt)
if self.characterModel.Parent ~= nil then
self:StepAnimate(dt)
end
end, self, "earlyStepped", 150)
return self
end
function AnimateComponent:delete()
if self.OnStateChangedEvent then
self.OnStateChangedEvent:Disconnect()
end
if self.ChildAddedConnection then
self.ChildAddedConnection:Disconnect()
end
if self.ChildRemovedConnection then
self.ChildRemovedConnection:Disconnect()
end
self.CharacterComponentInterface:CallFunction("RemoveHeartbeatCallback", self, "earlyStepped")
end
return AnimateComponent
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
]]>
-
ClientAutoMove
-
ClientBodyColor
-
ClientControlStateMachine
-
AirState
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ AirState ]]--
local characterComponents = script.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseState = stateMachineRef.baseState
local AirState = setmetatable({}, baseState)
AirState.__index = AirState
AirState.airControlPercent = 0.8
AirState.airJumpCount = 1
function AirState.new()
local self = setmetatable(baseState.new(), AirState)
self.Name = script.Name
self.StateEnum = Enum.HumanoidStateType.Freefall
return self
end
function AirState:OnEnter(stateMachine)
local cci = stateMachine.characterComponentInterface
stateMachine.stateContext.AirStateNoJump = false
stateMachine.stateContext.JumpCount = 0
stateMachine.Impulse = Vector3.new(0, 0, 0)
cci:SetVariable("Jump", false)
cci:SetVariable("MovementAcceleration", 0.25)
end
function AirState:OnHeartbeat(stateMachine, _)
local cci = stateMachine.characterComponentInterface
local move = cci:GetVariable("MoveDirection", true) * stateMachine.stateContext.WalkSpeedConfig.Value
cci:SetVariable("TargetMovementVelocity", move)
cci:SetVariable("TargetFacing", move.Unit)
end
return AirState.new()
-
ClimbLadderTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ ClimbLadderTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local ClimbLadderTransition = setmetatable({}, baseTransition)
ClimbLadderTransition.__index = ClimbLadderTransition
function ClimbLadderTransition.new()
local self = setmetatable(baseTransition.new(), ClimbLadderTransition)
self.Name = script.Name
return self
end
function ClimbLadderTransition:Test(stateMachine)
local results = stateMachine.characterComponentInterface:GetVariable("HasLadder")
if not results then
stateMachine.stateContext.LadderLanded = false
end
return results and not stateMachine.stateContext.LadderLanded
end
return ClimbLadderTransition.new()
-
To
LadderState
-
DeadTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ DeadTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local DeadTransition = setmetatable({}, baseTransition)
DeadTransition.__index = DeadTransition
function DeadTransition.new()
local self = setmetatable(baseTransition.new(), DeadTransition)
self.Name = script.Name
return self
end
function DeadTransition:Test(stateMachine)
local died = false
local currentHealthConfig = stateMachine.characterComponentInterface.Configurations["CurrentHealth"]
if currentHealthConfig then
died = currentHealthConfig.Value <= 0
end
return died
end
return DeadTransition.new()
-
To
DeadState
-
LandedTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ LandedTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local LandedTransition = setmetatable({}, baseTransition)
LandedTransition.__index = LandedTransition
function LandedTransition.new()
local self = setmetatable(baseTransition.new(), LandedTransition)
self.Name = script.Name
return self
end
function LandedTransition:Test(stateMachine)
local cci = stateMachine.characterComponentInterface
return cci:GetVariable("IsGrounded") and stateMachine.characterModel.PrimaryPart.Velocity.Y < 1
end
return LandedTransition.new()
-
To
GroundState
-
WaterTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ WaterTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local WaterTransition = setmetatable({}, baseTransition)
WaterTransition.__index = WaterTransition
function WaterTransition.new()
local self = setmetatable(baseTransition.new(), WaterTransition)
self.Name = script.Name
return self
end
function WaterTransition:Test(stateMachine)
return stateMachine.characterComponentInterface:GetVariable("IsBuoyant")
end
return WaterTransition.new()
-
To
SwimState
-
DeadState
-
RespawnTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ RespawnTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local RespawnTransition = setmetatable({}, baseTransition)
RespawnTransition.__index = RespawnTransition
function RespawnTransition.new()
local self = setmetatable(baseTransition.new(), RespawnTransition)
self.Name = script.Name
return self
end
function RespawnTransition:Test(stateMachine)
local respawnTime = stateMachine.characterComponentInterface.Configurations["RespawnTime"].Value
return stateMachine.stateContext.timeInState >= respawnTime
end
return RespawnTransition.new()
-
To
GroundState
-
GroundState
0.01 and angle < maxAngle then
cci:SetVariable("TargetMovementVelocity", move)
cci:SetVariable("TargetFacing", move.Unit)
else
local side = normal:Cross(Vector3.new(0, 1, 0))
local down = normal:Cross(side)
cci:SetVariable("TargetMovementVelocity", down.Unit * walkSpeed)
cci:SetVariable("TargetFacing", move.Unit)
end
end
end
return GroundState
]]>
-
ClimbLadderTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ ClimbLadderTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local ClimbLadderTransition = setmetatable({}, baseTransition)
ClimbLadderTransition.__index = ClimbLadderTransition
function ClimbLadderTransition.new()
local self = setmetatable(baseTransition.new(), ClimbLadderTransition)
self.Name = script.Name
return self
end
function ClimbLadderTransition:Test(stateMachine)
local results = stateMachine.characterComponentInterface:GetVariable("HasLadder")
if not results then
stateMachine.stateContext.LadderLanded = false
end
return results and not stateMachine.stateContext.LadderLanded
end
return ClimbLadderTransition.new()
-
To
LadderState
-
DeadTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ DeadTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local DeadTransition = setmetatable({}, baseTransition)
DeadTransition.__index = DeadTransition
function DeadTransition.new()
local self = setmetatable(baseTransition.new(), DeadTransition)
self.Name = script.Name
return self
end
function DeadTransition:Test(stateMachine)
local died = false
local currentHealthConfig = stateMachine.characterComponentInterface.Configurations["CurrentHealth"]
if currentHealthConfig then
died = currentHealthConfig.Value <= 0
end
return died
end
return DeadTransition.new()
-
To
DeadState
-
JumpedTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ JumpedTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local JumpedTransition = setmetatable({}, baseTransition)
JumpedTransition.__index = JumpedTransition
function JumpedTransition.new()
local self = setmetatable(baseTransition.new(), JumpedTransition)
self.Name = script.Name
return self
end
function JumpedTransition:Test(stateMachine)
local cci = stateMachine.characterComponentInterface
if cci:GetVariable("IsGrounded") and cci:GetVariable("Jump") and cci:GetVariable("GroundDistance") < 1.015625 then
local normal = cci:GetVariable("SurfaceNormal")
local angle = math.acos(normal:Dot(Vector3.new(0, 1, 0))) * 180.0 / math.pi
local maxAngle = cci.Configurations["MaxSlopeAngle"].Value
if maxAngle > 0.01 and angle < maxAngle then
stateMachine.stateContext.JumpDir = Vector3.new(0, 1, 0)
return true
end
end
return false
end
return JumpedTransition.new()
-
To
JumpState
-
SitTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ Sit Transition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local SitTransition = setmetatable({}, baseTransition)
SitTransition.__index = SitTransition
function SitTransition.new()
local self = setmetatable(baseTransition.new(), SitTransition)
self.Name = script.Name
return self
end
function SitTransition:Test(stateMachine)
local SurfaceObject = stateMachine.characterComponentInterface:GetVariable("SurfacePart")
local lastSeat = 0.0
if stateMachine.stateContext.lastSeat ~= nil then
lastSeat = stateMachine.stateContext.lastSeat
end
return SurfaceObject ~= nil and
(SurfaceObject:IsA("Seat") or SurfaceObject:IsA("VehicleSeat")) and
SurfaceObject.Occupant == nil and
tick() - lastSeat > 2.0
end
return SitTransition.new()
-
To
SitState
-
TakeOffTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ TakeOffTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local TakeOffTransition = setmetatable({}, baseTransition)
TakeOffTransition.__index = TakeOffTransition
function TakeOffTransition.new()
local self = setmetatable(baseTransition.new(), TakeOffTransition)
self.Name = script.Name
return self
end
function TakeOffTransition:Test(stateMachine)
local v = not stateMachine.characterComponentInterface:GetVariable("IsGrounded")
return v
end
return TakeOffTransition.new()
-
To
AirState
-
WaterTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ WaterTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local WaterTransition = setmetatable({}, baseTransition)
WaterTransition.__index = WaterTransition
function WaterTransition.new()
local self = setmetatable(baseTransition.new(), WaterTransition)
self.Name = script.Name
return self
end
function WaterTransition:Test(stateMachine)
return stateMachine.characterComponentInterface:GetVariable("IsBuoyant")
end
return WaterTransition.new()
-
To
SwimState
-
JumpState
-
DeadTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ DeadTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local DeadTransition = setmetatable({}, baseTransition)
DeadTransition.__index = DeadTransition
function DeadTransition.new()
local self = setmetatable(baseTransition.new(), DeadTransition)
self.Name = script.Name
return self
end
function DeadTransition:Test(stateMachine)
local died = false
local currentHealthConfig = stateMachine.characterComponentInterface.Configurations["CurrentHealth"]
if currentHealthConfig then
died = currentHealthConfig.Value <= 0
end
return died
end
return DeadTransition.new()
-
To
DeadState
-
FlyTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ FlyTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local FlyTransition = setmetatable({}, baseTransition)
FlyTransition.__index = FlyTransition
function FlyTransition.new()
local self = setmetatable(baseTransition.new(), FlyTransition)
self.Name = script.Name
return self
end
function FlyTransition:Test(_)
return true
end
return FlyTransition.new()
-
To
AirState
-
LadderState
0.1 then
move = faceDir:Dot(moveDir)
end
local up = Vector3.new(0, move, 0)
cci:SetVariable("TargetMovementVelocity", up * stateMachine.stateContext.WalkSpeedConfig.Value)
end
return LadderState.new()
]]>
-
DeadTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ DeadTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local DeadTransition = setmetatable({}, baseTransition)
DeadTransition.__index = DeadTransition
function DeadTransition.new()
local self = setmetatable(baseTransition.new(), DeadTransition)
self.Name = script.Name
return self
end
function DeadTransition:Test(stateMachine)
local died = false
local currentHealthConfig = stateMachine.characterComponentInterface.Configurations["CurrentHealth"]
if currentHealthConfig then
died = currentHealthConfig.Value <= 0
end
return died
end
return DeadTransition.new()
-
To
DeadState
-
FlyTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ FlyTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local FlyTransition = setmetatable({}, baseTransition)
FlyTransition.__index = FlyTransition
function FlyTransition.new()
local self = setmetatable(baseTransition.new(), FlyTransition)
self.Name = script.Name
return self
end
function FlyTransition:Test(stateMachine)
return not stateMachine.characterComponentInterface:GetVariable("HasLadder")
end
return FlyTransition.new()
-
To
AirState
-
JumpedTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ JumpedTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local JumpedTransition = setmetatable({}, baseTransition)
JumpedTransition.__index = JumpedTransition
function JumpedTransition.new()
local self = setmetatable(baseTransition.new(), JumpedTransition)
self.Name = script.Name
return self
end
function JumpedTransition:Test(stateMachine)
local cci = stateMachine.characterComponentInterface
if cci:GetVariable("Jump") then
local cf = cci:GetVariable("WorldCFrame")
local faceDir = cf.LookVector
local jumpDir = Vector3.new(0, 1, 0) - faceDir
jumpDir = jumpDir.Unit
stateMachine.stateContext.JumpDir = jumpDir
return true
end
end
return JumpedTransition.new()
-
To
JumpState
-
LadderTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ LandedTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local LandedTransition = setmetatable({}, baseTransition)
LandedTransition.__index = LandedTransition
function LandedTransition.new()
local self = setmetatable(baseTransition.new(), LandedTransition)
self.Name = script.Name
return self
end
function LandedTransition:Test(stateMachine)
local cci = stateMachine.characterComponentInterface
if not cci:GetVariable("IsGrounded") then
stateMachine.stateContext.LostGround = true
elseif stateMachine.stateContext.LostGround
or cci:GetVariable("TargetMovementVelocity").Y < -0.1
or cci:GetVariable("GroundDistance") < 0.75
then
stateMachine.stateContext.LadderLanded = true
return true
end
return false
end
return LandedTransition.new()
-
To
GroundState
-
SitState
-
DeadTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ DeadTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local DeadTransition = setmetatable({}, baseTransition)
DeadTransition.__index = DeadTransition
function DeadTransition.new()
local self = setmetatable(baseTransition.new(), DeadTransition)
self.Name = script.Name
return self
end
function DeadTransition:Test(stateMachine)
local died = false
local currentHealthConfig = stateMachine.characterComponentInterface.Configurations["CurrentHealth"]
if currentHealthConfig then
died = currentHealthConfig.Value <= 0
end
return died
end
return DeadTransition.new()
-
To
DeadState
-
JumpedTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ JumpedTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local JumpedTransition = setmetatable({}, baseTransition)
JumpedTransition.__index = JumpedTransition
function JumpedTransition.new()
local self = setmetatable(baseTransition.new(), JumpedTransition)
self.Name = script.Name
return self
end
function JumpedTransition:Test(stateMachine)
local cci = stateMachine.characterComponentInterface
if cci:GetVariable("Jump") then
stateMachine.stateContext.JumpDir = Vector3.new(0, 1, 0)
return true
end
return false
end
return JumpedTransition.new()
-
To
JumpState
-
SwimState
-
ClimbLadderTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ ClimbLadderTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local ClimbLadderTransition = setmetatable({}, baseTransition)
ClimbLadderTransition.__index = ClimbLadderTransition
function ClimbLadderTransition.new()
local self = setmetatable(baseTransition.new(), ClimbLadderTransition)
self.Name = script.Name
return self
end
function ClimbLadderTransition:Test(stateMachine)
return stateMachine.characterComponentInterface:GetVariable("HasLadder")
end
return ClimbLadderTransition.new()
-
To
LadderState
-
DeadTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ DeadTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local DeadTransition = setmetatable({}, baseTransition)
DeadTransition.__index = DeadTransition
function DeadTransition.new()
local self = setmetatable(baseTransition.new(), DeadTransition)
self.Name = script.Name
return self
end
function DeadTransition:Test(stateMachine)
local died = false
local currentHealthConfig = stateMachine.characterComponentInterface.Configurations["CurrentHealth"]
if currentHealthConfig then
died = currentHealthConfig.Value <= 0
end
return died
end
return DeadTransition.new()
-
To
DeadState
-
NoWaterTransition
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[ NoWaterTransition ]]--
local characterComponents = script.Parent.Parent.Parent.Parent
local stateMachineRef = require(characterComponents:WaitForChild("BaseStateMachineRef"))
local baseTransition = stateMachineRef.baseTransition
local NoWaterTransition = setmetatable({}, baseTransition)
NoWaterTransition.__index = NoWaterTransition
function NoWaterTransition.new()
local self = setmetatable(baseTransition.new(), NoWaterTransition)
self.Name = script.Name
return self
end
function NoWaterTransition:Test(stateMachine)
return not stateMachine.characterComponentInterface:GetVariable("IsBuoyant")
end
return NoWaterTransition.new()
-
To
AirState
-
ClientEquipment
GetAccessoryList() : Returns a list of all current attached accessories.
NOTE: There are no registered variables in this module.
]]--
local ClientEquipment = {}
ClientEquipment.__index = ClientEquipment
ClientEquipment.ModuleName = "Equipment"
------------------------------------------------------------------------------------------------------------------------
-- Equipment FUNCTIONS AND DATA
------------------------------------------------------------------------------------------------------------------------
function ClientEquipment:GetAccessoryList()
local list = {}
for _, child in pairs(self.Character:GetChildren()) do
if child:IsA("Accessory") then
table.insert(list, child)
end
end
return list
end
function ClientEquipment:EquipItem(Item, IsEquip)
if not Item then
return
end
if Item:IsA("Accessory") then
if (IsEquip and (Item.Parent == nil or Item.Parent:FindFirstChild("HumanoidRootPart") == nil)) or
(not IsEquip and Item.Parent == self.Character) then
if self.ServerOnly then
self.EquipEvent:Fire(Item, IsEquip)
else
self.EquipEvent:FireServer(Item, IsEquip)
end
end
end
end
function ClientEquipment.new(CharacterComponentInterface, ServerOnly)
local self = {
Name = script.Name,
CharacterComponentInterface = CharacterComponentInterface,
Character = CharacterComponentInterface.characterModel,
ModuleConfigurationObject =
CharacterComponentInterface.ConfigurationsObject:FindFirstChild(ClientEquipment.ModuleName),
ServerOnly = ServerOnly,
}
setmetatable(self, ClientEquipment)
self.EquipEvent = self.ModuleConfigurationObject:WaitForChild("EquipItemEvent")
local variablePrefix = ""
if ServerOnly then
variablePrefix = "Client"
end
CharacterComponentInterface:RegisterFunction(variablePrefix .. "AddItem",
CharacterComponentInterface:MapToFunctionInModule(self, "EquipItem"))
CharacterComponentInterface:RegisterFunction(variablePrefix .. "GetAccessoryList",
CharacterComponentInterface:MapToFunctionInModule(self, "GetAccessoryList"))
return self
end
--Remove and cleanup events
function ClientEquipment:delete()
end
return ClientEquipment
]]>
-
ClientHealth
-
ClientHeartbeat
Priority then
idx = i
found = true
break
end
end
local callbackRecord = {
callback = Callback,
componentInstance = ComponentInstance,
heartbeatInstance = self,
priority = Priority,
delete = false,
}
if not found then
table.insert(callbackList, callbackRecord)
else
table.insert(callbackList, idx, callbackRecord)
end
end
function ClientHeartbeat:RemoveHeartbeatCallback(componentInstance, heartbeatType)
local callbackList = _callbackLists[heartbeatType]
if callbackList == nil then
return
end
for i = 1, #callbackList do
local record = callbackList[i]
if record.componentInstance == componentInstance then
record.delete = true
_callbackLists[heartbeatType .. "Garbage"] = true
return
end
end
end
function ClientHeartbeat.new(CharacterComponentInterface, ServerOnly)
local self = {
name = script.Name,
characterComponentInterface = CharacterComponentInterface,
characterModel = CharacterComponentInterface.characterModel,
}
setmetatable(self, ClientHeartbeat)
if not ServerOnly then
CharacterComponentInterface:RegisterFunction("AddHeartbeatCallback",
CharacterComponentInterface:MapToFunctionInModule(self, "AddHeartbeatCallback"))
CharacterComponentInterface:RegisterFunction("RemoveHeartbeatCallback",
CharacterComponentInterface:MapToFunctionInModule(self, "RemoveHeartbeatCallback"))
end
return self
end
local function DeleteHeartbeatType(self, heartbeatType)
local callbackList = _callbackLists[heartbeatType]
for i = #callbackList, 1, -1 do
local record = callbackList[i]
if record.heartbeatInstance == self then
record.delete = true
_callbackLists[heartbeatType .. "Garbage"] = true
return
end
end
end
function ClientHeartbeat:delete()
-- Removing all callbacks registered for this instance in the global lists
DeleteHeartbeatType(self, "heartbeat")
DeleteHeartbeatType(self, "stepped")
DeleteHeartbeatType(self, "earlyStepped")
end
------------------------------------------------------------------------------------------------
-- If more heartbeat locations are neeeded, they can be added here
------------------------------------------------------------------------------------------------
RunService.Heartbeat:Connect(function(dt)
DoCallbacks("heartbeat", dt)
end)
RunService.Stepped:Connect(function(_, dt)
DoCallbacks("stepped", dt)
end)
RunService.EarlyStepped:Connect(function(_, dt)
DoCallbacks("earlyStepped", dt)
end)
------------------------------------------------------------------------------------------------
return ClientHeartbeat
]]>
-
ClientPhysicsController
0.1 then
local ladderHit = helper.LastLadderHitLocation
local ladderUp = helper.LastLadderUpAxis
local ladderLook = helper.LastLadderLookAxis
-- For stability, if ladder axis has not changed meaningfully do not move attachments.
if ladderPart ~= a1.Parent or a1.WorldAxis:Dot(ladderUp) < 0.9
or a1.WorldSecondaryAxis:Dot(ladderLook) < 0.9
or Ray.new(ladderHit, ladderUp):Distance(a0.WorldPosition) < 0.1
then
a1.Parent = ladderPart -- TODO: desync
a1.WorldPosition = ladderHit
a1.WorldAxis = ladderUp
a1.WorldSecondaryAxis = ladderLook
end
end
self.relativeVelocity = self.rootPart:GetRelativeVelocityAt(ladderPart, a0.WorldPosition)
else
local hipHeight = cci.Configurations["StepHeight"].Value + 1
local hit = cci:GetVariable("SurfacePart")
local position = cci:GetVariable("SurfacePoint")
local normal = cci:GetVariable("SurfaceNormal")
disableAndRecallA1(climber, rootPart)
-- TODO: Replace BodyGyro with something else
gyro.MaxTorque = VECTOR_MAX_TORQUE
local grounded = not not hit
levitator.Enabled = grounded
glider.Enabled = not grounded
if grounded then
self.LastNormal = normal
self.LastSurface = hit
levitator.TargetPosition = hipHeight
local a1 = levitator.Attachment1
if not a1 then
-- TODO: now desynced, request new Attachment1 from server.
a1 = Instance.new("Attachment")
a1.Name = "Attachment1"
levitator.Attachment1 = a1
end
-- TODO: larger problem: changing parent is desyncronizing. This really shouldn't use an
-- attachment at all. Consider Humanoid platforms. Should go through physics replication.
a1.Parent = hit
a1.WorldPosition = position
a1.WorldAxis = normal
levitator.MotorVelocity = self.DesiredVelocity
self.relativeVelocity = self.rootPart:GetRelativeVelocityAt(hit, position)
else
glider.Velocity = self.DesiredVelocity
self.relativeVelocity = self.rootPart.Velocity
end
-- Direction
local desiredFacing = self.DesiredFacing.Unit
if desiredFacing.Magnitude > 0 then
local dot = gyro.CFrame.LookVector:Dot(rootPart.CFrame.LookVector)
if dot > -0.5 then
gyro.CFrame = CFrame.new(rootPart.Position, rootPart.Position + desiredFacing)
else
local cross = VECTOR_UP:Cross(desiredFacing)
if cross:Dot(rootPart.CFrame.LookVector) > 0 then
gyro.CFrame = CFrame.new(rootPart.Position, rootPart.Position + cross)
else
gyro.CFrame = CFrame.new(rootPart.Position, rootPart.Position - cross)
end
end
end
end
-- Jump impulse
local impulse = self.ImpulseSpeed
if impulse.Magnitude > 0.01 then
local current = rootPart.Velocity
local yImpulse = math.max(0, impulse.Y - current.Y)
rootPart.Velocity = current + Vector3.new(impulse.X, yImpulse, impulse.Z)
end
self.ImpulseSpeed = VECTOR_ZERO
end
------------------------------------------------------------------------------------------------
function ClientPhysicsController.new(characterComponentInterface)
local self = {
name = script.Name,
cci = characterComponentInterface,
characterModel = characterComponentInterface.characterModel,
rootPart = characterComponentInterface.characterModel.PrimaryPart,
gyro = characterComponentInterface.characterModel.PrimaryPart:WaitForChild("BodyGyro"),
levitator = characterComponentInterface.characterModel.PrimaryPart:WaitForChild("LevitationConstraint"),
climber = characterComponentInterface.characterModel.PrimaryPart:WaitForChild("PrismaticConstraint"),
glider = characterComponentInterface.characterModel.PrimaryPart:WaitForChild("LinearVelocity"),
characterHelper = characterComponentInterface:GetCharacterHelper(),
relativeVelocity = VECTOR_ZERO,
DesiredVelocity = VECTOR_ZERO,
DesiredFacing = Vector3.new(0, 0, -1),
ImpulseSpeed = VECTOR_ZERO,
MovementAcceleration = 1.0,
gravity = game.Workspace.Gravity,
IsClimbing = false,
}
setmetatable(self, ClientPhysicsController)
characterComponentInterface:CallFunction("AddHeartbeatCallback", onStepped, self, "earlyStepped", 100)
-- register variables with component module
characterComponentInterface:RegisterVariable("TargetMovementVelocity",
characterComponentInterface:MapGetToVariableInModule(self, "DesiredVelocity"),
characterComponentInterface:MapSetToSetFunctionInModule(self, "SetTargetMovementVelocity"))
characterComponentInterface:RegisterVariable("MovementAcceleration",
characterComponentInterface:MapGetToVariableInModule(self, "MovementAcceleration"),
characterComponentInterface:MapSetToSetFunctionInModule(self, "SetMovementAcceleration"))
characterComponentInterface:RegisterVariable("TargetFacing",
characterComponentInterface:MapGetToVariableInModule(self, "DesiredFacing"),
characterComponentInterface:MapSetToSetFunctionInModule(self, "SetTargetFacing"))
characterComponentInterface:RegisterVariable("ImpulseSpeed",
characterComponentInterface:MapGetToVariableInModule(self, "ImpulseSpeed"),
characterComponentInterface:MapSetToSetFunctionInModule(self, "SetImpulseSpeed"))
characterComponentInterface:RegisterVariable("WorldVelocity",
characterComponentInterface:MapGetToGetFunctionInModule(self, "GetWorldVelocity"),
characterComponentInterface:ReadOnlySetFunction("WorldVelocity"))
characterComponentInterface:RegisterVariable("WorldCFrame",
characterComponentInterface:MapGetToGetFunctionInModule(self, "GetWorldCFrame"),
characterComponentInterface:ReadOnlySetFunction("WorldCFrame"))
characterComponentInterface:RegisterVariable("IsClimbing",
characterComponentInterface:MapGetToVariableInModule(self, "IsClimbing"),
characterComponentInterface:MapSetToSetFunctionInModule(self, "SetIsClimbing"))
return self
end
function ClientPhysicsController:delete()
self.cci:CallFunction("RemoveHeartbeatCallback", self, "earlyStepped")
end
function ClientPhysicsController:SetTargetMovementVelocity(movementVelocity)
-- Vector3 (In) - Desired world velocity based on player input to move the character root object.
self.DesiredVelocity = movementVelocity
end
function ClientPhysicsController:SetMovementAcceleration(movementAcceleration)
-- Vector3 (In) - Desired modifier to accelaration to desired movement
-- TODO: actually update max acceleration on constraints
self.MovementAcceleration = movementAcceleration
end
function ClientPhysicsController:SetTargetFacing(facingDirection)
-- Vector3 (In) - Desired world facing of controller
self.DesiredFacing = facingDirection
end
function ClientPhysicsController:SetImpulseSpeed(impulseSpeed)
-- Vector3 (In) - Any additional forces being applied to the character based on states or other input factors.
-- This will be multiplied by the mass of the character to derive the required impulse
self.ImpulseSpeed = impulseSpeed
end
function ClientPhysicsController:SetIsClimbing(value)
self.IsClimbing = value
end
function ClientPhysicsController:GetWorldVelocity()
-- Vector3 (Out) - The resulting current velocity of the character after physical simulation is applied.
return self.relativeVelocity
end
function ClientPhysicsController:GetWorldCFrame()
-- CFrame (Out) - The resulting current velocity of the character after physical simulation is applied.
return self.rootPart.CFrame
end
return ClientPhysicsController
]]>
-
ClientPhysicsSensors
1 then
local hasLadder = self.characterHelper:CheckForLadder()
self.hasLadder = hasLadder
self.lastLadderCheck = 0
return hasLadder
end
return self.hasLadder
end
-- Bool (Out) - Is the character on a surface?
function ClientPhysicsSensors:IsGrounded()
return self.grounded
end
-- Bool (Out) - Is the character in water?
function ClientPhysicsSensors:IsBuoyant()
return self.characterHelper:IsPartBuoyant(self.rootPart)
end
--[[
GetBuoyancy : Vector3 (Out) - Any resulting forces due to fluid buoyancy that are
currently being applied to the character.
GetSurfaceVelocity : Vector3 (Out) - The resulting current velocity of the character after physical
simulation is applied with respect to the current surface (if any)
--]]
-- Object (Out) - The current object that the character is currently resting on (if any)
function ClientPhysicsSensors:GetSurfacePart()
return self.lastSurface
end
-- Vector3 (Out) - The surface normal that the character is currently resting on (if any)
function ClientPhysicsSensors:GetSurfaceNormal()
return self.lastNormal
end
--[[
GetSurfaceMaterial : Material (Out) - The surface material of the object face that the character is
currently resting on (if any)
maybe? : Current Contacts (List) - List of objects that are currently contacting the character and
the amount of force that they are applying as a result of the contact
--]]
return ClientPhysicsSensors
]]>
-
ClientPlateDisplay
-
ClientSound
0.1 then
-- Play a landing sound if the character dropped from a large distance
local vol = math.min(1.0, math.max(0.0, (self.fallSpeed - 50) / 110))
local landingSound = self.sounds[SFX.Landing]
landingSound.Volume = vol
Util.Play(landingSound)
self.fallSpeed = 0
end
if speed and speed > 0.5 then
Util.Resume(sound)
self:SetSoundInPlayingLoopedSounds(sound)
elseif speed then
self:StopPlayingLoopedSoundsExcept()
end
end;
[Enum.HumanoidStateType.Swimming] = function(self)
local speed = Util.Speed(self.head)
if self.activeState ~= Enum.HumanoidStateType.Swimming and speed > 0.1 then
local splashSound = self.sounds[SFX.Splash]
splashSound.Volume = math.clamp(
Util.YForLineGivenXAndTwoPts(
Util.VerticalSpeed(self.head),
100, 0.28,
350, 1),
0,1)
Util.Play(splashSound)
end
do
local sound = self.sounds[SFX.Swimming]
self:StopPlayingLoopedSoundsExcept(sound)
Util.Resume(sound)
self:SetSoundInPlayingLoopedSounds(sound)
end
end;
[Enum.HumanoidStateType.Climbing] = function(self)
local sound = self.sounds[SFX.Climbing]
local speed = Util.VerticalSpeed(self.head)
if speed and math.abs(speed) > 0.1 then
Util.Resume(sound)
self:StopPlayingLoopedSoundsExcept(sound)
else
Util.Pause(sound)
self:StopPlayingLoopedSoundsExcept(sound)
end
self:SetSoundInPlayingLoopedSounds(sound)
end;
[Enum.HumanoidStateType.Jumping] = function(self)
if self.activeState == Enum.HumanoidStateType.Jumping then
return
end
self:StopPlayingLoopedSoundsExcept()
local sound = self.sounds[SFX.Jumping]
Util.Play(sound)
end;
[Enum.HumanoidStateType.GettingUp] = function(self)
self:StopPlayingLoopedSoundsExcept()
local sound = self.sounds[SFX.GettingUp]
Util.Play(sound)
end;
[Enum.HumanoidStateType.Freefall] = function(self)
self.fallSpeed = math.max(self.fallSpeed, Util.VerticalSpeed(self.head))
if self.activeState == Enum.HumanoidStateType.Freefall then
return
end
local sound = self.sounds[SFX.FreeFalling]
sound.Volume = 0
self:StopPlayingLoopedSoundsExcept()
end;
[Enum.HumanoidStateType.FallingDown] = function(self)
self:StopPlayingLoopedSoundsExcept()
end;
[Enum.HumanoidStateType.Landed] = function(self)
self:StopPlayingLoopedSoundsExcept()
if Util.VerticalSpeed(self.head) > 75 then
local landingSound = self.sounds[SFX.Landing]
landingSound.Volume = math.clamp(
Util.YForLineGivenXAndTwoPts(
Util.VerticalSpeed(self.head),
50, 0,
100, 1),
0,1)
Util.Play(landingSound)
end
end;
[Enum.HumanoidStateType.Seated] = function(self)
self:StopPlayingLoopedSoundsExcept()
end;
}
-----------------------------------------------------------------------------------------------------------------------
-- Verify and set that "sound" is in "playingLoopedSounds".
function ClientSound:SetSoundInPlayingLoopedSounds(sound)
for i = 1, #(self.playingLoopedSounds) do
if self.playingLoopedSounds[i] == sound then
return
end
end
table.insert(self.playingLoopedSounds, sound)
end
-- Stop all active looped sounds except parameter "except". If "except" is not
-- passed, all looped sounds will be stopped.
function ClientSound:StopPlayingLoopedSoundsExcept(except)
for i = #(self.playingLoopedSounds), 1, -1 do
if self.playingLoopedSounds[i] ~= except then
Util.Pause(self.playingLoopedSounds[i])
table.remove(self.playingLoopedSounds, i)
end
end
end
-- Handle state event fired or OnChange fired
function ClientSound:StateUpdated(state)
if stateUpdateHandler[state] then
stateUpdateHandler[state](self)
end
self.activeState = state
end
function ClientSound:OnStepped(stepDeltaSeconds)
local sound = self.sounds[SFX.FreeFalling]
if self.activeState == Enum.HumanoidStateType.Freefall then
if self.head.Velocity.Y < 0 and Util.VerticalSpeed(self.head) > 75 then
Util.Resume(sound)
local normalizedIncrement = stepDeltaSeconds / ANIMATION_LENGTH_SECONDS
sound.Volume = math.clamp(sound.Volume + normalizedIncrement, 0, 1)
else
sound.Volume = 0
end
else
Util.Pause(sound)
end
if self.activeState == Enum.HumanoidStateType.Running or
self.activeState == Enum.HumanoidStateType.Swimming or
self.activeState == Enum.HumanoidStateType.Climbing or
self.activeState == Enum.HumanoidStateType.Freefall then
stateUpdateHandler[self.activeState](self)
end
end
-----------------------------------------------------------------------------------------------------------------------
function ClientSound.new(characterComponentInterface)
local self = {
name = script.Name,
characterComponentInterface = characterComponentInterface,
characterModel = characterComponentInterface.characterModel,
rootPart = characterComponentInterface.characterModel.PrimaryPart,
sounds = {},
fallSpeed = 0,
-- List of all active Looped sounds
playingLoopedSounds = {},
-- Last seen Enum.HumanoidStateType
activeState = nil,
}
setmetatable(self, ClientSound)
-- Notify the server a new character has been loaded
AddCharacterLoadedEvent:FireServer()
-- Notify the sound dispatcher this character has left.
Players.LocalPlayer.CharacterRemoving:connect(function(character)
RemoveCharacterEvent:FireServer(game.Players.LocalPlayer)
end)
self.head = self.characterModel:WaitForChild("Head")
self.sounds[SFX.Died] = self.head:WaitForChild("Died")
self.sounds[SFX.Running] = self.head:WaitForChild("Running")
self.sounds[SFX.Swimming] = self.head:WaitForChild("Swimming")
self.sounds[SFX.Climbing] = self.head:WaitForChild("Climbing")
self.sounds[SFX.Jumping] = self.head:WaitForChild("Jumping")
self.sounds[SFX.GettingUp] = self.head:WaitForChild("GettingUp")
self.sounds[SFX.FreeFalling] = self.head:WaitForChild("FreeFalling")
self.sounds[SFX.Landing] = self.head:WaitForChild("Landing")
self.sounds[SFX.Splash] = self.head:WaitForChild("Splash")
local DefaultServerSoundEvent = soundEventFolder:WaitForChild("DefaultServerSoundEvent")
DefaultServerSoundEvent.OnClientEvent:connect(function(sound, playing, resetPosition)
if resetPosition and sound.TimePosition ~= 0 then
sound.TimePosition = 0
end
if sound.IsPlaying ~= playing then
sound.Playing = playing
end
end)
local OnStateChangedEventObject = nil
while not OnStateChangedEventObject do
OnStateChangedEventObject = characterComponentInterface:GetVariable("OnStateChanged")
wait()
end
self.onStateChangedEvent = OnStateChangedEventObject.Event:Connect(
function(NewStateName)
local state = self.characterComponentInterface:CallFunction("GetState", NewStateName)
if state then
self:StateUpdated(state.StateEnum)
end
end)
local currentStateEnum = characterComponentInterface:GetVariable("CurrentStateEnum")
self:StateUpdated(currentStateEnum)
characterComponentInterface:CallFunction("AddHeartbeatCallback",
function(s, dt)
if self.characterModel.Parent ~= nil then
self:OnStepped(dt)
end
end, self, "earlyStepped", 280)
return self
end
function ClientSound:delete()
print("ClientSound:delete")
self.characterComponentInterface:CallFunction("RemoveHeartbeatCallback", self, "earlyStepped")
if self.onStateChangedEvent then
self.onStateChangedEvent:Disconnect()
end
end
return ClientSound
]]>
-
SharedCharacterComponents
-
BaseStateMachine
-
BaseState
-
BaseTransition
-
CharacterComponentInterface
1.0 then
Direction = Direction.Unit
end
if CameraRelative then
local camera = workspace.Camera
local cameraCFrame = camera.CFrame
Direction = cameraCFrame:VectorToWorldSpace(Direction)
end
Module.Variables.MoveDirection = Direction
end
local function GetMoveDirection(Module, NoVerticalMovement)
if NoVerticalMovement then
local moveDir = Vector3.new(Module.Variables.MoveDirection.x, 0, Module.Variables.MoveDirection.z)
if moveDir.Magnitude < 0.01 then
return Vector3.new(0, 0, 0)
end
local len = Module.Variables.MoveDirection.Magnitude
moveDir = moveDir.Unit * len
return moveDir
else
return Module.Variables.MoveDirection
end
end
local function GetMoveOverride(Module)
return Module.Variables.MoveOverride
end
function CharacterComponentInterface:LoadComponents(NameList, ComponentLocation)
-- Load default components
for _, name in pairs(NameList) do
if self.LoadModules[name] == nil or self.LoadModules[name] == true then
if self.Modules[name] ~= nil then
self.Modules[name]:delete()
end
self.Modules[name] = require(ComponentLocation:WaitForChild(name)).new(self, self.ServerOnly)
end
end
-- Load user components
for name, module in pairs(self.UserModules) do
if self.Modules[name] == nil then
self.Modules[name] = require(module).new(self, self.ServerOnly)
end
end
self.UserModules = {}
end
-----------------------------------------------------------------------------------------------------------------------
-- I N T E R N A L C H A R A C T E R H E L P E R
-----------------------------------------------------------------------------------------------------------------------
function CharacterComponentInterface:GetCharacterHelper()
return self.characterHelper
end
-----------------------------------------------------------------------------------------------------------------------
-- S T U B F U N C T I O N S F O R C O M P O N E N T S
-----------------------------------------------------------------------------------------------------------------------
function CharacterComponentInterface:ReadOnlySetFunction(VariableName)
return function(Module, Value)
warn(VariableName, "is a read only character variable.")
end
end
function CharacterComponentInterface:MapGetToVariableInModule(VariableModule, VariableName)
if VariableModule then
return function(Module)
return VariableModule[VariableName]
end
else
return nil
end
end
function CharacterComponentInterface:MapGetToGetFunctionInModule(VariableModule, GetFunctionName)
if VariableModule then
return function(Module, ...)
return VariableModule[GetFunctionName](VariableModule, ...)
end
else
return nil
end
end
function CharacterComponentInterface:MapSetToSetFunctionInModule(VariableModule, SetFunctionName)
if VariableModule then
return function(Module, Value, ...)
return VariableModule[SetFunctionName](VariableModule, Value, ...)
end
else
return nil
end
end
function CharacterComponentInterface:MapToFunctionInModule(VariableModule, FunctionName)
if VariableModule then
return function(Module, ...)
return VariableModule[FunctionName](VariableModule, ...)
end
else
return nil
end
end
-----------------------------------------------------------------------------------------------------------------------
-- P U B L I C I N T E R F A C E S
-----------------------------------------------------------------------------------------------------------------------
function CharacterComponentInterface.new()
local self = setmetatable({},CharacterComponentInterface)
self.Variables = {}
self.VariableFunctionsSet = {}
self.VariableFunctionsGet = {}
self.RegisteredFunctions = {}
self.Variables.jump = false
self.Variables.MoveDirection = Vector3.new(0, 0, 0)
self.Variables.MoveOverride = false
self.LoadModules = {}
self.UserModules = {}
self.Modules = {}
self.Configurations = {}
return self
end
function CharacterComponentInterface:delete()
for _, module in pairs(self.Modules) do
if module ~= nil then
module:delete()
end
end
self.Modules = {}
end
function CharacterComponentInterface:RegisterConfigurations(configurationName, changedCallback)
local configurationFolder = self.ConfigurationsObject:FindFirstChild(configurationName)
if configurationFolder then
for _, item in pairs(configurationFolder:GetChildren()) do
if self.Configurations[item.Name] == nil then
self.Configurations[item.Name] = {}
end
local config = self.Configurations[item.Name]
config.Object = item
if item:IsA("ValueBase") then
config.Value = item.Value
config.Changed = item.Changed:Connect(function(newValue)
config.Value = newValue
if changedCallback ~= nil then
changedCallback(newValue)
end
end)
end
end
end
end
-----------------------------------------------------------------------------------------------------------------------
--
function CharacterComponentInterface:RegisterVariable(VariableName, GetFunction, SetFunction)
if GetFunction and type(GetFunction) == "function" and SetFunction and type(SetFunction) == "function" then
self.VariableFunctionsGet[VariableName] = GetFunction
self.VariableFunctionsSet[VariableName] = SetFunction
else
warn("You must specify both a GetFunction and a SetFunction for ", VariableName)
end
end
function CharacterComponentInterface:GetVariable(VariableName, ...)
if self.VariableFunctionsGet[VariableName] then
return self.VariableFunctionsGet[VariableName](self, ...)
else
return self.Variables[VariableName]
end
end
function CharacterComponentInterface:SetVariable(VariableName, Value, ...)
if self.VariableFunctionsSet[VariableName] then
self.VariableFunctionsSet[VariableName](self, Value, ...)
else
self.Variables[VariableName] = Value
end
end
-----------------------------------------------------------------------------------------------------------------------
--
function CharacterComponentInterface:RegisterFunction(FunctionName, Function)
if Function and type(Function) == "function" then
self.RegisteredFunctions[FunctionName] = Function
else
warn("You must specify a Function for ", FunctionName)
end
end
function CharacterComponentInterface:CallFunction(FunctionName, ...)
if self.RegisteredFunctions[FunctionName] then
return self.RegisteredFunctions[FunctionName](self, ...)
else
warn("Attempted to call unregistered function :", FunctionName)
end
end
-----------------------------------------------------------------------------------------------------------------------
--
function CharacterComponentInterface:LoadDefaultComponent(ModuleName, LoadBoolean)
self.LoadModules[ModuleName] = LoadBoolean
end
function CharacterComponentInterface:LoadUserComponent(ComponentModule)
self.UserModules[ComponentModule.Name] = ComponentModule
end
function CharacterComponentInterface:SetupClient(CharacterModel, ServerOnly)
-- Don't set up components if there is a Humanoid
local Humanoid = CharacterModel:FindFirstChildOfClass("Humanoid")
while Humanoid do
wait()
Humanoid = CharacterModel:FindFirstChildOfClass("Humanoid")
end
local replicatedStorage = game:GetService("ReplicatedStorage")
local characterComponents = replicatedStorage:WaitForChild("CharacterComponents")
local clientCharacterComponents = characterComponents:WaitForChild("ClientCharacterComponents")
local characterScripts = CharacterModel:WaitForChild("CharacterComponentScripts")
self.ConfigurationsObject = characterScripts:WaitForChild("Configurations")
self.VariableFunctionsGet["MoveDirection"] = GetMoveDirection
self.VariableFunctionsSet["MoveDirection"] = SetMoveDirection
self.VariableFunctionsGet["MoveDirectionSource"] = GetMoveOverride
self.VariableFunctionsSet["MoveDirectionSource"] = nil
self.characterModel = CharacterModel
self.ServerOnly = ServerOnly
self.characterHelper = characterScripts:WaitForChild("CharacterHelper")
self:LoadComponents(ClientModuleNames, clientCharacterComponents)
end
function CharacterComponentInterface:SetupServer(CharacterModel, ServerOnly)
-- Don't set up components if there is a Humanoid
local Humanoid = CharacterModel:FindFirstChildOfClass("Humanoid")
while Humanoid do
wait()
Humanoid = CharacterModel:FindFirstChildOfClass("Humanoid")
end
local ServerScriptService = game:GetService("ServerScriptService")
local ServerCharacterComponents = ServerScriptService:WaitForChild("ServerCharacterComponents")
local characterScripts = CharacterModel:WaitForChild("CharacterComponentScripts")
self.ConfigurationsObject = characterScripts:WaitForChild("Configurations")
self.characterModel = CharacterModel
self.ServerOnly = ServerOnly
self.characterHelper = characterScripts:WaitForChild("CharacterHelper")
self:LoadComponents(ServerModuleNames, ServerCharacterComponents)
end
return CharacterComponentInterface.new()
]]>
-
TestPlaceScripts
-
MoveCharacterEvent
-
ServerScriptService
-
AssignPlayers
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
local sc = game.StarterPlayer:FindFirstChild("StarterCharacter")
if sc then
sc.PrimaryPart = sc.HumanoidRootPart
local sound = game.StarterPlayer.StarterCharacterScripts:FindFirstChild("Sound")
if sound then
sound.Parent = nil
end
sc.Sound.Parent = game.StarterPlayer.StarterCharacterScripts
sc.Health.Parent = game.StarterPlayer.StarterCharacterScripts
sc.Animate.Parent = game.StarterPlayer.StarterCharacterScripts
end
local Players = game:GetService("Players")
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
local function createJoint(jointName,att0,att1)
local part0,part1 = att0.Parent,att1.Parent
local newMotor = part1:FindFirstChild(jointName)
if not (newMotor and newMotor:IsA("Motor6D")) then
newMotor = Instance.new("Motor6D")
end
newMotor.Name = jointName
newMotor.Part0 = part0
newMotor.Part1 = part1
newMotor.C0 = att0.CFrame
newMotor.C1 = att1.CFrame
newMotor.Parent = part1
end
local function buildJointsFromAttachments(part, characterParts)
if not part then
return
end
-- first, loop thru all of the part's children to find attachments
for _,attachment in pairs(part:GetChildren()) do
if attachment:IsA("Attachment") then
-- only do joint build from "RigAttachments"
local attachmentName = attachment.Name
local findPos = attachmentName:find("RigAttachment")
if findPos then
-- also don't make double joints (there is the same named
-- rigattachment under two parts)
local jointName = attachmentName:sub(1,findPos-1)
local joint = part:FindFirstChild(jointName)
if not joint or not joint:IsA("Motor6D") then
-- try to find other part with same rig attachment name
for _,characterPart in pairs(characterParts) do
if part ~= characterPart then
local matchingAttachment = characterPart:FindFirstChild(attachmentName)
if matchingAttachment and matchingAttachment:IsA("Attachment") then
createJoint(jointName,attachment,matchingAttachment)
buildJointsFromAttachments(characterPart,characterParts)
break
end
end
end
end
end
end
end
end
local function buildRigFromAttachments(rootPart)
local characterParts = {}
for i,descendant in ipairs(rootPart.Parent:GetDescendants()) do
if descendant:IsA("BasePart") then
table.insert(characterParts, descendant)
end
end
buildJointsFromAttachments(rootPart, characterParts)
end
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
local function CleanupCharacter(character)
local cci = character:FindFirstChild("CharacterComponentScripts"):FindFirstChild("ComponentInterfaceInstance")
if cci ~= nil then
local cciInstance = require(cci)
cciInstance:delete()
end
end
local function SetupCharacter(character)
local player = Players:GetPlayerFromCharacter(character)
local rootPart = player.Character:WaitForChild("HumanoidRootPart")
-- rebuild joints - This is needed since Rojo can't maintain object references
buildRigFromAttachments(rootPart)
-- assign network owners
while not rootPart:IsDescendantOf(workspace) do
wait()
end
rootPart:SetNetworkOwner(player)
-- Remove default scripts
local scriptNames = { "Animate", "Sound", "Health" }
for _, name in pairs(scriptNames) do
local scriptObject = character:WaitForChild(name)
scriptObject.Parent = nil
end
-- Remove Humanoid (if one)
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid.Parent = nil
local anCon = Instance.new("AnimationController", character)
Instance.new("Animator", anCon)
end
end
Players.PlayerAdded:Connect(function(player)
print(player.Name .. " joined the game!")
player.CharacterAdded:Connect(SetupCharacter)
player.CharacterRemoving:Connect(CleanupCharacter)
end)
Players.PlayerRemoving:Connect(function(player)
print(player.Name .. " left the game!")
end)
-
MoveScript
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MoveCharacterEvent = ReplicatedStorage:WaitForChild("TestPlaceScripts"):WaitForChild("MoveCharacterEvent")
local function OnMoveCharacter(player)
local character = player.Character
character.Parent = nil
wait(2)
character.Parent = workspace
end
MoveCharacterEvent.OnServerEvent:Connect(OnMoveCharacter)
-
ServerCharacterComponents
-
ServerControlStateMachine
-
ServerEquipment
GetAccessoryList() : Returns a list of all current attached accessories.
NOTE: There are no registered variables in this module.
]]--
local ServerEquipment = {}
ServerEquipment.__index = ServerEquipment
ServerEquipment.ModuleName = "Equipment"
------------------------------------------------------------------------------------------------------------------------
-- Equipment FUNCTIONS AND DATA
------------------------------------------------------------------------------------------------------------------------
function ServerEquipment:GetAccessoryList()
local list = {}
for _, child in pairs(self.Character:GetChildren()) do
if child:IsA("Accessory") then
table.insert(list, child)
end
end
return list
end
function ServerEquipment:EquipItem(Item, IsEquip)
if not Item then
return
end
if Item:IsA("Accessory") then
if IsEquip and (Item.Parent == nil or Item.Parent:FindFirstChild("HumanoidRootPart") == nil) then
Item.Parent = self.Character
elseif not IsEquip and Item.Parent == self.Character then
Item.Parent = nil
end
end
end
function ServerEquipment.new(CharacterComponentInterface, ServerOnly)
local self = {
Name = script.Name,
CharacterComponentInterface = CharacterComponentInterface,
Character = CharacterComponentInterface.characterModel,
ModuleConfigurationObject =
CharacterComponentInterface.ConfigurationsObject:FindFirstChild(ServerEquipment.ModuleName),
ServerOnly = ServerOnly,
}
setmetatable(self, ServerEquipment)
-- setup equipping event
if self.ServerOnly then
self.EquipEvent = Instance.new("BindableEvent")
self.OnEventConnection = self.EquipEvent.Event:Connect(
function(Item, IsEquip)
self:EquipItem(Item, IsEquip)
end)
else
self.EquipEvent = Instance.new("RemoteEvent")
self.OnEventConnection = self.EquipEvent.OnServerEvent:Connect(
function(Player, Item, IsEquip)
if Player.Character == self.Character then
self:EquipItem(Item, IsEquip)
end
end)
end
self.EquipEvent.Name = "EquipItemEvent"
self.EquipEvent.Parent = self.ModuleConfigurationObject
local variablePrefix = ""
if ServerOnly then
variablePrefix = "Server"
end
CharacterComponentInterface:RegisterFunction(variablePrefix .. "AddItem",
CharacterComponentInterface:MapToFunctionInModule(self, "EquipItem"))
CharacterComponentInterface:RegisterFunction(variablePrefix .. "GetAccessoryList",
CharacterComponentInterface:MapToFunctionInModule(self, "GetAccessoryList"))
self.ChildAddedConnection = self.Character.ChildAdded:Connect(function(Instance)
if Instance:IsA("Accessory") then
self.CharacterComponentInterface:CallFunction("BuildRigFromAttachments", true)
end
end)
return self
end
--Remove and cleanup events
function ServerEquipment:delete()
self.OnEventConnection:Disconnect()
self.ChildAddedConnection:Disconnect()
self.EquipEvent:Destroy()
end
return ServerEquipment
]]>
-
ServerHealth
0 then
self.lastTickUpdate = self.lastTickUpdate + deltaTime
if self.lastTickUpdate > REGEN_STEP then
if self.currentHealth.Value < self.maxHealth.Value then
local dh = self.lastTickUpdate * self.healthRegenRate.Value * self.maxHealth.Value
self.currentHealth.Object.Value = math.min(self.currentHealth.Value + dh, self.maxHealth.Value)
end
self.lastTickUpdate = 0.0
end
else
if self.characterModel.PrimaryPart and self.characterModel.PrimaryPart:IsA("Part") then
self.characterModel.PrimaryPart.Anchored = true
end
self.alive = false
end
end
end
------------------------------------------------------------------------------------------------
function ServerHealth.new(characterComponentInterface)
-- register configurations. Needs to be before self declaration since it references configurations.
characterComponentInterface:RegisterConfigurations("Health")
local self = {
name = script.Name,
characterComponentInterface = characterComponentInterface,
characterModel = characterComponentInterface.characterModel,
maxHealth = characterComponentInterface.Configurations["MaxHealth"],
currentHealth = characterComponentInterface.Configurations["CurrentHealth"],
healthRegenRate = characterComponentInterface.Configurations["HealthRegenRate"],
lastTickUpdate = 0.0,
alive = true
}
setmetatable(self, ServerHealth)
characterComponentInterface:CallFunction("AddHeartbeatCallback",
function(s, dt)
if self.characterModel.Parent ~= nil then
self:OnHeartbeat(dt)
end
end, self, "earlyStepped", 290)
return self
end
function ServerHealth:delete()
self.characterComponentInterface:CallFunction("RemoveHeartbeatCallback", self, "earlyStepped")
end
return ServerHealth
]]>
-
ServerHeartbeat
Priority then
idx = i
found = true
break
end
end
local callbackRecord = {
callback = Callback,
componentInstance = ComponentInstance,
heartbeatInstance = self,
priority = Priority,
delete = false,
}
if not found then
table.insert(callbackList, callbackRecord)
else
table.insert(callbackList, idx, callbackRecord)
end
end
function ServerHeartbeat:RemoveHeartbeatCallback(componentInstance, heartbeatType)
local callbackList = _callbackLists[heartbeatType]
if callbackList == nil then
return
end
for i = 1, #callbackList do
local record = callbackList[i]
if record.componentInstance == componentInstance then
record.delete = true
_callbackLists[heartbeatType .. "Garbage"] = true
return
end
end
end
function ServerHeartbeat.new(CharacterComponentInterface, ServerOnly)
local self = {
name = script.Name,
characterComponentInterface = CharacterComponentInterface,
characterModel = CharacterComponentInterface.characterModel,
}
setmetatable(self, ServerHeartbeat)
CharacterComponentInterface:RegisterFunction("AddHeartbeatCallback",
CharacterComponentInterface:MapToFunctionInModule(self, "AddHeartbeatCallback"))
CharacterComponentInterface:RegisterFunction("RemoveHeartbeatCallback",
CharacterComponentInterface:MapToFunctionInModule(self, "RemoveHeartbeatCallback"))
return self
end
local function DeleteHeartbeatType(self, heartbeatType)
local callbackList = _callbackLists[heartbeatType]
for i = #callbackList, 1, -1 do
local record = callbackList[i]
if record.heartbeatInstance == self then
record.delete = true
_callbackLists[heartbeatType .. "Garbage"] = true
return
end
end
end
function ServerHeartbeat:delete()
-- Removing all callbacks registered for this instance in the global lists
DeleteHeartbeatType(self, "heartbeat")
DeleteHeartbeatType(self, "stepped")
DeleteHeartbeatType(self, "earlyStepped")
end
------------------------------------------------------------------------------------------------
-- If more heartbeat locations are neeeded, they can be added here
------------------------------------------------------------------------------------------------
RunService.Heartbeat:Connect(function(dt)
DoCallbacks("heartbeat", dt)
end)
RunService.Stepped:Connect(function(_, dt)
DoCallbacks("stepped", dt)
end)
RunService.EarlyStepped:Connect(function(_, dt)
DoCallbacks("earlyStepped", dt)
end)
------------------------------------------------------------------------------------------------
return ServerHeartbeat
]]>
-
ServerPhysicsController
-
ServerPlateDisplay
-
ServerRigScale
0.1 and self.cumulativeLegRight > 0.1 then
local legParts = {}
--Find which leg and which part require scaling
local yScale = self.cumulativeLegRight / self.cumulativeLegLeft;
if self.cumulativeLegLeft > self.cumulativeLegRight then
yScale = self.cumulativeLegLeft / self.cumulativeLegRight
legParts = {}
for _, part in pairs(characterParts) do
if part.Name == "RightUpperLeg" or part.Name == "RightLowerLeg" or part.Name == "RightFoot" then
table.insert(legParts, part)
end
end
else
for _, part in pairs(characterParts) do
if part.Name == "LeftUpperLeg" or part.Name == "LeftLowerLeg" or part.Name == "LeftFoot" then
table.insert(legParts, part)
end
end
end
--scale parts
local adjustScale = Vector3.new(1.0, yScale, 1.0)
for _, part in pairs(legParts) do
local originalSize = getOriginalSize(part)
local currentScale = part.Size / originalSize
local totalScale = currentScale * adjustScale
part.Size = originalSize * totalScale
--scale attachments
for _, child in pairs(part:GetChildren()) do
local attachment = child:FindFirstChildWhichIsA("Attachment")
if attachment then
local originalPosition = attachment:FindFirstChild(originalPositionName)
if originalPosition then
local originalP = originalPosition.Value
attachment.Position = originalP * totalScale
end
end
end
end
end
self.cumulativeStepHeightLeft = 0.0
self.cumulativeStepHeightRight = 0.0
self.cumulativeLegLeft = 0.0
self.cumulativeLegRight = 0.0
--build the character joints after scaling
self:TraverseRigFromAttachmentsInternal(rootPart, characterParts, true)
local stepHeight = math.max(self.cumulativeStepHeightLeft, self.cumulativeStepHeightRight)
if math.abs(self.cumulativeStepHeightLeft - self.cumulativeStepHeightRight) < stepHeight then
stepHeight = math.min(self.cumulativeStepHeightLeft, self.cumulativeStepHeightRight)
end
if stepHeight < 0.0 then
stepHeight = (rootPart.Size.Y / 2)
end
self:SetStepHeight(stepHeight)
end
--Builds the joints on a character
function ServerRigScale:BuildJoints()
local character = self.character
local characterParts = self:GetCharacterParts()
self:BuildJointsFromAttachments(character.HumanoidRootPart, characterParts)
end
--Accessory scale functions---------------------------------------------------------------------------------------------
--Scales the attachment or special mesh child found on a part
local function scaleChildrenOfPart(part, scaleVector)
for _,child in pairs(part:GetChildren()) do
if child:IsA("Attachment") then
local originalPosition = child.Position
child.Position = originalPosition * scaleVector
elseif child:IsA("SpecialMesh") then
if child.MeshType ~= "Head" then
local orignalScale = child.Scale
child.Scale = orignalScale * scaleVector
end
end
end
end
--Returns the matching attachment found on the character
function ServerRigScale:FindFirstMatchingAttachment(attachmentName)
local characterParts = self:GetCharacterParts()
for _,part in pairs(characterParts) do
for _,child in pairs(part:GetChildren()) do
if child.Name == attachmentName then
return child
end
end
end
return nil
end
--Returns the character part the accessory is attached to
function ServerRigScale:GetAttachedPart(accessory)
local handle = accessory:FindFirstChild("Handle")
if not handle then
return nil
end
local accessoryWeld = handle:FindFirstChild("AccessoryWeld")
if accessoryWeld then
local attachedPart
if (accessoryWeld.Part0 ~= handle) then
attachedPart = accessoryWeld.Part0
else
attachedPart = accessoryWeld.Part1
end
return attachedPart
end
local accessoryAttachment = handle:FindFirstChildWhichIsA("Attachment")
if accessoryAttachment then
local matchingAttachment = self:FindFirstMatchingAttachment(accessoryAttachment.Name)
if matchingAttachment and matchingAttachment.Parent then
return matchingAttachment.Parent
end
end
return self.character.Head
end
--Scale individual accessory using values found in the configurations folder
function ServerRigScale:ScaleAccessory(accessory, bodyScaleVector, headScaleVector, bodyTypeScale, bodyProportionScale)
local handle = accessory:FindFirstChild("Handle")
if not handle then
return
end
local attachedPart = self:GetAttachedPart(accessory)
local newScaleVector = bodyScaleVector
if attachedPart.Name == "Head" then
newScaleVector = headScaleVector
end
--find appropriate relative scaling with attached part
if attachedPart then
local scale = Vector3.new(1.0, 1.0, 1.0)
local accessoryProportion = "Classic"
if accessory:FindFirstChild("AvatarPartScaleType") then
accessoryProportion = accessory.AvatarPartScaleType.Value
end
if accessoryProportion ~= "Classic" then
scale = getPartScale(attachedPart, 0.0, 0.0, accessoryProportion, accessoryProportion);
end
local attachedPartProportion = "Classic"
if attachedPart:FindFirstChild("AvatarPartScaleType") then
attachedPartProportion = attachedPart.AvatarPartScaleType.Value
end
scale = scale * getPartScale(attachedPart, bodyProportionScale, bodyTypeScale, attachedPartProportion, "Classic");
newScaleVector = newScaleVector * scale;
end
local originalSize = getOriginalSize(handle)
local currentScaleVector = handle.Size / originalSize;
local relativeScaleVector = newScaleVector / currentScaleVector;
--scale accessory and as well as its welds and attachments
scaleChildrenOfPart(handle, relativeScaleVector)
handle.Size = originalSize * newScaleVector;
accessory:RebuildWeld()
end
--Scale accessories using values found in the configurations folder
function ServerRigScale:ScaleAccessories(bodyScaleVector, headScaleVector, anthroPercent, wideToNarrow)
for _, item in pairs(self.character:GetChildren()) do
if item:IsA("Accessory") then
self:ScaleAccessory(item,bodyScaleVector,headScaleVector,anthroPercent,wideToNarrow)
end
end
end
--General character scale functions-------------------------------------------------------------------------------------
--Used to check if a character is an R6
function ServerRigScale:CheckR6()
local characterParts = self:GetCharacterParts()
return #characterParts == 6
end
--Scale character part and any attachments using values found in the configurations folder
function ServerRigScale:ScaleCharacterPart(part, bodyScaleVector, headScaleVector, anthroPercent, wideToNarrow)
local partName = part.Name
local originalSize = getOriginalSize(part)
local newScaleVector = bodyScaleVector
if partName == "Head" then
newScaleVector = headScaleVector
end
--check for native part information on special mesh in the Head Part
if part and partName == "Head" then
local mesh = part:FindFirstChildWhichIsA("SpecialMesh")
if mesh then
local nameNative = "AvatarPartScaleType"
local meshScaleTypeValue = mesh:FindFirstChild(nameNative)
if meshScaleTypeValue then
local headScaleTypeValue = part:FindFirstChild(nameNative)
if not headScaleTypeValue then
headScaleTypeValue = Instance.new("StringValue")
if headScaleTypeValue then
headScaleTypeValue.Name(nameNative)
headScaleTypeValue.Parent(part)
end
end
if headScaleTypeValue then
headScaleTypeValue.Value = meshScaleTypeValue.Value
end
elseif not part:IsA("MeshPart") then
local headScaleTypeValue = part:findFirstChild(nameNative)
if headScaleTypeValue then
headScaleTypeValue:Destroy()
end
end
elseif not part:IsA("MeshPart") then
local nameNative = "AvatarPartScaleType";
local headScaleTypeValue = part:findFirstChild(nameNative)
if headScaleTypeValue then
headScaleTypeValue:Destroy();
end
end
end
--find the appropriate scale for the part
local humanoidPropType = "Classic"
if part:FindFirstChild("AvatarPartScaleType") then
humanoidPropType = part.AvatarPartScaleType.Value
end
local scale = getPartScale(part, wideToNarrow, anthroPercent, humanoidPropType, humanoidPropType)
--scale head mesh and attachments
if part and partName == "Head" then
local mesh = part:FindFirstChildWhichIsA("SpecialMesh")
if mesh then
local headScale = newScaleVector
if mesh.MeshType.Name == "Head" then
headScale = Vector3.new(1.0,1.0,1.0)
end
local originalScale = getOriginalMeshScale(mesh)
if mesh.MeshType.Name ~= "Head" then
mesh.Scale = originalScale * scale * headScale
end
local attachmentNames = {"FaceCenterAttachment", "FaceFrontAttachment", "HairAttachment",
"HatAttachment", "NeckRigAttachment"}
for _, name in pairs(attachmentNames) do
local originalPosValue = mesh:FindFirstChild(name)
local headAttachment = part:FindFirstChild(name)
local originalPosition = headAttachment:FindFirstChild(originalPositionName)
if headAttachment and originalPosition then
if originalPosValue then
originalPosition.Value = originalPosValue
else
originalPosition.Value = headAttachmentMap[name]
end
end
end
end
end
--scale the part
part.Size = originalSize * scale * newScaleVector
--scale attachments
for _, child in pairs(part:GetChildren()) do
if child:IsA("Attachment") then
local originalAttachment = getOriginalAttachmentPosition(child)
child.Position = originalAttachment * scale * newScaleVector
end
end
end
--Scales the character including any accessories and attachments
--NOTE: Scaling is supported only for R15 Characters
function ServerRigScale:ScaleCharacter()
if self:CheckR6() then
return
end
--scale parts
local config = self.CharacterComponentInterface.Configurations
local bodyScaleVector = Vector3.new(config["BodyWidthScale"].Value,
config["BodyHeightScale"].Value,
config["BodyDepthScale"].Value)
local headScaleVector = Vector3.new(config["HeadScale"].Value,config["HeadScale"].Value,config["HeadScale"].Value)
local anthroPercent = config["BodyTypeScale"].Value
local wideToNarrow = config["BodyProportionScale"].Value
local characterParts = self:GetCharacterParts()
for _, part in pairs(characterParts) do
if part then
self:ScaleCharacterPart(part, bodyScaleVector, headScaleVector, anthroPercent, wideToNarrow)
end
end
--scale step height
local stepHeight = lerp(stepHeightWide, stepHeightNarrow, wideToNarrow)
local newStepHeight = lerp(2.0, stepHeight, anthroPercent)
self:SetStepHeight(newStepHeight * bodyScaleVector.Y)
--scale accessories
self:ScaleAccessories(bodyScaleVector, headScaleVector, anthroPercent, wideToNarrow)
self.bodyScale = bodyScaleVector
self.headScale = headScaleVector.X
--build up joints
self:BuildJoints()
end
------------------------------------------------------------------------------------------------------------------------
-- MODULE FUNCTIONS
------------------------------------------------------------------------------------------------------------------------
function ServerRigScale.new(characterComponentInterface)
local self = {
Name = script.Name,
CharacterComponentInterface = characterComponentInterface,
character = characterComponentInterface.characterModel,
rootPart = characterComponentInterface.characterModel.PrimaryPart,
bodyScale = Vector3.new(1.0,1.0,1.0),
headScale = 0.0,
cumulativeStepHeightLeft = 0.0,
cumulativeStepHeightRight = 0.0,
cumulativeLegLeft = 0.0,
cumulativeLegRight = 0.0
}
setmetatable(self, ServerRigScale)
-- register configurations
characterComponentInterface:RegisterConfigurations("RigScale",
function(_)
self:ScaleCharacter()
end)
--Inital scale
self:ScaleCharacter()
-- register functions
characterComponentInterface:RegisterFunction("BuildRigFromAttachments",
characterComponentInterface:MapToFunctionInModule(self, "BuildRigFromAttachments"))
return self
end
function ServerRigScale:delete()
end
--bool - Hacky way of calling a function at the moment.
--This builds the rig for the character from the current attachments.
function ServerRigScale:BuildRigFromAttachments(check)
if not check then
return
end
local rootPart = self.rootPart
local characterParts = self:GetCharacterParts()
if not self:CheckR6() then
self:BuildJointsFromAttachments(rootPart, characterParts)
self:ScaleCharacter()
end
end
return ServerRigScale
]]>
-
ServerSound
-
StarterGui
-
ScreenGui
-
Buffer
0.5
0.5
0
0
0
0.699999988079071
0.11800000071525574
0
0.18400000035762787
0
0
256
0
32
-
WorkspaceButton
true
0
0
true
true
1
1
1
0
0.10588236153125763
0.16470588743686676
0.20784315466880798
1
false
false
3
0
1
false
[null]
[null]
[null]
[null]
0.0078125
0
1.28125
0
[null]
0
true
false
[null]
0
80
0
25
0
0
Exit Workspace
0
0
0
false
14
0
0
0
1
0
0
false
2
1
true
1
-
LocalScript
false
{2BA5F936-44F7-412E-BC95-1EA45075E8D9}
local button = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TestPlaceScripts = ReplicatedStorage:WaitForChild("TestPlaceScripts")
local MoveCharacterEvent = TestPlaceScripts:WaitForChild("MoveCharacterEvent")
button.MouseButton1Down:connect(function()
MoveCharacterEvent:FireServer()
end)
-
StateDebugLabel
0.5
0.5
0
0
0
1
17
0.5
0
0.5
0
1
-8
1
0
State: N/A
1
1
1
18
0
-
LocalScript
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer or Players:GetPropertyChangedSignal("LocalPlayer") or Players.LocalPlayer
local stateDebugLabel = script.Parent
local character = nil
while character == nil do
character = player.Character
end
local cci = require(character:WaitForChild("CharacterComponentScripts"):WaitForChild("ComponentInterfaceInstance"))
while true do
-- local character = player.Character
-- local humanoid = character and character:FindFirstChildOfClass("Humanoid")
-- local state = humanoid and humanoid:GetState().Name
local state = cci:GetVariable("CurrentStateEnum")
local stateName = state and state.Name or "N/A"
stateDebugLabel.Text = "State: " .. stateName
RunService.RenderStepped:Wait()
end
-
StarterPlayer
-
StarterCharacter
0
0
0
1
0
0
0
1
0
0
0
1
[96]
-
HumanoidRootPart
false
-0.5
0.5
0
0
-0.5
0.5
4
0
-35.35728
60.832367
40.429756
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
2
2
1
-0.5
0.5
3
0
1
0
0
0
-
RootRigAttachment
-0.000607906
-0.81877613
0.033983894
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.0006079060258343816
-0.8187761306762695
0.03398389369249344
-
OriginalSize
2
2
1
-
LeftHand
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-36.126816
59.529976
40.576588
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.24898862838745117
0.6131927967071533
0.3323974907398224
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065408
https://assetdelivery.roblox.com/v1/asset/?id=3934065408
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.24898862838745117
0.6131927967071533
0.3323974907398224
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
LeftWristRigAttachment
-0.025452733
0.3046073
0.049758196
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.025452733039855957
0.3046073019504547
0.049758195877075195
-
LeftWrist
-0.11797005
-0.39579457
0.015762076
1
0
0
0
1
0
0
0
1
-0.025452733
0.3046073
0.049758196
1
0
0
0
1
0
0
0
1
0
false
0
[105]
[106]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.24898862838745117
0.6131927967071533
0.3323974907398224
-
RightUpperArm
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-34.748657
61.029594
40.553684
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.39513614773750305
0.942173957824707
0.4249786138534546
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065381
https://assetdelivery.roblox.com/v1/asset/?id=3934065381
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.39513614773750305
0.942173957824707
0.4249786138534546
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
RightShoulderRigAttachment
-0.076161385
0.3345083
-0.0012780055
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.07616138458251953
0.3345082998275757
-0.0012780055403709412
-
RightElbowRigAttachment
0.040880978
-0.4066136
0.030482814
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.04088097810745239
-0.4066135883331299
0.030482813715934753
-
RightShoulder
0.532176
0.31034005
0.091338284
1
0
0
0
1
0
0
0
1
-0.076161385
0.3345083
-0.0012780055
1
0
0
0
1
0
0
0
1
0
false
0
[115]
[116]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.39513614773750305
0.942173957824707
0.4249786138534546
-
RightLowerArm
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-34.67977
60.231476
40.610374
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.4327073097229004
0.889136791229248
0.4252088963985443
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065406
https://assetdelivery.roblox.com/v1/asset/?id=3934065406
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.4327073097229004
0.889136791229248
0.4252088963985443
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
RightElbowRigAttachment
-0.028005898
0.39150482
-0.02620709
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.028005897998809814
0.39150482416152954
-0.0262070894241333
-
RightWristRigAttachment
0.119244516
-0.39689308
0.015973017
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.1192445158958435
-0.39689308404922485
0.015973016619682312
-
RightElbow
0.040880978
-0.4066136
0.030482814
1
0
0
0
1
0
0
0
1
-0.028005898
0.39150482
-0.02620709
1
0
0
0
1
0
0
0
1
0
false
0
[116]
[125]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.4327073097229004
0.889136791229248
0.4252088963985443
-
RightUpperLeg
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.07688
59.164463
40.409157
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.5554730892181396
1.3316420316696167
0.7053832411766052
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065387
https://assetdelivery.roblox.com/v1/asset/?id=3934065387
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.5554730892181396
1.331642508506775
0.7053832411766052
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
RightHipRigAttachment
-0.0026204586
0.6679041
0.01602125
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.0026204586029052734
0.6679038405418396
0.016021249815821648
-
RightKneeRigAttachment
-0.020522952
-0.59555167
0.049337804
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.02052295207977295
-0.5955514311790466
0.049337804317474365
-
OriginalSize
0.5554730892181396
1.3316420316696167
0.7053832411766052
-
RightHip
0.27634314
-0.101884976
0.00011147326
1
0
0
0
1
0
0
0
1
-0.0026204586
0.6679041
0.01602125
1
0
0
0
1
0
0
0
1
0
false
0
[135]
[136]
-
AvatarPartScaleType
ProportionsSlender
-
RightLowerLeg
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.06421
57.92662
40.53936
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.4296979308128357
1.4310376644134521
0.5790980458259583
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065394
https://assetdelivery.roblox.com/v1/asset/?id=3934065394
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.4296979308128357
1.4310381412506104
0.5790980458259583
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
RightKneeRigAttachment
-0.03319463
0.6422912
-0.0808638
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.03319463133811951
0.6422909498214722
-0.08086380362510681
-
RightAnkleRigAttachment
0.0010480881
-0.7746442
0.09195016
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.0010480880737304688
-0.7746438980102539
0.09195016324520111
-
OriginalSize
0.4296979308128357
1.4310376644134521
0.5790980458259583
-
RightKnee
-0.020522952
-0.59555167
0.049337804
1
0
0
0
1
0
0
0
1
-0.03319463
0.6422912
-0.0808638
1
0
0
0
1
0
0
0
1
0
false
0
[136]
[145]
-
AvatarPartScaleType
ProportionsSlender
-
LeftFoot
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.660244
56.98195
40.36777
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.3247062861919403
0.6436786651611328
0.9374623894691467
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065396
https://assetdelivery.roblox.com/v1/asset/?id=3934065396
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.3247062861919403
0.6436786651611328
0.9374623894691467
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
LeftAnkleRigAttachment
0.007632643
0.17003131
0.26353702
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.007632642984390259
0.17003130912780762
0.2635370194911957
-
LeftAnkle
-0.0022327602
-0.7746978
0.09171689
1
0
0
0
1
0
0
0
1
0.007632643
0.17003131
0.26353702
1
0
0
0
1
0
0
0
1
0
false
0
[151]
[152]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.3247062861919403
0.6436786651611328
0.9374623894691467
-
LeftLowerArm
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-36.034298
60.230377
40.610584
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.43274736404418945
0.8891100883483887
0.4252088665962219
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065576
https://assetdelivery.roblox.com/v1/asset/?id=3934065576
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.43274736404418945
0.8891100883483887
0.4252088665962219
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
LeftElbowRigAttachment
0.02927661
0.3926015
-0.026417091
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.029276609420776367
0.39260149002075195
-0.026417091488838196
-
LeftWristRigAttachment
-0.11797005
-0.39579457
0.015762076
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.1179700493812561
-0.3957945704460144
0.015762075781822205
-
LeftElbow
-0.03995645
-0.4060647
0.030424759
1
0
0
0
1
0
0
0
1
0.02927661
0.3926015
-0.026417091
1
0
0
0
1
0
0
0
1
0
false
0
[161]
[105]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.43274736404418945
0.8891100883483887
0.4252088665962219
-
LeftLowerLeg
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.65038
57.926678
40.539593
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.4297199249267578
1.4310553073883057
0.5792606472969055
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065606
https://assetdelivery.roblox.com/v1/asset/?id=3934065606
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.4297199249267578
1.4310553073883057
0.5792606472969055
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
LeftKneeRigAttachment
0.032010406
0.6422378
-0.081097215
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.032010406255722046
0.6422377824783325
-0.08109721541404724
-
LeftAnkleRigAttachment
-0.0022327602
-0.7746978
0.09171689
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.002232760190963745
-0.7746977806091309
0.09171689301729202
-
LeftKnee
0.019307911
-0.5955982
0.04933771
1
0
0
0
1
0
0
0
1
0.032010406
0.6422378
-0.081097215
1
0
0
0
1
0
0
0
1
0
false
0
[170]
[151]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.4297199249267578
1.4310553073883057
0.5792606472969055
-
LeftUpperLeg
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.637676
59.164513
40.409157
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.5554731488227844
1.331610918045044
0.70538330078125
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065609
https://assetdelivery.roblox.com/v1/asset/?id=3934065609
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.5554731488227844
1.331610918045044
0.70538330078125
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
LeftHipRigAttachment
0.0014059246
0.66785705
0.016021186
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.0014059245586395264
0.6678570508956909
0.016021186485886574
-
LeftKneeRigAttachment
0.019307911
-0.5955982
0.04933771
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.01930791139602661
-0.5955982208251953
0.049337711185216904
-
LeftHip
-0.28042528
-0.10188474
0.00011146953
1
0
0
0
1
0
0
0
1
0.0014059246
0.66785705
0.016021186
1
0
0
0
1
0
0
0
1
0
false
0
[135]
[170]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.5554731488227844
1.331610918045044
0.70538330078125
-
RightFoot
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.05435
56.98192
40.36746
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.32470619678497314
0.6436238288879395
0.937462329864502
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065630
https://assetdelivery.roblox.com/v1/asset/?id=3934065630
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.32470619678497314
0.6436240673065186
0.937462329864502
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
RightAnkleRigAttachment
-0.008807838
0.17005855
0.26385164
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.008807837963104248
0.1700584888458252
0.2638516426086426
-
OriginalSize
0.32470619678497314
0.6436238288879395
0.937462329864502
-
RightAnkle
0.0010480881
-0.7746442
0.09195016
1
0
0
0
1
0
0
0
1
-0.008807838
0.17005855
0.26385164
1
0
0
0
1
0
0
0
1
0
false
0
[145]
[186]
-
AvatarPartScaleType
ProportionsSlender
-
LeftUpperArm
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.965065
61.029045
40.55374
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.39597806334495544
0.9424078464508057
0.42509543895721436
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065546
https://assetdelivery.roblox.com/v1/asset/?id=3934065546
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.39597806334495544
0.9424078464508057
0.42509543895721436
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
LeftShoulderRigAttachment
0.07708573
0.33506155
-0.0013367459
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.07708573341369629
0.33506155014038086
-0.0013367459177970886
-
LeftElbowRigAttachment
-0.03995645
-0.4060647
0.030424759
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.03995645046234131
-0.4060646891593933
0.030424758791923523
-
LeftShoulder
-0.53098595
0.31034386
0.09133796
1
0
0
0
1
0
0
0
1
0.07708573
0.33506155
-0.0013367459
1
0
0
0
1
0
0
0
1
0
false
0
[115]
[161]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.39597806334495544
0.9424078464508057
0.42509543895721436
-
UpperTorso
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.356995
61.053764
40.461067
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
1.2573397159576416
1.5161899328231812
1.0650634765625
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065561
https://assetdelivery.roblox.com/v1/asset/?id=3934065561
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
1.2573397159576416
1.5161899328231812
1.0650634765625
rbxassetid://3934065684
-0.5
0.5
0
0
0
0
0
0
-
WaistRigAttachment
0.00160679
-0.69307566
-0.13708577
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.001606789999641478
-0.6930756568908691
-0.13708576560020447
-
NeckRigAttachment
-0.00028551545
0.61014855
0.059081264
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.0002855154452845454
0.610148549079895
0.05908126384019852
-
LeftShoulderRigAttachment
-0.53098595
0.31034386
0.09133796
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.530985951423645
0.310343861579895
0.09133795648813248
-
RightShoulderRigAttachment
0.532176
0.31034005
0.091338284
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.5321760177612305
0.3103400468826294
0.09133828431367874
-
Waist
0.00045886415
0.42643553
-0.10108509
1
0
0
0
1
0
0
0
1
0.00160679
-0.69307566
-0.13708577
1
0
0
0
1
0
0
0
1
0
false
0
[135]
[115]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
1.2573397159576416
1.5161899328231812
1.0650634765625
-
Head
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.368633
62.163597
40.50809
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.83642578125
1.1683197021484375
0.9020295143127441
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065587
https://assetdelivery.roblox.com/v1/asset/?id=3934065587
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.83642578125
1.1683197021484375
0.9020295143127441
rbxassetid://3934065716
-0.5
0.5
0
0
0
0
0
0
-
NeckRigAttachment
0.011352291
-0.49968445
0.012058221
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.011352291330695152
-0.4996844530105591
0.01205822080373764
-
Neck
-0.00028551545
0.61014855
0.059081264
1
0
0
0
1
0
0
0
1
0.011352291
-0.49968445
0.012058221
1
0
0
0
1
0
0
0
1
0
false
0
[115]
[212]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.83642578125
1.1683197021484375
0.9020295143127441
-
RightHand
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-34.58733
59.531105
40.576588
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.24898815155029297
0.6131889820098877
0.3323974907398224
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065611
https://assetdelivery.roblox.com/v1/asset/?id=3934065611
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.24898815155029297
0.6131889820098877
0.3323974907398224
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
RightWristRigAttachment
0.026803672
0.30347684
0.04975809
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.026803672313690186
0.30347684025764465
0.04975809156894684
-
RightWrist
0.119244516
-0.39689308
0.015973017
1
0
0
0
1
0
0
0
1
0.026803672
0.30347684
0.04975809
1
0
0
0
1
0
0
0
1
0
false
0
[125]
[219]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.24898815155029297
0.6131889820098877
0.3323974907398224
-
LowerTorso
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.355846
59.934254
40.425068
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
1.2410783767700195
0.9438430666923523
0.8493633270263672
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065615
https://assetdelivery.roblox.com/v1/asset/?id=3934065615
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
1.2410783767700195
0.9438430666923523
0.8493633270263672
rbxassetid://3934065684
-0.5
0.5
0
0
0
0
0
0
-
RootRigAttachment
-0.0020411294
0.07933888
0.038673006
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.002041129395365715
0.07933887839317322
0.03867300599813461
-
LeftHipRigAttachment
-0.28042528
-0.10188474
0.00011146953
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.2804252803325653
-0.10188473761081696
0.00011146953329443932
-
RightHipRigAttachment
0.27634314
-0.101884976
0.00011147326
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.27634313702583313
-0.10188497602939606
0.00011147325858473778
-
WaistRigAttachment
0.00045886415
0.42643553
-0.10108509
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.00045886414591223
0.42643553018569946
-0.10108508914709091
-
Root
-0.000607906
-0.81877613
0.033983894
1
0
0
0
1
0
0
0
1
-0.0020411294
0.07933888
0.038673006
1
0
0
0
1
0
0
0
1
0
false
0
[96]
[135]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
1.2410783767700195
0.9438430666923523
0.8493633270263672
-
Sound
true
{F7642D38-837C-42DE-B31D-95955B455200}
-- This script intentionally left blank
-
Animate
true
{3A393054-F805-4C53-A32A-204C540BDC1A}
animTable[animName][idx].weight) do
roll = roll - animTable[animName][idx].weight
idx = idx + 1
end
return idx
end
function playAnimation(animName, transitionTime, humanoid, forceReroll)
local idx = rollAnimation(animName)
local anim = animTable[animName][idx].anim
-- switch animation
if (anim ~= currentAnimInstance) and ((animName ~= currentAnim) or forceReroll) then
-- print(animName, idx)
if (currentAnimTrack ~= nil) then
currentAnimTrack:Stop(transitionTime)
currentAnimTrack:Destroy()
end
if (runAnimTrack ~= nil) then
runAnimTrack:Stop(transitionTime)
runAnimTrack:Destroy()
if userNoUpdateOnLoop == true then
runAnimTrack = nil
end
end
currentAnimSpeed = 1.0
-- load it to the humanoid; get AnimationTrack
currentAnimTrack = humanoid:LoadAnimation(anim)
currentAnimTrack.Priority = Enum.AnimationPriority.Core
-- play the animation
currentAnimTrack:Play(transitionTime)
currentAnim = animName
currentAnimInstance = anim
-- set up keyframe name triggers
if (currentAnimKeyframeHandler ~= nil) then
currentAnimKeyframeHandler:disconnect()
end
currentAnimKeyframeHandler = currentAnimTrack.KeyframeReached:connect(keyFrameReachedFunc)
-- check to see if we need to blend a walk/run animation
if animName == "walk" then
local runAnimName = "run"
local runIdx = rollAnimation(runAnimName)
runAnimTrack = humanoid:LoadAnimation(animTable[runAnimName][runIdx].anim)
runAnimTrack.Priority = Enum.AnimationPriority.Core
runAnimTrack:Play(transitionTime)
if (runAnimKeyframeHandler ~= nil) then
runAnimKeyframeHandler:disconnect()
end
runAnimKeyframeHandler = runAnimTrack.KeyframeReached:connect(keyFrameReachedFunc)
end
end
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
local toolAnimName = ""
local toolAnimTrack = nil
local toolAnimInstance = nil
local currentToolAnimKeyframeHandler = nil
function toolKeyFrameReachedFunc(frameName)
if (frameName == "End") then
playToolAnimation(toolAnimName, 0.0, Humanoid)
end
end
function playToolAnimation(animName, transitionTime, humanoid, priority)
local idx = rollAnimation(animName)
local anim = animTable[animName][idx].anim
if (toolAnimInstance ~= anim) then
if (toolAnimTrack ~= nil) then
toolAnimTrack:Stop()
toolAnimTrack:Destroy()
transitionTime = 0
end
-- load it to the humanoid; get AnimationTrack
toolAnimTrack = humanoid:LoadAnimation(anim)
if priority then
toolAnimTrack.Priority = priority
end
-- play the animation
toolAnimTrack:Play(transitionTime)
toolAnimName = animName
toolAnimInstance = anim
currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc)
end
end
function stopToolAnimations()
local oldAnim = toolAnimName
if (currentToolAnimKeyframeHandler ~= nil) then
currentToolAnimKeyframeHandler:disconnect()
end
toolAnimName = ""
toolAnimInstance = nil
if (toolAnimTrack ~= nil) then
toolAnimTrack:Stop()
toolAnimTrack:Destroy()
toolAnimTrack = nil
end
return oldAnim
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
-- STATE CHANGE HANDLERS
function onRunning(speed)
if speed > 0.5 then
local scale = 16.0
playAnimation("walk", 0.2, Humanoid)
setAnimationSpeed(speed / scale)
pose = "Running"
else
if emoteNames[currentAnim] == nil then
playAnimation("idle", 0.2, Humanoid)
pose = "Standing"
end
end
end
function onDied()
pose = "Dead"
end
function onJumping()
playAnimation("jump", 0.1, Humanoid)
jumpAnimTime = jumpAnimDuration
pose = "Jumping"
end
function onClimbing(speed)
local scale = 5.0
playAnimation("climb", 0.1, Humanoid)
setAnimationSpeed(speed / scale)
pose = "Climbing"
end
function onGettingUp()
pose = "GettingUp"
end
function onFreeFall()
if (jumpAnimTime <= 0) then
playAnimation("fall", fallTransitionTime, Humanoid)
end
pose = "FreeFall"
end
function onFallingDown()
pose = "FallingDown"
end
function onSeated()
pose = "Seated"
end
function onPlatformStanding()
pose = "PlatformStanding"
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
function onSwimming(speed)
if speed > 1.00 then
local scale = 10.0
playAnimation("swim", 0.4, Humanoid)
setAnimationSpeed(speed / scale)
pose = "Swimming"
else
playAnimation("swimidle", 0.4, Humanoid)
pose = "Standing"
end
end
function animateTool()
if (toolAnim == "None") then
playToolAnimation("toolnone", toolTransitionTime, Humanoid, Enum.AnimationPriority.Idle)
return
end
if (toolAnim == "Slash") then
playToolAnimation("toolslash", 0, Humanoid, Enum.AnimationPriority.Action)
return
end
if (toolAnim == "Lunge") then
playToolAnimation("toollunge", 0, Humanoid, Enum.AnimationPriority.Action)
return
end
end
function getToolAnim(tool)
for _, c in ipairs(tool:GetChildren()) do
if c.Name == "toolanim" and c.className == "StringValue" then
return c
end
end
return nil
end
local lastTick = 0
function stepAnimate(currentTime)
local amplitude = 1
local frequency = 1
local deltaTime = currentTime - lastTick
lastTick = currentTime
local climbFudge = 0
local setAngles = false
if (jumpAnimTime > 0) then
jumpAnimTime = jumpAnimTime - deltaTime
end
-- print("stepAnimate", currentTime, pose)
if (pose == "FreeFall" and jumpAnimTime <= 0) then
playAnimation("fall", fallTransitionTime, Humanoid)
elseif (pose == "Seated") then
playAnimation("sit", 0.5, Humanoid)
return
elseif (pose == "Running" or pose == "Standing") then
local velocity = cci:GetVariable("WorldVelocity")
local speed = velocity.Magnitude
onRunning(speed)
-- elseif (pose == "Running") then
-- playAnimation("walk", 0.2, Humanoid)
elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then
stopAllAnimations()
amplitude = 0.1
frequency = 1
setAngles = true
end
-- Tool Animation handling
local tool = Character:FindFirstChildOfClass("Tool")
if tool and tool:FindFirstChild("Handle") then
local animStringValueObject = getToolAnim(tool)
if animStringValueObject then
toolAnim = animStringValueObject.Value
-- message recieved, delete StringValue
animStringValueObject.Parent = nil
toolAnimTime = currentTime + .3
end
if currentTime > toolAnimTime then
toolAnimTime = 0
toolAnim = "None"
end
animateTool()
else
stopToolAnimations()
toolAnim = "None"
toolAnimInstance = nil
toolAnimTime = 0
end
end
-- connect events
local function OnStateChanged(NewStateName)
if NewStateName then
if NewStateName == "GroundState" then
pose = "Running"
elseif NewStateName == "JumpState" then
onJumping()
elseif NewStateName == "AirState" then
onFreeFall()
end
-- print(NewStateName)
end
end
local OnStateChangedEvent = nil
while not OnStateChangedEvent do
OnStateChangedEvent = cci:GetVariable("OnStateChanged")
wait()
end
OnStateChangedEvent.Event:Connect(OnStateChanged)
--[[
Humanoid.Died:connect(onDied)
Humanoid.Running:connect(onRunning)
Humanoid.Jumping:connect(onJumping)
Humanoid.Climbing:connect(onClimbing)
Humanoid.GettingUp:connect(onGettingUp)
Humanoid.FreeFalling:connect(onFreeFall)
Humanoid.FallingDown:connect(onFallingDown)
Humanoid.Seated:connect(onSeated)
Humanoid.PlatformStanding:connect(onPlatformStanding)
Humanoid.Swimming:connect(onSwimming)
--]]
-- setup emote chat hook
game:GetService("Players").LocalPlayer.Chatted:connect(function(msg)
local emote = ""
if (string.sub(msg, 1, 3) == "/e ") then
emote = string.sub(msg, 4)
elseif (string.sub(msg, 1, 7) == "/emote ") then
emote = string.sub(msg, 8)
end
if (pose == "Standing" and emoteNames[emote] ~= nil) then
playAnimation(emote, 0.1, Humanoid)
end
end)
-- initialize to idle
playAnimation("idle", 0.1, Humanoid)
pose = "Standing"
-- loop to handle timed state transitions and tool animations
while Character.Parent ~= nil do
local _, currentGameTime = wait(0.1)
stepAnimate(currentGameTime)
end
]]>
-
Health
true
{FEE0CCE7-26F8-4B26-A845-6CC54D23551E}
-- nothing here
-
AnimationController
-
Animator
-
StarterCharacterScripts
-
CharacterComponentScripts
-
CharacterHelper
1.2000000476837158
-
ComponentInterfaceInstance
-
ComponentLoaderClient
-
ComponentLoaderServer
-
Configurations
-
Animate
-
cheer
-
CheerAnim
http://www.roblox.com/asset/?id=507770677
-
climb
-
ClimbAnim
http://www.roblox.com/asset/?id=507765644
-
dance
-
Animation1
http://www.roblox.com/asset/?id=507771019
-
Weight
10
-
Animation2
http://www.roblox.com/asset/?id=507771955
-
Weight
10
-
Animation3
http://www.roblox.com/asset/?id=507772104
-
Weight
10
-
dance2
-
Animation1
http://www.roblox.com/asset/?id=507776043
-
Weight
10
-
Animation2
http://www.roblox.com/asset/?id=507776720
-
Weight
10
-
Animation3
http://www.roblox.com/asset/?id=507776879
-
Weight
10
-
dance3
-
Animation1
http://www.roblox.com/asset/?id=507777268
-
Weight
10
-
Animation2
http://www.roblox.com/asset/?id=507777451
-
Weight
10
-
Animation3
http://www.roblox.com/asset/?id=507777623
-
Weight
10
-
fall
-
FallAnim
http://www.roblox.com/asset/?id=507767968
-
idle
-
Animation1
http://www.roblox.com/asset/?id=507766388
-
Weight
9
-
Animation2
http://www.roblox.com/asset/?id=507766666
-
Weight
1
-
jump
-
JumpAnim
http://www.roblox.com/asset/?id=507765000
-
laugh
-
LaughAnim
http://www.roblox.com/asset/?id=507770818
-
point
-
PointAnim
http://www.roblox.com/asset/?id=507770453
-
run
-
RunAnim
http://www.roblox.com/asset/?id=913376220
-
sit
-
SitAnim
http://www.roblox.com/asset/?id=2506281703
-
swim
-
Swim
http://www.roblox.com/asset/?id=913384386
-
swimidle
-
SwimIdle
http://www.roblox.com/asset/?id=913389285
-
toollunge
-
ToolLungeAnim
http://www.roblox.com/asset/?id=522638767
-
toolnone
-
ToolNoneAnim
http://www.roblox.com/asset/?id=507768375
-
toolslash
-
ToolSlashAnim
http://www.roblox.com/asset/?id=522635514
-
walk
-
WalkAnim
http://www.roblox.com/asset/?id=913402848
-
wave
-
WaveAnim
http://www.roblox.com/asset/?id=507770239
-
RigScale
-
BodyDepthScale
1
-
BodyHeightScale
1
-
BodyProportionScale
1
-
BodyTypeScale
1
-
BodyWidthScale
1
-
HeadScale
1
-
Health
-
CurrentHealth
100
-
HealthRegenRate
0.01
-
MaxHealth
100
-
ControlStateMachine
-
MaxSlopeAngle
60
-
StepHeight
2.9
-
WalkSpeed
16
-
RespawnTime
3
-
AutoMove
-
MoveTimeout
8
-
DistanceEpsilon
0.3
-
Equipment
-
StarterPlayerScripts
-
PlayerModule
-
CameraModule
-
BaseCamera
0 and camera.ViewportSize.Y > 0 and (camera.ViewportSize.Y > camera.ViewportSize.X) then
-- Screen has portrait orientation, swap X and Y sensitivity
return translationVector * Vector2.new( sensitivity.Y, sensitivity.X)
end
return translationVector * sensitivity
end
function BaseCamera:Enable(enable)
if self.enabled ~= enable then
self.enabled = enable
if self.enabled then
self:ConnectInputEvents()
if FFlagPlayerScriptsBindAtPriority then
self:BindContextActions()
end
if Players.LocalPlayer.CameraMode == Enum.CameraMode.LockFirstPerson then
self.currentSubjectDistance = 0.5
if not self.inFirstPerson then
self:EnterFirstPerson()
end
end
else
self:DisconnectInputEvents()
if FFlagPlayerScriptsBindAtPriority then
self:UnbindContextActions()
end
-- Clean up additional event listeners and reset a bunch of properties
self:Cleanup()
end
end
end
function BaseCamera:GetEnabled()
return self.enabled
end
function BaseCamera:OnInputBegan(input, processed)
if input.UserInputType == Enum.UserInputType.Touch then
self:OnTouchBegan(input, processed)
elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
self:OnMouse2Down(input, processed)
elseif input.UserInputType == Enum.UserInputType.MouseButton3 then
self:OnMouse3Down(input, processed)
end
-- Keyboard
if not FFlagPlayerScriptsBindAtPriority then
if input.UserInputType == Enum.UserInputType.Keyboard then
self:OnKeyDown(input, processed)
end
end
end
function BaseCamera:OnInputChanged(input, processed)
if input.UserInputType == Enum.UserInputType.Touch then
self:OnTouchChanged(input, processed)
elseif input.UserInputType == Enum.UserInputType.MouseMovement then
self:OnMouseMoved(input, processed)
elseif input.UserInputType == Enum.UserInputType.MouseWheel then
self:OnMouseWheel(input, processed)
end
end
function BaseCamera:OnInputEnded(input, processed)
if input.UserInputType == Enum.UserInputType.Touch then
self:OnTouchEnded(input, processed)
elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
self:OnMouse2Up(input, processed)
elseif input.UserInputType == Enum.UserInputType.MouseButton3 then
self:OnMouse3Up(input, processed)
end
-- Keyboard
if not FFlagPlayerScriptsBindAtPriority then
if input.UserInputType == Enum.UserInputType.Keyboard then
self:OnKeyUp(input, processed)
end
end
end
function BaseCamera:ConnectInputEvents()
self.inputBeganConn = UserInputService.InputBegan:Connect(function(input, processed)
self:OnInputBegan(input, processed)
end)
self.inputChangedConn = UserInputService.InputChanged:Connect(function(input, processed)
self:OnInputChanged(input, processed)
end)
self.inputEndedConn = UserInputService.InputEnded:Connect(function(input, processed)
self:OnInputEnded(input, processed)
end)
self.touchActivateConn = UserInputService.TouchTapInWorld:Connect(function(touchPos, processed)
self:OnTouchTap(touchPos)
end)
self.menuOpenedConn = GuiService.MenuOpened:connect(function()
self:ResetInputStates()
end)
self.gamepadConnectedConn = UserInputService.GamepadDisconnected:connect(function(gamepadEnum)
if self.activeGamepad ~= gamepadEnum then return end
self.activeGamepad = nil
self:AssignActivateGamepad()
end)
self.gamepadDisconnectedConn = UserInputService.GamepadConnected:connect(function(gamepadEnum)
if self.activeGamepad == nil then
self:AssignActivateGamepad()
end
end)
if not FFlagPlayerScriptsBindAtPriority then
self:BindGamepadInputActions()
end
self:AssignActivateGamepad()
self:UpdateMouseBehavior()
end
function BaseCamera:BindContextActions()
self:BindGamepadInputActions()
self:BindKeyboardInputActions()
end
function BaseCamera:AssignActivateGamepad()
local connectedGamepads = UserInputService:GetConnectedGamepads()
if #connectedGamepads > 0 then
for i = 1, #connectedGamepads do
if self.activeGamepad == nil then
self.activeGamepad = connectedGamepads[i]
elseif connectedGamepads[i].Value < self.activeGamepad.Value then
self.activeGamepad = connectedGamepads[i]
end
end
end
if self.activeGamepad == nil then -- nothing is connected, at least set up for gamepad1
self.activeGamepad = Enum.UserInputType.Gamepad1
end
end
function BaseCamera:DisconnectInputEvents()
if self.inputBeganConn then
self.inputBeganConn:Disconnect()
self.inputBeganConn = nil
end
if self.inputChangedConn then
self.inputChangedConn:Disconnect()
self.inputChangedConn = nil
end
if self.inputEndedConn then
self.inputEndedConn:Disconnect()
self.inputEndedConn = nil
end
end
function BaseCamera:UnbindContextActions()
for i = 1, #self.boundContextActions do
ContextActionService:UnbindAction(self.boundContextActions[i])
end
self.boundContextActions = {}
end
function BaseCamera:Cleanup()
if self.menuOpenedConn then
self.menuOpenedConn:Disconnect()
self.menuOpenedConn = nil
end
if self.mouseLockToggleConn then
self.mouseLockToggleConn:Disconnect()
self.mouseLockToggleConn = nil
end
if self.gamepadConnectedConn then
self.gamepadConnectedConn:Disconnect()
self.gamepadConnectedConn = nil
end
if self.gamepadDisconnectedConn then
self.gamepadDisconnectedConn:Disconnect()
self.gamepadDisconnectedConn = nil
end
if self.subjectStateChangedConn then
self.subjectStateChangedConn:Disconnect()
self.subjectStateChangedConn = nil
end
if self.viewportSizeChangedConn then
self.viewportSizeChangedConn:Disconnect()
self.viewportSizeChangedConn = nil
end
if self.touchActivateConn then
self.touchActivateConn:Disconnect()
self.touchActivateConn = nil
end
self.turningLeft = false
self.turningRight = false
self.lastCameraTransform = nil
self.lastSubjectCFrame = nil
self.userPanningTheCamera = false
self.rotateInput = Vector2.new()
self.gamepadPanningCamera = Vector2.new(0,0)
-- Reset input states
self.startPos = nil
self.lastPos = nil
self.panBeginLook = nil
self.isRightMouseDown = false
self.isMiddleMouseDown = false
self.fingerTouches = {}
self.numUnsunkTouches = 0
self.startingDiff = nil
self.pinchBeginZoom = nil
-- Unlock mouse for example if right mouse button was being held down
if UserInputService.MouseBehavior ~= Enum.MouseBehavior.LockCenter then
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
-- This is called when settings menu is opened
function BaseCamera:ResetInputStates()
self.isRightMouseDown = false
self.isMiddleMouseDown = false
self:OnMousePanButtonReleased() -- this function doesn't seem to actually need parameters
if UserInputService.TouchEnabled then
--[[menu opening was causing serious touch issues
this should disable all active touch events if
they're active when menu opens.]]
for inputObject in pairs(self.fingerTouches) do
self.fingerTouches[inputObject] = nil
end
self.panBeginLook = nil
self.startPos = nil
self.lastPos = nil
self.userPanningTheCamera = false
self.startingDiff = nil
self.pinchBeginZoom = nil
self.numUnsunkTouches = 0
end
end
function BaseCamera:GetGamepadPan(name, state, input)
if input.UserInputType == self.activeGamepad and input.KeyCode == Enum.KeyCode.Thumbstick2 then
-- if self.L3ButtonDown then
-- -- L3 Thumbstick is depressed, right stick controls dolly in/out
-- if (input.Position.Y > THUMBSTICK_DEADZONE) then
-- self.currentZoomSpeed = 0.96
-- elseif (input.Position.Y < -THUMBSTICK_DEADZONE) then
-- self.currentZoomSpeed = 1.04
-- else
-- self.currentZoomSpeed = 1.00
-- end
-- else
if state == Enum.UserInputState.Cancel then
self.gamepadPanningCamera = ZERO_VECTOR2
return
end
local inputVector = Vector2.new(input.Position.X, -input.Position.Y)
if inputVector.magnitude > THUMBSTICK_DEADZONE then
self.gamepadPanningCamera = Vector2.new(input.Position.X, -input.Position.Y)
else
self.gamepadPanningCamera = ZERO_VECTOR2
end
--end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Sink
end
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Pass
end
end
function BaseCamera:DoKeyboardPanTurn(name, state, input)
if not self.hasGameLoaded and VRService.VREnabled then
return Enum.ContextActionResult.Pass
end
if state == Enum.UserInputState.Cancel then
self.turningLeft = false
self.turningRight = false
return Enum.ContextActionResult.Sink
end
if self.panBeginLook == nil and self.keyPanEnabled then
if input.KeyCode == Enum.KeyCode.Left then
self.turningLeft = state == Enum.UserInputState.Begin
elseif input.KeyCode == Enum.KeyCode.Right then
self.turningRight = state == Enum.UserInputState.Begin
end
return Enum.ContextActionResult.Sink
end
return Enum.ContextActionResult.Pass
end
function BaseCamera:DoPanRotateCamera(rotateAngle)
local angle = Util.RotateVectorByAngleAndRound(self:GetCameraLookVector() * Vector3.new(1,0,1), rotateAngle, math.pi*0.25)
if angle ~= 0 then
self.rotateInput = self.rotateInput + Vector2.new(angle, 0)
self.lastUserPanCamera = tick()
self.lastCameraTransform = nil
end
end
function BaseCamera:DoKeyboardPan(name, state, input)
if not self.hasGameLoaded and VRService.VREnabled then
return Enum.ContextActionResult.Pass
end
if state ~= Enum.UserInputState.Begin then
return Enum.ContextActionResult.Pass
end
if self.panBeginLook == nil and self.keyPanEnabled then
if input.KeyCode == Enum.KeyCode.Comma then
self:DoPanRotateCamera(-math.pi*0.1875)
elseif input.KeyCode == Enum.KeyCode.Period then
self:DoPanRotateCamera(math.pi*0.1875)
elseif input.KeyCode == Enum.KeyCode.PageUp then
self.rotateInput = self.rotateInput + Vector2.new(0,math.rad(15))
self.lastCameraTransform = nil
elseif input.KeyCode == Enum.KeyCode.PageDown then
self.rotateInput = self.rotateInput + Vector2.new(0,math.rad(-15))
self.lastCameraTransform = nil
end
return Enum.ContextActionResult.Sink
end
return Enum.ContextActionResult.Pass
end
function BaseCamera:DoGamepadZoom(name, state, input)
if input.UserInputType == self.activeGamepad then
if input.KeyCode == Enum.KeyCode.ButtonR3 then
if state == Enum.UserInputState.Begin then
if self.distanceChangeEnabled then
if self:GetCameraToSubjectDistance() > 0.5 then
self:SetCameraToSubjectDistance(0)
else
self:SetCameraToSubjectDistance(10)
end
end
end
elseif input.KeyCode == Enum.KeyCode.DPadLeft then
self.dpadLeftDown = (state == Enum.UserInputState.Begin)
elseif input.KeyCode == Enum.KeyCode.DPadRight then
self.dpadRightDown = (state == Enum.UserInputState.Begin)
end
if self.dpadLeftDown then
self.currentZoomSpeed = 1.04
elseif self.dpadRightDown then
self.currentZoomSpeed = 0.96
else
self.currentZoomSpeed = 1.00
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Sink
end
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Pass
end
-- elseif input.UserInputType == self.activeGamepad and input.KeyCode == Enum.KeyCode.ButtonL3 then
-- if (state == Enum.UserInputState.Begin) then
-- self.L3ButtonDown = true
-- elseif (state == Enum.UserInputState.End) then
-- self.L3ButtonDown = false
-- self.currentZoomSpeed = 1.00
-- end
-- end
end
function BaseCamera:DoKeyboardZoom(name, state, input)
if not self.hasGameLoaded and VRService.VREnabled then
return Enum.ContextActionResult.Pass
end
if state ~= Enum.UserInputState.Begin then
return Enum.ContextActionResult.Pass
end
if self.distanceChangeEnabled then
if input.KeyCode == Enum.KeyCode.I then
self:SetCameraToSubjectDistance( self.currentSubjectDistance - 5 )
elseif input.KeyCode == Enum.KeyCode.O then
self:SetCameraToSubjectDistance( self.currentSubjectDistance + 5 )
end
return Enum.ContextActionResult.Sink
end
return Enum.ContextActionResult.Pass
end
function BaseCamera:BindAction(actionName, actionFunc, createTouchButton, ...)
table.insert(self.boundContextActions, actionName)
ContextActionService:BindActionAtPriority(actionName, actionFunc, createTouchButton,
CAMERA_ACTION_PRIORITY, ...)
end
function BaseCamera:BindGamepadInputActions()
if FFlagPlayerScriptsBindAtPriority then
self:BindAction("BaseCameraGamepadPan", function(name, state, input) return self:GetGamepadPan(name, state, input) end,
false, Enum.KeyCode.Thumbstick2)
self:BindAction("BaseCameraGamepadZoom", function(name, state, input) return self:DoGamepadZoom(name, state, input) end,
false, Enum.KeyCode.DPadLeft, Enum.KeyCode.DPadRight, Enum.KeyCode.ButtonR3)
else
ContextActionService:BindAction("RootCamGamepadPan", function(name, state, input) self:GetGamepadPan(name, state, input) end, false, Enum.KeyCode.Thumbstick2)
ContextActionService:BindAction("RootCamGamepadZoom", function(name, state, input) self:DoGamepadZoom(name, state, input) end, false, Enum.KeyCode.ButtonR3)
--ContextActionService:BindAction("RootGamepadZoomAlt", function(name, state, input) self:DoGamepadZoom(name, state, input) end, false, Enum.KeyCode.ButtonL3)
ContextActionService:BindAction("RootGamepadZoomOut", function(name, state, input) self:DoGamepadZoom(name, state, input) end, false, Enum.KeyCode.DPadLeft)
ContextActionService:BindAction("RootGamepadZoomIn", function(name, state, input) self:DoGamepadZoom(name, state, input) end, false, Enum.KeyCode.DPadRight)
end
end
function BaseCamera:BindKeyboardInputActions()
self:BindAction("BaseCameraKeyboardPanArrowKeys", function(name, state, input) return self:DoKeyboardPanTurn(name, state, input) end,
false, Enum.KeyCode.Left, Enum.KeyCode.Right)
self:BindAction("BaseCameraKeyboardPan", function(name, state, input) return self:DoKeyboardPan(name, state, input) end,
false, Enum.KeyCode.Comma, Enum.KeyCode.Period, Enum.KeyCode.PageUp, Enum.KeyCode.PageDown)
self:BindAction("BaseCameraKeyboardZoom", function(name, state, input) return self:DoKeyboardZoom(name, state, input) end,
false, Enum.KeyCode.I, Enum.KeyCode.O)
end
function BaseCamera:OnTouchBegan(input, processed)
local canUseDynamicTouch = self.isDynamicThumbstickEnabled and not processed
if canUseDynamicTouch then
self.fingerTouches[input] = processed
if not processed then
self.inputStartPositions[input] = input.Position
self.inputStartTimes[input] = tick()
self.numUnsunkTouches = self.numUnsunkTouches + 1
end
end
end
function BaseCamera:OnTouchChanged(input, processed)
if self.fingerTouches[input] == nil then
if self.isDynamicThumbstickEnabled then
return
end
self.fingerTouches[input] = processed
if not processed then
self.numUnsunkTouches = self.numUnsunkTouches + 1
end
end
if self.numUnsunkTouches == 1 then
if self.fingerTouches[input] == false then
self.panBeginLook = self.panBeginLook or self:GetCameraLookVector()
self.startPos = self.startPos or input.Position
self.lastPos = self.lastPos or self.startPos
self.userPanningTheCamera = true
local delta = input.Position - self.lastPos
delta = Vector2.new(delta.X, delta.Y * UserGameSettings:GetCameraYInvertValue())
if self.panEnabled then
local desiredXYVector = self:InputTranslationToCameraAngleChange(delta, TOUCH_SENSITIVTY)
self.rotateInput = self.rotateInput + desiredXYVector
end
self.lastPos = input.Position
end
else
self.panBeginLook = nil
self.startPos = nil
self.lastPos = nil
self.userPanningTheCamera = false
end
if self.numUnsunkTouches == 2 then
local unsunkTouches = {}
for touch, wasSunk in pairs(self.fingerTouches) do
if not wasSunk then
table.insert(unsunkTouches, touch)
end
end
if #unsunkTouches == 2 then
local difference = (unsunkTouches[1].Position - unsunkTouches[2].Position).magnitude
if self.startingDiff and self.pinchBeginZoom then
local scale = difference / math.max(0.01, self.startingDiff)
local clampedScale = Util.Clamp(0.1, 10, scale)
if self.distanceChangeEnabled then
self:SetCameraToSubjectDistance(self.pinchBeginZoom / clampedScale)
end
else
self.startingDiff = difference
self.pinchBeginZoom = self:GetCameraToSubjectDistance()
end
end
else
self.startingDiff = nil
self.pinchBeginZoom = nil
end
end
function BaseCamera:CalcLookBehindRotateInput()
if not self.humanoidRootPart or not game.Workspace.CurrentCamera then
return nil
end
local cameraLookVector = game.Workspace.CurrentCamera.CFrame.lookVector
local newDesiredLook = (self.humanoidRootPart.CFrame.lookVector - Vector3.new(0,0.23,0)).unit
local horizontalShift = Util.GetAngleBetweenXZVectors(newDesiredLook, cameraLookVector)
local vertShift = math.asin(cameraLookVector.Y) - math.asin(newDesiredLook.Y)
if not Util.IsFinite(horizontalShift) then
horizontalShift = 0
end
if not Util.IsFinite(vertShift) then
vertShift = 0
end
return Vector2.new(horizontalShift, vertShift)
end
function BaseCamera:OnTouchTap(position)
if self.isDynamicThumbstickEnabled and not self.isAToolEquipped then
if self.lastTapTime and tick() - self.lastTapTime < MAX_TIME_FOR_DOUBLE_TAP then
self:SetCameraToSubjectDistance(self.defaultSubjectDistance)
else
if self.humanoidRootPart then
self.rotateInput = self:CalcLookBehindRotateInput()
end
end
self.lastTapTime = tick()
end
end
function BaseCamera:IsTouchTap(input)
-- We can't make the assumption that the input exists in the inputStartPositions because we may have switched from a different camera type.
if self.inputStartPositions[input] then
local posDelta = (self.inputStartPositions[input] - input.Position).magnitude
if posDelta < MAX_TAP_POS_DELTA then
local timeDelta = self.inputStartTimes[input] - tick()
if timeDelta < MAX_TAP_TIME_DELTA then
return true
end
end
end
return false
end
function BaseCamera:OnTouchEnded(input, processed)
if self.fingerTouches[input] == false then
if self.numUnsunkTouches == 1 then
self.panBeginLook = nil
self.startPos = nil
self.lastPos = nil
self.userPanningTheCamera = false
if self:IsTouchTap(input) then
self:OnTouchTap(input.Position)
end
elseif self.numUnsunkTouches == 2 then
self.startingDiff = nil
self.pinchBeginZoom = nil
end
end
if self.fingerTouches[input] ~= nil and self.fingerTouches[input] == false then
self.numUnsunkTouches = self.numUnsunkTouches - 1
end
self.fingerTouches[input] = nil
self.inputStartPositions[input] = nil
self.inputStartTimes[input] = nil
end
function BaseCamera:OnMouse2Down(input, processed)
if processed then return end
self.isRightMouseDown = true
self:OnMousePanButtonPressed(input, processed)
end
function BaseCamera:OnMouse2Up(input, processed)
self.isRightMouseDown = false
self:OnMousePanButtonReleased(input, processed)
end
function BaseCamera:OnMouse3Down(input, processed)
if processed then return end
self.isMiddleMouseDown = true
self:OnMousePanButtonPressed(input, processed)
end
function BaseCamera:OnMouse3Up(input, processed)
self.isMiddleMouseDown = false
self:OnMousePanButtonReleased(input, processed)
end
function BaseCamera:OnMouseMoved(input, processed)
if not self.hasGameLoaded and VRService.VREnabled then
return
end
local inputDelta = input.Delta
inputDelta = Vector2.new(inputDelta.X, inputDelta.Y * UserGameSettings:GetCameraYInvertValue())
if self.panEnabled and ((self.startPos and self.lastPos and self.panBeginLook) or self.inFirstPerson or self.inMouseLockedMode) then
local desiredXYVector = self:InputTranslationToCameraAngleChange(inputDelta,MOUSE_SENSITIVITY)
self.rotateInput = self.rotateInput + desiredXYVector
end
if self.startPos and self.lastPos and self.panBeginLook then
self.lastPos = self.lastPos + input.Delta
end
end
function BaseCamera:OnMousePanButtonPressed(input, processed)
if processed then return end
self:UpdateMouseBehavior()
self.panBeginLook = self.panBeginLook or self:GetCameraLookVector()
self.startPos = self.startPos or input.Position
self.lastPos = self.lastPos or self.startPos
self.userPanningTheCamera = true
end
function BaseCamera:OnMousePanButtonReleased(input, processed)
self:UpdateMouseBehavior()
if not (self.isRightMouseDown or self.isMiddleMouseDown) then
self.panBeginLook = nil
self.startPos = nil
self.lastPos = nil
self.userPanningTheCamera = false
end
end
function BaseCamera:OnMouseWheel(input, processed)
if not self.hasGameLoaded and VRService.VREnabled then
return
end
if not processed then
if self.distanceChangeEnabled then
local wheelInput = Util.Clamp(-1, 1, -input.Position.Z)
local newDistance
if self.inFirstPerson and wheelInput > 0 then
newDistance = FIRST_PERSON_DISTANCE_THRESHOLD
else
-- The 0.156 and 1.7 values are the slope and intercept of a line that is replacing the old
-- rk4Integrator function which was not being used as an integrator, only to get a delta as a function of distance,
-- which was linear as it was being used. These constants preserve the status quo behavior.
newDistance = self.currentSubjectDistance + 0.156 * self.currentSubjectDistance * wheelInput + 1.7 * math.sign(wheelInput)
end
self:SetCameraToSubjectDistance(newDistance)
end
end
end
--Remove with FFlagPlayerScriptsBindAtPriority
function BaseCamera:OnKeyDown(input, processed)
if not self.hasGameLoaded and VRService.VREnabled then
return
end
if processed then
return
end
if self.distanceChangeEnabled then
if input.KeyCode == Enum.KeyCode.I then
self:SetCameraToSubjectDistance( self.currentSubjectDistance - 5 )
elseif input.KeyCode == Enum.KeyCode.O then
self:SetCameraToSubjectDistance( self.currentSubjectDistance + 5 )
end
end
if self.panBeginLook == nil and self.keyPanEnabled then
if input.KeyCode == Enum.KeyCode.Left then
self.turningLeft = true
elseif input.KeyCode == Enum.KeyCode.Right then
self.turningRight = true
elseif input.KeyCode == Enum.KeyCode.Comma then
local angle = Util.RotateVectorByAngleAndRound(self:GetCameraLookVector() * Vector3.new(1,0,1), -math.pi*0.1875, math.pi*0.25)
if angle ~= 0 then
self.rotateInput = self.rotateInput + Vector2.new(angle, 0)
self.lastUserPanCamera = tick()
self.lastCameraTransform = nil
end
elseif input.KeyCode == Enum.KeyCode.Period then
local angle = Util.RotateVectorByAngleAndRound(self:GetCameraLookVector() * Vector3.new(1,0,1), math.pi*0.1875, math.pi*0.25)
if angle ~= 0 then
self.rotateInput = self.rotateInput + Vector2.new(angle, 0)
self.lastUserPanCamera = tick()
self.lastCameraTransform = nil
end
elseif input.KeyCode == Enum.KeyCode.PageUp then
self.rotateInput = self.rotateInput + Vector2.new(0,math.rad(15))
self.lastCameraTransform = nil
elseif input.KeyCode == Enum.KeyCode.PageDown then
self.rotateInput = self.rotateInput + Vector2.new(0,math.rad(-15))
self.lastCameraTransform = nil
end
end
end
--Remove with FFlagPlayerScriptsBindAtPriority
function BaseCamera:OnKeyUp(input, processed)
if input.KeyCode == Enum.KeyCode.Left then
self.turningLeft = false
elseif input.KeyCode == Enum.KeyCode.Right then
self.turningRight = false
end
end
function BaseCamera:UpdateMouseBehavior()
-- first time transition to first person mode or mouse-locked third person
if self.inFirstPerson or self.inMouseLockedMode then
pcall(function() UserGameSettings.RotationType = Enum.RotationType.CameraRelative end)
if UserInputService.MouseBehavior ~= Enum.MouseBehavior.LockCenter then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
end
else
pcall(function() UserGameSettings.RotationType = Enum.RotationType.MovementRelative end)
if self.isRightMouseDown or self.isMiddleMouseDown then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
end
function BaseCamera:UpdateForDistancePropertyChange()
-- Calling this setter with the current value will force checking that it is still
-- in range after a change to the min/max distance limits
self:SetCameraToSubjectDistance(self.currentSubjectDistance)
end
function BaseCamera:SetCameraToSubjectDistance(desiredSubjectDistance)
local player = Players.LocalPlayer
local lastSubjectDistance = self.currentSubjectDistance
-- By default, camera modules will respect LockFirstPerson and override the currentSubjectDistance with 0
-- regardless of what Player.CameraMinZoomDistance is set to, so that first person can be made
-- available by the developer without needing to allow players to mousewheel dolly into first person.
-- Some modules will override this function to remove or change first-person capability.
if player.CameraMode == Enum.CameraMode.LockFirstPerson then
self.currentSubjectDistance = 0.5
if not self.inFirstPerson then
self:EnterFirstPerson()
end
else
local newSubjectDistance = Util.Clamp(player.CameraMinZoomDistance, player.CameraMaxZoomDistance, desiredSubjectDistance)
if newSubjectDistance < FIRST_PERSON_DISTANCE_THRESHOLD then
self.currentSubjectDistance = 0.5
if not self.inFirstPerson then
self:EnterFirstPerson()
end
else
self.currentSubjectDistance = newSubjectDistance
if self.inFirstPerson then
self:LeaveFirstPerson()
end
end
end
-- Pass target distance and zoom direction to the zoom controller
ZoomController.SetZoomParameters(self.currentSubjectDistance, math.sign(desiredSubjectDistance - lastSubjectDistance))
-- Returned only for convenience to the caller to know the outcome
return self.currentSubjectDistance
end
function BaseCamera:SetCameraType( cameraType )
--Used by derived classes
self.cameraType = cameraType
end
function BaseCamera:GetCameraType()
return self.cameraType
end
-- Movement mode standardized to Enum.ComputerCameraMovementMode values
function BaseCamera:SetCameraMovementMode( cameraMovementMode )
self.cameraMovementMode = cameraMovementMode
end
function BaseCamera:GetCameraMovementMode()
return self.cameraMovementMode
end
function BaseCamera:SetIsMouseLocked(mouseLocked)
self.inMouseLockedMode = mouseLocked
self:UpdateMouseBehavior()
end
function BaseCamera:GetIsMouseLocked()
return self.inMouseLockedMode
end
function BaseCamera:SetMouseLockOffset(offsetVector)
self.mouseLockOffset = offsetVector
end
function BaseCamera:GetMouseLockOffset()
return self.mouseLockOffset
end
function BaseCamera:InFirstPerson()
return self.inFirstPerson
end
function BaseCamera:EnterFirstPerson()
-- Overridden in ClassicCamera, the only module which supports FirstPerson
end
function BaseCamera:LeaveFirstPerson()
-- Overridden in ClassicCamera, the only module which supports FirstPerson
end
-- Nominal distance, set by dollying in and out with the mouse wheel or equivalent, not measured distance
function BaseCamera:GetCameraToSubjectDistance()
return self.currentSubjectDistance
end
-- Actual measured distance to the camera Focus point, which may be needed in special circumstances, but should
-- never be used as the starting point for updating the nominal camera-to-subject distance (self.currentSubjectDistance)
-- since that is a desired target value set only by mouse wheel (or equivalent) input, PopperCam, and clamped to min max camera distance
function BaseCamera:GetMeasuredDistanceToFocus()
local camera = game.Workspace.CurrentCamera
if camera then
return (camera.CoordinateFrame.p - camera.Focus.p).magnitude
end
return nil
end
function BaseCamera:GetCameraLookVector()
return game.Workspace.CurrentCamera and game.Workspace.CurrentCamera.CFrame.lookVector or UNIT_Z
end
-- Replacements for RootCamera:RotateCamera() which did not actually rotate the camera
-- suppliedLookVector is not normally passed in, it's used only by Watch camera
function BaseCamera:CalculateNewLookCFrame(suppliedLookVector)
local currLookVector = suppliedLookVector or self:GetCameraLookVector()
local currPitchAngle = math.asin(currLookVector.y)
local yTheta = Util.Clamp(-MAX_Y + currPitchAngle, -MIN_Y + currPitchAngle, self.rotateInput.y)
local constrainedRotateInput = Vector2.new(self.rotateInput.x, yTheta)
local startCFrame = CFrame.new(ZERO_VECTOR3, currLookVector)
local newLookCFrame = CFrame.Angles(0, -constrainedRotateInput.x, 0) * startCFrame * CFrame.Angles(-constrainedRotateInput.y,0,0)
return newLookCFrame
end
function BaseCamera:CalculateNewLookVector(suppliedLookVector)
local newLookCFrame = self:CalculateNewLookCFrame(suppliedLookVector)
return newLookCFrame.lookVector
end
function BaseCamera:CalculateNewLookVectorVR()
local subjectPosition = self:GetSubjectPosition()
local vecToSubject = (subjectPosition - game.Workspace.CurrentCamera.CFrame.p)
local currLookVector = (vecToSubject * X1_Y0_Z1).unit
local vrRotateInput = Vector2.new(self.rotateInput.x, 0)
local startCFrame = CFrame.new(ZERO_VECTOR3, currLookVector)
local yawRotatedVector = (CFrame.Angles(0, -vrRotateInput.x, 0) * startCFrame * CFrame.Angles(-vrRotateInput.y,0,0)).lookVector
return (yawRotatedVector * X1_Y0_Z1).unit
end
function BaseCamera:GetHumanoid()
local player = Players.LocalPlayer
local character = player and player.Character
if character then
local resultHumanoid = self.humanoidCache[player]
if resultHumanoid and resultHumanoid.Parent == character then
return resultHumanoid
else
self.humanoidCache[player] = nil -- Bust Old Cache
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
self.humanoidCache[player] = humanoid
end
return humanoid
end
end
return nil
end
function BaseCamera:GetHumanoidPartToFollow(humanoid, humanoidStateType)
if humanoidStateType == Enum.HumanoidStateType.Dead then
local character = humanoid.Parent
if character then
return character:FindFirstChild("Head") or humanoid.Torso
else
return humanoid.Torso
end
else
return humanoid.Torso
end
end
function BaseCamera:UpdateGamepad()
local gamepadPan = self.gamepadPanningCamera
if gamepadPan and (self.hasGameLoaded or not VRService.VREnabled) then
gamepadPan = Util.GamepadLinearToCurve(gamepadPan)
local currentTime = tick()
if gamepadPan.X ~= 0 or gamepadPan.Y ~= 0 then
self.userPanningTheCamera = true
elseif gamepadPan == ZERO_VECTOR2 then
self.lastThumbstickRotate = nil
if self.lastThumbstickPos == ZERO_VECTOR2 then
self.currentSpeed = 0
end
end
local finalConstant = 0
if self.lastThumbstickRotate then
if VRService.VREnabled then
self.currentSpeed = self.vrMaxSpeed
else
local elapsedTime = (currentTime - self.lastThumbstickRotate) * 10
self.currentSpeed = self.currentSpeed + (self.maxSpeed * ((elapsedTime*elapsedTime)/self.numOfSeconds))
if self.currentSpeed > self.maxSpeed then self.currentSpeed = self.maxSpeed end
if self.lastVelocity then
local velocity = (gamepadPan - self.lastThumbstickPos)/(currentTime - self.lastThumbstickRotate)
local velocityDeltaMag = (velocity - self.lastVelocity).magnitude
if velocityDeltaMag > 12 then
self.currentSpeed = self.currentSpeed * (20/velocityDeltaMag)
if self.currentSpeed > self.maxSpeed then self.currentSpeed = self.maxSpeed end
end
end
end
local success, gamepadCameraSensitivity = pcall(function() return UserGameSettings.GamepadCameraSensitivity end)
finalConstant = success and (gamepadCameraSensitivity * self.currentSpeed) or self.currentSpeed
self.lastVelocity = (gamepadPan - self.lastThumbstickPos)/(currentTime - self.lastThumbstickRotate)
end
self.lastThumbstickPos = gamepadPan
self.lastThumbstickRotate = currentTime
return Vector2.new( gamepadPan.X * finalConstant, gamepadPan.Y * finalConstant * self.ySensitivity * UserGameSettings:GetCameraYInvertValue())
end
return ZERO_VECTOR2
end
-- [[ VR Support Section ]] --
function BaseCamera:ApplyVRTransform()
if not VRService.VREnabled then
return
end
--we only want this to happen in first person VR
local rootJoint = self.humanoidRootPart and self.humanoidRootPart:FindFirstChild("RootJoint")
if not rootJoint then
return
end
local cameraSubject = game.Workspace.CurrentCamera.CameraSubject
local isInVehicle = cameraSubject and cameraSubject:IsA("VehicleSeat")
if self.inFirstPerson and not isInVehicle then
local vrFrame = VRService:GetUserCFrame(Enum.UserCFrame.Head)
local vrRotation = vrFrame - vrFrame.p
rootJoint.C0 = CFrame.new(vrRotation:vectorToObjectSpace(vrFrame.p)) * CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
else
rootJoint.C0 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
end
end
function BaseCamera:IsInFirstPerson()
return self.inFirstPerson
end
function BaseCamera:ShouldUseVRRotation()
if not VRService.VREnabled then
return false
end
if not self.VRRotationIntensityAvailable and tick() - self.lastVRRotationIntensityCheckTime < 1 then
return false
end
local success, vrRotationIntensity = pcall(function() return StarterGui:GetCore("VRRotationIntensity") end)
self.VRRotationIntensityAvailable = success and vrRotationIntensity ~= nil
self.lastVRRotationIntensityCheckTime = tick()
self.shouldUseVRRotation = success and vrRotationIntensity ~= nil and vrRotationIntensity ~= "Smooth"
return self.shouldUseVRRotation
end
function BaseCamera:GetVRRotationInput()
local vrRotateSum = ZERO_VECTOR2
local success, vrRotationIntensity = pcall(function() return StarterGui:GetCore("VRRotationIntensity") end)
if not success then
return
end
local vrGamepadRotation = self.GamepadPanningCamera or ZERO_VECTOR2
local delayExpired = (tick() - self.lastVRRotationTime) >= self:GetRepeatDelayValue(vrRotationIntensity)
if math.abs(vrGamepadRotation.x) >= self:GetActivateValue() then
if (delayExpired or not self.vrRotateKeyCooldown[Enum.KeyCode.Thumbstick2]) then
local sign = 1
if vrGamepadRotation.x < 0 then
sign = -1
end
vrRotateSum = vrRotateSum + self:GetRotateAmountValue(vrRotationIntensity) * sign
self.vrRotateKeyCooldown[Enum.KeyCode.Thumbstick2] = true
end
elseif math.abs(vrGamepadRotation.x) < self:GetActivateValue() - 0.1 then
self.vrRotateKeyCooldown[Enum.KeyCode.Thumbstick2] = nil
end
if self.turningLeft then
if delayExpired or not self.vrRotateKeyCooldown[Enum.KeyCode.Left] then
vrRotateSum = vrRotateSum - self:GetRotateAmountValue(vrRotationIntensity)
self.vrRotateKeyCooldown[Enum.KeyCode.Left] = true
end
else
self.vrRotateKeyCooldown[Enum.KeyCode.Left] = nil
end
if self.turningRight then
if (delayExpired or not self.vrRotateKeyCooldown[Enum.KeyCode.Right]) then
vrRotateSum = vrRotateSum + self:GetRotateAmountValue(vrRotationIntensity)
self.vrRotateKeyCooldown[Enum.KeyCode.Right] = true
end
else
self.vrRotateKeyCooldown[Enum.KeyCode.Right] = nil
end
if vrRotateSum ~= ZERO_VECTOR2 then
self.lastVRRotationTime = tick()
end
return vrRotateSum
end
function BaseCamera:CancelCameraFreeze(keepConstraints)
if not keepConstraints then
self.cameraTranslationConstraints = Vector3.new(self.cameraTranslationConstraints.x, 1, self.cameraTranslationConstraints.z)
end
if self.cameraFrozen then
self.trackingHumanoid = nil
self.cameraFrozen = false
end
end
function BaseCamera:StartCameraFreeze(subjectPosition, humanoidToTrack)
if not self.cameraFrozen then
self.humanoidJumpOrigin = subjectPosition
self.trackingHumanoid = humanoidToTrack
self.cameraTranslationConstraints = Vector3.new(self.cameraTranslationConstraints.x, 0, self.cameraTranslationConstraints.z)
self.cameraFrozen = true
end
end
function BaseCamera:RescaleCameraOffset(newScaleFactor)
self.headHeightR15 = R15_HEAD_OFFSET * newScaleFactor
end
function BaseCamera:OnHumanoidSubjectChildAdded(child)
if child.Name == "BodyHeightScale" and child:IsA("NumberValue") then
if self.heightScaleChangedConn then
self.heightScaleChangedConn:Disconnect()
end
self.heightScaleChangedConn = child.Changed:Connect(function(newScaleFactor)
self:RescaleCameraOffset(newScaleFactor)
end)
self:RescaleCameraOffset(child.Value)
end
end
function BaseCamera:OnHumanoidSubjectChildRemoved(child)
if child.Name == "BodyHeightScale" then
self:RescaleCameraOffset(1)
if self.heightScaleChangedConn then
self.heightScaleChangedConn:Disconnect()
self.heightScaleChangedConn = nil
end
end
end
function BaseCamera:OnNewCameraSubject()
if self.subjectStateChangedConn then
self.subjectStateChangedConn:Disconnect()
self.subjectStateChangedConn = nil
end
if self.humanoidChildAddedConn then
self.humanoidChildAddedConn:Disconnect()
self.humanoidChildAddedConn = nil
end
if self.humanoidChildRemovedConn then
self.humanoidChildRemovedConn:Disconnect()
self.humanoidChildRemovedConn = nil
end
if self.heightScaleChangedConn then
self.heightScaleChangedConn:Disconnect()
self.heightScaleChangedConn = nil
end
local humanoid = workspace.CurrentCamera and workspace.CurrentCamera.CameraSubject
if self.trackingHumanoid ~= humanoid then
self:CancelCameraFreeze()
end
if humanoid and humanoid:IsA("Humanoid") then
self.humanoidChildAddedConn = humanoid.ChildAdded:Connect(function(child)
self:OnHumanoidSubjectChildAdded(child)
end)
self.humanoidChildRemovedConn = humanoid.ChildRemoved:Connect(function(child)
self:OnHumanoidSubjectChildRemoved(child)
end)
for _, child in pairs(humanoid:GetChildren()) do
self:OnHumanoidSubjectChildAdded(child)
end
self.subjectStateChangedConn = humanoid.StateChanged:Connect(function(oldState, newState)
if VRService.VREnabled and newState == Enum.HumanoidStateType.Jumping and not self.inFirstPerson then
self:StartCameraFreeze(self:GetSubjectPosition(), humanoid)
elseif newState ~= Enum.HumanoidStateType.Jumping and newState ~= Enum.HumanoidStateType.Freefall then
self:CancelCameraFreeze(true)
end
end)
end
end
function BaseCamera:GetVRFocus(subjectPosition, timeDelta)
local lastFocus = self.LastCameraFocus or subjectPosition
if not self.cameraFrozen then
self.cameraTranslationConstraints = Vector3.new(self.cameraTranslationConstraints.x, math.min(1, self.cameraTranslationConstraints.y + 0.42 * timeDelta), self.cameraTranslationConstraints.z)
end
local newFocus
if self.cameraFrozen and self.humanoidJumpOrigin and self.humanoidJumpOrigin.y > lastFocus.y then
newFocus = CFrame.new(Vector3.new(subjectPosition.x, math.min(self.humanoidJumpOrigin.y, lastFocus.y + 5 * timeDelta), subjectPosition.z))
else
newFocus = CFrame.new(Vector3.new(subjectPosition.x, lastFocus.y, subjectPosition.z):lerp(subjectPosition, self.cameraTranslationConstraints.y))
end
if self.cameraFrozen then
-- No longer in 3rd person
if self.inFirstPerson then -- not VRService.VREnabled
self:CancelCameraFreeze()
end
-- This case you jumped off a cliff and want to keep your character in view
-- 0.5 is to fix floating point error when not jumping off cliffs
if self.humanoidJumpOrigin and subjectPosition.y < (self.humanoidJumpOrigin.y - 0.5) then
self:CancelCameraFreeze()
end
end
return newFocus
end
function BaseCamera:GetRotateAmountValue(vrRotationIntensity)
vrRotationIntensity = vrRotationIntensity or StarterGui:GetCore("VRRotationIntensity")
if vrRotationIntensity then
if vrRotationIntensity == "Low" then
return VR_LOW_INTENSITY_ROTATION
elseif vrRotationIntensity == "High" then
return VR_HIGH_INTENSITY_ROTATION
end
end
return ZERO_VECTOR2
end
function BaseCamera:GetRepeatDelayValue(vrRotationIntensity)
vrRotationIntensity = vrRotationIntensity or StarterGui:GetCore("VRRotationIntensity")
if vrRotationIntensity then
if vrRotationIntensity == "Low" then
return VR_LOW_INTENSITY_REPEAT
elseif vrRotationIntensity == "High" then
return VR_HIGH_INTENSITY_REPEAT
end
end
return 0
end
function BaseCamera:Test()
print("BaseCamera:Test()")
end
function BaseCamera:Update(dt)
warn("BaseCamera:Update() This is a virtual function that should never be getting called.")
return game.Workspace.CurrentCamera.CFrame, game.Workspace.CurrentCamera.Focus
end
return BaseCamera
]]>
-
BaseOcclusion
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[
BaseOcclusion - Abstract base class for character occlusion control modules
2018 Camera Update - AllYourBlox
--]]
--[[ The Module ]]--
local BaseOcclusion = {}
BaseOcclusion.__index = BaseOcclusion
setmetatable(BaseOcclusion, { __call = function(_, ...) return BaseOcclusion.new(...) end})
function BaseOcclusion.new()
local self = setmetatable({}, BaseOcclusion)
return self
end
-- Called when character is added
function BaseOcclusion:CharacterAdded(char, player)
end
-- Called when character is about to be removed
function BaseOcclusion:CharacterRemoving(char, player)
end
function BaseOcclusion:OnCameraSubjectChanged(newSubject)
end
--[[ Derived classes are required to override and implement all of the following functions ]]--
function GetOcclusionMode()
-- Must be overridden in derived classes to return an Enum.DevCameraOcclusionMode value
warn("BaseOcclusion GetOcclusionMode must be overridden by derived classes")
return nil
end
function BaseOcclusion:Enable(enabled)
warn("BaseOcclusion Enable must be overridden by derived classes")
end
function BaseOcclusion:Update(dt, desiredCameraCFrame, desiredCameraFocus)
warn("BaseOcclusion Update must be overridden by derived classes")
return desiredCameraCFrame, desiredCameraFocus
end
return BaseOcclusion
-
CameraUtils
max
function CameraUtils.Clamp(low, high, val)
return math.min(math.max(val, low), high)
end
-- From TransparencyController
function CameraUtils.Round(num, places)
local decimalPivot = 10^places
return math.floor(num * decimalPivot + 0.5) / decimalPivot
end
function CameraUtils.IsFinite(val)
return val == val and val ~= math.huge and val ~= -math.huge
end
function CameraUtils.IsFiniteVector3(vec3)
return CameraUtils.IsFinite(vec3.X) and CameraUtils.IsFinite(vec3.Y) and CameraUtils.IsFinite(vec3.Z)
end
-- Legacy implementation renamed
function CameraUtils.GetAngleBetweenXZVectors(v1, v2)
return math.atan2(v2.X*v1.Z-v2.Z*v1.X, v2.X*v1.X+v2.Z*v1.Z)
end
function CameraUtils.RotateVectorByAngleAndRound(camLook, rotateAngle, roundAmount)
if camLook.Magnitude > 0 then
camLook = camLook.unit
local currAngle = math.atan2(camLook.z, camLook.x)
local newAngle = round((math.atan2(camLook.z, camLook.x) + rotateAngle) / roundAmount) * roundAmount
return newAngle - currAngle
end
return 0
end
-- K is a tunable parameter that changes the shape of the S-curve
-- the larger K is the more straight/linear the curve gets
local k = 0.35
local lowerK = 0.8
local function SCurveTranform(t)
t = CameraUtils.Clamp(-1,1,t)
if t >= 0 then
return (k*t) / (k - t + 1)
end
return -((lowerK*-t) / (lowerK + t + 1))
end
local DEADZONE = 0.1
local function toSCurveSpace(t)
return (1 + DEADZONE) * (2*math.abs(t) - 1) - DEADZONE
end
local function fromSCurveSpace(t)
return t/2 + 0.5
end
function CameraUtils.GamepadLinearToCurve(thumbstickPosition)
local function onAxis(axisValue)
local sign = 1
if axisValue < 0 then
sign = -1
end
local point = fromSCurveSpace(SCurveTranform(toSCurveSpace(math.abs(axisValue))))
point = point * sign
return CameraUtils.Clamp(-1, 1, point)
end
return Vector2.new(onAxis(thumbstickPosition.x), onAxis(thumbstickPosition.y))
end
-- This function converts 4 different, redundant enumeration types to one standard so the values can be compared
function CameraUtils.ConvertCameraModeEnumToStandard( enumValue )
if enumValue == Enum.TouchCameraMovementMode.Default then
return Enum.ComputerCameraMovementMode.Follow
end
if enumValue == Enum.ComputerCameraMovementMode.Default then
return Enum.ComputerCameraMovementMode.Classic
end
if enumValue == Enum.TouchCameraMovementMode.Classic or
enumValue == Enum.DevTouchCameraMovementMode.Classic or
enumValue == Enum.DevComputerCameraMovementMode.Classic or
enumValue == Enum.ComputerCameraMovementMode.Classic then
return Enum.ComputerCameraMovementMode.Classic
end
if enumValue == Enum.TouchCameraMovementMode.Follow or
enumValue == Enum.DevTouchCameraMovementMode.Follow or
enumValue == Enum.DevComputerCameraMovementMode.Follow or
enumValue == Enum.ComputerCameraMovementMode.Follow then
return Enum.ComputerCameraMovementMode.Follow
end
if enumValue == Enum.TouchCameraMovementMode.Orbital or
enumValue == Enum.DevTouchCameraMovementMode.Orbital or
enumValue == Enum.DevComputerCameraMovementMode.Orbital or
enumValue == Enum.ComputerCameraMovementMode.Orbital then
return Enum.ComputerCameraMovementMode.Orbital
end
-- Note: Only the Dev versions of the Enums have UserChoice as an option
if enumValue == Enum.DevTouchCameraMovementMode.UserChoice or
enumValue == Enum.DevComputerCameraMovementMode.UserChoice then
return Enum.DevComputerCameraMovementMode.UserChoice
end
-- For any unmapped options return Classic camera
return Enum.ComputerCameraMovementMode.Classic
end
return CameraUtils
]]>
-
ClassicCamera
1 then
self.lastCameraTransform = nil
end
if self.lastUpdate then
local gamepadRotation = self:UpdateGamepad()
if self:ShouldUseVRRotation() then
self.rotateInput = self.rotateInput + self:GetVRRotationInput()
else
-- Cap out the delta to 0.1 so we don't get some crazy things when we re-resume from
local delta = math.min(0.1, timeDelta)
if gamepadRotation ~= ZERO_VECTOR2 then
self.rotateInput = self.rotateInput + (gamepadRotation * delta)
end
local angle = 0
if not (isInVehicle or isOnASkateboard) then
angle = angle + (self.turningLeft and -120 or 0)
angle = angle + (self.turningRight and 120 or 0)
end
if angle ~= 0 then
self.rotateInput = self.rotateInput + Vector2.new(math.rad(angle * delta), 0)
end
end
end
-- Reset tween speed if user is panning
if self.userPanningTheCamera then
tweenSpeed = 0
self.lastUserPanCamera = tick()
end
local userRecentlyPannedCamera = now - self.lastUserPanCamera < TIME_BEFORE_AUTO_ROTATE
local subjectPosition = self:GetSubjectPosition()
if subjectPosition and player and camera then
local zoom = self:GetCameraToSubjectDistance()
if zoom < 0.5 then
zoom = 0.5
end
if self:GetIsMouseLocked() and not self:IsInFirstPerson() then
-- We need to use the right vector of the camera after rotation, not before
local newLookCFrame = self:CalculateNewLookCFrame(overrideCameraLookVector)
local offset = self:GetMouseLockOffset()
local cameraRelativeOffset = offset.X * newLookCFrame.rightVector + offset.Y * newLookCFrame.upVector + offset.Z * newLookCFrame.lookVector
--offset can be NAN, NAN, NAN if newLookVector has only y component
if Util.IsFiniteVector3(cameraRelativeOffset) then
subjectPosition = subjectPosition + cameraRelativeOffset
end
else
if not self.userPanningTheCamera and self.lastCameraTransform then
local isInFirstPerson = self:IsInFirstPerson()
if (isInVehicle or isOnASkateboard or (self.isFollowCamera and isClimbing)) and self.lastUpdate and humanoid and humanoid.Torso then
if isInFirstPerson then
if self.lastSubjectCFrame and (isInVehicle or isOnASkateboard) and cameraSubject:IsA('BasePart') then
local y = -Util.GetAngleBetweenXZVectors(self.lastSubjectCFrame.lookVector, cameraSubject.CFrame.lookVector)
if Util.IsFinite(y) then
self.rotateInput = self.rotateInput + Vector2.new(y, 0)
end
tweenSpeed = 0
end
elseif not userRecentlyPannedCamera then
local forwardVector = humanoid.Torso.CFrame.lookVector
if isOnASkateboard then
forwardVector = cameraSubject.CFrame.lookVector
end
tweenSpeed = Util.Clamp(0, tweenMaxSpeed, tweenSpeed + tweenAcceleration * timeDelta)
local percent = Util.Clamp(0, 1, tweenSpeed * timeDelta)
if self:IsInFirstPerson() and not (self.isFollowCamera and self.isClimbing) then
percent = 1
end
local y = Util.GetAngleBetweenXZVectors(forwardVector, self:GetCameraLookVector())
if Util.IsFinite(y) and math.abs(y) > 0.0001 then
self.rotateInput = self.rotateInput + Vector2.new(y * percent, 0)
end
end
elseif self.isFollowCamera and (not (isInFirstPerson or userRecentlyPannedCamera) and not VRService.VREnabled) then
-- Logic that was unique to the old FollowCamera module
local lastVec = -(self.lastCameraTransform.p - subjectPosition)
local y = Util.GetAngleBetweenXZVectors(lastVec, self:GetCameraLookVector())
-- This cutoff is to decide if the humanoid's angle of movement,
-- relative to the camera's look vector, is enough that
-- we want the camera to be following them. The point is to provide
-- a sizable dead zone to allow more precise forward movements.
local thetaCutoff = 0.4
-- Check for NaNs
if Util.IsFinite(y) and math.abs(y) > 0.0001 and math.abs(y) > thetaCutoff * timeDelta then
self.rotateInput = self.rotateInput + Vector2.new(y, 0)
end
end
end
end
if not self.isFollowCamera then
local VREnabled = VRService.VREnabled
if FFlagUserNewDefaultCameraAngle then
if VREnabled then
newCameraFocus = self:GetVRFocus(subjectPosition, timeDelta)
else
newCameraFocus = CFrame.new(subjectPosition + self:GetCameraSubjectOffset())
end
else
newCameraFocus = VREnabled and self:GetVRFocus(subjectPosition, timeDelta) or CFrame.new(subjectPosition)
end
local cameraFocusP = newCameraFocus.p
if VREnabled and not self:IsInFirstPerson() then
local cameraHeight = self:GetCameraHeight()
local vecToSubject = (subjectPosition - camera.CFrame.p)
local distToSubject = vecToSubject.magnitude
-- Only move the camera if it exceeded a maximum distance to the subject in VR
if distToSubject > zoom or self.rotateInput.x ~= 0 then
local desiredDist = math.min(distToSubject, zoom)
vecToSubject = self:CalculateNewLookVectorVR() * desiredDist
local newPos = cameraFocusP - vecToSubject
local desiredLookDir = camera.CFrame.lookVector
if self.rotateInput.x ~= 0 then
desiredLookDir = vecToSubject
end
local lookAt = Vector3.new(newPos.x + desiredLookDir.x, newPos.y, newPos.z + desiredLookDir.z)
self.rotateInput = ZERO_VECTOR2
newCameraCFrame = CFrame.new(newPos, lookAt) + Vector3.new(0, cameraHeight, 0)
end
else
local newLookVector = self:CalculateNewLookVector(overrideCameraLookVector)
self.rotateInput = ZERO_VECTOR2
newCameraCFrame = CFrame.new(cameraFocusP - (zoom * newLookVector), cameraFocusP)
end
else -- is FollowCamera
local newLookVector = self:CalculateNewLookVector(overrideCameraLookVector)
self.rotateInput = ZERO_VECTOR2
if FFlagUserNewDefaultCameraAngle then
if VRService.VREnabled then
newCameraFocus = self:GetVRFocus(subjectPosition, timeDelta)
else
newCameraFocus = CFrame.new(subjectPosition + self:GetCameraSubjectOffset())
end
else
if VRService.VREnabled then
newCameraFocus = self:GetVRFocus(subjectPosition, timeDelta)
elseif self.portraitMode then
newCameraFocus = CFrame.new(subjectPosition + PORTRAIT_OFFSET)
else
newCameraFocus = CFrame.new(subjectPosition)
end
end
newCameraCFrame = CFrame.new(newCameraFocus.p - (zoom * newLookVector), newCameraFocus.p) + Vector3.new(0, self:GetCameraHeight(), 0)
end
self.lastCameraTransform = newCameraCFrame
self.lastCameraFocus = newCameraFocus
if (isInVehicle or isOnASkateboard) and cameraSubject:IsA('BasePart') then
self.lastSubjectCFrame = cameraSubject.CFrame
else
self.lastSubjectCFrame = nil
end
end
self.lastUpdate = now
return newCameraCFrame, newCameraFocus
end
function ClassicCamera:EnterFirstPerson()
self.inFirstPerson = true
self:UpdateMouseBehavior()
end
function ClassicCamera:LeaveFirstPerson()
self.inFirstPerson = false
self:UpdateMouseBehavior()
end
return ClassicCamera
]]>
-
Invisicam
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[
Invisicam - Occlusion module that makes objects occluding character view semi-transparent
2018 Camera Update - AllYourBlox
--]]
--[[ Camera Maths Utilities Library ]]--
local Util = require(script.Parent:WaitForChild("CameraUtils"))
--[[ Top Level Roblox Services ]]--
local PlayersService = game:GetService("Players")
local RunService = game:GetService("RunService")
--[[ Constants ]]--
local ZERO_VECTOR3 = Vector3.new(0,0,0)
local USE_STACKING_TRANSPARENCY = true -- Multiple items between the subject and camera get transparency values that add up to TARGET_TRANSPARENCY
local TARGET_TRANSPARENCY = 0.75 -- Classic Invisicam's Value, also used by new invisicam for parts hit by head and torso rays
local TARGET_TRANSPARENCY_PERIPHERAL = 0.5 -- Used by new SMART_CIRCLE mode for items not hit by head and torso rays
local MODE = {
--CUSTOM = 1, -- Retired, unused
LIMBS = 2, -- Track limbs
MOVEMENT = 3, -- Track movement
CORNERS = 4, -- Char model corners
CIRCLE1 = 5, -- Circle of casts around character
CIRCLE2 = 6, -- Circle of casts around character, camera relative
LIMBMOVE = 7, -- LIMBS mode + MOVEMENT mode
SMART_CIRCLE = 8, -- More sample points on and around character
CHAR_OUTLINE = 9, -- Dynamic outline around the character
}
local LIMB_TRACKING_SET = {
-- Body parts common to R15 and R6
['Head'] = true,
-- Body parts unique to R6
['Left Arm'] = true,
['Right Arm'] = true,
['Left Leg'] = true,
['Right Leg'] = true,
-- Body parts unique to R15
['LeftLowerArm'] = true,
['RightLowerArm'] = true,
['LeftUpperLeg'] = true,
['RightUpperLeg'] = true
}
local CORNER_FACTORS = {
Vector3.new(1,1,-1),
Vector3.new(1,-1,-1),
Vector3.new(-1,-1,-1),
Vector3.new(-1,1,-1)
}
local CIRCLE_CASTS = 10
local MOVE_CASTS = 3
local SMART_CIRCLE_CASTS = 24
local SMART_CIRCLE_INCREMENT = 2.0 * math.pi / SMART_CIRCLE_CASTS
local CHAR_OUTLINE_CASTS = 24
-- Used to sanitize user-supplied functions
local function AssertTypes(param, ...)
local allowedTypes = {}
local typeString = ''
for _, typeName in pairs({...}) do
allowedTypes[typeName] = true
typeString = typeString .. (typeString == '' and '' or ' or ') .. typeName
end
local theType = type(param)
assert(allowedTypes[theType], typeString .. " type expected, got: " .. theType)
end
-- Helper function for Determinant of 3x3, not in CameraUtils for performance reasons
local function Det3x3(a,b,c,d,e,f,g,h,i)
return (a*(e*i-f*h)-b*(d*i-f*g)+c*(d*h-e*g))
end
-- Smart Circle mode needs the intersection of 2 rays that are known to be in the same plane
-- because they are generated from cross products with a common vector. This function is computing
-- that intersection, but it's actually the general solution for the point halfway between where
-- two skew lines come nearest to each other, which is more forgiving.
local function RayIntersection(p0, v0, p1, v1)
local v2 = v0:Cross(v1)
local d1 = p1.x - p0.x
local d2 = p1.y - p0.y
local d3 = p1.z - p0.z
local denom = Det3x3(v0.x,-v1.x,v2.x,v0.y,-v1.y,v2.y,v0.z,-v1.z,v2.z)
if (denom == 0) then
return ZERO_VECTOR3 -- No solution (rays are parallel)
end
local t0 = Det3x3(d1,-v1.x,v2.x,d2,-v1.y,v2.y,d3,-v1.z,v2.z) / denom
local t1 = Det3x3(v0.x,d1,v2.x,v0.y,d2,v2.y,v0.z,d3,v2.z) / denom
local s0 = p0 + t0 * v0
local s1 = p1 + t1 * v1
local s = s0 + 0.5 * ( s1 - s0 )
-- 0.25 studs is a threshold for deciding if the rays are
-- close enough to be considered intersecting, found through testing
if (s1-s0).Magnitude < 0.25 then
return s
else
return ZERO_VECTOR3
end
end
--[[ The Module ]]--
local BaseOcclusion = require(script.Parent:WaitForChild("BaseOcclusion"))
local Invisicam = setmetatable({}, BaseOcclusion)
Invisicam.__index = Invisicam
function Invisicam.new()
local self = setmetatable(BaseOcclusion.new(), Invisicam)
self.char = nil
self.humanoidRootPart = nil
self.torsoPart = nil
self.headPart = nil
self.childAddedConn = nil
self.childRemovedConn = nil
self.behaviors = {} -- Map of modes to behavior fns
self.behaviors[MODE.LIMBS] = self.LimbBehavior
self.behaviors[MODE.MOVEMENT] = self.MoveBehavior
self.behaviors[MODE.CORNERS] = self.CornerBehavior
self.behaviors[MODE.CIRCLE1] = self.CircleBehavior
self.behaviors[MODE.CIRCLE2] = self.CircleBehavior
self.behaviors[MODE.LIMBMOVE] = self.LimbMoveBehavior
self.behaviors[MODE.SMART_CIRCLE] = self.SmartCircleBehavior
self.behaviors[MODE.CHAR_OUTLINE] = self.CharacterOutlineBehavior
self.mode = MODE.SMART_CIRCLE
self.behaviorFunction = self.SmartCircleBehavior
self.savedHits = {} -- Objects currently being faded in/out
self.trackedLimbs = {} -- Used in limb-tracking casting modes
self.camera = game.Workspace.CurrentCamera
self.enabled = false
return self
end
function Invisicam:Enable(enable)
self.enabled = enable
if not enable then
self:Cleanup()
end
end
function Invisicam:GetOcclusionMode()
return Enum.DevCameraOcclusionMode.Invisicam
end
--[[ Module functions ]]--
function Invisicam:LimbBehavior(castPoints)
for limb, _ in pairs(self.trackedLimbs) do
castPoints[#castPoints + 1] = limb.Position
end
end
function Invisicam:MoveBehavior(castPoints)
for i = 1, MOVE_CASTS do
local position, velocity = self.humanoidRootPart.Position, self.humanoidRootPart.Velocity
local horizontalSpeed = Vector3.new(velocity.X, 0, velocity.Z).Magnitude / 2
local offsetVector = (i - 1) * self.humanoidRootPart.CFrame.lookVector * horizontalSpeed
castPoints[#castPoints + 1] = position + offsetVector
end
end
function Invisicam:CornerBehavior(castPoints)
local cframe = self.humanoidRootPart.CFrame
local centerPoint = cframe.p
local rotation = cframe - centerPoint
local halfSize = self.char:GetExtentsSize() / 2 --NOTE: Doesn't update w/ limb animations
castPoints[#castPoints + 1] = centerPoint
for i = 1, #CORNER_FACTORS do
castPoints[#castPoints + 1] = centerPoint + (rotation * (halfSize * CORNER_FACTORS[i]))
end
end
function Invisicam:CircleBehavior(castPoints)
local cframe = nil
if self.mode == MODE.CIRCLE1 then
cframe = self.humanoidRootPart.CFrame
else
local camCFrame = self.camera.CoordinateFrame
cframe = camCFrame - camCFrame.p + self.humanoidRootPart.Position
end
castPoints[#castPoints + 1] = cframe.p
for i = 0, CIRCLE_CASTS - 1 do
local angle = (2 * math.pi / CIRCLE_CASTS) * i
local offset = 3 * Vector3.new(math.cos(angle), math.sin(angle), 0)
castPoints[#castPoints + 1] = cframe * offset
end
end
function Invisicam:LimbMoveBehavior(castPoints)
self:LimbBehavior(castPoints)
self:MoveBehavior(castPoints)
end
function Invisicam:CharacterOutlineBehavior(castPoints)
local torsoUp = self.torsoPart.CFrame.upVector.unit
local torsoRight = self.torsoPart.CFrame.rightVector.unit
-- Torso cross of points for interior coverage
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p + torsoUp
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p - torsoUp
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p + torsoRight
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p - torsoRight
if self.headPart then
castPoints[#castPoints + 1] = self.headPart.CFrame.p
end
local cframe = CFrame.new(ZERO_VECTOR3,Vector3.new(self.camera.CoordinateFrame.lookVector.X,0,self.camera.CoordinateFrame.lookVector.Z))
local centerPoint = (self.torsoPart and self.torsoPart.Position or self.humanoidRootPart.Position)
local partsWhitelist = {self.torsoPart}
if self.headPart then
partsWhitelist[#partsWhitelist + 1] = self.headPart
end
for i = 1, CHAR_OUTLINE_CASTS do
local angle = (2 * math.pi * i / CHAR_OUTLINE_CASTS)
local offset = cframe * (3 * Vector3.new(math.cos(angle), math.sin(angle), 0))
offset = Vector3.new(offset.X, math.max(offset.Y, -2.25), offset.Z)
local ray = Ray.new(centerPoint + offset, -3 * offset)
local hit, hitPoint = game.Workspace:FindPartOnRayWithWhitelist(ray, partsWhitelist, false, false)
if hit then
-- Use hit point as the cast point, but nudge it slightly inside the character so that bumping up against
-- walls is less likely to cause a transparency glitch
castPoints[#castPoints + 1] = hitPoint + 0.2 * (centerPoint - hitPoint).unit
end
end
end
function Invisicam:SmartCircleBehavior(castPoints)
local torsoUp = self.torsoPart.CFrame.upVector.unit
local torsoRight = self.torsoPart.CFrame.rightVector.unit
-- SMART_CIRCLE mode includes rays to head and 5 to the torso.
-- Hands, arms, legs and feet are not included since they
-- are not canCollide and can therefore go inside of parts
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p + torsoUp
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p - torsoUp
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p + torsoRight
castPoints[#castPoints + 1] = self.torsoPart.CFrame.p - torsoRight
if self.headPart then
castPoints[#castPoints + 1] = self.headPart.CFrame.p
end
local cameraOrientation = self.camera.CFrame - self.camera.CFrame.p
local torsoPoint = Vector3.new(0,0.5,0) + (self.torsoPart and self.torsoPart.Position or self.humanoidRootPart.Position)
local radius = 2.5
-- This loop first calculates points in a circle of radius 2.5 around the torso of the character, in the
-- plane orthogonal to the camera's lookVector. Each point is then raycast to, to determine if it is within
-- the free space surrounding the player (not inside anything). Two iterations are done to adjust points that
-- are inside parts, to try to move them to valid locations that are still on their camera ray, so that the
-- circle remains circular from the camera's perspective, but does not cast rays into walls or parts that are
-- behind, below or beside the character and not really obstructing view of the character. This minimizes
-- the undesirable situation where the character walks up to an exterior wall and it is made invisible even
-- though it is behind the character.
for i = 1, SMART_CIRCLE_CASTS do
local angle = SMART_CIRCLE_INCREMENT * i - 0.5 * math.pi
local offset = radius * Vector3.new(math.cos(angle), math.sin(angle), 0)
local circlePoint = torsoPoint + cameraOrientation * offset
-- Vector from camera to point on the circle being tested
local vp = circlePoint - self.camera.CFrame.p
local ray = Ray.new(torsoPoint, circlePoint - torsoPoint)
local hit, hp, hitNormal = game.Workspace:FindPartOnRayWithIgnoreList(ray, {self.char}, false, false )
local castPoint = circlePoint
if hit then
local hprime = hp + 0.1 * hitNormal.unit -- Slightly offset hit point from the hit surface
local v0 = hprime - torsoPoint -- Vector from torso to offset hit point
local d0 = v0.magnitude
local perp = (v0:Cross(vp)).unit
-- Vector from the offset hit point, along the hit surface
local v1 = (perp:Cross(hitNormal)).unit
-- Vector from camera to offset hit
local vprime = (hprime - self.camera.CFrame.p).unit
-- This dot product checks to see if the vector along the hit surface would hit the correct
-- side of the invisicam cone, or if it would cross the camera look vector and hit the wrong side
if ( v0.unit:Dot(-v1) < v0.unit:Dot(vprime)) then
castPoint = RayIntersection(hprime, v1, circlePoint, vp)
if castPoint.Magnitude > 0 then
local ray = Ray.new(hprime, castPoint - hprime)
local hit, hitPoint, hitNormal = game.Workspace:FindPartOnRayWithIgnoreList(ray, {self.char}, false, false )
if hit then
local hprime2 = hitPoint + 0.1 * hitNormal.unit
castPoint = hprime2
end
else
castPoint = hprime
end
else
castPoint = hprime
end
local ray = Ray.new(torsoPoint, (castPoint - torsoPoint))
local hit, hitPoint, hitNormal = game.Workspace:FindPartOnRayWithIgnoreList(ray, {self.char}, false, false )
if hit then
local castPoint2 = hitPoint - 0.1 * (castPoint - torsoPoint).unit
castPoint = castPoint2
end
end
castPoints[#castPoints + 1] = castPoint
end
end
function Invisicam:CheckTorsoReference()
if self.char then
self.torsoPart = self.char:FindFirstChild("Torso")
if not self.torsoPart then
self.torsoPart = self.char:FindFirstChild("UpperTorso")
if not self.torsoPart then
self.torsoPart = self.char:FindFirstChild("HumanoidRootPart")
end
end
self.headPart = self.char:FindFirstChild("Head")
end
end
function Invisicam:CharacterAdded(char, player)
-- We only want the LocalPlayer's character
if player~=PlayersService.LocalPlayer then return end
if self.childAddedConn then
self.childAddedConn:Disconnect()
self.childAddedConn = nil
end
if self.childRemovedConn then
self.childRemovedConn:Disconnect()
self.childRemovedConn = nil
end
self.char = char
self.trackedLimbs = {}
local function childAdded(child)
if child:IsA("BasePart") then
if LIMB_TRACKING_SET[child.Name] then
self.trackedLimbs[child] = true
end
if (child.Name == "Torso" or child.Name == "UpperTorso") then
self.torsoPart = child
end
if (child.Name == "Head") then
self.headPart = child
end
end
end
local function childRemoved(child)
self.trackedLimbs[child] = nil
-- If removed/replaced part is 'Torso' or 'UpperTorso' double check that we still have a TorsoPart to use
self:CheckTorsoReference()
end
self.childAddedConn = char.ChildAdded:Connect(childAdded)
self.childRemovedConn = char.ChildRemoved:Connect(childRemoved)
for _, child in pairs(self.char:GetChildren()) do
childAdded(child)
end
end
function Invisicam:SetMode(newMode)
AssertTypes(newMode, 'number')
for modeName, modeNum in pairs(MODE) do
if modeNum == newMode then
self.mode = newMode
self.behaviorFunction = self.behaviors[self.mode]
return
end
end
error("Invalid mode number")
end
function Invisicam:GetObscuredParts()
return self.savedHits
end
-- Want to turn off Invisicam? Be sure to call this after.
function Invisicam:Cleanup()
for hit, originalFade in pairs(self.savedHits) do
hit.LocalTransparencyModifier = originalFade
end
end
function Invisicam:Update(dt, desiredCameraCFrame, desiredCameraFocus)
-- Bail if there is no Character
if not self.enabled or not self.char then
return desiredCameraCFrame, desiredCameraFocus
end
self.camera = game.Workspace.CurrentCamera
-- TODO: Move this to a GetHumanoidRootPart helper, probably combine with CheckTorsoReference
-- Make sure we still have a HumanoidRootPart
if not self.humanoidRootPart then
local humanoid = self.char:FindFirstChildOfClass("Humanoid")
if humanoid and humanoid.RootPart then
self.humanoidRootPart = humanoid.RootPart
else
-- Not set up with Humanoid? Try and see if there's one in the Character at all:
self.humanoidRootPart = self.char:FindFirstChild("HumanoidRootPart")
if not self.humanoidRootPart then
-- Bail out, since we're relying on HumanoidRootPart existing
return desiredCameraCFrame, desiredCameraFocus
end
end
-- TODO: Replace this with something more sensible
local ancestryChangedConn
ancestryChangedConn = self.humanoidRootPart.AncestryChanged:Connect(function(child, parent)
if child == self.humanoidRootPart and not parent then
self.humanoidRootPart = nil
if ancestryChangedConn and ancestryChangedConn.Connected then
ancestryChangedConn:Disconnect()
ancestryChangedConn = nil
end
end
end)
end
if not self.torsoPart then
self:CheckTorsoReference()
if not self.torsoPart then
-- Bail out, since we're relying on Torso existing, should never happen since we fall back to using HumanoidRootPart as torso
return desiredCameraCFrame, desiredCameraFocus
end
end
-- Make a list of world points to raycast to
local castPoints = {}
self.behaviorFunction(self, castPoints)
-- Cast to get a list of objects between the camera and the cast points
local currentHits = {}
local ignoreList = {self.char}
local function add(hit)
currentHits[hit] = true
if not self.savedHits[hit] then
self.savedHits[hit] = hit.LocalTransparencyModifier
end
end
local hitParts
local hitPartCount = 0
-- Hash table to treat head-ray-hit parts differently than the rest of the hit parts hit by other rays
-- head/torso ray hit parts will be more transparent than peripheral parts when USE_STACKING_TRANSPARENCY is enabled
local headTorsoRayHitParts = {}
local partIsTouchingCamera = {}
local perPartTransparencyHeadTorsoHits = TARGET_TRANSPARENCY
local perPartTransparencyOtherHits = TARGET_TRANSPARENCY
if USE_STACKING_TRANSPARENCY then
-- This first call uses head and torso rays to find out how many parts are stacked up
-- for the purpose of calculating required per-part transparency
local headPoint = self.headPart and self.headPart.CFrame.p or castPoints[1]
local torsoPoint = self.torsoPart and self.torsoPart.CFrame.p or castPoints[2]
hitParts = self.camera:GetPartsObscuringTarget({headPoint, torsoPoint}, ignoreList)
-- Count how many things the sample rays passed through, including decals. This should only
-- count decals facing the camera, but GetPartsObscuringTarget does not return surface normals,
-- so my compromise for now is to just let any decal increase the part count by 1. Only one
-- decal per part will be considered.
for i = 1, #hitParts do
local hitPart = hitParts[i]
hitPartCount = hitPartCount + 1 -- count the part itself
headTorsoRayHitParts[hitPart] = true
for _, child in pairs(hitPart:GetChildren()) do
if child:IsA('Decal') or child:IsA('Texture') then
hitPartCount = hitPartCount + 1 -- count first decal hit, then break
break
end
end
end
if (hitPartCount > 0) then
perPartTransparencyHeadTorsoHits = math.pow( ((0.5 * TARGET_TRANSPARENCY) + (0.5 * TARGET_TRANSPARENCY / hitPartCount)), 1 / hitPartCount )
perPartTransparencyOtherHits = math.pow( ((0.5 * TARGET_TRANSPARENCY_PERIPHERAL) + (0.5 * TARGET_TRANSPARENCY_PERIPHERAL / hitPartCount)), 1 / hitPartCount )
end
end
-- Now get all the parts hit by all the rays
hitParts = self.camera:GetPartsObscuringTarget(castPoints, ignoreList)
local partTargetTransparency = {}
-- Include decals and textures
for i = 1, #hitParts do
local hitPart = hitParts[i]
partTargetTransparency[hitPart] =headTorsoRayHitParts[hitPart] and perPartTransparencyHeadTorsoHits or perPartTransparencyOtherHits
-- If the part is not already as transparent or more transparent than what invisicam requires, add it to the list of
-- parts to be modified by invisicam
if hitPart.Transparency < partTargetTransparency[hitPart] then
add(hitPart)
end
-- Check all decals and textures on the part
for _, child in pairs(hitPart:GetChildren()) do
if child:IsA('Decal') or child:IsA('Texture') then
if (child.Transparency < partTargetTransparency[hitPart]) then
partTargetTransparency[child] = partTargetTransparency[hitPart]
add(child)
end
end
end
end
-- Invisibilize objects that are in the way, restore those that aren't anymore
for hitPart, originalLTM in pairs(self.savedHits) do
if currentHits[hitPart] then
-- LocalTransparencyModifier gets whatever value is required to print the part's total transparency to equal perPartTransparency
hitPart.LocalTransparencyModifier = (hitPart.Transparency < 1) and ((partTargetTransparency[hitPart] - hitPart.Transparency) / (1.0 - hitPart.Transparency)) or 0
else -- Restore original pre-invisicam value of LTM
hitPart.LocalTransparencyModifier = originalLTM
self.savedHits[hitPart] = nil
end
end
-- Invisicam does not change the camera values
return desiredCameraCFrame, desiredCameraFocus
end
return Invisicam
-
LegacyCamera
1 then
self.lastDistanceToSubject = nil
end
local subjectPosition = self:GetSubjectPosition()
if self.cameraType == Enum.CameraType.Fixed then
if self.lastUpdate then
-- Cap out the delta to 0.1 so we don't get some crazy things when we re-resume from
local delta = math.min(0.1, now - self.lastUpdate)
local gamepadRotation = self:UpdateGamepad()
self.rotateInput = self.rotateInput + (gamepadRotation * delta)
end
if subjectPosition and player and camera then
local distanceToSubject = self:GetCameraToSubjectDistance()
local newLookVector = self:CalculateNewLookVector()
self.rotateInput = ZERO_VECTOR2
newCameraFocus = camera.Focus -- Fixed camera does not change focus
newCameraCFrame = CFrame.new(camera.CFrame.p, camera.CFrame.p + (distanceToSubject * newLookVector))
end
elseif self.cameraType == Enum.CameraType.Attach then
if subjectPosition and camera then
local distanceToSubject = self:GetCameraToSubjectDistance()
local humanoid = self:GetHumanoid()
if self.lastUpdate and humanoid and humanoid.RootPart then
-- Cap out the delta to 0.1 so we don't get some crazy things when we re-resume from
local delta = math.min(0.1, now - self.lastUpdate)
local gamepadRotation = self:UpdateGamepad()
self.rotateInput = self.rotateInput + (gamepadRotation * delta)
local forwardVector = humanoid.RootPart.CFrame.lookVector
local y = Util.GetAngleBetweenXZVectors(forwardVector, self:GetCameraLookVector())
if Util.IsFinite(y) then
-- Preserve vertical rotation from user input
self.rotateInput = Vector2.new(y, self.rotateInput.Y)
end
end
local newLookVector = self:CalculateNewLookVector()
self.rotateInput = ZERO_VECTOR2
newCameraFocus = CFrame.new(subjectPosition)
newCameraCFrame = CFrame.new(subjectPosition - (distanceToSubject * newLookVector), subjectPosition)
end
elseif self.cameraType == Enum.CameraType.Watch then
if subjectPosition and player and camera then
local cameraLook = nil
local humanoid = self:GetHumanoid()
if humanoid and humanoid.RootPart then
local diffVector = subjectPosition - camera.CFrame.p
cameraLook = diffVector.unit
if self.lastDistanceToSubject and self.lastDistanceToSubject == self:GetCameraToSubjectDistance() then
-- Don't clobber the zoom if they zoomed the camera
local newDistanceToSubject = diffVector.magnitude
self:SetCameraToSubjectDistance(newDistanceToSubject)
end
end
local distanceToSubject = self:GetCameraToSubjectDistance()
local newLookVector = self:CalculateNewLookVector(cameraLook)
self.rotateInput = ZERO_VECTOR2
newCameraFocus = CFrame.new(subjectPosition)
newCameraCFrame = CFrame.new(subjectPosition - (distanceToSubject * newLookVector), subjectPosition)
self.lastDistanceToSubject = distanceToSubject
end
else
-- Unsupported type, return current values unchanged
return camera.CFrame, camera.Focus
end
self.lastUpdate = now
return newCameraCFrame, newCameraFocus
end
return LegacyCamera
]]>
-
MouseLockController
-
OrbitalCamera
THUMBSTICK_DEADZONE) then
self.gamepadDollySpeedMultiplier = 0.96
elseif (input.Position.Y < -THUMBSTICK_DEADZONE) then
self.gamepadDollySpeedMultiplier = 1.04
else
self.gamepadDollySpeedMultiplier = 1.00
end
else
if state == Enum.UserInputState.Cancel then
self.gamepadPanningCamera = ZERO_VECTOR2
return
end
local inputVector = Vector2.new(input.Position.X, -input.Position.Y)
if inputVector.magnitude > THUMBSTICK_DEADZONE then
self.gamepadPanningCamera = Vector2.new(input.Position.X, -input.Position.Y)
else
self.gamepadPanningCamera = ZERO_VECTOR2
end
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Sink
end
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Pass
end
end
function OrbitalCamera:DoGamepadZoom(name, state, input)
if input.UserInputType == self.activeGamepad and (input.KeyCode == Enum.KeyCode.ButtonR3 or input.KeyCode == Enum.KeyCode.ButtonL3) then
if (state == Enum.UserInputState.Begin) then
self.r3ButtonDown = input.KeyCode == Enum.KeyCode.ButtonR3
self.l3ButtonDown = input.KeyCode == Enum.KeyCode.ButtonL3
elseif (state == Enum.UserInputState.End) then
if (input.KeyCode == Enum.KeyCode.ButtonR3) then
self.r3ButtonDown = false
elseif (input.KeyCode == Enum.KeyCode.ButtonL3) then
self.l3ButtonDown = false
end
if (not self.r3ButtonDown) and (not self.l3ButtonDown) then
self.gamepadDollySpeedMultiplier = 1.00
end
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Sink
end
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Pass
end
end
function OrbitalCamera:BindGamepadInputActions()
if FFlagPlayerScriptsBindAtPriority then
self:BindAction("OrbitalCamGamepadPan", function(name, state, input) self:GetGamepadPan(name, state, input) end,
false, Enum.KeyCode.Thumbstick2)
self:BindAction("OrbitalCamGamepadZoom", function(name, state, input) self:DoGamepadZoom(name, state, input) end,
false, Enum.KeyCode.ButtonR3, Enum.KeyCode.ButtonL3)
else
local ContextActionService = game:GetService('ContextActionService')
ContextActionService:BindAction("OrbitalCamGamepadPan", function(name, state, input) self:GetGamepadPan(name, state, input) end, false, Enum.KeyCode.Thumbstick2)
ContextActionService:BindAction("OrbitalCamGamepadZoom", function(name, state, input) self:DoGamepadZoom(name, state, input) end, false, Enum.KeyCode.ButtonR3)
ContextActionService:BindAction("OrbitalCamGamepadZoomAlt", function(name, state, input) self:DoGamepadZoom(name, state, input) end, false, Enum.KeyCode.ButtonL3)
end
end
-- [[ Update ]]--
function OrbitalCamera:Update(dt)
local now = tick()
local timeDelta = (now - self.lastUpdate)
local userPanningTheCamera = (self.UserPanningTheCamera == true)
local camera = workspace.CurrentCamera
local newCameraCFrame = camera.CFrame
local newCameraFocus = camera.Focus
local player = PlayersService.LocalPlayer
local humanoid = self:GetHumanoid()
local cameraSubject = camera and camera.CameraSubject
local isInVehicle = cameraSubject and cameraSubject:IsA('VehicleSeat')
local isOnASkateboard = cameraSubject and cameraSubject:IsA('SkateboardPlatform')
if self.lastUpdate == nil or timeDelta > 1 then
self.lastCameraTransform = nil
end
if self.lastUpdate then
local gamepadRotation = self:UpdateGamepad()
if self:ShouldUseVRRotation() then
self.RotateInput = self.RotateInput + self:GetVRRotationInput()
else
-- Cap out the delta to 0.1 so we don't get some crazy things when we re-resume from
local delta = math.min(0.1, timeDelta)
if gamepadRotation ~= ZERO_VECTOR2 then
userPanningTheCamera = true
self.rotateInput = self.rotateInput + (gamepadRotation * delta)
end
local angle = 0
if not (isInVehicle or isOnASkateboard) then
angle = angle + (self.TurningLeft and -120 or 0)
angle = angle + (self.TurningRight and 120 or 0)
end
if angle ~= 0 then
self.rotateInput = self.rotateInput + Vector2.new(math.rad(angle * delta), 0)
userPanningTheCamera = true
end
end
end
-- Reset tween speed if user is panning
if userPanningTheCamera then
tweenSpeed = 0
self.lastUserPanCamera = tick()
end
local userRecentlyPannedCamera = now - self.lastUserPanCamera < TIME_BEFORE_AUTO_ROTATE
local subjectPosition = self:GetSubjectPosition()
if subjectPosition and player and camera then
-- Process any dollying being done by gamepad
-- TODO: Move this
if self.gamepadDollySpeedMultiplier ~= 1 then
self:SetCameraToSubjectDistance(self.currentSubjectDistance * self.gamepadDollySpeedMultiplier)
end
local VREnabled = VRService.VREnabled
newCameraFocus = VREnabled and self:GetVRFocus(subjectPosition, timeDelta) or CFrame.new(subjectPosition)
local cameraFocusP = newCameraFocus.p
if VREnabled and not self:IsInFirstPerson() then
local cameraHeight = self:GetCameraHeight()
local vecToSubject = (subjectPosition - camera.CFrame.p)
local distToSubject = vecToSubject.magnitude
-- Only move the camera if it exceeded a maximum distance to the subject in VR
if distToSubject > self.currentSubjectDistance or self.rotateInput.x ~= 0 then
local desiredDist = math.min(distToSubject, self.currentSubjectDistance)
-- Note that CalculateNewLookVector is overridden from BaseCamera
vecToSubject = self:CalculateNewLookVector(vecToSubject.unit * X1_Y0_Z1, Vector2.new(self.rotateInput.x, 0)) * desiredDist
local newPos = cameraFocusP - vecToSubject
local desiredLookDir = camera.CFrame.lookVector
if self.rotateInput.x ~= 0 then
desiredLookDir = vecToSubject
end
local lookAt = Vector3.new(newPos.x + desiredLookDir.x, newPos.y, newPos.z + desiredLookDir.z)
self.RotateInput = ZERO_VECTOR2
newCameraCFrame = CFrame.new(newPos, lookAt) + Vector3.new(0, cameraHeight, 0)
end
else
-- self.RotateInput is a Vector2 of mouse movement deltas since last update
self.curAzimuthRad = self.curAzimuthRad - self.rotateInput.x
if self.useAzimuthLimits then
self.curAzimuthRad = Util.Clamp(self.minAzimuthAbsoluteRad, self.maxAzimuthAbsoluteRad, self.curAzimuthRad)
else
self.curAzimuthRad = (self.curAzimuthRad ~= 0) and (math.sign(self.curAzimuthRad) * (math.abs(self.curAzimuthRad) % TAU)) or 0
end
self.curElevationRad = Util.Clamp(self.minElevationRad, self.maxElevationRad, self.curElevationRad + self.rotateInput.y)
local cameraPosVector = self.currentSubjectDistance * ( CFrame.fromEulerAnglesYXZ( -self.curElevationRad, self.curAzimuthRad, 0 ) * UNIT_Z )
local camPos = subjectPosition + cameraPosVector
newCameraCFrame = CFrame.new(camPos, subjectPosition)
self.rotateInput = ZERO_VECTOR2
end
self.lastCameraTransform = newCameraCFrame
self.lastCameraFocus = newCameraFocus
if (isInVehicle or isOnASkateboard) and cameraSubject:IsA('BasePart') then
self.lastSubjectCFrame = cameraSubject.CFrame
else
self.lastSubjectCFrame = nil
end
end
self.lastUpdate = now
return newCameraCFrame, newCameraFocus
end
return OrbitalCamera
]]>
-
Poppercam
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[
Poppercam - Occlusion module that brings the camera closer to the subject when objects are blocking the view.
--]]
local ZoomController = require(script.Parent:WaitForChild("ZoomController"))
local TransformExtrapolator = {} do
TransformExtrapolator.__index = TransformExtrapolator
local CF_IDENTITY = CFrame.new()
local function cframeToAxis(cframe)
local axis, angle = cframe:toAxisAngle()
return axis*angle
end
local function axisToCFrame(axis)
local angle = axis.magnitude
if angle > 1e-5 then
return CFrame.fromAxisAngle(axis, angle)
end
return CF_IDENTITY
end
local function extractRotation(cf)
local _, _, _, xx, yx, zx, xy, yy, zy, xz, yz, zz = cf:components()
return CFrame.new(0, 0, 0, xx, yx, zx, xy, yy, zy, xz, yz, zz)
end
function TransformExtrapolator.new()
return setmetatable({
lastCFrame = nil,
}, TransformExtrapolator)
end
function TransformExtrapolator:Step(dt, currentCFrame)
local lastCFrame = self.lastCFrame or currentCFrame
self.lastCFrame = currentCFrame
local currentPos = currentCFrame.p
local currentRot = extractRotation(currentCFrame)
local lastPos = lastCFrame.p
local lastRot = extractRotation(lastCFrame)
-- Estimate velocities from the delta between now and the last frame
-- This estimation can be a little noisy.
local dp = (currentPos - lastPos)/dt
local dr = cframeToAxis(currentRot*lastRot:inverse())/dt
local function extrapolate(t)
local p = dp*t + currentPos
local r = axisToCFrame(dr*t)*currentRot
return r + p
end
return {
extrapolate = extrapolate,
posVelocity = dp,
rotVelocity = dr,
}
end
function TransformExtrapolator:Reset()
self.lastCFrame = nil
end
end
--[[ The Module ]]--
local BaseOcclusion = require(script.Parent:WaitForChild("BaseOcclusion"))
local Poppercam = setmetatable({}, BaseOcclusion)
Poppercam.__index = Poppercam
function Poppercam.new()
local self = setmetatable(BaseOcclusion.new(), Poppercam)
self.focusExtrapolator = TransformExtrapolator.new()
return self
end
function Poppercam:GetOcclusionMode()
return Enum.DevCameraOcclusionMode.Zoom
end
function Poppercam:Enable(enable)
self.focusExtrapolator:Reset()
end
function Poppercam:Update(renderDt, desiredCameraCFrame, desiredCameraFocus, cameraController)
local rotatedFocus = CFrame.new(desiredCameraFocus.p, desiredCameraCFrame.p)*CFrame.new(
0, 0, 0,
-1, 0, 0,
0, 1, 0,
0, 0, -1
)
local extrapolation = self.focusExtrapolator:Step(renderDt, rotatedFocus)
local zoom = ZoomController.Update(renderDt, rotatedFocus, extrapolation)
return rotatedFocus*CFrame.new(0, 0, zoom), desiredCameraFocus
end
-- Called when character is added
function Poppercam:CharacterAdded(character, player)
end
-- Called when character is about to be removed
function Poppercam:CharacterRemoving(character, player)
end
function Poppercam:OnCameraSubjectChanged(newSubject)
end
return Poppercam
-
Poppercam_Classic
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[
Poppercam - Occlusion module that brings the camera closer to the subject when objects are blocking the view
Refactored for 2018 Camera Update but functionality is unchanged - AllYourBlox
--]]
--[[ Camera Maths Utilities Library ]]--
local Util = require(script.Parent:WaitForChild("CameraUtils"))
local PlayersService = game:GetService("Players")
local POP_RESTORE_RATE = 0.3
local MIN_CAMERA_ZOOM = 0.5
local VALID_SUBJECTS = {
'Humanoid',
'VehicleSeat',
'SkateboardPlatform',
}
local portraitPopperFixFlagExists, portraitPopperFixFlagEnabled = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserPortraitPopperFix")
end)
local FFlagUserPortraitPopperFix = portraitPopperFixFlagExists and portraitPopperFixFlagEnabled
--[[ The Module ]]--
local BaseOcclusion = require(script.Parent:WaitForChild("BaseOcclusion"))
local Poppercam = setmetatable({}, BaseOcclusion)
Poppercam.__index = Poppercam
function Poppercam.new()
local self = setmetatable(BaseOcclusion.new(), Poppercam)
self.camera = nil
self.cameraSubjectChangeConn = nil
self.subjectPart = nil
self.playerCharacters = {} -- For ignoring in raycasts
self.vehicleParts = {} -- Also just for ignoring
self.lastPopAmount = 0
self.lastZoomLevel = 0
self.popperEnabled = false
return self
end
function Poppercam:GetOcclusionMode()
return Enum.DevCameraOcclusionMode.Zoom
end
function Poppercam:Enable(enable)
end
-- Called when character is added
function Poppercam:CharacterAdded(char, player)
self.playerCharacters[player] = char
end
-- Called when character is about to be removed
function Poppercam:CharacterRemoving(char, player)
self.playerCharacters[player] = nil
end
function Poppercam:Update(dt, desiredCameraCFrame, desiredCameraFocus)
if self.popperEnabled then
self.camera = game.Workspace.CurrentCamera
local newCameraCFrame = desiredCameraCFrame
local focusPoint = desiredCameraFocus.p
if FFlagUserPortraitPopperFix and self.subjectPart then
focusPoint = self.subjectPart.CFrame.p
end
local ignoreList = {}
for _, character in pairs(self.playerCharacters) do
ignoreList[#ignoreList + 1] = character
end
for i = 1, #self.vehicleParts do
ignoreList[#ignoreList + 1] = self.vehicleParts[i]
end
-- Get largest cutoff distance
-- Note that the camera CFrame must be set here, because the current implementation of GetLargestCutoffDistance
-- uses the current camera CFrame directly (it cannot yet be passed the desiredCameraCFrame).
local prevCameraCFrame = self.camera.CFrame
self.camera.CFrame = desiredCameraCFrame
self.camera.Focus = desiredCameraFocus
local largest = self.camera:GetLargestCutoffDistance(ignoreList)
-- Then check if the player zoomed since the last frame,
-- and if so, reset our pop history so we stop tweening
local zoomLevel = (desiredCameraCFrame.p - focusPoint).Magnitude
if math.abs(zoomLevel - self.lastZoomLevel) > 0.001 then
self.lastPopAmount = 0
end
-- Finally, zoom the camera in (pop) by that most-cut-off amount, or the last pop amount if that's more
local popAmount = largest
if self.lastPopAmount > popAmount then
popAmount = self.lastPopAmount
end
if popAmount > 0 then
newCameraCFrame = desiredCameraCFrame + (desiredCameraCFrame.lookVector * popAmount)
self.lastPopAmount = popAmount - POP_RESTORE_RATE -- Shrink it for the next frame
if self.lastPopAmount < 0 then
self.lastPopAmount = 0
end
end
self.lastZoomLevel = zoomLevel
-- Stop shift lock being able to see through walls by manipulating Camera focus inside the wall
-- if EnabledCamera and EnabledCamera:GetShiftLock() and not EnabledCamera:IsInFirstPerson() then
-- if EnabledCamera:GetCameraActualZoom() < 1 then
-- local subjectPosition = EnabledCamera.lastSubjectPosition
-- if subjectPosition then
-- Camera.Focus = CFrame_new(subjectPosition)
-- Camera.CFrame = CFrame_new(subjectPosition - MIN_CAMERA_ZOOM*EnabledCamera:GetCameraLook(), subjectPosition)
-- end
-- end
-- end
return newCameraCFrame, desiredCameraFocus
end
-- Return unchanged values
return desiredCameraCFrame, desiredCameraFocus
end
function Poppercam:OnCameraSubjectChanged(newSubject)
self.vehicleParts = {}
self.lastPopAmount = 0
if newSubject then
-- Determine if we should be popping at all
self.popperEnabled = false
for _, subjectType in pairs(VALID_SUBJECTS) do
if newSubject:IsA(subjectType) then
self.popperEnabled = true
break
end
end
-- Get all parts of the vehicle the player is controlling
if newSubject:IsA('VehicleSeat') then
self.vehicleParts = newSubject:GetConnectedParts(true)
end
if FFlagUserPortraitPopperFix then
if newSubject:IsA("BasePart") then
self.subjectPart = newSubject
elseif newSubject:IsA("Model") then
if newSubject.PrimaryPart then
self.subjectPart = newSubject.PrimaryPart
else
-- Model has no PrimaryPart set, just use first BasePart
-- we can find as better-than-nothing solution (can still fail)
for _, child in pairs(newSubject:GetChildren()) do
if child:IsA("BasePart") then
self.subjectPart = child
break
end
end
end
elseif newSubject:IsA("Humanoid") then
self.subjectPart = newSubject.RootPart
end
end
end
end
return Poppercam
-
TransparencyController
-
ZoomController
maxValue then
x1 = maxValue
v1 = 0
end
self.x = x1
self.v = v1
return x1
end
end
local zoomSpring = ConstrainedSpring.new(ZOOM_STIFFNESS, ZOOM_DEFAULT, cameraMinZoomDistance, cameraMaxZoomDistance)
local function stepTargetZoom(z, dz, zoomMin, zoomMax)
z = clamp(z + dz*(1 + z*ZOOM_ACCELERATION), zoomMin, zoomMax)
if z < DIST_OPAQUE then
z = dz <= 0 and zoomMin or DIST_OPAQUE
end
return z
end
local zoomDelta = 0
local Zoom = {} do
function Zoom.Update(renderDt, focus, extrapolation)
local poppedZoom = math.huge
if zoomSpring.goal > DIST_OPAQUE then
-- Make a pessimistic estimate of zoom distance for this step without accounting for poppercam
local maxPossibleZoom = max(
zoomSpring.x,
stepTargetZoom(zoomSpring.goal, zoomDelta, cameraMinZoomDistance, cameraMaxZoomDistance)
)
-- Run the Popper algorithm on the feasible zoom range, [cameraMinZoomDistance, maxPossibleZoom]
poppedZoom = Popper(
focus*CFrame.new(0, 0, cameraMinZoomDistance),
maxPossibleZoom - cameraMinZoomDistance,
extrapolation
) + cameraMinZoomDistance
end
zoomSpring.minValue = cameraMinZoomDistance
zoomSpring.maxValue = min(cameraMaxZoomDistance, poppedZoom)
return zoomSpring:Step(renderDt)
end
function Zoom.SetZoomParameters(targetZoom, newZoomDelta)
zoomSpring.goal = targetZoom
zoomDelta = newZoomDelta
end
end
return Zoom
]]>
-
Popper
= dist then
return false
end
end
debug.profileend()
end
do
-- Test screen-space offsets from the focus for the presence of soft limits
debug.profilebegin('testOffsets')
for _, offset in ipairs(SCAN_SAMPLE_OFFSETS) do
local scaledOffset = offset
local pos, isHit = getCollisionPoint(fP, fX*scaledOffset.x + fY*scaledOffset.y)
if queryPoint(pos, (fP + fZ*dist - pos).Unit, dist) == inf then
return false
end
end
debug.profileend()
end
debug.profileend()
return true
end
local function Popper(focus, targetDist, focusExtrapolation)
debug.profilebegin('popper')
subjectRoot = subjectPart and subjectPart:GetRootPart() or subjectPart
local dist = targetDist
local soft, hard = queryViewport(focus, targetDist)
if hard < dist then
dist = hard
end
if soft < dist and testPromotion(focus, targetDist, focusExtrapolation) then
dist = soft
end
subjectRoot = nil
debug.profileend()
return dist
end
return Popper
]]>
-
ControlModule
-
BaseCharacterController
--[[
Copyright 2019, Roblox, Inc., all rights reserved.
This software, is proprietary to Roblox, Inc and it is licensed to you under the
terms of Roblox’s Limited Use License, a copy of which should have been
provided to you with this software (the "License"). You may not use the
software except in compliance with the License, unless you have executed a
separate written license with Roblox for use of the Software, in which case
your separate license will control.
This software is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, for limited uses as
described in greater detail in the License.
]]
--[[
BaseCharacterController - Abstract base class for character controllers, not intended to be
directly instantiated.
2018 PlayerScripts Update - AllYourBlox
--]]
local ZERO_VECTOR3 = Vector3.new(0,0,0)
--[[ Roblox Services ]]--
local Players = game:GetService("Players")
--[[ The Module ]]--
local BaseCharacterController = {}
BaseCharacterController.__index = BaseCharacterController
function BaseCharacterController.new()
local self = setmetatable({}, BaseCharacterController)
self.enabled = false
self.moveVector = ZERO_VECTOR3
self.isJumping = false
return self
end
function BaseCharacterController:GetMoveVector()
return self.moveVector
end
function BaseCharacterController:GetIsJumping()
return self.isJumping
end
-- Override in derived classes to set self.enabled and return boolean indicating
-- whether Enable/Disable was successful. Return true if controller is already in the requested state.
function BaseCharacterController:Enable(enable)
error("BaseCharacterController:Enable must be overridden in derived classes and should not be called.")
return false
end
return BaseCharacterController
-
ClickToMoveController
y then
return x
else
return y
end
end
end
Utility.ViewSizeX = ViewSizeX
local function ViewSizeY()
local camera = workspace.CurrentCamera
local x = camera and camera.ViewportSize.X or 0
local y = camera and camera.ViewportSize.Y or 0
if y == 0 then
return 768
else
if x > y then
return y
else
return x
end
end
end
Utility.ViewSizeY = ViewSizeY
local function FindCharacterAncestor(part)
if part then
local humanoid = part:FindFirstChild("Humanoid")
if humanoid then
return part, humanoid
else
return FindCharacterAncestor(part.Parent)
end
end
end
Utility.FindCharacterAncestor = FindCharacterAncestor
local function Raycast(ray, ignoreNonCollidable, ignoreList)
local ignoreList = ignoreList or {}
local hitPart, hitPos, hitNorm, hitMat = RayCastIgnoreList(workspace, ray, ignoreList)
if hitPart then
if ignoreNonCollidable and hitPart.CanCollide == false then
table.insert(ignoreList, hitPart)
return Raycast(ray, ignoreNonCollidable, ignoreList)
end
return hitPart, hitPos, hitNorm, hitMat
end
return nil, nil
end
Utility.Raycast = Raycast
local function AveragePoints(positions)
local avgPos = ZERO_VECTOR2
if #positions > 0 then
for i = 1, #positions do
avgPos = avgPos + positions[i]
end
avgPos = avgPos / #positions
end
return avgPos
end
Utility.AveragePoints = AveragePoints
end
local humanoidCache = {}
local function findPlayerHumanoid(player)
local character = player and player.Character
if character then
local resultHumanoid = humanoidCache[player]
if resultHumanoid and resultHumanoid.Parent == character then
return resultHumanoid
else
humanoidCache[player] = nil -- Bust Old Cache
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoidCache[player] = humanoid
end
return humanoid
end
end
end
--------------------------CHARACTER CONTROL-------------------------------
local CurrentIgnoreList
local function GetCharacter()
return Player and Player.Character
end
local function GetTorso()
local humanoid = findPlayerHumanoid(Player)
return humanoid and humanoid.RootPart
end
local function getIgnoreList()
if CurrentIgnoreList then
return CurrentIgnoreList
end
CurrentIgnoreList = {}
table.insert(CurrentIgnoreList, GetCharacter())
return CurrentIgnoreList
end
-----------------------------------PATHER--------------------------------------
local popupAdornee
local function getPopupAdorneePart()
--Handle the case of the adornee part getting deleted (camera changed, maybe)
if popupAdornee and not popupAdornee.Parent then
popupAdornee = nil
end
--If the adornee doesn't exist yet, create it
if not popupAdornee then
popupAdornee = Instance.new("Part")
popupAdornee.Name = "ClickToMovePopupAdornee"
popupAdornee.Transparency = 1
popupAdornee.CanCollide = false
popupAdornee.Anchored = true
popupAdornee.Size = Vector3.new(2, 2, 2)
popupAdornee.CFrame = CFrame.new()
popupAdornee.Parent = workspace.CurrentCamera
end
return popupAdornee
end
local activePopups = {}
local function createNewPopup(popupType)
local newModel = Instance.new("ImageHandleAdornment")
newModel.AlwaysOnTop = false
newModel.Transparency = 1
newModel.Size = ZERO_VECTOR2
newModel.SizeRelativeOffset = ZERO_VECTOR3
newModel.Image = "rbxasset://textures/ui/move.png"
newModel.ZIndex = 20
local radius = 0
if popupType == "DestinationPopup" then
newModel.Color3 = Color3.fromRGB(0, 175, 255)
radius = 1.25
elseif popupType == "DirectWalkPopup" then
newModel.Color3 = Color3.fromRGB(0, 175, 255)
radius = 1.25
elseif popupType == "FailurePopup" then
newModel.Color3 = Color3.fromRGB(255, 100, 100)
radius = 1.25
elseif popupType == "PatherPopup" then
newModel.Color3 = Color3.fromRGB(255, 255, 255)
radius = 1
newModel.ZIndex = 10
end
newModel.Size = Vector2.new(5, 0.1) * radius
local dataStructure = {}
dataStructure.Model = newModel
activePopups[#activePopups + 1] = newModel
function dataStructure:TweenIn()
local tweenInfo = TweenInfo.new(1.5, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out)
local tween1 = TweenService:Create(newModel, tweenInfo, { Size = Vector2.new(2,2) * radius })
tween1:Play()
TweenService:Create(newModel, TweenInfo.new(0.25, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, false, 0.1), { Transparency = 0, SizeRelativeOffset = Vector3.new(0, radius * 1.5, 0) }):Play()
return tween1
end
function dataStructure:TweenOut()
local tweenInfo = TweenInfo.new(0.25, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
local tween1 = TweenService:Create(newModel, tweenInfo, { Size = ZERO_VECTOR2 })
tween1:Play()
coroutine.wrap(function()
tween1.Completed:Wait()
for i = 1, #activePopups do
if activePopups[i] == newModel then
table.remove(activePopups, i)
break
end
end
end)()
return tween1
end
function dataStructure:Place(position, dest)
-- place the model at position
if not self.Model.Parent then
local popupAdorneePart = getPopupAdorneePart()
self.Model.Parent = popupAdorneePart
self.Model.Adornee = popupAdorneePart
--Start the 10-stud long ray 2.5 studs above where the tap happened and point straight down to try to find
--the actual ground position.
local ray = Ray.new(position + Vector3.new(0, 2.5, 0), Vector3.new(0, -10, 0))
local hitPart, hitPoint, hitNormal = workspace:FindPartOnRayWithIgnoreList(ray, { workspace.CurrentCamera, Player.Character })
self.Model.CFrame = CFrame.new(hitPoint) + Vector3.new(0, -radius,0)
end
end
return dataStructure
end
local function createPopupPath(points, numCircles)
-- creates a path with the provided points, using the path and number of circles provided
local popups = {}
local stopTraversing = false
local function killPopup(i)
-- kill all popups before and at i
for iter, v in pairs(popups) do
if iter <= i then
local tween = v:TweenOut()
spawn(function()
tween.Completed:Wait()
v.Model:Destroy()
end)
popups[iter] = nil
end
end
end
local function stopFunction()
stopTraversing = true
killPopup(#points)
end
spawn(function()
for i = 1, #points do
if stopTraversing then
break
end
local includeWaypoint = i % numCircles == 0
and i < #points
and (points[#points].Position - points[i].Position).magnitude > 4
if includeWaypoint then
local popup = createNewPopup("PatherPopup")
popups[i] = popup
local nextPopup = points[i+1]
popup:Place(points[i].Position, nextPopup and nextPopup.Position or points[#points].Position)
local tween = popup:TweenIn()
wait(0.2)
end
end
end)
return stopFunction, killPopup
end
local function Pather(character, endPoint, surfaceNormal)
local this = {}
this.Cancelled = false
this.Started = false
this.Finished = Instance.new("BindableEvent")
this.PathFailed = Instance.new("BindableEvent")
this.PathComputing = false
this.PathComputed = false
this.TargetPoint = endPoint
this.TargetSurfaceNormal = surfaceNormal
this.DiedConn = nil
this.SeatedConn = nil
this.MoveToConn = nil
this.BlockedConn = nil
this.CurrentPoint = 0
function this:Cleanup()
if this.stopTraverseFunc then
this.stopTraverseFunc()
this.stopTraverseFunc = nil
end
if this.MoveToConn then
this.MoveToConn:Disconnect()
this.MoveToConn = nil
end
if this.BlockedConn then
this.BlockedConn:Disconnect()
this.BlockedConn = nil
end
if this.DiedConn then
this.DiedConn:Disconnect()
this.DiedConn = nil
end
if this.SeatedConn then
this.SeatedConn:Disconnect()
this.SeatedConn = nil
end
this.humanoid = nil
end
function this:Cancel()
this.Cancelled = true
this:Cleanup()
end
function this:OnPathInterrupted()
-- Stop moving
this.Cancelled = true
this:OnPointReached(false)
end
function this:ComputePath()
local humanoid = findPlayerHumanoid(Player)
local torso = humanoid and humanoid.Torso
local success = false
if torso then
if this.PathComputed or this.PathComputing then return end
this.PathComputing = true
success = pcall(function()
this.pathResult = PathfindingService:FindPathAsync(torso.CFrame.p, this.TargetPoint)
end)
this.pointList = this.pathResult and this.pathResult:GetWaypoints()
if this.pathResult and FFlagUserNavigationClickToMoveUsePathBlocked then
this.BlockedConn = this.pathResult.Blocked:Connect(function(blockedIdx) this:OnPathBlocked(blockedIdx) end)
end
this.PathComputing = false
this.PathComputed = this.pathResult and this.pathResult.Status == Enum.PathStatus.Success or false
end
return true
end
function this:IsValidPath()
if not this.pathResult then
this:ComputePath()
end
return this.pathResult.Status == Enum.PathStatus.Success
end
this.Recomputing = false
function this:OnPathBlocked(blockedWaypointIdx)
local pathBlocked = blockedWaypointIdx >= this.CurrentPoint
if not pathBlocked or this.Recomputing then
return
end
this.Recomputing = true
if this.stopTraverseFunc then
this.stopTraverseFunc()
this.stopTraverseFunc = nil
end
this.pathResult:ComputeAsync(this.humanoid.Torso.CFrame.p, this.TargetPoint)
this.pointList = this.pathResult:GetWaypoints()
this.PathComputed = this.pathResult and this.pathResult.Status == Enum.PathStatus.Success or false
if SHOW_PATH then
this.stopTraverseFunc, this.setPointFunc = createPopupPath(this.pointList, 4, true)
end
if this.PathComputed then
this.humanoid = findPlayerHumanoid(Player)
this.CurrentPoint = 1 -- The first waypoint is always the start location. Skip it.
this:OnPointReached(true) -- Move to first point
else
this.PathFailed:Fire()
this:Cleanup()
end
this.Recomputing = false
end
function this:OnPointReached(reached)
if reached and not this.Cancelled then
local nextWaypointIdx = this.CurrentPoint + 1
if nextWaypointIdx > #this.pointList then
-- End of path reached
if this.stopTraverseFunc then
this.stopTraverseFunc()
end
this.Finished:Fire()
this:Cleanup()
else
local currentWaypoint = this.pointList[this.CurrentPoint]
local nextWaypoint = this.pointList[nextWaypointIdx]
-- If airborne, only allow to keep moving
-- if nextWaypoint.Action ~= Jump, or path mantains a direction
-- Otherwise, wait until the humanoid gets to the ground
local currentState = this.humanoid:GetState()
local isInAir = currentState == Enum.HumanoidStateType.FallingDown
or currentState == Enum.HumanoidStateType.Freefall
or currentState == Enum.HumanoidStateType.Jumping
if isInAir then
local shouldWaitForGround = nextWaypoint.Action == Enum.PathWaypointAction.Jump
if not shouldWaitForGround and this.CurrentPoint > 1 then
local prevWaypoint = this.pointList[this.CurrentPoint - 1]
local prevDir = currentWaypoint.Position - prevWaypoint.Position
local currDir = nextWaypoint.Position - currentWaypoint.Position
local prevDirXZ = Vector2.new(prevDir.x, prevDir.z).Unit
local currDirXZ = Vector2.new(currDir.x, currDir.z).Unit
local THRESHOLD_COS = 0.996 -- ~cos(5 degrees)
shouldWaitForGround = prevDirXZ:Dot(currDirXZ) < THRESHOLD_COS
end
if shouldWaitForGround then
this.humanoid.FreeFalling:Wait()
-- Give time to the humanoid's state to change
-- Otherwise, the jump flag in Humanoid
-- will be reset by the state change
wait(0.1)
end
end
-- Move to the next point
if this.setPointFunc then
this.setPointFunc(nextWaypointIdx)
end
if nextWaypoint.Action == Enum.PathWaypointAction.Jump then
this.humanoid.Jump = true
end
this.humanoid:MoveTo(nextWaypoint.Position)
this.CurrentPoint = nextWaypointIdx
end
else
this.PathFailed:Fire()
this:Cleanup()
end
end
function this:Start()
if CurrentSeatPart then
return
end
this.humanoid = findPlayerHumanoid(Player)
if not this.humanoid then
this.PathFailed:Fire()
return
end
if this.Started then return end
this.Started = true
if SHOW_PATH then
-- choose whichever one Mike likes best
this.stopTraverseFunc, this.setPointFunc = createPopupPath(this.pointList, 4)
end
if #this.pointList > 0 then
this.SeatedConn = this.humanoid.Seated:Connect(function(reached) this:OnPathInterrupted() end)
this.DiedConn = this.humanoid.Died:Connect(function(reached) this:OnPathInterrupted() end)
this.MoveToConn = this.humanoid.MoveToFinished:Connect(function(reached) this:OnPointReached(reached) end)
this.CurrentPoint = 1 -- The first waypoint is always the start location. Skip it.
this:OnPointReached(true) -- Move to first point
else
this.PathFailed:Fire()
if this.stopTraverseFunc then
this.stopTraverseFunc()
end
end
end
this:ComputePath()
if not this.PathComputed then
-- set the end point towards the camera and raycasted towards the ground in case we hit a wall
local offsetPoint = this.TargetPoint + this.TargetSurfaceNormal*1.5
local ray = Ray.new(offsetPoint, Vector3.new(0,-1,0)*50)
local newHitPart, newHitPos = RayCastIgnoreList(workspace, ray, getIgnoreList())
if newHitPart then
this.TargetPoint = newHitPos
end
-- try again
this:ComputePath()
end
return this
end
-------------------------------------------------------------------------
local function IsInBottomLeft(pt)
local joystickHeight = math.min(Utility.ViewSizeY() * 0.33, 250)
local joystickWidth = joystickHeight
return pt.X <= joystickWidth and pt.Y > Utility.ViewSizeY() - joystickHeight
end
local function IsInBottomRight(pt)
local joystickHeight = math.min(Utility.ViewSizeY() * 0.33, 250)
local joystickWidth = joystickHeight
return pt.X >= Utility.ViewSizeX() - joystickWidth and pt.Y > Utility.ViewSizeY() - joystickHeight
end
local function CheckAlive(character)
local humanoid = findPlayerHumanoid(Player)
return humanoid ~= nil and humanoid.Health > 0
end
local function GetEquippedTool(character)
if character ~= nil then
for _, child in pairs(character:GetChildren()) do
if child:IsA('Tool') then
return child
end
end
end
end
local ExistingPather = nil
local ExistingIndicator = nil
local PathCompleteListener = nil
local PathFailedListener = nil
local function CleanupPath()
DrivingTo = nil
if ExistingPather then
ExistingPather:Cancel()
end
if PathCompleteListener then
PathCompleteListener:Disconnect()
PathCompleteListener = nil
end
if PathFailedListener then
PathFailedListener:Disconnect()
PathFailedListener = nil
end
if ExistingIndicator then
local obj = ExistingIndicator
local tween = obj:TweenOut()
local tweenCompleteEvent = nil
tweenCompleteEvent = tween.Completed:connect(function()
tweenCompleteEvent:Disconnect()
obj.Model:Destroy()
end)
ExistingIndicator = nil
end
end
local function getExtentsSize(Parts)
local maxX,maxY,maxZ = -math.huge,-math.huge,-math.huge
local minX,minY,minZ = math.huge,math.huge,math.huge
for i = 1, #Parts do
maxX,maxY,maxZ = math.max(maxX, Parts[i].Position.X), math.max(maxY, Parts[i].Position.Y), math.max(maxZ, Parts[i].Position.Z)
minX,minY,minZ = math.min(minX, Parts[i].Position.X), math.min(minY, Parts[i].Position.Y), math.min(minZ, Parts[i].Position.Z)
end
return Region3.new(Vector3.new(minX, minY, minZ), Vector3.new(maxX, maxY, maxZ))
end
local function inExtents(Extents, Position)
if Position.X < (Extents.CFrame.p.X - Extents.Size.X/2) or Position.X > (Extents.CFrame.p.X + Extents.Size.X/2) then
return false
end
if Position.Z < (Extents.CFrame.p.Z - Extents.Size.Z/2) or Position.Z > (Extents.CFrame.p.Z + Extents.Size.Z/2) then
return false
end
--ignoring Y for now
return true
end
local function showQuickPopupAsync(position, popupType)
local popup = createNewPopup(popupType)
popup:Place(position, Vector3.new(0,position.y,0))
local tweenIn = popup:TweenIn()
tweenIn.Completed:Wait()
local tweenOut = popup:TweenOut()
tweenOut.Completed:Wait()
popup.Model:Destroy()
popup = nil
end
local FailCount = 0
local function OnTap(tapPositions, goToPoint)
-- Good to remember if this is the latest tap event
local camera = workspace.CurrentCamera
local character = Player.Character
if not CheckAlive(character) then return end
-- This is a path tap position
if #tapPositions == 1 or goToPoint then
if camera then
local unitRay = camera:ScreenPointToRay(tapPositions[1].x, tapPositions[1].y)
local ray = Ray.new(unitRay.Origin, unitRay.Direction*1000)
-- inivisicam stuff
local initIgnore = getIgnoreList()
local invisicamParts = {} --InvisicamModule and InvisicamModule:GetObscuredParts() or {}
local ignoreTab = {}
-- add to the ignore list
for i, v in pairs(invisicamParts) do
ignoreTab[#ignoreTab+1] = i
end
for i = 1, #initIgnore do
ignoreTab[#ignoreTab+1] = initIgnore[i]
end
--
local myHumanoid = findPlayerHumanoid(Player)
local hitPart, hitPt, hitNormal, hitMat = Utility.Raycast(ray, true, ignoreTab)
local hitChar, hitHumanoid = Utility.FindCharacterAncestor(hitPart)
local torso = GetTorso()
local startPos = torso.CFrame.p
if goToPoint then
hitPt = goToPoint
hitChar = nil
end
if hitChar and hitHumanoid and hitHumanoid.RootPart and (hitHumanoid.Torso.CFrame.p - torso.CFrame.p).magnitude < 7 then
CleanupPath()
if myHumanoid then
myHumanoid:MoveTo(hitPt)
end
-- Do shoot
local currentWeapon = GetEquippedTool(character)
if currentWeapon then
currentWeapon:Activate()
LastFired = tick()
end
elseif hitPt and character and not CurrentSeatPart then
local thisPather = Pather(character, hitPt, hitNormal)
if thisPather:IsValidPath() then
FailCount = 0
thisPather:Start()
if BindableEvent_OnFailStateChanged then
BindableEvent_OnFailStateChanged:Fire(false)
end
CleanupPath()
local destinationPopup = createNewPopup("DestinationPopup")
destinationPopup:Place(hitPt, Vector3.new(0,hitPt.y,0))
local failurePopup = createNewPopup("FailurePopup")
local currentTween = destinationPopup:TweenIn()
ExistingPather = thisPather
ExistingIndicator = destinationPopup
PathCompleteListener = thisPather.Finished.Event:Connect(function()
if destinationPopup then
if ExistingIndicator == destinationPopup then
ExistingIndicator = nil
end
local tween = destinationPopup:TweenOut()
local tweenCompleteEvent = nil
tweenCompleteEvent = tween.Completed:Connect(function()
tweenCompleteEvent:Disconnect()
destinationPopup.Model:Destroy()
destinationPopup = nil
end)
end
if hitChar then
local humanoid = findPlayerHumanoid(Player)
local currentWeapon = GetEquippedTool(character)
if currentWeapon then
currentWeapon:Activate()
LastFired = tick()
end
if humanoid then
humanoid:MoveTo(hitPt)
end
end
end)
PathFailedListener = thisPather.PathFailed.Event:Connect(function()
CleanupPath()
if failurePopup then
failurePopup:Place(hitPt, Vector3.new(0,hitPt.y,0))
local failTweenIn = failurePopup:TweenIn()
failTweenIn.Completed:Wait()
local failTweenOut = failurePopup:TweenOut()
failTweenOut.Completed:Wait()
failurePopup.Model:Destroy()
failurePopup = nil
end
end)
else
if hitPt then
-- Feedback here for when we don't have a good path
local foundDirectPath = false
if (hitPt-startPos).Magnitude < 25 and (startPos.y-hitPt.y > -3) then
-- move directly here
if myHumanoid then
if myHumanoid.Sit then
myHumanoid.Jump = true
end
myHumanoid:MoveTo(hitPt)
foundDirectPath = true
end
end
coroutine.wrap(showQuickPopupAsync)(hitPt, foundDirectPath and "DirectWalkPopup" or "FailurePopup")
end
end
elseif hitPt and character and CurrentSeatPart then
local destinationPopup = createNewPopup("DestinationPopup")
ExistingIndicator = destinationPopup
destinationPopup:Place(hitPt, Vector3.new(0,hitPt.y,0))
destinationPopup:TweenIn()
DrivingTo = hitPt
local ConnectedParts = CurrentSeatPart:GetConnectedParts(true)
while wait() do
if CurrentSeatPart and ExistingIndicator == destinationPopup then
local ExtentsSize = getExtentsSize(ConnectedParts)
if inExtents(ExtentsSize, hitPt) then
local popup = destinationPopup
spawn(function()
local tweenOut = popup:TweenOut()
tweenOut.Completed:Wait()
popup.Model:Destroy()
end)
destinationPopup = nil
DrivingTo = nil
break
end
else
if CurrentSeatPart == nil and destinationPopup == ExistingIndicator then
DrivingTo = nil
OnTap(tapPositions, hitPt)
end
local popup = destinationPopup
spawn(function()
local tweenOut = popup:TweenOut()
tweenOut.Completed:Wait()
popup.Model:Destroy()
end)
destinationPopup = nil
break
end
end
end
end
elseif #tapPositions >= 2 then
if camera then
-- Do shoot
local avgPoint = Utility.AveragePoints(tapPositions)
local unitRay = camera:ScreenPointToRay(avgPoint.x, avgPoint.y)
local currentWeapon = GetEquippedTool(character)
if currentWeapon then
currentWeapon:Activate()
LastFired = tick()
end
end
end
end
local function IsFinite(num)
return num == num and num ~= 1/0 and num ~= -1/0
end
local function findAngleBetweenXZVectors(vec2, vec1)
return math.atan2(vec1.X*vec2.Z-vec1.Z*vec2.X, vec1.X*vec2.X + vec1.Z*vec2.Z)
end
local function DisconnectEvent(event)
if event then
event:Disconnect()
end
end
--[[ The ClickToMove Controller Class ]]--
local KeyboardController = require(script.Parent:WaitForChild("Keyboard"))
local ClickToMove = setmetatable({}, KeyboardController)
ClickToMove.__index = ClickToMove
function ClickToMove.new(CONTROL_ACTION_PRIORITY)
local self = setmetatable(KeyboardController.new(CONTROL_ACTION_PRIORITY), ClickToMove)
print("Instantiating ClickToMove Controller")
self.fingerTouches = {}
self.numUnsunkTouches = 0
-- PC simulation
self.mouse1Down = tick()
self.mouse1DownPos = Vector2.new()
self.mouse2DownTime = tick()
self.mouse2DownPos = Vector2.new()
self.mouse2UpTime = tick()
self.tapConn = nil
self.inputBeganConn = nil
self.inputChangedConn = nil
self.inputEndedConn = nil
self.humanoidDiedConn = nil
self.characterChildAddedConn = nil
self.onCharacterAddedConn = nil
self.characterChildRemovedConn = nil
self.renderSteppedConn = nil
self.humanoidSeatedConn = nil
self.running = false
self.wasdEnabled = false
return self
end
function ClickToMove:DisconnectEvents()
DisconnectEvent(self.tapConn)
DisconnectEvent(self.inputBeganConn)
DisconnectEvent(self.inputChangedConn)
DisconnectEvent(self.inputEndedConn)
DisconnectEvent(self.humanoidDiedConn)
DisconnectEvent(self.characterChildAddedConn)
DisconnectEvent(self.onCharacterAddedConn)
DisconnectEvent(self.renderSteppedConn)
DisconnectEvent(self.characterChildRemovedConn)
-- TODO: Resolve with ControlScript handling of seating for vehicles
DisconnectEvent(self.humanoidSeatedConn)
pcall(function() RunService:UnbindFromRenderStep("ClickToMoveRenderUpdate") end)
end
function ClickToMove:OnTouchBegan(input, processed)
if self.fingerTouches[input] == nil and not processed then
self.numUnsunkTouches = self.numUnsunkTouches + 1
end
self.fingerTouches[input] = processed
end
function ClickToMove:OnTouchChanged(input, processed)
if self.fingerTouches[input] == nil then
self.fingerTouches[input] = processed
if not processed then
self.numUnsunkTouches = self.numUnsunkTouches + 1
end
end
end
function ClickToMove:OnTouchEnded(input, processed)
if self.fingerTouches[input] ~= nil and self.fingerTouches[input] == false then
self.numUnsunkTouches = self.numUnsunkTouches - 1
end
self.fingerTouches[input] = nil
end
function ClickToMove:OnCharacterAdded(character)
self:DisconnectEvents()
self.inputBeganConn = UserInputService.InputBegan:Connect(function(input, processed)
if input.UserInputType == Enum.UserInputType.Touch then
self:OnTouchBegan(input, processed)
-- Give back controls when they tap both sticks
local wasInBottomLeft = IsInBottomLeft(input.Position)
local wasInBottomRight = IsInBottomRight(input.Position)
if wasInBottomRight or wasInBottomLeft then
for otherInput, _ in pairs(self.fingerTouches) do
if otherInput ~= input then
local otherInputInLeft = IsInBottomLeft(otherInput.Position)
local otherInputInRight = IsInBottomRight(otherInput.Position)
if otherInput.UserInputState ~= Enum.UserInputState.End and ((wasInBottomLeft and otherInputInRight) or (wasInBottomRight and otherInputInLeft)) then
if BindableEvent_OnFailStateChanged then
BindableEvent_OnFailStateChanged:Fire(true)
end
return
end
end
end
end
end
-- Cancel path when you use the keyboard controls.
if processed == false and input.UserInputType == Enum.UserInputType.Keyboard and movementKeys[input.KeyCode] then
CleanupPath()
end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
self.mouse1DownTime = tick()
self.mouse1DownPos = input.Position
end
if input.UserInputType == Enum.UserInputType.MouseButton2 then
self.mouse2DownTime = tick()
self.mouse2DownPos = input.Position
end
end)
self.inputChangedConn = UserInputService.InputChanged:Connect(function(input, processed)
if input.UserInputType == Enum.UserInputType.Touch then
self:OnTouchChanged(input, processed)
end
end)
self.inputEndedConn = UserInputService.InputEnded:Connect(function(input, processed)
if input.UserInputType == Enum.UserInputType.Touch then
self:OnTouchEnded(input, processed)
end
if input.UserInputType == Enum.UserInputType.MouseButton2 then
self.mouse2UpTime = tick()
local currPos = input.Position
if self.mouse2UpTime - self.mouse2DownTime < 0.25 and (currPos - self.mouse2DownPos).magnitude < 5 and self.moveVector.Magnitude<=0 then
local positions = {currPos}
OnTap(positions)
end
end
end)
self.tapConn = UserInputService.TouchTap:Connect(function(touchPositions, processed)
if not processed then
OnTap(touchPositions)
end
end)
local function computeThrottle(dist)
if dist > .2 then
return 0.5+(dist^2)/2
else
return 0
end
end
local lastSteer = 0
--kP = how much the steering corrects for the current error in driving angle
--kD = how much the steering corrects for how quickly the error in driving angle is changing
local kP = 1
local kD = 0.5
local function getThrottleAndSteer(object, point)
local throttle, steer = 0, 0
local oCF = object.CFrame
local relativePosition = oCF:pointToObjectSpace(point)
local relativeZDirection = -relativePosition.z
local relativeDistance = relativePosition.magnitude
-- throttle quadratically increases from 0-1 as distance from the selected point goes from 0-50, after 50, throttle is 1.
-- this allows shorter distance travel to have more fine-tuned control.
throttle = computeThrottle(math.min(1,relativeDistance/50))*math.sign(relativeZDirection)
local steerAngle = -math.atan2(-relativePosition.x, -relativePosition.z)
steer = steerAngle/(math.pi/4)
local steerDelta = steer - lastSteer
lastSteer = steer
local pdSteer = kP * steer + kD * steer
return throttle, pdSteer
end
local function Update()
if CurrentSeatPart then
if DrivingTo then
local throttle, steer = getThrottleAndSteer(CurrentSeatPart, DrivingTo)
CurrentSeatPart.ThrottleFloat = throttle
CurrentSeatPart.SteerFloat = steer
else
CurrentSeatPart.ThrottleFloat = 0
CurrentSeatPart.SteerFloat = 0
end
end
local cameraPos = workspace.CurrentCamera.CFrame.p
for i = 1, #activePopups do
local popup = activePopups[i]
popup.CFrame = CFrame.new(popup.CFrame.p, cameraPos)
end
end
RunService:BindToRenderStep("ClickToMoveRenderUpdate",Enum.RenderPriority.Camera.Value - 1,Update)
local function OnCharacterChildAdded(child)
if UserInputService.TouchEnabled then
if child:IsA('Tool') then
child.ManualActivationOnly = true
end
end
if child:IsA('Humanoid') then
DisconnectEvent(self.humanoidDiedConn)
self.humanoidDiedConn = child.Died:Connect(function()
if ExistingIndicator then
DebrisService:AddItem(ExistingIndicator.Model, 1)
end
end)
end
end
self.characterChildAddedConn = character.ChildAdded:Connect(function(child)
OnCharacterChildAdded(child)
end)
self.characterChildRemovedConn = character.ChildRemoved:Connect(function(child)
if UserInputService.TouchEnabled then
if child:IsA('Tool') then
child.ManualActivationOnly = false
end
end
end)
for _, child in pairs(character:GetChildren()) do
OnCharacterChildAdded(child)
end
end
function ClickToMove:Start()
self:Enable(true)
end
function ClickToMove:Stop()
self:Enable(false)
end
function ClickToMove:Enable(enable, enableWASD)
if enable then
if not self.running then
if Player.Character then -- retro-listen
self:OnCharacterAdded(Player.Character)
end
self.onCharacterAddedConn = Player.CharacterAdded:Connect(function(char)
self:OnCharacterAdded(char)
end)
self.running = true
end
else
if self.running then
self:DisconnectEvents()
CleanupPath()
-- Restore tool activation on shutdown
if UserInputService.TouchEnabled then
local character = Player.Character
if character then
for _, child in pairs(character:GetChildren()) do
if child:IsA('Tool') then
child.ManualActivationOnly = false
end
end
end
end
DrivingTo = nil
self.running = false
end
end
-- Extension for initializing Keyboard input as this class now derives from Keyboard
if UserInputService.KeyboardEnabled and enable ~= self.enabled then
self.forwardValue = 0
self.backwardValue = 0
self.leftValue = 0
self.rightValue = 0
self.moveVector = ZERO_VECTOR3
if enable then
self:BindContextActions()
self:ConnectFocusEventListeners()
else
self:UnbindContextActions()
self:DisconnectFocusEventListeners()
end
end
self.wasdEnabled = enable and enableWASD or false
self.enabled = enable
end
-- Overrides Keyboard:UpdateMovement(inputState) to conditionally consider self.wasdEnabled
function ClickToMove:UpdateMovement(inputState)
if inputState == Enum.UserInputState.Cancel then
self.moveVector = ZERO_VECTOR3
elseif self.wasdEnabled then
self.moveVector = Vector3.new(self.leftValue + self.rightValue, 0, self.forwardValue + self.backwardValue)
end
end
return ClickToMove
]]>
-
DynamicThumbstick
500
if isBigScreen then
ThumbstickSize = ThumbstickSize * 2
ThumbstickRingSize = ThumbstickRingSize * 2
MiddleSize = MiddleSize * 2
MiddleSpacing = MiddleSpacing * 2
RadiusOfDeadZone = RadiusOfDeadZone * 2
RadiusOfMaxSpeed = RadiusOfMaxSpeed * 2
end
local function layoutThumbstickFrame(portraitMode)
if portraitMode then
self.thumbstickFrame.Size = UDim2.new(1, 0, 0.4, 0)
self.thumbstickFrame.Position = UDim2.new(0, 0, 0.6, 0)
else
self.thumbstickFrame.Size = UDim2.new(0.4, 0, 2/3, 0)
self.thumbstickFrame.Position = UDim2.new(0, 0, 1/3, 0)
end
end
self.thumbstickFrame = Instance.new("TextButton")
self.thumbstickFrame.Text = ""
self.thumbstickFrame.Name = "DynamicThumbstickFrame"
self.thumbstickFrame.Visible = false
self.thumbstickFrame.BackgroundTransparency = 1.0
self.thumbstickFrame.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
layoutThumbstickFrame(false)
self.startImage = Instance.new("ImageLabel")
self.startImage.Name = "ThumbstickStart"
self.startImage.Visible = true
self.startImage.BackgroundTransparency = 1
self.startImage.Image = TOUCH_CONTROLS_SHEET
self.startImage.ImageRectOffset = Vector2.new(1,1)
self.startImage.ImageRectSize = Vector2.new(144, 144)
self.startImage.ImageColor3 = Color3.new(0, 0, 0)
self.startImage.AnchorPoint = Vector2.new(0.5, 0.5)
self.startImage.Position = UDim2.new(0, ThumbstickRingSize * 3.3, 1, -ThumbstickRingSize * 2.8)
self.startImage.Size = UDim2.new(0, ThumbstickRingSize * 3.7, 0, ThumbstickRingSize * 3.7)
self.startImage.ZIndex = 10
self.startImage.Parent = self.thumbstickFrame
self.endImage = Instance.new("ImageLabel")
self.endImage.Name = "ThumbstickEnd"
self.endImage.Visible = true
self.endImage.BackgroundTransparency = 1
self.endImage.Image = TOUCH_CONTROLS_SHEET
self.endImage.ImageRectOffset = Vector2.new(1,1)
self.endImage.ImageRectSize = Vector2.new(144, 144)
self.endImage.AnchorPoint = Vector2.new(0.5, 0.5)
self.endImage.Position = self.startImage.Position
self.endImage.Size = UDim2.new(0, ThumbstickSize * 0.8, 0, ThumbstickSize * 0.8)
self.endImage.ZIndex = 10
self.endImage.Parent = self.thumbstickFrame
for i = 1, NUM_MIDDLE_IMAGES do
self.middleImages[i] = Instance.new("ImageLabel")
self.middleImages[i].Name = "ThumbstickMiddle"
self.middleImages[i].Visible = false
self.middleImages[i].BackgroundTransparency = 1
self.middleImages[i].Image = TOUCH_CONTROLS_SHEET
self.middleImages[i].ImageRectOffset = Vector2.new(1,1)
self.middleImages[i].ImageRectSize = Vector2.new(144, 144)
self.middleImages[i].ImageTransparency = MIDDLE_TRANSPARENCIES[i]
self.middleImages[i].AnchorPoint = Vector2.new(0.5, 0.5)
self.middleImages[i].ZIndex = 9
self.middleImages[i].Parent = self.thumbstickFrame
end
local CameraChangedConn = nil
local function onCurrentCameraChanged()
if CameraChangedConn then
CameraChangedConn:Disconnect()
CameraChangedConn = nil
end
local newCamera = workspace.CurrentCamera
if newCamera then
local function onViewportSizeChanged()
local size = newCamera.ViewportSize
local portraitMode = size.X < size.Y
layoutThumbstickFrame(portraitMode)
end
CameraChangedConn = newCamera:GetPropertyChangedSignal("ViewportSize"):Connect(onViewportSizeChanged)
onViewportSizeChanged()
end
end
workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(onCurrentCameraChanged)
if workspace.CurrentCamera then
onCurrentCameraChanged()
end
self.moveTouchStartPosition = nil
self.startImageFadeTween = nil
self.endImageFadeTween = nil
self.middleImageFadeTweens = {}
local function doMove(direction)
local currentMoveVector = direction
-- Scaled Radial Dead Zone
local inputAxisMagnitude = currentMoveVector.magnitude
if inputAxisMagnitude < RadiusOfDeadZone then
currentMoveVector = Vector3.new()
else
currentMoveVector = currentMoveVector.unit*(1 - math.max(0, (RadiusOfMaxSpeed - currentMoveVector.magnitude)/RadiusOfMaxSpeed))
currentMoveVector = Vector3.new(currentMoveVector.x, 0, currentMoveVector.y)
end
self.moveVector = currentMoveVector
end
local function layoutMiddleImages(startPos, endPos)
local startDist = (ThumbstickSize / 2) + MiddleSize
local vector = endPos - startPos
local distAvailable = vector.magnitude - (ThumbstickRingSize / 2) - MiddleSize
local direction = vector.unit
local distNeeded = MiddleSpacing * NUM_MIDDLE_IMAGES
local spacing = MiddleSpacing
if distNeeded < distAvailable then
spacing = distAvailable / NUM_MIDDLE_IMAGES
end
for i = 1, NUM_MIDDLE_IMAGES do
local image = self.middleImages[i]
local distWithout = startDist + (spacing * (i - 2))
local currentDist = startDist + (spacing * (i - 1))
if distWithout < distAvailable then
local pos = endPos - direction * currentDist
local exposedFraction = math.clamp(1 - ((currentDist - distAvailable) / spacing), 0, 1)
image.Visible = true
image.Position = UDim2.new(0, pos.X, 0, pos.Y)
image.Size = UDim2.new(0, MiddleSize * exposedFraction, 0, MiddleSize * exposedFraction)
else
image.Visible = false
end
end
end
local function moveStick(pos)
local startPos = Vector2.new(self.moveTouchStartPosition.X, self.moveTouchStartPosition.Y) - self.thumbstickFrame.AbsolutePosition
local endPos = Vector2.new(pos.X, pos.Y) - self.thumbstickFrame.AbsolutePosition
self.endImage.Position = UDim2.new(0, endPos.X, 0, endPos.Y)
layoutMiddleImages(startPos, endPos)
end
-- input connections
self.thumbstickFrame.InputBegan:Connect(function(inputObject)
if inputObject.UserInputType ~= Enum.UserInputType.Touch or inputObject.UserInputState ~= Enum.UserInputState.Begin then
return
end
if self.moveTouchObject then
return
end
if self.isFirstTouch then
self.isFirstTouch = false
local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0)
TweenService:Create(self.startImage, tweenInfo, {Size = UDim2.new(0, 0, 0, 0)}):Play()
TweenService:Create(self.endImage, tweenInfo, {Size = UDim2.new(0, ThumbstickSize, 0, ThumbstickSize), ImageColor3 = Color3.new(0,0,0)}):Play()
end
self.moveTouchObject = inputObject
self.moveTouchStartPosition = inputObject.Position
local startPosVec2 = Vector2.new(inputObject.Position.X - self.thumbstickFrame.AbsolutePosition.X, inputObject.Position.Y - self.thumbstickFrame.AbsolutePosition.Y)
self.startImage.Visible = true
self.startImage.Position = UDim2.new(0, startPosVec2.X, 0, startPosVec2.Y)
self.endImage.Visible = true
self.endImage.Position = self.startImage.Position
self:FadeThumbstick(true)
moveStick(inputObject.Position)
if FADE_IN_OUT_BACKGROUND then
local playerGui = Players.LocalPlayer:FindFirstChildOfClass("PlayerGui")
local hasFadedBackgroundInOrientation = false
-- only fade in/out the background once per orientation
if playerGui then
if playerGui.CurrentScreenOrientation == Enum.ScreenOrientation.LandscapeLeft or
playerGui.CurrentScreenOrientation == Enum.ScreenOrientation.LandscapeRight then
hasFadedBackgroundInOrientation = self.hasFadedBackgroundInLandscape
self.hasFadedBackgroundInLandscape = true
elseif playerGui.CurrentScreenOrientation == Enum.ScreenOrientation.Portrait then
hasFadedBackgroundInOrientation = self.hasFadedBackgroundInPortrait
self.hasFadedBackgroundInPortrait = true
end
end
if not hasFadedBackgroundInOrientation then
self.fadeInAndOutHalfDuration = FADE_IN_OUT_HALF_DURATION_DEFAULT
self.fadeInAndOutBalance = FADE_IN_OUT_BALANCE_DEFAULT
self.tweenInAlphaStart = tick()
end
end
end)
self.onTouchMovedConn = UserInputService.TouchMoved:connect(function(inputObject)
if inputObject == self.moveTouchObject then
self.thumbstickFrame.Active = false
local direction = Vector2.new(inputObject.Position.x - self.moveTouchStartPosition.x, inputObject.Position.y - self.moveTouchStartPosition.y)
if math.abs(direction.x) > 0 or math.abs(direction.y) > 0 then
doMove(direction)
moveStick(inputObject.Position)
end
end
end)
self.onRenderSteppedConn = RunService.RenderStepped:Connect(function()
if self.tweenInAlphaStart ~= nil then
local delta = tick() - self.tweenInAlphaStart
local fadeInTime = (self.fadeInAndOutHalfDuration * 2 * self.fadeInAndOutBalance)
self.thumbstickFrame.BackgroundTransparency = 1 - FADE_IN_OUT_MAX_ALPHA*math.min(delta/fadeInTime, 1)
if delta > fadeInTime then
self.tweenOutAlphaStart = tick()
self.tweenInAlphaStart = nil
end
elseif self.tweenOutAlphaStart ~= nil then
local delta = tick() - self.tweenOutAlphaStart
local fadeOutTime = (self.fadeInAndOutHalfDuration * 2) - (self.fadeInAndOutHalfDuration * 2 * self.fadeInAndOutBalance)
self.thumbstickFrame.BackgroundTransparency = 1 - FADE_IN_OUT_MAX_ALPHA + FADE_IN_OUT_MAX_ALPHA*math.min(delta/fadeOutTime, 1)
if delta > fadeOutTime then
self.tweenOutAlphaStart = nil
end
end
end)
self.onTouchEndedConn = UserInputService.TouchEnded:connect(function(inputObject)
if inputObject == self.moveTouchObject then
self:OnInputEnded()
end
end)
GuiService.MenuOpened:connect(function()
if self.moveTouchObject then
self:OnInputEnded()
end
end)
local playerGui = Players.LocalPlayer:FindFirstChildOfClass("PlayerGui")
while not playerGui do
Players.LocalPlayer.ChildAdded:wait()
playerGui = Players.LocalPlayer:FindFirstChildOfClass("PlayerGui")
end
local playerGuiChangedConn = nil
local originalScreenOrientationWasLandscape = playerGui.CurrentScreenOrientation == Enum.ScreenOrientation.LandscapeLeft or
playerGui.CurrentScreenOrientation == Enum.ScreenOrientation.LandscapeRight
local function longShowBackground()
self.fadeInAndOutHalfDuration = 2.5
self.fadeInAndOutBalance = 0.05
self.tweenInAlphaStart = tick()
end
playerGuiChangedConn = playerGui.Changed:connect(function(prop)
if prop == "CurrentScreenOrientation" then
if (originalScreenOrientationWasLandscape and playerGui.CurrentScreenOrientation == Enum.ScreenOrientation.Portrait) or
(not originalScreenOrientationWasLandscape and playerGui.CurrentScreenOrientation ~= Enum.ScreenOrientation.Portrait) then
playerGuiChangedConn:disconnect()
longShowBackground()
if originalScreenOrientationWasLandscape then
self.hasFadedBackgroundInPortrait = true
else
self.hasFadedBackgroundInLandscape = true
end
end
end
end)
self.thumbstickFrame.Parent = parentFrame
spawn(function()
if game:IsLoaded() then
longShowBackground()
else
game.Loaded:wait()
longShowBackground()
end
end)
end
return DynamicThumbstick
]]>
-
Gamepad
thumbstickDeadzone then
self.moveVector = Vector3.new(inputObject.Position.X, 0, -inputObject.Position.Y)
else
self.moveVector = ZERO_VECTOR3
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Sink
end
end
ContextActionService:BindActivate(self.activeGamepad, Enum.KeyCode.ButtonR2)
if FFlagPlayerScriptsBindAtPriority then
ContextActionService:BindActionAtPriority("jumpAction", handleJumpAction, false,
self.CONTROL_ACTION_PRIORITY, Enum.KeyCode.ButtonA)
ContextActionService:BindActionAtPriority("moveThumbstick", handleThumbstickInput, false,
self.CONTROL_ACTION_PRIORITY, Enum.KeyCode.Thumbstick1)
else
ContextActionService:BindAction("jumpAction",handleJumpAction, false, Enum.KeyCode.ButtonA)
ContextActionService:BindAction("moveThumbstick",handleThumbstickInput, false, Enum.KeyCode.Thumbstick1)
end
return true
end
function Gamepad:UnbindContextActions()
if self.activeGamepad ~= NONE then
ContextActionService:UnbindActivate(self.activeGamepad, Enum.KeyCode.ButtonR2)
end
ContextActionService:UnbindAction("moveThumbstick")
ContextActionService:UnbindAction("jumpAction")
end
function Gamepad:OnNewGamepadConnected()
-- A new gamepad has been connected.
local bestGamepad = self:GetHighestPriorityGamepad()
if bestGamepad == self.activeGamepad then
-- A new gamepad was connected, but our active gamepad is not changing
return
end
if bestGamepad == NONE then
-- There should be an active gamepad when GamepadConnected fires, so this should not
-- normally be hit. If there is no active gamepad, unbind actions but leave
-- the module enabled and continue to listen for a new gamepad connection.
warn("Gamepad:OnNewGamepadConnected found no connected gamepads")
self:UnbindContextActions()
return
end
if self.activeGamepad ~= NONE then
-- Switching from one active gamepad to another
self:UnbindContextActions()
end
self.activeGamepad = bestGamepad
self:BindContextActions()
end
function Gamepad:OnCurrentGamepadDisconnected()
if self.activeGamepad ~= NONE then
ContextActionService:UnbindActivate(self.activeGamepad, Enum.KeyCode.ButtonR2)
end
local bestGamepad = self:GetHighestPriorityGamepad()
if self.activeGamepad ~= NONE and bestGamepad == self.activeGamepad then
warn("Gamepad:OnCurrentGamepadDisconnected found the supposedly disconnected gamepad in connectedGamepads.")
self:UnbindContextActions()
self.activeGamepad = NONE
return
end
if bestGamepad == NONE then
-- No active gamepad, unbinding actions but leaving gamepad connection listener active
self:UnbindContextActions()
self.activeGamepad = NONE
else
-- Set new gamepad as active and bind to tool activation
self.activeGamepad = bestGamepad
ContextActionService:BindActivate(self.activeGamepad, Enum.KeyCode.ButtonR2)
end
end
function Gamepad:ConnectGamepadConnectionListeners()
self.gamepadConnectedConn = UserInputService.GamepadConnected:Connect(function(gamepadEnum)
self:OnNewGamepadConnected()
end)
self.gamepadDisconnectedConn = UserInputService.GamepadDisconnected:Connect(function(gamepadEnum)
if self.activeGamepad == gamepadEnum then
self:OnCurrentGamepadDisconnected()
end
end)
end
function Gamepad:DisconnectGamepadConnectionListeners()
if self.gamepadConnectedConn then
self.gamepadConnectedConn:Disconnect()
self.gamepadConnectedConn = nil
end
if self.gamepadDisconnectedConn then
self.gamepadDisconnectedConn:Disconnect()
self.gamepadDisconnectedConn = nil
end
end
return Gamepad
]]>
-
Keyboard
-
PathDisplay
distToNextPoint then
distanceBudget = distanceBudget - distToNextPoint
currentIdx = currentIdx - 1
else
local dirToNextPoint = toNextPoint.unit
local pointPos = currentPoint + (dirToNextPoint * distanceBudget)
local point = renderPoint(pointPos, false)
if point then
renderedPoints[#renderedPoints + 1] = point
end
distanceBudget = distanceBudget + PathDisplay.spacing
end
end
end
pointModel.Parent = workspace.CurrentCamera
end
return PathDisplay
]]>
-
TouchDPad
jumpRadius then
local angle = math.atan2(direction.y, direction.x)
local octant = (math.floor(8 * angle / (2 * math.pi) + 8.5)%8) + 1
self.moveVector = COMPASS_DIR[octant]
end
if not self.flBtn.Visible and self.moveVector == COMPASS_DIR[7] then
self.flBtn.Visible = true
self.frBtn.Visible = true
end
end
self.DPadFrame.InputBegan:Connect(function(inputObject)
if self.touchObject or inputObject.UserInputType ~= Enum.UserInputType.Touch then
return
end
self.touchObject = inputObject
normalizeDirection(self.touchObject.Position)
end)
self.DPadFrame.InputChanged:Connect(function(inputObject)
if inputObject == self.touchObject then
normalizeDirection(self.touchObject.Position)
self.isJumping = false
end
end)
self.DPadFrame.InputEnded:connect(function(inputObject)
if inputObject == self.touchObject then
self:OnInputEnded()
end
end)
GuiService.MenuOpened:Connect(function()
if self.touchObject then
self:OnInputEnded()
end
end)
self.DPadFrame.Parent = parentFrame
end
return TouchDPad
]]>
-
TouchJump
0 then
self.jumpButton.Visible = true
end
end
end
else
self.jumpButton.Visible = false
self.isJumping = false
self.jumpButton.ImageRectOffset = Vector2.new(1, 146)
end
end
function TouchJump:UpdateEnabled()
if self.jumpPower > 0 and self.jumpStateEnabled then
self:EnableButton(true)
else
self:EnableButton(false)
end
end
function TouchJump:HumanoidChanged(prop)
local humanoid = Players.LocalPlayer.Character and Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
if humanoid then
if prop == "JumpPower" then
self.jumpPower = humanoid.JumpPower
self:UpdateEnabled()
elseif prop == "Parent" then
if not humanoid.Parent then
self.humanoidChangeConn:Disconnect()
end
end
end
end
function TouchJump:HumanoidStateEnabledChanged(state, isEnabled)
if state == Enum.HumanoidStateType.Jumping then
self.jumpStateEnabled = isEnabled
self:UpdateEnabled()
end
end
function TouchJump:CharacterAdded(char)
if self.humanoidChangeConn then
self.humanoidChangeConn:Disconnect()
self.humanoidChangeConn = nil
end
self.humanoid = char:FindFirstChildOfClass("Humanoid")
while not self.humanoid do
char.ChildAdded:wait()
self.humanoid = char:FindFirstChildOfClass("Humanoid")
end
self.humanoidJumpPowerConn = self.humanoid:GetPropertyChangedSignal("JumpPower"):Connect(function()
self.jumpPower = self.humanoid.JumpPower
self:UpdateEnabled()
end)
self.humanoidParentConn = self.humanoid:GetPropertyChangedSignal("Parent"):Connect(function()
if not self.humanoid.Parent then
self.humanoidJumpPowerConn:Disconnect()
self.humanoidJumpPowerConn = nil
self.humanoidParentConn:Disconnect()
self.humanoidParentConn = nil
end
end)
self.humanoidStateEnabledChangedConn = self.humanoid.StateEnabledChanged:Connect(function(state, enabled)
self:HumanoidStateEnabledChanged(state, enabled)
end)
self.jumpPower = self.humanoid.JumpPower
self.jumpStateEnabled = self.humanoid:GetStateEnabled(Enum.HumanoidStateType.Jumping)
self:UpdateEnabled()
end
function TouchJump:SetupCharacterAddedFunction()
self.characterAddedConn = Players.LocalPlayer.CharacterAdded:Connect(function(char)
self:CharacterAdded(char)
end)
if Players.LocalPlayer.Character then
self:CharacterAdded(Players.LocalPlayer.Character)
end
end
function TouchJump:Enable(enable, parentFrame)
self.parentUIFrame = parentFrame
self.externallyEnabled = enable
self:EnableButton(enable)
end
function TouchJump:Create()
if not self.parentUIFrame then
return
end
if self.jumpButton then
self.jumpButton:Destroy()
self.jumpButton = nil
end
local minAxis = math.min(self.parentUIFrame.AbsoluteSize.x, self.parentUIFrame.AbsoluteSize.y)
local isSmallScreen = minAxis <= 500
local jumpButtonSize = isSmallScreen and 70 or 120
self.jumpButton = Instance.new("ImageButton")
self.jumpButton.Name = "JumpButton"
self.jumpButton.Visible = false
self.jumpButton.BackgroundTransparency = 1
self.jumpButton.Image = TOUCH_CONTROL_SHEET
self.jumpButton.ImageRectOffset = Vector2.new(1, 146)
self.jumpButton.ImageRectSize = Vector2.new(144, 144)
self.jumpButton.Size = UDim2.new(0, jumpButtonSize, 0, jumpButtonSize)
self.jumpButton.Position = isSmallScreen and UDim2.new(1, -(jumpButtonSize*1.5-10), 1, -jumpButtonSize - 20) or
UDim2.new(1, -(jumpButtonSize*1.5-10), 1, -jumpButtonSize * 1.75)
local touchObject = nil
self.jumpButton.InputBegan:connect(function(inputObject)
--A touch that starts elsewhere on the screen will be sent to a frame's InputBegan event
--if it moves over the frame. So we check that this is actually a new touch (inputObject.UserInputState ~= Enum.UserInputState.Begin)
if touchObject or inputObject.UserInputType ~= Enum.UserInputType.Touch
or inputObject.UserInputState ~= Enum.UserInputState.Begin then
return
end
touchObject = inputObject
self.jumpButton.ImageRectOffset = Vector2.new(146, 146)
self.isJumping = true
end)
local OnInputEnded = function()
touchObject = nil
self.isJumping = false
self.jumpButton.ImageRectOffset = Vector2.new(1, 146)
end
self.jumpButton.InputEnded:connect(function(inputObject)
if inputObject == touchObject then
OnInputEnded()
end
end)
GuiService.MenuOpened:connect(function()
if touchObject then
OnInputEnded()
end
end)
if not self.characterAddedConn then
self:SetupCharacterAddedFunction()
end
self.jumpButton.Parent = self.parentUIFrame
end
return TouchJump
]]>
-
TouchThumbpad
0.5 then -- UP
if not self.isUp then
self.isUp, self.isDown = true, false
doTween(self.uArrow, self.lgArrowSize, UDim2.new(0.5, -self.smArrowSize.X.Offset, 0, self.smImgOffset - 1.5*self.smArrowSize.Y.Offset))
doTween(self.dArrow, self.smArrowSize, UDim2.new(0.5, -0.5*self.smArrowSize.X.Offset, 1, self.lgImgOffset))
end
elseif forwardDot < -0.5 then -- DOWN
if not self.isDown then
self.isDown, self.isUp = true, false
doTween(self.dArrow, self.lgArrowSize, UDim2.new(0.5, -self.smArrowSize.X.Offset, 1, self.lgImgOffset + 0.5*self.smArrowSize.Y.Offset))
doTween(self.uArrow, self.smArrowSize, UDim2.new(0.5, -0.5*self.smArrowSize.X.Offset, 0, self.smImgOffset))
end
else
self.isUp, self.isDown = false, false
doTween(self.dArrow, self.smArrowSize, UDim2.new(0.5, -0.5*self.smArrowSize.X.Offset, 1, self.lgImgOffset))
doTween(self.uArrow, self.smArrowSize, UDim2.new(0.5, -0.5*self.smArrowSize.X.Offset, 0, self.smImgOffset))
end
if rightDot > 0.5 then
if not self.isRight then
self.isRight, self.isLeft = true, false
doTween(self.rArrow, self.lgArrowSize, UDim2.new(1, self.lgImgOffset + 0.5*self.smArrowSize.X.Offset, 0.5, -self.smArrowSize.Y.Offset))
doTween(self.lArrow, self.smArrowSize, UDim2.new(0, self.smImgOffset, 0.5, -0.5*self.smArrowSize.Y.Offset))
end
elseif rightDot < -0.5 then
if not self.isLeft then
self.isLeft, self.isRight = true, false
doTween(self.lArrow, self.lgArrowSize, UDim2.new(0, self.smImgOffset - 1.5*self.smArrowSize.X.Offset, 0.5, -self.smArrowSize.Y.Offset))
doTween(self.rArrow, self.smArrowSize, UDim2.new(1, self.lgImgOffset, 0.5, -0.5*self.smArrowSize.Y.Offset))
end
else
self.isRight, self.isLeft = false, false
doTween(self.lArrow, self.smArrowSize, UDim2.new(0, self.smImgOffset, 0.5, -0.5*self.smArrowSize.Y.Offset))
doTween(self.rArrow, self.smArrowSize, UDim2.new(1, self.lgImgOffset, 0.5, -0.5*self.smArrowSize.Y.Offset))
end
end
--input connections
self.thumbpadFrame.InputBegan:connect(function(inputObject)
--A touch that starts elsewhere on the screen will be sent to a frame's InputBegan event
--if it moves over the frame. So we check that this is actually a new touch (inputObject.UserInputState ~= Enum.UserInputState.Begin)
if self.touchObject or inputObject.UserInputType ~= Enum.UserInputType.Touch
or inputObject.UserInputState ~= Enum.UserInputState.Begin then
return
end
self.thumbpadFrame.Position = UDim2.new(0, inputObject.Position.x - 0.5*self.thumbpadFrame.AbsoluteSize.x, 0, inputObject.Position.y - 0.5*self.thumbpadFrame.Size.Y.Offset)
padOrigin = Vector3.new(self.thumbpadFrame.AbsolutePosition.x +0.5* self.thumbpadFrame.AbsoluteSize.x,
self.thumbpadFrame.AbsolutePosition.y + 0.5*self.thumbpadFrame.AbsoluteSize.y, 0)
doMove(inputObject.Position)
self.touchObject = inputObject
end)
self.touchChangedConn = UserInputService.TouchMoved:connect(function(inputObject, isProcessed)
if inputObject == self.touchObject then
doMove(self.touchObject.Position)
end
end)
self.touchEndedConn = UserInputService.TouchEnded:Connect(function(inputObject)
if inputObject == self.touchObject then
self:OnInputEnded()
end
end)
self.menuOpenedConn = GuiService.MenuOpened:Connect(function()
if self.touchObject then
self:OnInputEnded()
end
end)
self.thumbpadFrame.Parent = parentFrame
end
return TouchThumbpad
]]>
-
TouchThumbstick
maxLength then
local offset = relativePosition.unit * maxLength
self.thumbstickFrame.Position = UDim2.new(
0, pos.x - self.thumbstickFrame.AbsoluteSize.x/2 - offset.x,
0, pos.y - self.thumbstickFrame.AbsoluteSize.y/2 - offset.y)
else
length = math.min(length, maxLength)
relativePosition = relativePosition.unit * length
end
self.stickImage.Position = UDim2.new(0, relativePosition.x + self.stickImage.AbsoluteSize.x/2, 0, relativePosition.y + self.stickImage.AbsoluteSize.y/2)
end
-- input connections
self.thumbstickFrame.InputBegan:Connect(function(inputObject)
--A touch that starts elsewhere on the screen will be sent to a frame's InputBegan event
--if it moves over the frame. So we check that this is actually a new touch (inputObject.UserInputState ~= Enum.UserInputState.Begin)
if self.moveTouchObject or inputObject.UserInputType ~= Enum.UserInputType.Touch
or inputObject.UserInputState ~= Enum.UserInputState.Begin then
return
end
self.moveTouchObject = inputObject
self.thumbstickFrame.Position = UDim2.new(0, inputObject.Position.x - self.thumbstickFrame.Size.X.Offset/2, 0, inputObject.Position.y - self.thumbstickFrame.Size.Y.Offset/2)
centerPosition = Vector2.new(self.thumbstickFrame.AbsolutePosition.x + self.thumbstickFrame.AbsoluteSize.x/2,
self.thumbstickFrame.AbsolutePosition.y + self.thumbstickFrame.AbsoluteSize.y/2)
local direction = Vector2.new(inputObject.Position.x - centerPosition.x, inputObject.Position.y - centerPosition.y)
end)
self.onTouchMovedConn = UserInputService.TouchMoved:Connect(function(inputObject, isProcessed)
if inputObject == self.moveTouchObject then
centerPosition = Vector2.new(self.thumbstickFrame.AbsolutePosition.x + self.thumbstickFrame.AbsoluteSize.x/2,
self.thumbstickFrame.AbsolutePosition.y + self.thumbstickFrame.AbsoluteSize.y/2)
local direction = Vector2.new(inputObject.Position.x - centerPosition.x, inputObject.Position.y - centerPosition.y)
DoMove(direction)
MoveStick(inputObject.Position)
end
end)
self.onTouchEndedConn = UserInputService.TouchEnded:Connect(function(inputObject, isProcessed)
if inputObject == self.moveTouchObject then
self:OnInputEnded()
end
end)
GuiService.MenuOpened:Connect(function()
if self.moveTouchObject then
self:OnInputEnded()
end
end)
self.thumbstickFrame.Parent = parentFrame
end
return TouchThumbstick
]]>
-
VRNavigation
= 1 then
local dist = (currentPoints[1] - humanoid.Torso.Position).magnitude
expectedTimeToNextPoint = dist / humanoid.WalkSpeed
end
movementUpdateEvent:Fire("targetPoint", self.currentDestination)
end
function VRNavigation:GoToPoint(point)
currentPath = true
currentPoints = { point }
currentPointIdx = 1
moving = true
local humanoid = self:GetLocalHumanoid()
local distance = (humanoid.Torso.Position - point).magnitude
local estimatedTimeRemaining = distance / humanoid.WalkSpeed
timeReachedLastPoint = tick()
expectedTimeToNextPoint = estimatedTimeRemaining
movementUpdateEvent:Fire("targetPoint", point)
end
function VRNavigation:StopFollowingPath()
currentPath = nil
currentPoints = nil
currentPointIdx = 0
moving = false
self.moveVector = ZERO_VECTOR3
end
function VRNavigation:TryComputePath(startPos, destination)
local numAttempts = 0
local newPath = nil
while not newPath and numAttempts < 5 do
newPath = PathfindingService:ComputeSmoothPathAsync(startPos, destination, MAX_PATHING_DISTANCE)
numAttempts = numAttempts + 1
if newPath.Status == Enum.PathStatus.ClosestNoPath or newPath.Status == Enum.PathStatus.ClosestOutOfRange then
newPath = nil
break
end
if newPath and newPath.Status == Enum.PathStatus.FailStartNotEmpty then
startPos = startPos + (destination - startPos).unit
newPath = nil
end
if newPath and newPath.Status == Enum.PathStatus.FailFinishNotEmpty then
destination = destination + Vector3.new(0, 1, 0)
newPath = nil
end
end
return newPath
end
function VRNavigation:OnNavigationRequest(destinationCFrame, inputUserCFrame )
local destinationPosition = destinationCFrame.p
local lastDestination = self.currentDestination
if not IsFiniteVector3(destinationPosition) then
return
end
self.currentDestination = destinationPosition
local humanoid = self:GetLocalHumanoid()
if not humanoid or not humanoid.Torso then
return
end
local currentPosition = humanoid.Torso.Position
local distanceToDestination = (self.currentDestination - currentPosition).magnitude
if distanceToDestination < NO_PATH_THRESHOLD then
self:GoToPoint(self.currentDestination)
return
end
if not lastDestination or (self.currentDestination - lastDestination).magnitude > RECALCULATE_PATH_THRESHOLD then
local newPath = self:TryComputePath(currentPosition, self.currentDestination)
if newPath then
self:StartFollowingPath(newPath)
if PathDisplay then
PathDisplay.setCurrentPoints(self.currentPoints)
PathDisplay.renderPath()
end
else
self:StopFollowingPath()
if PathDisplay then
PathDisplay.clearRenderedPath()
end
end
else
if moving then
self.currentPoints[#currentPoints] = self.currentDestination
else
self:GoToPoint(self.currentDestination)
end
end
end
function VRNavigation:OnJumpAction(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
self.isJumping = true
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Sink
end
end
function VRNavigation:BindJumpAction(active)
if active then
if not self.isJumpBound then
self.isJumpBound = true
if FFlagPlayerScriptsBindAtPriority then
ContextActionService:BindActionAtPriority("VRJumpAction", (function() return self:OnJumpAction() end), false,
self.CONTROL_ACTION_PRIORITY, Enum.KeyCode.ButtonA)
else
ContextActionService:BindAction("VRJumpAction", (function() self:OnJumpAction() end), false, Enum.KeyCode.ButtonA)
end
end
else
if self.isJumpBound then
self.isJumpBound = false
ContextActionService:UnbindAction("VRJumpAction")
end
end
end
function VRNavigation:ControlCharacterGamepad(actionName, inputState, inputObject)
if inputObject.KeyCode ~= Enum.KeyCode.Thumbstick1 then return end
if inputState == Enum.UserInputState.Cancel then
self.moveVector = ZERO_VECTOR3
return
end
if inputState ~= Enum.UserInputState.End then
self:StopFollowingPath()
if PathDisplay then
PathDisplay.clearRenderedPath()
end
if self:ShouldUseNavigationLaser() then
self:BindJumpAction(true)
self:SetLaserPointerMode("Hidden")
end
if inputObject.Position.magnitude > THUMBSTICK_DEADZONE then
self.moveVector = Vector3.new(inputObject.Position.X, 0, -inputObject.Position.Y)
if self.moveVector.magnitude > 0 then
self.moveVector = self.moveVector.unit * math.min(1, inputObject.Position.magnitude)
end
self.moveLatch = true
end
else
self.moveVector = ZERO_VECTOR3
if self:ShouldUseNavigationLaser() then
self:BindJumpAction(false)
self:SetLaserPointerMode("Navigation")
end
if self.moveLatch then
self.moveLatch = false
movementUpdateEvent:Fire("offtrack")
end
end
if FFlagPlayerScriptsBindAtPriority then
return Enum.ContextActionResult.Sink
end
end
function VRNavigation:OnHeartbeat(dt)
local newMoveVector = self.moveVector
local humanoid = self:GetLocalHumanoid()
if not humanoid or not humanoid.Torso then
return
end
if self.moving and self.currentPoints then
local currentPosition = humanoid.Torso.Position
local goalPosition = currentPoints[1]
local vectorToGoal = (goalPosition - currentPosition) * XZ_VECTOR3
local moveDist = vectorToGoal.magnitude
local moveDir = vectorToGoal / moveDist
if moveDist < POINT_REACHED_THRESHOLD then
local estimatedTimeRemaining = 0
local prevPoint = currentPoints[1]
for i, point in pairs(currentPoints) do
if i ~= 1 then
local dist = (point - prevPoint).magnitude
prevPoint = point
estimatedTimeRemaining = estimatedTimeRemaining + (dist / humanoid.WalkSpeed)
end
end
table.remove(currentPoints, 1)
currentPointIdx = currentPointIdx + 1
if #currentPoints == 0 then
self:StopFollowingPath()
if PathDisplay then
PathDisplay.clearRenderedPath()
end
return
else
if PathDisplay then
PathDisplay.setCurrentPoints(currentPoints)
PathDisplay.renderPath()
end
local newGoal = currentPoints[1]
local distanceToGoal = (newGoal - currentPosition).magnitude
expectedTimeToNextPoint = distanceToGoal / humanoid.WalkSpeed
timeReachedLastPoint = tick()
end
else
local ignoreTable = {
game.Players.LocalPlayer.Character,
workspace.CurrentCamera
}
local obstructRay = Ray.new(currentPosition - Vector3.new(0, 1, 0), moveDir * 3)
local obstructPart, obstructPoint, obstructNormal = workspace:FindPartOnRayWithIgnoreList(obstructRay, ignoreTable)
if obstructPart then
local heightOffset = Vector3.new(0, 100, 0)
local jumpCheckRay = Ray.new(obstructPoint + moveDir * 0.5 + heightOffset, -heightOffset)
local jumpCheckPart, jumpCheckPoint, jumpCheckNormal = workspace:FindPartOnRayWithIgnoreList(jumpCheckRay, ignoreTable)
local heightDifference = jumpCheckPoint.Y - currentPosition.Y
if heightDifference < 6 and heightDifference > -2 then
humanoid.Jump = true
end
end
local timeSinceLastPoint = tick() - timeReachedLastPoint
if timeSinceLastPoint > expectedTimeToNextPoint + OFFTRACK_TIME_THRESHOLD then
self:StopFollowingPath()
if PathDisplay then
PathDisplay.clearRenderedPath()
end
movementUpdateEvent:Fire("offtrack")
end
newMoveVector = self.moveVector:Lerp(moveDir, dt * 10)
end
end
if IsFiniteVector3(newMoveVector) then
self.moveVector = newMoveVector
end
end
function VRNavigation:OnUserCFrameEnabled()
if self:ShouldUseNavigationLaser() then
self:BindJumpAction(false)
self:SetLaserPointerMode("Navigation")
else
self:BindJumpAction(true)
self:SetLaserPointerMode("Hidden")
end
end
function VRNavigation:Enable(enable)
self.moveVector = ZERO_VECTOR3
self.isJumping = false
if enable then
self.navigationRequestedConn = VRService.NavigationRequested:Connect(function(destinationCFrame, inputUserCFrame) self:OnNavigationRequest(destinationCFrame, inputUserCFrame) end)
self.heartbeatConn = RunService.Heartbeat:Connect(function(dt) self:OnHeartbeat(dt) end)
if FFlagPlayerScriptsBindAtPriority then
ContextActionService:BindAction("MoveThumbstick", (function(actionName, inputState, inputObject) return self:ControlCharacterGamepad(actionName, inputState, inputObject) end),
false, self.CONTROL_ACTION_PRIORITY, Enum.KeyCode.Thumbstick1)
else
ContextActionService:BindAction("MoveThumbstick", (function(actionName, inputState, inputObject) self:ControlCharacterGamepad(actionName, inputState, inputObject) end), false, Enum.KeyCode.Thumbstick1)
end
ContextActionService:BindActivate(Enum.UserInputType.Gamepad1, Enum.KeyCode.ButtonR2)
self.userCFrameEnabledConn = VRService.UserCFrameEnabled:Connect(function() self:OnUserCFrameEnabled() end)
self:OnUserCFrameEnabled()
pcall(function()
VRService:SetTouchpadMode(Enum.VRTouchpad.Left, Enum.VRTouchpadMode.VirtualThumbstick)
VRService:SetTouchpadMode(Enum.VRTouchpad.Right, Enum.VRTouchpadMode.ABXY)
end)
self.enabled = true
else
-- Disable
self:StopFollowingPath()
ContextActionService:UnbindAction("MoveThumbstick")
ContextActionService:UnbindActivate(Enum.UserInputType.Gamepad1, Enum.KeyCode.ButtonR2)
self:BindJumpAction(false)
self:SetLaserPointerMode("Disabled")
if self.navigationRequestedConn then
self.navigationRequestedConn:Disconnect()
self.navigationRequestedConn = nil
end
if self.heartbeatConn then
self.heartbeatConn:Disconnect()
self.heartbeatConn = nil
end
if self.userCFrameEnabledConn then
self.userCFrameEnabledConn:Disconnect()
self.userCFrameEnabledConn = nil
end
self.enabled = false
end
end
return VRNavigation
]]>
-
VehicleController
-
PlayerScriptsLoader
-
Workspace
-
NPC1
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
HumanoidRootPart
false
-0.5
0.5
0
0
-0.5
0.5
4
0
-35.35728
60.832367
40.429756
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
2
2
1
-0.5
0.5
3
0
1
0
0
0
-
RootRigAttachment
-0.000607906
-0.81877613
0.033983894
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.0006079060258343816
-0.8187761306762695
0.03398389369249344
-
OriginalSize
2
2
1
-
LeftHand
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-36.126816
59.529976
40.576588
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.24898862838745117
0.6131927967071533
0.3323974907398224
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065408
https://assetdelivery.roblox.com/v1/asset/?id=3934065408
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.24898862838745117
0.6131927967071533
0.3323974907398224
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
LeftWristRigAttachment
-0.025452733
0.3046073
0.049758196
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.025452733039855957
0.3046073019504547
0.049758195877075195
-
LeftWrist
-0.11797005
-0.39579457
0.015762076
1
0
0
0
1
0
0
0
1
-0.025452733
0.3046073
0.049758196
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.24898862838745117
0.6131927967071533
0.3323974907398224
-
RightUpperArm
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-34.748657
61.029594
40.553684
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.39513614773750305
0.942173957824707
0.4249786138534546
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065381
https://assetdelivery.roblox.com/v1/asset/?id=3934065381
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.39513614773750305
0.942173957824707
0.4249786138534546
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
RightShoulderRigAttachment
-0.076161385
0.3345083
-0.0012780055
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.07616138458251953
0.3345082998275757
-0.0012780055403709412
-
RightElbowRigAttachment
0.040880978
-0.4066136
0.030482814
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.04088097810745239
-0.4066135883331299
0.030482813715934753
-
RightShoulder
0.532176
0.31034005
0.091338284
1
0
0
0
1
0
0
0
1
-0.076161385
0.3345083
-0.0012780055
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.39513614773750305
0.942173957824707
0.4249786138534546
-
RightLowerArm
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-34.67977
60.231476
40.610374
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.4327073097229004
0.889136791229248
0.4252088963985443
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065406
https://assetdelivery.roblox.com/v1/asset/?id=3934065406
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.4327073097229004
0.889136791229248
0.4252088963985443
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
RightElbowRigAttachment
-0.028005898
0.39150482
-0.02620709
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.028005897998809814
0.39150482416152954
-0.0262070894241333
-
RightWristRigAttachment
0.119244516
-0.39689308
0.015973017
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.1192445158958435
-0.39689308404922485
0.015973016619682312
-
RightElbow
0.040880978
-0.4066136
0.030482814
1
0
0
0
1
0
0
0
1
-0.028005898
0.39150482
-0.02620709
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.4327073097229004
0.889136791229248
0.4252088963985443
-
RightUpperLeg
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.07688
59.164463
40.409157
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.5554730892181396
1.3316420316696167
0.7053832411766052
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065387
https://assetdelivery.roblox.com/v1/asset/?id=3934065387
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.5554730892181396
1.331642508506775
0.7053832411766052
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
RightHipRigAttachment
-0.0026204586
0.6679041
0.01602125
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.0026204586029052734
0.6679038405418396
0.016021249815821648
-
RightKneeRigAttachment
-0.020522952
-0.59555167
0.049337804
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.02052295207977295
-0.5955514311790466
0.049337804317474365
-
OriginalSize
0.5554730892181396
1.3316420316696167
0.7053832411766052
-
RightHip
0.27634314
-0.101884976
0.00011147326
1
0
0
0
1
0
0
0
1
-0.0026204586
0.6679041
0.01602125
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
RightLowerLeg
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.06421
57.92662
40.53936
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.4296979308128357
1.4310376644134521
0.5790980458259583
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065394
https://assetdelivery.roblox.com/v1/asset/?id=3934065394
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.4296979308128357
1.4310381412506104
0.5790980458259583
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
RightKneeRigAttachment
-0.03319463
0.6422912
-0.0808638
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.03319463133811951
0.6422909498214722
-0.08086380362510681
-
RightAnkleRigAttachment
0.0010480881
-0.7746442
0.09195016
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.0010480880737304688
-0.7746438980102539
0.09195016324520111
-
OriginalSize
0.4296979308128357
1.4310376644134521
0.5790980458259583
-
RightKnee
-0.020522952
-0.59555167
0.049337804
1
0
0
0
1
0
0
0
1
-0.03319463
0.6422912
-0.0808638
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
LeftFoot
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.660244
56.98195
40.36777
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.3247062861919403
0.6436786651611328
0.9374623894691467
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065396
https://assetdelivery.roblox.com/v1/asset/?id=3934065396
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.3247062861919403
0.6436786651611328
0.9374623894691467
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
LeftAnkleRigAttachment
0.007632643
0.17003131
0.26353702
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.007632642984390259
0.17003130912780762
0.2635370194911957
-
LeftAnkle
-0.0022327602
-0.7746978
0.09171689
1
0
0
0
1
0
0
0
1
0.007632643
0.17003131
0.26353702
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.3247062861919403
0.6436786651611328
0.9374623894691467
-
LeftLowerArm
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-36.034298
60.230377
40.610584
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.43274736404418945
0.8891100883483887
0.4252088665962219
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065576
https://assetdelivery.roblox.com/v1/asset/?id=3934065576
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.43274736404418945
0.8891100883483887
0.4252088665962219
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
LeftElbowRigAttachment
0.02927661
0.3926015
-0.026417091
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.029276609420776367
0.39260149002075195
-0.026417091488838196
-
LeftWristRigAttachment
-0.11797005
-0.39579457
0.015762076
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.1179700493812561
-0.3957945704460144
0.015762075781822205
-
LeftElbow
-0.03995645
-0.4060647
0.030424759
1
0
0
0
1
0
0
0
1
0.02927661
0.3926015
-0.026417091
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.43274736404418945
0.8891100883483887
0.4252088665962219
-
LeftLowerLeg
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.65038
57.926678
40.539593
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.4297199249267578
1.4310553073883057
0.5792606472969055
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065606
https://assetdelivery.roblox.com/v1/asset/?id=3934065606
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.4297199249267578
1.4310553073883057
0.5792606472969055
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
LeftKneeRigAttachment
0.032010406
0.6422378
-0.081097215
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.032010406255722046
0.6422377824783325
-0.08109721541404724
-
LeftAnkleRigAttachment
-0.0022327602
-0.7746978
0.09171689
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.002232760190963745
-0.7746977806091309
0.09171689301729202
-
LeftKnee
0.019307911
-0.5955982
0.04933771
1
0
0
0
1
0
0
0
1
0.032010406
0.6422378
-0.081097215
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.4297199249267578
1.4310553073883057
0.5792606472969055
-
LeftUpperLeg
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.637676
59.164513
40.409157
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.5554731488227844
1.331610918045044
0.70538330078125
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065609
https://assetdelivery.roblox.com/v1/asset/?id=3934065609
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.5554731488227844
1.331610918045044
0.70538330078125
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
LeftHipRigAttachment
0.0014059246
0.66785705
0.016021186
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.0014059245586395264
0.6678570508956909
0.016021186485886574
-
LeftKneeRigAttachment
0.019307911
-0.5955982
0.04933771
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.01930791139602661
-0.5955982208251953
0.049337711185216904
-
LeftHip
-0.28042528
-0.10188474
0.00011146953
1
0
0
0
1
0
0
0
1
0.0014059246
0.66785705
0.016021186
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.5554731488227844
1.331610918045044
0.70538330078125
-
RightFoot
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.05435
56.98192
40.36746
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.32470619678497314
0.6436238288879395
0.937462329864502
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065630
https://assetdelivery.roblox.com/v1/asset/?id=3934065630
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.32470619678497314
0.6436240673065186
0.937462329864502
rbxassetid://3934065568
-0.5
0.5
0
0
0
0
0
0
-
RightAnkleRigAttachment
-0.008807838
0.17005855
0.26385164
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.008807837963104248
0.1700584888458252
0.2638516426086426
-
OriginalSize
0.32470619678497314
0.6436238288879395
0.937462329864502
-
RightAnkle
0.0010480881
-0.7746442
0.09195016
1
0
0
0
1
0
0
0
1
-0.008807838
0.17005855
0.26385164
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
LeftUpperArm
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.965065
61.029045
40.55374
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.39597806334495544
0.9424078464508057
0.42509543895721436
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065546
https://assetdelivery.roblox.com/v1/asset/?id=3934065546
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.39597806334495544
0.9424078464508057
0.42509543895721436
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
LeftShoulderRigAttachment
0.07708573
0.33506155
-0.0013367459
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.07708573341369629
0.33506155014038086
-0.0013367459177970886
-
LeftElbowRigAttachment
-0.03995645
-0.4060647
0.030424759
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.03995645046234131
-0.4060646891593933
0.030424758791923523
-
LeftShoulder
-0.53098595
0.31034386
0.09133796
1
0
0
0
1
0
0
0
1
0.07708573
0.33506155
-0.0013367459
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.39597806334495544
0.9424078464508057
0.42509543895721436
-
UpperTorso
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.356995
61.053764
40.461067
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
1.2573397159576416
1.5161899328231812
1.0650634765625
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065561
https://assetdelivery.roblox.com/v1/asset/?id=3934065561
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
1.2573397159576416
1.5161899328231812
1.0650634765625
rbxassetid://3934065684
-0.5
0.5
0
0
0
0
0
0
-
WaistRigAttachment
0.00160679
-0.69307566
-0.13708577
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.001606789999641478
-0.6930756568908691
-0.13708576560020447
-
NeckRigAttachment
-0.00028551545
0.61014855
0.059081264
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.0002855154452845454
0.610148549079895
0.05908126384019852
-
LeftShoulderRigAttachment
-0.53098595
0.31034386
0.09133796
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.530985951423645
0.310343861579895
0.09133795648813248
-
RightShoulderRigAttachment
0.532176
0.31034005
0.091338284
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.5321760177612305
0.3103400468826294
0.09133828431367874
-
Waist
0.00045886415
0.42643553
-0.10108509
1
0
0
0
1
0
0
0
1
0.00160679
-0.69307566
-0.13708577
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
1.2573397159576416
1.5161899328231812
1.0650634765625
-
Head
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.368633
62.163597
40.50809
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.83642578125
1.1683197021484375
0.9020295143127441
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065587
https://assetdelivery.roblox.com/v1/asset/?id=3934065587
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.83642578125
1.1683197021484375
0.9020295143127441
rbxassetid://3934065716
-0.5
0.5
0
0
0
0
0
0
-
NeckRigAttachment
0.011352291
-0.49968445
0.012058221
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.011352291330695152
-0.4996844530105591
0.01205822080373764
-
Neck
-0.00028551545
0.61014855
0.059081264
1
0
0
0
1
0
0
0
1
0.011352291
-0.49968445
0.012058221
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.83642578125
1.1683197021484375
0.9020295143127441
-
RightHand
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-34.58733
59.531105
40.576588
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
0.24898815155029297
0.6131889820098877
0.3323974907398224
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065611
https://assetdelivery.roblox.com/v1/asset/?id=3934065611
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
0.24898815155029297
0.6131889820098877
0.3323974907398224
rbxassetid://3934065579
-0.5
0.5
0
0
0
0
0
0
-
RightWristRigAttachment
0.026803672
0.30347684
0.04975809
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.026803672313690186
0.30347684025764465
0.04975809156894684
-
RightWrist
0.119244516
-0.39689308
0.015973017
1
0
0
0
1
0
0
0
1
0.026803672
0.30347684
0.04975809
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
0.24898815155029297
0.6131889820098877
0.3323974907398224
-
LowerTorso
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-35.355846
59.934254
40.425068
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
[null]
-0.5
0.5
0
0
1.2410783767700195
0.9438430666923523
0.8493633270263672
-0.5
0.5
0
0
false
false
1312
https://assetdelivery.roblox.com/v1/asset/?id=3934065615
https://assetdelivery.roblox.com/v1/asset/?id=3934065615
+KXn2PVkmG8K5+S8Au8qxA==
0
1
-0.5
0.5
0
0
0
0
0
0
1.2410783767700195
0.9438430666923523
0.8493633270263672
rbxassetid://3934065684
-0.5
0.5
0
0
0
0
0
0
-
RootRigAttachment
-0.0020411294
0.07933888
0.038673006
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.002041129395365715
0.07933887839317322
0.03867300599813461
-
LeftHipRigAttachment
-0.28042528
-0.10188474
0.00011146953
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
-0.2804252803325653
-0.10188473761081696
0.00011146953329443932
-
RightHipRigAttachment
0.27634314
-0.101884976
0.00011147326
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.27634313702583313
-0.10188497602939606
0.00011147325858473778
-
WaistRigAttachment
0.00045886415
0.42643553
-0.10108509
1
0
0
0
1
0
0
0
1
false
-
OriginalPosition
0.00045886414591223
0.42643553018569946
-0.10108508914709091
-
Root
-0.000607906
-0.81877613
0.033983894
1
0
0
0
1
0
0
0
1
-0.0020411294
0.07933888
0.038673006
1
0
0
0
1
0
0
0
1
0
false
0
[null]
[null]
-
AvatarPartScaleType
ProportionsSlender
-
OriginalSize
1.2410783767700195
0.9438430666923523
0.8493633270263672
-
AnimationController
-
Animator
-
InitNPC
false
{2A4F0D42-6F8A-419C-A580-CA921397D3B3}
-
CharacterComponentScripts
-
CharacterHelper
1.2000000476837158
-
Configurations
-
Animate
-
cheer
-
CheerAnim
http://www.roblox.com/asset/?id=507770677
-
climb
-
ClimbAnim
http://www.roblox.com/asset/?id=507765644
-
dance
-
Animation1
http://www.roblox.com/asset/?id=507771019
-
Weight
10
-
Animation2
http://www.roblox.com/asset/?id=507771955
-
Weight
10
-
Animation3
http://www.roblox.com/asset/?id=507772104
-
Weight
10
-
dance2
-
Animation1
http://www.roblox.com/asset/?id=507776043
-
Weight
10
-
Animation2
http://www.roblox.com/asset/?id=507776720
-
Weight
10
-
Animation3
http://www.roblox.com/asset/?id=507776879
-
Weight
10
-
dance3
-
Animation1
http://www.roblox.com/asset/?id=507777268
-
Weight
10
-
Animation2
http://www.roblox.com/asset/?id=507777451
-
Weight
10
-
Animation3
http://www.roblox.com/asset/?id=507777623
-
Weight
10
-
fall
-
FallAnim
http://www.roblox.com/asset/?id=507767968
-
idle
-
Animation1
http://www.roblox.com/asset/?id=507766388
-
Weight
9
-
Animation2
http://www.roblox.com/asset/?id=507766666
-
Weight
1
-
jump
-
JumpAnim
http://www.roblox.com/asset/?id=507765000
-
laugh
-
LaughAnim
http://www.roblox.com/asset/?id=507770818
-
point
-
PointAnim
http://www.roblox.com/asset/?id=507770453
-
run
-
RunAnim
http://www.roblox.com/asset/?id=913376220
-
sit
-
SitAnim
http://www.roblox.com/asset/?id=2506281703
-
swim
-
Swim
http://www.roblox.com/asset/?id=913384386
-
swimidle
-
SwimIdle
http://www.roblox.com/asset/?id=913389285
-
toollunge
-
ToolLungeAnim
http://www.roblox.com/asset/?id=522638767
-
toolnone
-
ToolNoneAnim
http://www.roblox.com/asset/?id=507768375
-
toolslash
-
ToolSlashAnim
http://www.roblox.com/asset/?id=522635514
-
walk
-
WalkAnim
http://www.roblox.com/asset/?id=913402848
-
wave
-
WaveAnim
http://www.roblox.com/asset/?id=507770239
-
RigScale
-
BodyDepthScale
1
-
BodyHeightScale
1
-
BodyProportionScale
1
-
BodyTypeScale
1
-
BodyWidthScale
1
-
HeadScale
1
-
Health
-
CurrentHealth
100
-
HealthRegenRate
0.01
-
MaxHealth
100
-
ControlStateMachine
-
MaxSlopeAngle
60
-
StepHeight
2.9
-
WalkSpeed
16
-
RespawnTime
3
-
AutoMove
-
MoveTimeout
8
-
DistanceEpsilon
0.3
-
Equipment
-
CharacterComponentLoaderNPC
false
{89E3AFD9-CC00-48DA-B9B8-AF87552DB921}
-
ComponentInterfaceInstance
{E517C07A-A701-4F7C-91D7-6C120A3C3EB8}
-
PirateHat
0
-0.35
0
1
0
0
0
1
0
0
0
1
-
Handle
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-21.867058
55.476696
59.119255
0.33885098
-0.9408397
-0.0007934656
0.00009259278
0.0008767066
-0.9999996
0.94084007
0.33885077
0.00038418785
true
true
0
10724005
false
2
-0.5
0.5
0
0
-0.5
0.5
0
0
true
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1.930400013923645
0.772159993648529
0.9652000069618225
-0.5
0.5
0
0
0
0
0
0
-
Mesh
2
2
http://www.roblox.com/asset/?id=1028848
5
0
0
0
0.9652000069618225
0.9652000069618225
0.9652000069618225
http://www.roblox.com/asset/?id=1028847
1
1
1
-
HatAttachment
0.000000008357078
-0.2413
-0.00026277013
1
0
0
0
1
0
0
0
1
false
-
OriginalSize
2
0.800000011920929
1
-
TestingModel
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
SpawnLocation
false
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-48.243233
50.19346
68.79402
1
0
0
0
1
0
0
0
1
false
true
0
10724005
false
0
true
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
true
0
-0.5
0.5
0
0
0
0
0
0
1
8
4
8
194
-0.5
0.5
0
0
1
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-58.812996
55.327988
47.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-66.813
54.85299
63.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
20
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-66.813
54.85299
67.0843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
20
0.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-66.813
54.85299
71.0843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
20
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
54.328003
52.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.050000011920928955
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
55.327988
51.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
56.327988
50.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
57.327988
49.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
58.32798
48.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
59.32798
47.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
60.32798
46.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
61.32798
45.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-103.81285
61.852974
70.0843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
2
17
2
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-100.31285
54.102997
70.0843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-100.43211
55.10298
70.99012
0.9659258
0
-0.25881904
0
1
0
0.25881904
0
0.9659258
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-100.781784
56.10298
71.8343
0.8660254
0
-0.5
0
1
0
0.5
0
0.8660254
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-101.338
57.10298
72.55915
0.7071067
0
-0.70710677
0
1
0
0.70710677
0
0.7071067
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-102.06285
58.102974
73.115364
0.4999999
0
-0.8660253
0
1
0
0.8660253
0
0.4999999
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-102.90697
59.102974
73.46497
0.25881898
0
-0.9659257
0
1
0
0.9659257
0
0.25881898
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-103.81285
60.102974
73.584236
-0.000000029802322
0
-0.9999998
0
1
0
0.9999998
0
-0.000000029802322
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-104.71872
61.102974
73.46497
-0.258819
0
-0.96592563
0
1
0
0.96592563
0
-0.258819
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-105.562836
62.102974
73.115364
-0.49999994
0
-0.8660252
0
1
0
0.8660252
0
-0.49999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.28769
63.102974
72.55915
-0.70710665
0
-0.7071066
0
1
0
0.7071066
0
-0.70710665
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.8439
64.102974
71.8343
-0.8660252
0
-0.49999982
0
1
0
0.49999982
0
-0.8660252
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-107.19357
65.102974
70.99018
-0.9659256
0
-0.25881892
0
1
0
0.25881892
0
-0.9659256
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-107.312836
66.102974
70.0843
-0.9999997
0
0.000000059604645
0
1
0
-0.000000059604645
0
-0.9999997
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-107.19357
67.102974
69.178474
-0.9659255
0
0.258819
0
1
0
-0.258819
0
-0.9659255
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.8439
68.102974
68.3343
-0.8660251
0
0.49999988
0
1
0
-0.49999988
0
-0.8660251
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.28769
69.102974
67.60944
-0.707106
0
0.7071061
0
1
0
-0.7071061
0
-0.707106
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
1.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-97.56291
56.60298
69.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-97.64647
57.60298
71.21894
0.9659258
0
-0.25881904
0
1
0
0.25881904
0
0.9659258
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.15025
58.602974
72.77625
0.8660254
0
-0.5
0
1
0
0.5
0
0.8660254
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-99.03996
59.602974
74.150154
0.7071067
0
-0.70710677
0
1
0
0.70710677
0
0.7071067
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-100.25487
60.602974
75.246895
0.4999999
0
-0.8660253
0
1
0
0.8660253
0
0.4999999
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-101.712265
61.602974
75.99189
0.25881898
0
-0.9659257
0
1
0
0.9659257
0
0.25881898
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-103.31285
62.602974
76.334236
-0.000000029802322
0
-0.9999998
0
1
0
0.9999998
0
-0.000000029802322
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-104.94748
63.602974
76.25068
-0.258819
0
-0.96592563
0
1
0
0.96592563
0
-0.258819
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.50485
64.602974
75.746895
-0.49999994
0
-0.8660252
0
1
0
0.8660252
0
-0.49999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-107.87863
65.602974
74.85725
-0.70710665
0
-0.7071066
0
1
0
0.7071066
0
-0.70710665
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-108.975494
66.602974
73.64228
-0.8660252
0
-0.49999982
0
1
0
0.49999982
0
-0.8660252
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-109.72049
67.602974
72.18488
-0.9659256
0
-0.25881892
0
1
0
0.25881892
0
-0.9659256
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-110.062836
68.602974
70.5843
-0.9999997
0
0.000000059604645
0
1
0
-0.000000059604645
0
-0.9999997
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-109.97928
69.602974
68.94965
-0.9659255
0
0.258819
0
1
0
-0.258819
0
-0.9659255
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-109.475494
70.602974
67.39234
-0.8660251
0
0.49999988
0
1
0
-0.49999988
0
-0.8660251
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-108.585785
71.602974
66.01844
-0.707106
0
0.7071061
0
1
0
-0.7071061
0
-0.707106
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
4.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-97.56291
58.852974
69.5843
0.99729043
0.07356457
0
-0.037819743
0.5127097
-0.8577286
-0.06309843
0.85540456
0.5141027
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-97.64647
59.852974
71.21894
0.97963965
-0.15033707
-0.13305956
-0.037819743
0.5127097
-0.8577286
0.19716936
0.8452972
0.49658516
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.15025
60.852974
72.77625
0.895228
-0.3639935
-0.25705135
-0.037819743
0.5127097
-0.8577286
0.44400036
0.7775843
0.445226
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-99.03996
61.852974
74.150154
0.7498081
-0.5528442
-0.36352554
-0.037819743
0.5127097
-0.8577286
0.66057354
0.65688014
0.3635255
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-100.25487
62.852974
75.246895
0.55328995
-0.7040197
-0.44522598
-0.037819743
0.5127097
-0.8577286
0.83212954
0.491411
0.25705132
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-101.712265
63.852974
75.99189
0.3190661
-0.80721724
-0.4965851
-0.037819743
0.5127097
-0.8577286
0.9469774
0.29245284
0.13305956
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-103.31285
64.852974
76.334236
0.06309839
-0.85540444
-0.51410264
-0.037819743
0.5127097
-0.8577286
0.99729025
0.07356453
-0.000000015321454
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-104.94748
65.852974
76.25068
-0.19716935
-0.84529704
-0.49658504
-0.037819743
0.5127097
-0.8577286
0.9796395
-0.15033706
-0.13305958
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.50485
66.852974
75.746895
-0.4440003
-0.7775842
-0.44522592
-0.037819743
0.5127097
-0.8577286
0.89522785
-0.36399347
-0.25705138
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-107.87863
67.852974
74.85725
-0.6605734
-0.6568801
-0.36352545
-0.037819743
0.5127097
-0.8577286
0.74980795
-0.5528441
-0.36352548
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-108.975494
68.852974
73.64228
-0.8321294
-0.4914109
-0.2570513
-0.037819743
0.5127097
-0.8577286
0.5532899
-0.70401967
-0.44522592
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-109.72049
69.852974
72.18488
-0.94697726
-0.29245278
-0.13305952
-0.037819743
0.5127097
-0.8577286
0.31906605
-0.8072171
-0.49658504
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-110.062836
70.852974
70.5843
-0.99729013
-0.07356449
0.00000003064291
-0.037819743
0.5127097
-0.8577286
0.063098356
-0.8554043
-0.51410264
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-109.97928
71.852974
68.94965
-0.97963935
0.15033707
0.13305958
-0.037819743
0.5127097
-0.8577286
-0.19716935
-0.845297
-0.49658498
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-109.475494
72.85297
67.39234
-0.89522773
0.36399344
0.25705135
-0.037819743
0.5127097
-0.8577286
-0.44400027
-0.7775841
-0.4452259
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-108.585785
73.85297
66.01844
-0.74980736
0.55284375
0.3635252
-0.037819743
0.5127097
-0.8577286
-0.6605729
-0.65687954
-0.36352515
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
2
0.5
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.31268
55.808243
95.139725
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.75
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
55.63147
95.31654
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
0.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
55.366302
95.93526
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.81268
55.98503
95.31654
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
53.952103
96.995926
-0.00000004371139
0
-1
-0.70710677
0.70710677
0.00000003090862
0.70710677
0.70710677
-0.00000003090862
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.75
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.18768
53.68696
97.26106
-0.00000004371139
0
-1
-0.70710677
0.70710677
0.00000003090862
0.70710677
0.70710677
-0.00000003090862
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
0.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.81268
53.86373
97.43782
-0.00000004371139
0
-1
-0.70710677
0.70710677
0.00000003090862
0.70710677
0.70710677
-0.00000003090862
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
54.48243
96.81911
-0.00000004371139
0
-1
-0.70710677
0.70710677
0.00000003090862
0.70710677
0.70710677
-0.00000003090862
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
55.54309
95.40492
-0.00000004371139
0
1
0.70710677
0.70710677
0.00000003090862
-0.70710677
0.70710677
-0.00000003090862
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.75
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.43774
55.808243
95.139725
-0.00000004371139
0
1
0.70710677
0.70710677
0.00000003090862
-0.70710677
0.70710677
-0.00000003090862
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
0.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-227.81274
55.98503
95.31654
-0.00000004371139
0
1
0.70710677
0.70710677
0.00000003090862
-0.70710677
0.70710677
-0.00000003090862
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
55.366302
95.93526
-0.00000004371139
0
1
0.70710677
0.70710677
0.00000003090862
-0.70710677
0.70710677
-0.00000003090862
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.31274
53.68696
97.26106
-1
0
0.00000008742278
0.00000006181724
0.70710677
0.70710677
-0.00000006181724
0.70710677
-0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.75
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
53.86373
97.084305
-1
0
0.00000008742278
0.00000006181724
0.70710677
0.70710677
-0.00000006181724
0.70710677
-0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
0.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
54.48243
96.81911
-1
0
0.00000008742278
0.00000006181724
0.70710677
0.70710677
-0.00000006181724
0.70710677
-0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-227.81274
53.86373
97.43782
-1
0
0.00000008742278
0.00000006181724
0.70710677
0.70710677
-0.00000006181724
0.70710677
-0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
55.101135
96.55397
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
12
0.25
3.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
53.598564
97.17268
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
0.5
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
53.86373
97.43782
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
1.75
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
55.719864
95.051346
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
0.5
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
55.98503
95.31654
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
1.75
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.18774
57.752792
99.20564
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
57.929565
99.3824
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.43768
57.752792
99.20564
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
55.012756
97.70302
-1
0
-0.00000008742278
-0.00000006181724
0.70710677
0.70710677
0.00000006181724
0.70710677
-0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
55.366302
96.81911
-1
0
-0.00000008742278
-0.00000006181724
0.70710677
0.70710677
0.00000006181724
0.70710677
-0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.5
1.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
56.250183
96.46559
-1
0
-0.00000008742278
-0.00000006181724
0.70710677
0.70710677
0.00000006181724
0.70710677
-0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.56274
59.255394
98.76369
-1
0
-0.00000008742278
-0.00000006181724
0.70710677
0.70710677
0.00000006181724
0.70710677
-0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
8.75
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.43774
57.841187
99.29402
-1
0
-0.00000008742278
-0.00000006181724
0.70710677
0.70710677
0.00000006181724
0.70710677
-0.70710677
true
true
0
5917762
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
7.5
2.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.56274
57.310852
100.708206
-1
0
-0.00000008742278
-0.00000006181724
0.70710677
0.70710677
0.00000006181724
0.70710677
-0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
8.75
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
59.874107
102.56435
-1
-0.000000000000007642742
0.00000008742278
-0.00000006181724
-0.7071067
-0.7071068
0.00000006181724
-0.7071068
0.7071067
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
60.757988
102.21083
-1
-0.000000000000007642742
0.00000008742278
-0.00000006181724
-0.7071067
-0.7071068
0.00000006181724
-0.7071068
0.7071067
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
1.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.68774
61.111534
101.32692
-1
-0.000000000000007642742
0.00000008742278
-0.00000006181724
-0.7071067
-0.7071068
0.00000006181724
-0.7071068
0.7071067
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.18774
59.167
100.61983
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
59.343773
100.796585
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.43768
59.167
100.61983
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.18774
60.581215
102.03407
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.43768
60.581215
102.03407
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.68768
60.757988
102.21083
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.68768
61.81864
101.50374
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11.25
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.68768
60.05088
103.2715
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11.25
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-228.18774
56.338577
97.7914
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
56.51535
97.968155
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.43768
56.338577
97.7914
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
56.250183
96.46559
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
55.366302
96.81911
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.5
1.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
55.012756
97.70302
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.06268
57.310852
100.708206
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
8.75
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.18768
57.841187
99.29402
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
5917762
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
7.5
2.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-217.06268
59.255394
98.76369
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
8.75
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
61.111534
101.32692
1
0
0
0
-0.7071068
0.7071067
0
-0.7071067
-0.7071068
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
60.757988
102.21083
1
0
0
0
-0.7071068
0.7071067
0
-0.7071067
-0.7071068
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
1.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-216.93768
59.874107
102.56435
1
0
0
0
-0.7071068
0.7071067
0
-0.7071067
-0.7071068
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
56.161804
105.569595
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
68
16
8
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-210.81265
54.48243
98.056595
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-210.81265
55.896637
99.47078
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-210.81265
57.310852
100.885025
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-210.81265
58.72506
102.29921
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-210.81265
60.139275
103.713394
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-210.81265
61.55349
105.12764
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-210.81265
62.96769
106.541824
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-210.81265
64.381905
107.95607
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-202.81265
54.747597
97.7914
1
0
0
0
0.99999994
0
0
0
0.99999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-202.81265
56.161804
99.20564
1
0
0
0
0.99999994
0
0
0
0.99999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-202.81265
57.57602
100.61983
1
0
0
0
0.99999994
0
0
0
0.99999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-202.81265
58.990227
102.03407
1
0
0
0
0.99999994
0
0
0
0.99999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-202.81265
60.40444
103.44826
1
0
0
0
0.99999994
0
0
0
0.99999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-202.81265
61.81864
104.86244
1
0
0
0
0.99999994
0
0
0
0.99999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-202.81265
63.232857
106.27669
1
0
0
0
0.99999994
0
0
0
0.99999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-202.81265
64.64707
107.69087
1
0
0
0
0.99999994
0
0
0
0.99999994
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-194.81268
54.747597
97.7914
0.8314696
-0.55557024
0
0.39284748
0.5879378
-0.70710677
0.39284748
0.5879378
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-194.81268
56.161804
99.20564
0.8314696
-0.55557024
0
0.39284748
0.5879378
-0.70710677
0.39284748
0.5879378
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-194.81268
57.57602
100.61983
0.8314696
-0.55557024
0
0.39284748
0.5879378
-0.70710677
0.39284748
0.5879378
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-194.81268
58.990227
102.03407
0.8314696
-0.55557024
0
0.39284748
0.5879378
-0.70710677
0.39284748
0.5879378
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-194.81268
60.40444
103.44826
0.8314696
-0.55557024
0
0.39284748
0.5879378
-0.70710677
0.39284748
0.5879378
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-194.81268
61.81864
104.86244
0.8314696
-0.55557024
0
0.39284748
0.5879378
-0.70710677
0.39284748
0.5879378
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-194.81268
63.232857
106.27669
0.8314696
-0.55557024
0
0.39284748
0.5879378
-0.70710677
0.39284748
0.5879378
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-194.81268
64.64707
107.69087
0.8314696
-0.55557024
0
0.39284748
0.5879378
-0.70710677
0.39284748
0.5879378
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-186.81271
54.040497
97.084305
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-186.81271
55.277924
98.32173
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-186.81271
56.69214
99.73598
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-186.81271
58.10633
101.15016
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-186.81271
59.520546
102.56435
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-186.81271
60.93476
103.97859
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-186.81271
62.348976
105.39278
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-186.81271
63.76319
106.80702
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-178.81274
54.570824
97.61464
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-178.81274
55.98503
99.028824
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-178.81274
57.399246
100.44307
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-178.81274
58.81344
101.857254
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-178.81274
60.227654
103.2715
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-178.81274
61.64187
104.685684
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-178.81274
63.056084
106.09993
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-178.81274
64.4703
107.514114
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-170.81274
54.747597
97.7914
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-170.81274
56.161804
99.20564
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-170.81274
57.57602
100.61983
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-170.81274
58.990227
102.03407
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-170.81274
60.40444
103.44826
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-170.81274
61.81864
104.86244
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-170.81274
63.232857
106.27669
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-170.81274
64.64707
107.69087
1
0
0
0
0.70710677
-0.70710677
0
0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Truss
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-103.81285
27.35302
56.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
2
52
2
-0.5
0.5
0
0
0
0
0
0
0
-
Truss
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-105.812836
27.35302
56.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
2
52
2
-0.5
0.5
0
0
0
0
0
0
0
-
Truss
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-107.812836
27.35302
56.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
2
52
2
-0.5
0.5
0
0
0
0
0
0
0
-
Truss
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-101.81285
27.35302
56.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
2
52
2
-0.5
0.5
0
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.31274
53.728004
93.959305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.75
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
53.728004
94.209305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
0.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
53.977997
94.834305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.81274
53.977997
93.959305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
53.728004
96.584305
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.75
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.18774
53.728004
96.959305
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
0.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.81274
53.977997
96.959305
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
53.977997
96.084305
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
53.728004
94.334305
-0.00000004371139
0
1
0
1
0
-1
0
-0.00000004371139
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.75
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.43777
53.728004
93.959305
-0.00000004371139
0
1
0
1
0
-1
0
-0.00000004371139
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
0.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-155.81277
53.977997
93.959305
-0.00000004371139
0
1
0
1
0
-1
0
-0.00000004371139
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
53.977997
94.834305
-0.00000004371139
0
1
0
1
0
-1
0
-0.00000004371139
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.31277
53.728004
96.959305
-1
0
0.00000008742278
0
1
0
-0.00000008742278
0
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.75
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
53.728004
96.709305
-1
0
0.00000008742278
0
1
0
-0.00000008742278
0
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
0.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
53.977997
96.084305
-1
0
0.00000008742278
0
1
0
-0.00000008742278
0
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-155.81277
53.977997
96.959305
-1
0
0.00000008742278
0
1
0
-0.00000008742278
0
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.81274
54.227997
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
12
0.25
3.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.81274
53.603004
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
0.5
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.81274
53.977997
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
1.75
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.81274
53.603004
93.959305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.75
0.5
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.81274
53.977997
93.959305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
1.75
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.18777
57.97798
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.81274
58.227974
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.43774
57.97798
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
54.97798
96.334305
-1
0
-0.00000008742278
0
1
0
0.00000008742278
0
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
54.60299
95.459305
-1
0
-0.00000008742278
0
1
0
0.00000008742278
0
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.5
1.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
54.97798
94.584305
-1
0
-0.00000008742278
0
1
0
0.00000008742278
0
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.56277
58.727974
94.084305
-1
0
-0.00000008742278
0
1
0
0.00000008742278
0
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
8.75
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.43777
58.102974
95.459305
-1
0
-0.00000008742278
0
1
0
0.00000008742278
0
-1
true
true
0
5917762
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
7.5
2.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.56277
58.727974
96.834305
-1
0
-0.00000008742278
0
1
0
0.00000008742278
0
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
8.75
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
61.852974
96.334305
-1
-0.000000000000007642742
0.00000008742278
0
-1
-0.00000008742278
0.00000008742278
-0.00000008742278
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
62.227974
95.459305
-1
-0.000000000000007642742
0.00000008742278
0
-1
-0.00000008742278
0.00000008742278
-0.00000008742278
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
1.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.68777
61.852974
94.584305
-1
-0.000000000000007642742
0.00000008742278
0
-1
-0.00000008742278
0.00000008742278
-0.00000008742278
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.18777
59.977974
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.81274
60.227974
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.43774
59.977974
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.18777
61.977974
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.43774
61.977974
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.68774
62.227974
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.68774
62.477974
94.209305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11.25
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.68774
62.477974
96.709305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11.25
0.25
0.25
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-156.18777
55.97798
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-150.81274
56.22798
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
11
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.43774
55.97798
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.25
2.75
-0.5
0.5
0
0
0
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
54.97798
94.584305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
54.60299
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.5
1.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
54.97798
96.334305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.25
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.06274
58.727974
96.834305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
8.75
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.18774
58.102974
95.459305
1
0
0
0
1
0
0
0
1
true
true
0
5917762
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
7.5
2.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.06274
58.727974
94.084305
1
0
0
0
1
0
0
0
1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
8.75
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
61.852974
94.584305
1
0
0
0
-1
-0.00000008742278
0
0.00000008742278
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
62.227974
95.459305
1
0
0
0
-1
-0.00000008742278
0
0.00000008742278
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
0.75
1.25
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-144.93774
61.852974
96.334305
1
0
0
0
-1
-0.00000008742278
0
0.00000008742278
-1
true
true
0
7100491
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
512
0
-0.5
0.5
0
0
0
0
0
0
1
0.25
1.5
0.5
-0.5
0.5
0
0
0
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-126.81282
61.352974
101.084305
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
68
16
8
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-138.81274
54.85299
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-138.81274
56.85298
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-138.81274
58.852974
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-138.81274
60.852974
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-138.81274
62.852974
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-138.81274
64.852974
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-138.81274
66.852974
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-138.81274
68.852974
96.959305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
0.25
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-130.81282
54.85299
96.584305
1
0
0
0
0.70710677
0.70710677
0
-0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-130.81282
56.85298
96.584305
1
0
0
0
0.70710677
0.70710677
0
-0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-130.81282
58.852974
96.584305
1
0
0
0
0.70710677
0.70710677
0
-0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-130.81282
60.852974
96.584305
1
0
0
0
0.70710677
0.70710677
0
-0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-130.81282
62.852974
96.584305
1
0
0
0
0.70710677
0.70710677
0
-0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-130.81282
64.852974
96.584305
1
0
0
0
0.70710677
0.70710677
0
-0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-130.81282
66.852974
96.584305
1
0
0
0
0.70710677
0.70710677
0
-0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-130.81282
68.852974
96.584305
1
0
0
0
0.70710677
0.70710677
0
-0.70710677
0.70710677
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-122.812836
54.85299
96.584305
0.8314696
-0.55557024
0
0.55557024
0.8314696
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-122.812836
56.85298
96.584305
0.8314696
-0.55557024
0
0.55557024
0.8314696
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-122.812836
58.852974
96.584305
0.8314696
-0.55557024
0
0.55557024
0.8314696
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-122.812836
60.852974
96.584305
0.8314696
-0.55557024
0
0.55557024
0.8314696
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-122.812836
62.852974
96.584305
0.8314696
-0.55557024
0
0.55557024
0.8314696
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-122.812836
64.852974
96.584305
0.8314696
-0.55557024
0
0.55557024
0.8314696
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-122.812836
66.852974
96.584305
0.8314696
-0.55557024
0
0.55557024
0.8314696
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-122.812836
68.852974
96.584305
0.8314696
-0.55557024
0
0.55557024
0.8314696
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-114.812805
53.853004
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-114.812805
55.60298
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-114.812805
57.60298
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-114.812805
59.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-114.812805
61.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-114.812805
63.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-114.812805
65.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-114.812805
67.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.812836
54.60299
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.812836
56.60298
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.812836
58.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.812836
60.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.812836
62.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.812836
64.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.812836
66.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-106.812836
68.602974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.81291
54.85299
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.81291
56.85298
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.81291
58.852974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.81291
60.852974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.81291
62.852974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.81291
64.852974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.81291
66.852974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-98.81291
68.852974
96.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-81.31291
55.35298
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
4
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-84.31291
55.35298
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
4
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-82.8129
57.85298
55.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-84.31291
55.35298
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
4
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-81.31291
55.35298
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
4
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-50.81298
54.328003
47.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.050000011920928955
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-57.312996
53.853004
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-60.312996
53.853004
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-58.812996
54.85299
55.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-60.312996
53.853004
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-57.312996
53.853004
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-42.812923
53.82801
47.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.050000011920928955
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.603004
52.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.853004
51.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
54.102997
50.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
54.352997
49.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
54.60299
48.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
54.85299
47.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
3
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
55.10298
46.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
3.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
55.35298
45.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
4
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
53.82801
52.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.050000011920928955
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.328003
51.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.827995
50.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
55.327988
49.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
55.827988
48.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
56.327988
47.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
56.827988
46.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
57.327988
45.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-206.81265
54.102997
52.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-206.81265
54.85299
51.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
3
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-206.81265
55.60298
50.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
4.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-206.81265
56.35298
49.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
6
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-206.81265
57.10298
48.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
7.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-206.81265
57.85298
47.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
9
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-206.81265
58.602974
46.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
10.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-206.81265
59.352974
45.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
12
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-112.81282
25.353022
45.08429
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
8
56
24
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-124.812836
17.35301
49.08429
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
16
40
16
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
57.35298
61.084305
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
8
8
8
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-124.812836
25.353022
37.08429
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
16
56
8
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-100.81285
25.353022
81.084305
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
16
56
48
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-100.81285
25.353022
37.08429
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
16
56
8
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-122.812836
55.35298
61.084305
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
4
8
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-112.81282
-0.6469834
49.08429
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
40
4
16
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
25.353022
69.0843
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
132
56
72
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-52.813
25.353
69.084
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
80
56
72
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-120.812775
25.353022
81.084305
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
24
56
48
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
53.478004
76.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.25
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
53.478004
74.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.25
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
53.478004
72.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.25
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
53.478004
68.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.25
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
53.478004
70.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.25
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
53.478004
66.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.25
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
53.478004
64.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.25
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
53.478004
62.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.25
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
53.603004
76.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
53.603004
74.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
53.603004
72.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
53.603004
68.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
53.603004
70.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
53.603004
66.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
53.603004
64.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-182.81274
53.603004
62.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-66.813
56.327988
47.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.853004
76.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.853004
74.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.853004
72.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.853004
68.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.853004
70.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.853004
66.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.853004
64.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-174.81274
53.853004
62.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part1
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
54.85299
51.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
20
-0.5
0.5
0
0
0
0
0
0
-
Attachment
0
0
0
-0.00000004371139
-1
0
1
-0.00000004371139
0
0
0
1
false
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
WeldConstraint
703
-140.50002
271
1
0
0
0
1
0
0
0
1
703
-143.00002
279
1
0
0
0
1
0
0
0
1
true
[null]
[null]
-
WeldConstraint
703
-140.50002
271
1
0
0
0
1
0
0
0
1
703
-143.00002
263
1
0
0
0
1
0
0
0
1
true
[null]
[null]
-
Part0
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
53.853004
51.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
2
1
2
-0.5
0.5
0
0
0
0
0
0
-
Attachment
0
1
0
-0.00000004371139
-1
0
1
-0.00000004371139
0
0
0
1
false
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
AlignPosition
false
[null]
[null]
194
true
10000
999999
false
10
false
false
-
HingeConstraint
1
0
6
[null]
[null]
1009
true
false
-45
999999
999999
0.15000000596046448
0
0
0
45
true
-
Part1
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
57.35299
59.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
4
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part1
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
57.35299
43.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
4
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-82.8129
58.32798
47.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
38.85302
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
40.85302
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
42.85302
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
44.853012
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
46.853004
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
48.853012
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
50.853004
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
52.853004
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
54.85299
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
56.85298
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
58.852974
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-128.81282
60.852974
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
272
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
53.853004
52.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
54.352997
51.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
54.85299
50.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
3
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
55.35298
49.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
4
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
55.85298
48.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
56.35298
47.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
6
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
56.85298
46.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
7
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-190.81271
57.35298
45.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
8
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.352997
76.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.352997
74.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.352997
72.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.352997
68.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.352997
70.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.352997
66.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.352997
64.5843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-166.81274
54.352997
62.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part1
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
54.85299
75.0843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
20
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Attachment
0
0
0
-0.00000004371139
-1
0
1
-0.00000004371139
0
0
0
1
false
-
WeldConstraint
703
-140.50002
271
1
0
0
0
1
0
0
0
1
703
-143.00002
279
1
0
0
0
1
0
0
0
1
true
[null]
[null]
-
WeldConstraint
703
-140.50002
271
1
0
0
0
1
0
0
0
1
703
-143.00002
263
1
0
0
0
1
0
0
0
1
true
[null]
[null]
-
Part0
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
53.853004
75.0843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
2
1
2
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Attachment
0
1
0
-0.00000004371139
-1
0
1
-0.00000004371139
0
0
0
1
false
-
HingeConstraint
1
0
1
[null]
[null]
1009
true
false
-45
999999
999999
0.15000000596046448
0
0
0
45
true
-
AlignPosition
false
[null]
[null]
194
true
10000
999999
false
10
false
false
-
Part1
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
57.35299
83.0843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
4
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part1
false
-0.5
0.5
0
0
-0.5
0.5
0
0
-222.81268
57.35299
67.0843
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
4
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-82.8129
55.85298
39.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
5
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-66.813
54.85299
39.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
3
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-42.812923
53.603004
39.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-149.5188
55.316162
73.23414
-0.00000004371139
0.19509035
-0.98078525
0
0.98078525
0.19509035
1
0.00000000852767
-0.000000042871484
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
16
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-142.1629
53.853004
73.23414
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
false
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
0.5
-0.5
0.5
0
0
1
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-149.09198
56.723114
67.23414
-0.00000004371139
0.38268346
-0.9238795
0
0.9238795
0.38268346
1
0.000000016727626
-0.000000040384055
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
16
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-142.1629
53.853004
67.23414
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
false
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
0.5
-0.5
0.5
0
0
1
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-148.39893
58.01976
61.234146
-0.00000004371139
0.55557024
-0.83146954
0
0.83146954
0.55557024
1
0.000000024284747
-0.000000036344687
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
16
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-142.1629
53.853004
61.234146
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
false
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
0.5
-0.5
0.5
0
0
1
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-147.46619
59.156273
55.234146
-0.00000004371139
0.7071068
-0.7071067
0
0.7071067
0.7071068
1
0.00000003090862
-0.000000030908616
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
16
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-142.1629
53.853004
55.234146
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
false
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
0.5
-0.5
0.5
0
0
1
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-146.32965
60.088997
49.23413
-0.00000004371139
0.83146966
-0.5555701
0
0.5555701
0.83146966
1
0.000000036344694
-0.000000024284741
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
16
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-142.1629
53.853004
49.23413
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
false
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
0.5
-0.5
0.5
0
0
1
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-145.03302
60.782066
43.23413
-0.00000004371139
0.9238795
-0.3826834
0
0.3826834
0.9238795
1
0.000000040384055
-0.000000016727622
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
16
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-142.1629
53.853004
43.23413
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
false
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
0.5
-0.5
0.5
0
0
1
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-143.62604
61.208855
37.23413
-0.00000004371139
0.98078525
-0.1950903
0
0.1950903
0.98078525
1
0.000000042871484
-0.0000000085276675
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
16
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-142.1629
53.853004
37.23413
-0.00000004371139
0
-1
0
1
0
1
0
-0.00000004371139
false
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
6
0.5
0.5
-0.5
0.5
0
0
1
0
0
0
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-58.812996
54.352997
39.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
2
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-85.84398
56.60298
91.084305
0.49999997
-0.86602545
0
0.86602545
0.49999997
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
8
20
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-79.781906
56.60298
91.084305
0.49999997
0.86602545
0
-0.86602545
0.49999997
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
8
20
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-82.8129
54.85299
91.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.5
18
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-74.81297
55.35298
39.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
4
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-71.28783
57.32785
91.084305
0.70710677
-0.70710677
0
0.70710677
0.70710677
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
8
20
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-66.33815
57.32785
91.084305
0.70710677
0.70710677
0
-0.70710677
0.70710677
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
8
20
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-68.81294
54.85299
91.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.5
18
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-50.81298
53.853004
39.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-55.062992
57.884064
91.084305
0.8660254
0.5
0
-0.5
0.8660254
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
8
20
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-58.562992
57.884064
91.084305
0.8660254
-0.5
0
0.5
0.8660254
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
8
20
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-56.812996
54.85299
91.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.5
18
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-73.31297
54.85299
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
3
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-76.31299
54.85299
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
3
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-74.81297
56.85298
55.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-76.31299
54.85299
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
3
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-73.31297
54.85299
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
3
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-47.718864
58.23371
91.084305
0.9659258
-0.25881904
0
0.25881904
0.9659258
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
8
20
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-45.907097
58.23371
91.084305
0.9659258
0.25881904
0
-0.25881904
0.9659258
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
8
20
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-46.81298
54.85299
91.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
0.5
0.5
18
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-49.31298
53.603004
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-52.312996
53.603004
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-50.81298
54.102997
55.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.5
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-52.312996
53.603004
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-49.31298
53.603004
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
0.5
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-74.81297
57.327988
47.08429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-65.313
54.352997
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-68.31294
54.352997
56.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-66.813
55.85298
55.084305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
4
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-68.31294
54.352997
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-65.313
54.352997
53.584305
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
1
2
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Model
0
0
0
1
0
0
0
1
0
0
0
1
[null]
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
54.827995
52.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
56.327988
51.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000000074505806
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
57.827988
50.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
59.32798
49.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
60.82798
48.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
62.32798
47.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
63.82798
46.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-198.81268
65.32798
45.58429
1
0
0
0
1
0
0
0
1
true
true
0
16736355
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
0.05000019073486328
1
-0.5
0.5
0
0
0
0
0
0
-
Texture
0
0
0
1
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
2
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
4
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
5
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
3
8
8
rbxassetid://1369654266
0.75
-
Texture
0
0
0
0
8
8
rbxassetid://1369654266
0.75
-
Seat
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-30.789986
53.85301
87.06995
1
0
0
0
1
0
0
0
1
true
true
0
7070173
false
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
4
-0.5
0.5
0
0
0
0
0
0
-
VehicleSeat
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-30.919998
53.85301
75.1
1
0
0
0
1
0
0
0
1
true
true
0
12407783
false
false
-0.5
0.5
0
0
true
-0.5
0.5
0
0
false
false
256
25
0
-0.5
0.5
0
0
0
0
0
0
4
1
4
0
0
0
0
-0.5
0.5
0
0
10
0
1
0
0
0
-
Part
true
-0.5
0.5
0
0
-0.5
0.5
0
0
-18.813004
53.853
99.084
1
0
0
0
1
0
0
0
1
true
true
0
65280
false
1
-0.5
0.5
0
0
-0.5
0.5
0
0
false
false
256
0
-0.5
0.5
0
0
0
0
0
0
1
4
1
4
-0.5
0.5
0
0
0
0
0
0
-
Script
false
{59116F58-BA02-42E9-8807-5A09F6ECB889}
local Brick = script.Parent
local function PlayerTouched(Part)
local Parent = Part.Parent
if game.Players:GetPlayerFromCharacter(Parent) then
Parent.CharacterComponentScripts.Configurations.Health.CurrentHealth.Value = 0
end
end
Brick.Touched:connect(PlayerTouched)
-
TestingTerrain
true
-0.5
0.5
0
0
-0.5
0.5
4
0
0
0
0
1
0
0
0
1
0
0
0
1
true
true
0
10724005
false
-0.5
0.5
0
0
-0.5
0.5
0
0
true
false
256
0
-0.5
0.5
0
0
0
0
0
0
2044
252
2044
-0.5
0.5
3
0
0
0
0
0
0.0470588244497776
0.3294117748737335
0.3607843220233917
1
0.30000001192092896
0.15000000596046448
10
Q1NHUEhTAAAAAEJMT0NL