This commit is contained in:
lx
2026-07-06 13:39:13 -04:00
commit 34bf440a8c
2694 changed files with 77580 additions and 0 deletions
+502
View File
@@ -0,0 +1,502 @@
--BackpackScript3D: VR port of backpack interface using a 3D panel
--written by 0xBAADF00D
local ICON_SIZE = 48
local ICON_SPACING = 52
local PIXELS_PER_STUD = 64
local SLOT_BORDER_SIZE = 0
local SLOT_BORDER_SELECTED_SIZE = 4
local SLOT_BORDER_COLOR = Color3.new(90/255, 142/255, 233/255)
local SLOT_BACKGROUND_COLOR = Color3.new(0.2, 0.2, 0.2)
local SLOT_HOVER_BACKGROUND_COLOR = Color3.new(90/255, 90/255, 90/255)
local HOPPERBIN_ANGLE = math.rad(-45)
local HOPPERBIN_ROTATION = CFrame.Angles(HOPPERBIN_ANGLE, 0, 0)
local HOPPERBIN_OFFSET = Vector3.new(0, 0, -5)
local HEALTHBAR_SPACE = 12
local HEALTHBAR_WIDTH = 82
local HEALTHBAR_HEIGHT = 5
local NAME_SPACE = 14
local Tools = {}
local ToolsList = {}
local slotIcons = {}
local BackpackScript = {}
local topbarEnabled = false
local player = game.Players.LocalPlayer
local currentHumanoid = nil
local CoreGui = game:GetService('CoreGui')
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
local Panel3D = require(RobloxGui.Modules.VR.Panel3D)
local Util = require(RobloxGui.Modules.Settings.Utility)
local ContextActionService = game:GetService("ContextActionService")
local BackpackPanel = Panel3D.Get("Backpack")
BackpackPanel:ResizeStuds(5, 2)
BackpackPanel:SetType(Panel3D.Type.Fixed, { CFrame = CFrame.new(0, 0, -5) })
BackpackPanel:SetVisible(true)
local toolsFrame = Instance.new("TextButton", BackpackPanel:GetGUI()) --prevent clicks falling through in case you have a rocket launcher and blow yourself up
toolsFrame.Text = ""
toolsFrame.Size = UDim2.new(1, 0, 0, ICON_SIZE)
toolsFrame.BackgroundTransparency = 1
toolsFrame.Selectable = false
local insetAdjustY = toolsFrame.AbsolutePosition.Y
toolsFrame.Position = UDim2.new(0, 0, 0, HEALTHBAR_SPACE + NAME_SPACE)
--Healthbar color function stolen from Topbar.lua
local HEALTH_BACKGROUND_COLOR = Color3.new(228/255, 236/255, 246/255)
local HEALTH_RED_COLOR = Color3.new(255/255, 28/255, 0/255)
local HEALTH_YELLOW_COLOR = Color3.new(250/255, 235/255, 0)
local HEALTH_GREEN_COLOR = Color3.new(27/255, 252/255, 107/255)
local healthbarBack = Instance.new("ImageLabel", BackpackPanel:GetGUI())
healthbarBack.ImageColor3 = HEALTH_BACKGROUND_COLOR
healthbarBack.BackgroundTransparency = 1
healthbarBack.ScaleType = Enum.ScaleType.Slice
healthbarBack.SliceCenter = Rect.new(10, 10, 10, 10)
healthbarBack.Name = "HealthbarContainer"
healthbarBack.Image = "rbxasset://textures/ui/Menu/rectBackgroundWhite.png"
local healthbarFront = Instance.new("ImageLabel", healthbarBack)
healthbarFront.ImageColor3 = HEALTH_GREEN_COLOR
healthbarFront.BackgroundTransparency = 1
healthbarFront.ScaleType = Enum.ScaleType.Slice
healthbarFront.SliceCenter = Rect.new(10, 10, 10, 10)
healthbarFront.Size = UDim2.new(1, 0, 1, 0)
healthbarFront.Position = UDim2.new(0, 0, 0, 0)
healthbarFront.Name = "HealthbarFill"
healthbarFront.Image = "rbxasset://textures/ui/Menu/rectBackgroundWhite.png"
local playerName = Instance.new("TextLabel", BackpackPanel:GetGUI())
playerName.Name = "PlayerName"
playerName.BackgroundTransparency = 1
playerName.TextColor3 = Color3.new(1, 1, 1)
playerName.Text = player.Name
playerName.Font = Enum.Font.SourceSansBold
playerName.FontSize = Enum.FontSize.Size12
playerName.TextXAlignment = Enum.TextXAlignment.Left
playerName.Size = UDim2.new(1, 0, 0, NAME_SPACE)
local healthColorToPosition = {
[Vector3.new(HEALTH_RED_COLOR.r, HEALTH_RED_COLOR.g, HEALTH_RED_COLOR.b)] = 0.1;
[Vector3.new(HEALTH_YELLOW_COLOR.r, HEALTH_YELLOW_COLOR.g, HEALTH_YELLOW_COLOR.b)] = 0.5;
[Vector3.new(HEALTH_GREEN_COLOR.r, HEALTH_GREEN_COLOR.g, HEALTH_GREEN_COLOR.b)] = 0.8;
}
local min = 0.1
local minColor = HEALTH_RED_COLOR
local max = 0.8
local maxColor = HEALTH_GREEN_COLOR
local function HealthbarColorTransferFunction(healthPercent)
if healthPercent < min then
return minColor
elseif healthPercent > max then
return maxColor
end
-- Shepard's Interpolation
local numeratorSum = Vector3.new(0,0,0)
local denominatorSum = 0
for colorSampleValue, samplePoint in pairs(healthColorToPosition) do
local distance = healthPercent - samplePoint
if distance == 0 then
-- If we are exactly on an existing sample value then we don't need to interpolate
return Color3.new(colorSampleValue.x, colorSampleValue.y, colorSampleValue.z)
else
local wi = 1 / (distance*distance)
numeratorSum = numeratorSum + wi * colorSampleValue
denominatorSum = denominatorSum + wi
end
end
local result = numeratorSum / denominatorSum
return Color3.new(result.x, result.y, result.z)
end
---
local backpackEnabled = true
local healthbarEnabled = true
local function UpdateLayout()
local width, height = 100, 100
local borderSize = (ICON_SPACING - ICON_SIZE) / 2
local x = borderSize
local y = 0
for _, tool in ipairs(ToolsList) do
local slot = Tools[tool]
if slot then
slot.icon.Position = UDim2.new(0, x, 0, y)
x = x + ICON_SPACING
end
end
if #ToolsList == 0 then
width = HEALTHBAR_WIDTH
height = HEALTHBAR_SPACE + NAME_SPACE
BackpackPanel.showCursor = false
else
width = #ToolsList * ICON_SPACING
height = ICON_SIZE + HEALTHBAR_SPACE + NAME_SPACE
BackpackPanel.showCursor = true
end
BackpackPanel:ResizePixels(width, height)
playerName.Position = UDim2.new(0, borderSize, 0, 0)
healthbarBack.Position = UDim2.new(0, borderSize, 0, NAME_SPACE + (HEALTHBAR_SPACE - HEALTHBAR_HEIGHT) / 2)
healthbarBack.Size = UDim2.new(0, HEALTHBAR_WIDTH, 0, HEALTHBAR_HEIGHT)
end
local function UpdateHealth(humanoid)
local percentHealth = humanoid.Health / humanoid.MaxHealth
if percentHealth ~= percentHealth then
percentHealth = 1
end
healthbarFront.BackgroundColor3 = HealthbarColorTransferFunction(percentHealth)
healthbarFront.Size = UDim2.new(percentHealth, 0, 1, 0)
end
local function SetTransparency(transparency)
for i, v in pairs(Tools) do
v.bg.ImageTransparency = transparency
v.image.ImageTransparency = transparency
v.text.TextTransparency = transparency
end
healthbarBack.ImageTransparency = transparency
healthbarFront.ImageTransparency = transparency
end
local function OnHotbarEquipPrimary(actionName, state, obj)
if state ~= Enum.UserInputState.Begin then
return
end
for tool, slot in pairs(Tools) do
if slot.hovered then
slot.OnClick()
return
end
end
end
local function EnableHotbarInput(enable)
if not backpackEnabled then
enable = false
end
if not currentHumanoid then
return
end
if enable then
ContextActionService:BindCoreAction("HotbarEquipPrimary", OnHotbarEquipPrimary, false, Enum.KeyCode.ButtonA, Enum.KeyCode.ButtonR2, Enum.UserInputType.MouseButton1)
else
ContextActionService:UnbindCoreAction("HotbarEquipPrimary")
end
end
local function AddTool(tool)
if Tools[tool] then
return
end
local slot = {}
Tools[tool] = slot
table.insert(ToolsList, tool)
slot.hovered = false
slot.tool = tool
slot.icon = Instance.new("TextButton", toolsFrame)
slot.icon.Text = ""
slot.icon.Size = UDim2.new(0, ICON_SIZE, 0, ICON_SIZE)
slot.icon.BackgroundColor3 = Color3.new(0, 0, 0)
slot.icon.Selectable = true
slot.icon.BackgroundTransparency = 1
slotIcons[tool] = slot.icon
slot.bg = Instance.new("ImageLabel", slot.icon)
slot.bg.Position = UDim2.new(0, -1, 0, -1)
slot.bg.Size = UDim2.new(1, 2, 1, 2)
slot.bg.Image = "rbxasset://textures/ui/Menu/rectBackground.png"
slot.bg.ScaleType = Enum.ScaleType.Slice
slot.bg.SliceCenter = Rect.new(10, 10, 10, 10)
slot.bg.BackgroundTransparency = 1
slot.image = Instance.new("ImageLabel", slot.icon)
slot.image.Position = UDim2.new(0, 1, 0, 1)
slot.image.Size = UDim2.new(1, -2, 1, -2)
slot.image.BackgroundTransparency = 1
slot.image.Selectable = false
slot.text = Instance.new("TextLabel", slot.icon)
slot.text.Position = UDim2.new(0, 1, 0, 1)
slot.text.Size = UDim2.new(1, -2, 1, -2)
slot.text.BackgroundTransparency = 1
slot.text.TextColor3 = Color3.new(1, 1, 1)
slot.text.Font = Enum.Font.SourceSans
slot.text.FontSize = Enum.FontSize.Size12
slot.text.ClipsDescendants = true
slot.text.Selectable = false
local selectionObject = Util:Create'ImageLabel'
{
Name = 'SelectionObject';
Size = UDim2.new(1,0,1,0);
BackgroundTransparency = 1;
Image = "rbxasset://textures/ui/Keyboard/key_selection_9slice.png";
ImageTransparency = 0;
ScaleType = Enum.ScaleType.Slice;
SliceCenter = Rect.new(12,12,52,52);
BorderSizePixel = 0;
}
slot.icon.SelectionImageObject = selectionObject
local function updateToolData()
slot.image.Image = tool.TextureId
slot.text.Text = tool.TextureId == "" and tool.Name or ""
end
updateToolData()
slot.OnClick = function()
if not player.Character then return end
local humanoid = player.Character:FindFirstChild("Humanoid")
if not humanoid then return end
local in_backpack = tool.Parent == player.Backpack
humanoid:UnequipTools()
if in_backpack then
humanoid:EquipTool(tool)
end
end
slot.icon.MouseButton1Click:connect(slot.OnClick)
slot.OnEnter = function()
slot.hovered = true
end
slot.OnLeave = function()
slot.hovered = false
end
-- slot.icon.MouseEnter:connect(slot.OnEnter)
-- slot.icon.MouseLeave:connect(slot.OnLeave)
tool.Changed:connect(function(prop)
if prop == "Parent" then
if tool.Parent == player:FindFirstChild("Backpack") then
slot.bg.Size = UDim2.new(0, ICON_SIZE, 0, ICON_SIZE) --temporary hold-over until new backpack design comes along (can't use border with this antialiased frame stand-in)
slot.bg.Position = UDim2.new(0, 0, 0, 0)
elseif tool.Parent == player.Character then
slot.bg.Size = UDim2.new(0, ICON_SIZE + 8, 0, ICON_SIZE + 8)
slot.bg.Position = UDim2.new(0, -4, 0, -4)
end
elseif prop == "TextureId" or prop == "Name" then
updateToolData()
end
end)
UpdateLayout()
end
local humanoidChangedEvent = nil
local humanoidAncestryChangedEvent = nil
local function RegisterHumanoid(humanoid)
currentHumanoid = humanoid
if humanoidChangedEvent then
humanoidChangedEvent:disconnect()
humanoidChangedEvent = nil
end
if humanoidAncestryChangedEvent then
humanoidAncestryChangedEvent:disconnect()
humanoidAncestryChangedEvent = nil
end
if humanoid then
humanoidChangedEvent = humanoid.HealthChanged:connect(function() UpdateHealth(humanoid) end)
humanoidAncestryChangedEvent = humanoid.AncestryChanged:connect(function(child, parent)
if child == humanoid and parent ~= player.Character then
RegisterHumanoid(nil)
end
end)
UpdateHealth(humanoid)
end
end
local function OnChildAdded(child)
if child:IsA("Tool") or child:IsA("HopperBin") then
AddTool(child)
end
if child:IsA("Humanoid") and child.Parent == player.Character then
RegisterHumanoid(child)
end
end
local function RemoveTool(tool)
if not Tools[tool] then
return
end
Tools[tool].icon:Destroy()
for i, v in ipairs(ToolsList) do
if v == tool then
table.remove(ToolsList, i)
break
end
end
Tools[tool] = nil
slotIcons[tool] = nil
UpdateLayout()
end
local function OnChildRemoved(child)
if child:IsA("Tool") or child:IsA("HopperBin") then
if Tools[child] then
if child.Parent ~= player:FindFirstChild("Backpack") and child.Parent ~= player.Character then
RemoveTool(child)
end
end
end
end
local function OnCharacterAdded(character)
local backpack = player:WaitForChild("Backpack")
for i, v in ipairs(character:GetChildren()) do
if v:IsA("Humanoid") then
RegisterHumanoid(v)
break
end
end
for tool, v in pairs(Tools) do
RemoveTool(tool)
end
Tools = {}
ToolsList = {}
character.ChildAdded:connect(OnChildAdded)
character.ChildRemoved:connect(OnChildRemoved)
for i, v in ipairs(backpack:GetChildren()) do
OnChildAdded(v)
end
backpack.ChildAdded:connect(OnChildAdded)
backpack.ChildRemoved:connect(OnChildRemoved)
end
player.CharacterAdded:connect(OnCharacterAdded)
if player.Character then
spawn(function() OnCharacterAdded(player.Character) end)
end
local function OnHotbarEquip(actionName, state, obj)
if not backpackEnabled then
return
end
local character = player.Character
if not character then
return
end
if not currentHumanoid then
return
end
if state ~= Enum.UserInputState.Begin then
return
end
if #ToolsList == 0 then
return
end
local current = 0
for i, v in pairs(ToolsList) do
if v.Parent == character then
current = i
end
end
currentHumanoid:UnequipTools()
if obj.KeyCode == Enum.KeyCode.ButtonR1 then
current = current + 1
if current > #ToolsList then
current = 1
end
else
current = current - 1
if current < 1 then
current = #ToolsList
end
end
currentHumanoid:EquipTool(ToolsList[current])
end
local function OnCoreGuiChanged(coreGuiType, enabled)
-- Check for enabling/disabling the whole thing
if coreGuiType == Enum.CoreGuiType.Backpack or coreGuiType == Enum.CoreGuiType.All then
backpackEnabled = enabled
UpdateLayout()
if enabled then
ContextActionService:BindCoreAction("HotbarEquip2", OnHotbarEquip, false, Enum.KeyCode.ButtonL1, Enum.KeyCode.ButtonR1)
toolsFrame.Parent = BackpackPanel:GetGUI()
else
ContextActionService:UnbindCoreAction("HotbarEquip2")
toolsFrame.Parent = nil
end
end
if coreGuiType == Enum.CoreGuiType.Health or coreGuiType == Enum.CoreGuiType.All then
healthbarEnabled = enabled
UpdateLayout()
if enabled then
healthbarBack.Parent = BackpackPanel:GetGUI()
else
healthbarBack.Parent = nil
end
end
end
local StarterGui = game:GetService("StarterGui")
StarterGui.CoreGuiChangedSignal:connect(OnCoreGuiChanged)
OnCoreGuiChanged(Enum.CoreGuiType.Backpack, StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.Backpack))
OnCoreGuiChanged(Enum.CoreGuiType.Backpack, StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.All))
OnCoreGuiChanged(Enum.CoreGuiType.Health, StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.Health))
OnCoreGuiChanged(Enum.CoreGuiType.Health, StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.All))
local panelLocalCF = CFrame.new(0, -3.5, 5) * CFrame.Angles(math.rad(20), 0, 0)
function BackpackPanel:PreUpdate(cameraCF, cameraRenderCF, userHeadCF, lookRay)
--the backpack panel needs to go in front of the user when they look at it.
--if they aren't looking, we should be updating self.localCF
if self.transparency == 1 then
local headForwardCF = Panel3D.GetHeadLookXZ()
local panelOriginCF = CFrame.new(userHeadCF.p) * headForwardCF
self.localCF = panelOriginCF * panelLocalCF
end
end
function BackpackPanel:OnUpdate()
SetTransparency(self.transparency)
local hovered, tool = BackpackPanel:FindHoveredGuiElement(slotIcons)
if hovered and tool then
local slot = Tools[tool]
if not slot.hovered then
slot.OnEnter()
end
for i, v in pairs(Tools) do
if v.hovered and v ~= slot then
v.OnLeave()
end
end
end
end
function BackpackPanel:OnMouseEnter(x, y)
EnableHotbarInput(true)
end
function BackpackPanel:OnMouseLeave(x, y)
EnableHotbarInput(false)
end
return BackpackScript
File diff suppressed because it is too large Load Diff
+491
View File
@@ -0,0 +1,491 @@
--Panel3D: 3D GUI panels for VR
--written by 0xBAADF00D
local PIXELS_PER_STUD = 64
local SETTINGS_DISTANCE = 3.5
local CURSOR_HIDE_TIME = 2
local CURSOR_FADE_TIME = 0.125
local CoreGui = game:GetService('CoreGui')
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
local Panel3D = {}
Panel3D.Panels = {
Lower = 1,
Hamburger = 2,
Settings = 3,
Keyboard = 4,
Chat = 5
}
Panel3D.Orientation = {
Horizontal = 1,
Fixed = 2
}
Panel3D.Visibility = {
BelowAngleThreshold = 1,
Modal = 2,
Normal = 3
}
local panelDefaultVectors = {
[Panel3D.Panels.Lower] = CFrame.Angles(math.rad(-45), 0, 0):vectorToWorldSpace(Vector3.new(0, 0, -5)),
[Panel3D.Panels.Hamburger] = CFrame.Angles(math.rad(-55), 0, 0):vectorToWorldSpace(Vector3.new(0, 0, -5)),
[Panel3D.Panels.Settings] = Vector3.new(0, 0, -SETTINGS_DISTANCE),
[Panel3D.Panels.Keyboard] = CFrame.Angles(math.rad(-22.5), 0, 0):vectorToWorldSpace(Vector3.new(0, 0, -5)),
[Panel3D.Panels.Chat] = CFrame.Angles(math.rad(5), 0, 0):vectorToWorldSpace(Vector3.new(0, 0, -5))
}
local DEFAULT_PANEL_LOCK_THRESHOLD = math.rad(-25)
local panelTransparencyBias = { --tuned values; raise the opacity value to this power
[Panel3D.Panels.Lower] = 6.5,
[Panel3D.Panels.Hamburger] = 8,
[Panel3D.Panels.Settings] = 0,
[Panel3D.Panels.Keyboard] = 1.5,
[Panel3D.Panels.Chat] = 1.5
}
local panels = {}
local headScale = 1
local renderStepName = "Panel3D"
local cursor = Instance.new("ImageLabel")
cursor.Image = "rbxasset://textures/Cursors/Gamepad/Pointer.png"
cursor.Size = UDim2.new(0, 8, 0, 8)
cursor.BackgroundTransparency = 1
cursor.ZIndex = 10
local resetOrientationFlag = false
local currentModalPanel = nil
local GuiService = game:GetService("GuiService")
local UserInputService = game:GetService("UserInputService")
local cursorHidden = false
local hasTool = false
local lastMouseMove = tick()
local function OnCharacterAdded(character)
hasTool = false
for i, v in ipairs(character:GetChildren()) do
if v:IsA("Tool") then
hasTool = true
end
end
character.ChildAdded:connect(function(child)
if child:IsA("Tool") then
hasTool = true
lastMouseMove = tick() --kick the mouse when a tool is equipped
end
end)
character.ChildRemoved:connect(function(child)
if child:IsA("Tool") then
hasTool = false
end
end)
end
spawn(function()
while not game.Players.LocalPlayer do wait() end
game.Players.LocalPlayer.CharacterAdded:connect(OnCharacterAdded)
if game.Players.LocalPlayer.Character then OnCharacterAdded(game.Players.LocalPlayer.Character) end
end)
local function autoHideCursor(hide)
if not UserInputService.VREnabled then
cursorHidden = false
return
end
if hide then
--don't hide if there's a tool in the character
local character = game.Players.LocalPlayer.Character
if character and hasTool then
return
end
cursorHidden = true
UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.ForceHide
else
cursorHidden = false
UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.None
end
end
local function isCursorVisible()
--if ForceShow, the cursor is definitely visible at all times
if UserInputService.OverrideMouseIconBehavior == Enum.OverrideMouseIconBehavior.ForceShow then
return true
end
--if ForceHide, the cursor is definitely NOT visible
if UserInputService.OverrideMouseIconBehavior == Enum.OverrideMouseIconBehavior.ForceHide then
return false
end
--Otherwise, we need to check if the developer set MouseIconEnabled=false
if UserInputService.MouseIconEnabled and UserInputService.OverrideMouseIconBehavior == Enum.OverrideMouseIconBehavior.None then
return true
end
return false
end
UserInputService.InputChanged:connect(function(inputObj, processed)
if inputObj.UserInputType == Enum.UserInputType.MouseMovement then
lastMouseMove = tick()
autoHideCursor(false)
end
end)
game:GetService("RunService").Heartbeat:connect(function()
if isCursorVisible() then
cursorHidden = false
end
if lastMouseMove + CURSOR_HIDE_TIME < tick() and not GuiService.MenuIsOpen and not cursorHidden then
autoHideCursor(true)
end
end)
local function createPanel()
local panelPart = Instance.new("Part")
panelPart.Transparency = 1
panelPart.CanCollide = false
panelPart.Anchored = true
panelPart.Archivable = false
panelPart.Size = Vector3.new(1.5, 1.5, 1)
panelPart.Parent = workspace.CurrentCamera
local panelGUI = Instance.new("SurfaceGui", CoreGui)
panelGUI.Name = "GUI"
panelGUI.Adornee = panelPart
panelGUI.ToolPunchThroughDistance = 1000
panelGUI.Active = true
pcall(function() --todo: remove this when api is live
panelGUI.AlwaysOnTop = true
end)
return panelPart, panelGUI
end
function Panel3D.Get(panelId)
local panel = panels[panelId]
if not panel then
local panelName
for name, value in pairs(Panel3D.Panels) do
if value == panelId then
panelName = name
break
end
end
if not panelName then
error("Tried to request an invalid 3D panel")
end
local part, gui = createPanel()
panel = {}
panel.part = part
panel.part.Name = "GUI"--("%sPanel3D"):format(panelName)
panel.gui = gui
panel.gui.Name = ("%sPanelGUI"):format(panelName)
panel.vector = panelDefaultVectors[panelId]
panel.horizontalVector = Vector3.new(panel.vector.x, 0, panel.vector.z).unit
panel.pitchAngle = math.asin(panel.vector.unit.y)
panel.verticalRange = math.rad(5)
panel.horizontalRange = math.rad(5)
panel.transparencyCallbacks = {}
panel.OnMouseEnter = nil
panel.OnMouseLeave = nil
panel.pixelScale = 1
panel.visible = true
panel.visibilityBehavior = Panel3D.Visibility.BelowAngleThreshold
panel.orientationMode = Panel3D.Orientation.Horizontal
panel.orientation = nil
panel.cursorEnabled = true
panel.width = 1
panel.height = 1
function panel:AddTransparencyCallback(callback)
table.insert(panel.transparencyCallbacks, callback)
end
function panel:Resize(width, height, pixelsPerStud)
panel.width = width
panel.height = height
pixelsPerStud = pixelsPerStud or PIXELS_PER_STUD
panel.pixelScale = pixelsPerStud / PIXELS_PER_STUD
panel.part.Size = Vector3.new(panel.width * headScale, panel.height * headScale, 1)
panel.gui.CanvasSize = Vector2.new(pixelsPerStud * panel.width, pixelsPerStud * panel.height)
local distance = panel.vector.magnitude
panel.verticalRange = math.atan(panel.part.Size.Y / (2 * distance)) * 2
panel.horizontalRange = math.atan(panel.part.Size.X / (2 * distance)) * 2
end
function panel:ResizePixels(width, height)
local widthStuds = width / PIXELS_PER_STUD
local heightStuds = height / PIXELS_PER_STUD
panel:Resize(widthStuds, heightStuds)
end
function panel:SetModal()
panel.visible = false
panel.visibilityBehavior = Panel3D.Visibility.Modal
if panel.visible then
currentModalPanel = panel
if panel.orientationMode == Panel3D.Orientation.Fixed then
local userHeadCFrame = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)
panel.orientation = userHeadCFrame * CFrame.new(0, 0, -panel.vector.magnitude) * CFrame.Angles(0, math.pi, 0)
end
end
end
function panel:SetVisible(visible)
panel.visible = visible
if visible and panel.visibilityBehavior == Panel3D.Visibility.Modal then
currentModalPanel = panel
if panel.orientationMode == Panel3D.Orientation.Fixed then
local userHeadCFrame = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)
panel.orientation = userHeadCFrame * CFrame.new(0, 0, -panel.vector.magnitude) * CFrame.Angles(0, math.pi, 0)
end
else
if currentModalPanel == panel then
currentModalPanel = nil
end
end
end
panels[panelId] = panel
end
return panel
end
function Panel3D.ResetOrientation()
resetOrientationFlag = true
end
function Panel3D.GetGUI(panel)
local panelGUI = panelGUIs[panel]
if not panelGUI then
local part = Panel3D.GetPart(panel)
panelGUI = panelGUIs[panel]
end
return panelGUI
end
local zeroVector = Vector3.new(0, 0, 0)
local headXZ = CFrame.new()
local headOffset = Vector3.new()
local currentHoverPanel = nil
local savedMouseBehavior = Enum.MouseBehavior.Default
function Panel3D.OnRenderStep()
if not UserInputService.VREnabled then
return
end
local cameraCFrame = workspace.CurrentCamera.CFrame
local cameraRenderCFrame = workspace.CurrentCamera:GetRenderCFrame()
local userHeadCFrame = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)
local userHeadLook = userHeadCFrame.lookVector
local userHeadHorizontalVector = Vector3.new(userHeadLook.X, 0, userHeadLook.Z).unit
local userHeadPitch = math.asin(userHeadLook.Y)
local panelLockThreshold = DEFAULT_PANEL_LOCK_THRESHOLD
for panelId, panel in pairs(panels) do
if panel.pitchLockThreshold and panel.visible then
panelLockThreshold = math.max(panelLockThreshold, panel.pitchLockThreshold)
end
end
local isAboveThreshold = false
if userHeadPitch > panelLockThreshold or resetOrientationFlag then
isAboveThreshold = true
headXZ = CFrame.new(zeroVector, userHeadHorizontalVector)
headOffset = userHeadCFrame.p
resetOrientationFlag = false
end
local panelsOrigin = cameraCFrame * CFrame.new(headOffset) * headXZ
for panelId, panel in pairs(panels) do
if panel.visibilityBehavior == Panel3D.Visibility.BelowAngleThreshold then
panel.visible = not (isAboveThreshold or currentModalPanel)
end
if not panel.visible then
panel.part.Parent = nil
panel.gui.Adornee = nil
else
panel.part.Parent = workspace.CurrentCamera --TODO: move to new 3D gui space
panel.gui.Adornee = panel.part
local panelCFrame;
if panel.orientationMode == Panel3D.Orientation.Fixed and panel.orientation then
local pos = panel.orientation.p * headScale
panel.part.CFrame = workspace.CurrentCamera.CFrame * ((panel.orientation - panel.orientation.p) + pos)
panelCFrame = panel.part.CFrame
else
local panelPosition = panelsOrigin:pointToWorldSpace(panel.vector * headScale)
panelCFrame = CFrame.new(panelPosition, panelsOrigin.p)
panel.part.CFrame = panelCFrame
end
local toPanel = (panelCFrame.p - cameraRenderCFrame.p).unit
local transparency = panel.visible and 1 - (math.max(0, cameraRenderCFrame.lookVector:Dot(toPanel)) ^ panelTransparencyBias[panelId]) or 1
for _, callback in pairs(panel.transparencyCallbacks) do
callback(transparency)
end
end
end
--Render a cursor overlaid onto the panels
local cframe = cameraRenderCFrame
local ray = Ray.new(cframe.p, cframe.lookVector * 999)
local ignoreList = { game.Players.LocalPlayer.Character }
local part, endpoint = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
local hitPanel = nil
local hitPanelId = nil
for panelId, panel in pairs(panels) do
if part == panel.part then
hitPanel = panel
hitPanelId = panelId
end
end
if hitPanel then
if not currentHoverPanel then
savedMouseBehavior = UserInputService.MouseBehavior
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
else
if currentHoverPanel ~= hitPanel then
if currentHoverPanel.OnMouseLeave then
currentHoverPanel:OnMouseLeave()
end
end
end
if hitPanel.OnMouseEnter and currentHoverPanel ~= hitPanel then
hitPanel:OnMouseEnter()
end
currentHoverPanel = hitPanel
UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.ForceHide
if hitPanel.cursorEnabled then
cursor.Parent = hitPanel.gui
else
cursor.Parent = nil
end
local localEndpoint = part:GetRenderCFrame():pointToObjectSpace(endpoint)
local x = (localEndpoint.X / part.Size.X) + 0.5
local y = (localEndpoint.Y / part.Size.Y) + 0.5
x = 1 - x
y = 1 - y
cursor.Size = UDim2.new(0, 8 * hitPanel.pixelScale, 0, 8 * hitPanel.pixelScale)
cursor.Position = UDim2.new(x, -cursor.AbsoluteSize.x * 0.5, y, -cursor.AbsoluteSize.y * 0.5)
if hitPanel.visible and not modalPanelIsOpen then
hitPanel.part.Parent = workspace.CurrentCamera
for _, callback in pairs(hitPanel.transparencyCallbacks) do
callback(0)
end
end
else
if currentHoverPanel then
UserInputService.MouseBehavior = savedMouseBehavior
if currentHoverPanel.OnMouseLeave then
currentHoverPanel:OnMouseLeave()
end
end
currentHoverPanel = false
cursor.Parent = nil
end
end
-- RayPlaneIntersection
-- http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm
local function RayPlaneIntersection(ray, planeNormal, pointOnPlane)
planeNormal = planeNormal.unit
ray = ray.Unit
-- compute Pn (dot) Rd = Vd and check if Vd == 0 then we know ray is parallel to plane
local Vd = planeNormal:Dot(ray.Direction)
-- could fuzzy equals this a little bit to account for imprecision or very close angles to zero
if Vd == 0 then -- parallel, no intersection
return nil
end
local V0 = planeNormal:Dot(pointOnPlane - ray.Origin)
local t = V0 / Vd
if t < 0 then --plane is behind ray origin, and thus there is no intersection
return nil
end
return ray.Origin + ray.Direction * t
end
function Panel3D.FindHoveredGuiElement(panel, elements)
local cameraRenderCFrame = workspace.CurrentCamera and workspace.CurrentCamera:GetRenderCFrame()
local panelPart = panel.part
if cameraRenderCFrame and panelPart then
local panelPartSize = panelPart.Size
local panelSurfaceCFrame = panelPart.CFrame + panelPart.CFrame.lookVector * (panelPartSize.Z * 0.5)
local intersectionPt = RayPlaneIntersection(Ray.new(cameraRenderCFrame.p, cameraRenderCFrame.lookVector), panelSurfaceCFrame.lookVector, panelSurfaceCFrame.p)
if intersectionPt then
local localPoint = panelSurfaceCFrame:pointToObjectSpace(intersectionPt) * Vector3.new(-1, 1, 1) + Vector3.new(panelPartSize.X/2, -panelPartSize.Y/2, 0)
local guiPoint = Vector2.new((localPoint.X / panelPartSize.X) * panel.gui.AbsoluteSize.X, (localPoint.Y / panelPartSize.Y) * -panel.gui.AbsoluteSize.Y)
local x = guiPoint.x
local y = guiPoint.y
for _, item in pairs(elements) do
local minPt = item.AbsolutePosition
local maxPt = item.AbsolutePosition + item.AbsoluteSize
if minPt.X <= x and maxPt.X >= x and minPt.Y <= y and maxPt.Y >= y then
return item
end
end
end
end
end
game:GetService("RunService"):BindToRenderStep(renderStepName, Enum.RenderPriority.Last.Value, Panel3D.OnRenderStep)
local function OnCameraChanged(prop)
if prop == "HeadScale" then
pcall(function()
headScale = workspace.CurrentCamera.HeadScale
end)
for i, v in pairs(panels) do
v:Resize(v.width, v.height, v.pixelScale * PIXELS_PER_STUD)
end
end
end
local cameraChangedConn = nil
workspace.Changed:connect(function(prop)
if prop == "CurrentCamera" then
OnCameraChanged("HeadScale")
if cameraChangedConn then
cameraChangedConn:disconnect()
end
cameraChangedConn = workspace.CurrentCamera.Changed:connect(OnCameraChanged)
end
end)
if workspace.CurrentCamera then
OnCameraChanged("HeadScale")
cameraChangedConn = workspace.CurrentCamera.Changed:connect(OnCameraChanged)
end
return Panel3D
+628
View File
@@ -0,0 +1,628 @@
--[[
// FileName: PlayerDropDown.lua
// Written by: TheGamer101
// Description: Code for the player drop down in the PlayerList and Chat
]]
local moduleApiTable = {}
--[[ Services ]]--
local CoreGui = game:GetService('CoreGui')
local HttpService = game:GetService('HttpService')
local HttpRbxApiService = game:GetService('HttpRbxApiService')
local PlayersService = game:GetService('Players')
--[[ Script Variables ]]--
local LocalPlayer = PlayersService.LocalPlayer
--[[ Constants ]]--
local POPUP_ENTRY_SIZE_Y = 24
local ENTRY_PAD = 2
local BG_TRANSPARENCY = 0.5
local BG_COLOR = Color3.new(31/255, 31/255, 31/255)
local TEXT_STROKE_TRANSPARENCY = 0.75
local TEXT_COLOR = Color3.new(1, 1, 243/255)
local TEXT_STROKE_COLOR = Color3.new(34/255, 34/255, 34/255)
local MAX_FRIEND_COUNT = 200
local FRIEND_IMAGE = 'http://www.roblox.com/thumbs/avatar.ashx?userId='
--[[ Fast Flags ]]--
local followerSuccess, isFollowersEnabled = pcall(function() return settings():GetFFlag("EnableLuaFollowers") end)
local IsFollowersEnabled = followerSuccess and isFollowersEnabled
local serverFollowersSuccess, serverFollowersEnabled = pcall(function() return settings():GetFFlag("UserServerFollowers") end)
local IsServerFollowers = serverFollowersSuccess and serverFollowersEnabled
--[[ Modules ]]--
local RobloxGui = CoreGui:WaitForChild('RobloxGui')
local reportAbuseMenu = require(RobloxGui.Modules.Settings.Pages.ReportAbuseMenu)
--[[ Bindables ]]--
local BinbableFunction_SendNotification = nil
spawn(function()
BinbableFunction_SendNotification = RobloxGui:WaitForChild("SendNotification")
end)
--[[ Remotes ]]--
local RemoteEvent_NewFollower = nil
spawn(function()
local RobloxReplicatedStorage = game:GetService('RobloxReplicatedStorage')
RemoteEvent_NewFollower = RobloxReplicatedStorage:WaitForChild('NewFollower')
end)
--[[ Utility Functions ]]--
local function createSignal()
local sig = {}
local mSignaler = Instance.new('BindableEvent')
local mArgData = nil
local mArgDataCount = nil
function sig:fire(...)
mArgData = {...}
mArgDataCount = select('#', ...)
mSignaler:Fire()
end
function sig:connect(f)
if not f then error("connect(nil)", 2) end
return mSignaler.Event:connect(function()
f(unpack(mArgData, 1, mArgDataCount))
end)
end
function sig:wait()
mSignaler.Event:wait()
assert(mArgData, "Missing arg data, likely due to :TweenSize/Position corrupting threadrefs.")
return unpack(mArgData, 1, mArgDataCount)
end
return sig
end
--[[ Events ]]--
local BlockStatusChanged = createSignal()
--[[ Personal Server Stuff ]]--
local IsPersonalServer = false
local PersonalServerService = nil
if game.Workspace:FindFirstChild('PSVariable') then
IsPersonalServer = true
PersonalServerService = game:GetService('PersonalServerService')
end
game.Workspace.ChildAdded:connect(function(child)
if child.Name == 'PSVariable' and child:IsA('BoolValue') then
IsPersonalServer = true
PersonalServerService = game:GetService('PersonalServerService')
end
end)
local PRIVILEGE_LEVEL = {
OWNER = 255,
ADMIN = 240,
MEMBER = 128,
VISITOR = 10,
BANNED = 0,
}
local function onPrivilegeLevelSelect(player, rank)
while player.PersonalServerRank < rank do
PersonalServerService:Promote(player)
end
while player.PersonalServerRank > rank do
PersonalServerService:Demote(player)
end
end
--[[ Follower Notifications ]]--
local function sendNotification(title, text, image, duration, callback)
if BinbableFunction_SendNotification then
BinbableFunction_SendNotification:Invoke(title, text, image, duration, callback)
end
end
--[[ Friend Functions ]]--
local function getFriendStatus(selectedPlayer)
if selectedPlayer == LocalPlayer then
return Enum.FriendStatus.NotFriend
else
local success, result = pcall(function()
-- NOTE: Core script only
return LocalPlayer:GetFriendStatus(selectedPlayer)
end)
if success then
return result
else
return Enum.FriendStatus.NotFriend
end
end
end
-- if userId = nil, then it will get count for local player
local function getFriendCountAsync(userId)
local friendCount = nil
local wasSuccess, result = pcall(function()
local str = 'user/get-friendship-count'
if userId then
str = str..'?userId='..tostring(userId)
end
return HttpRbxApiService:GetAsync(str, true)
end)
if not wasSuccess then
print("getFriendCountAsync() failed because", result)
return nil
end
result = HttpService:JSONDecode(result)
if result["success"] and result["count"] then
friendCount = result["count"]
end
return friendCount
end
-- checks if we can send a friend request. Right now the only way we
-- can't is if one of the players is at the max friend limit
local function canSendFriendRequestAsync(otherPlayer)
local theirFriendCount = getFriendCountAsync(otherPlayer.userId)
local myFriendCount = getFriendCountAsync()
-- assume max friends if web call fails
if not myFriendCount or not theirFriendCount then
return false
end
if myFriendCount < MAX_FRIEND_COUNT and theirFriendCount < MAX_FRIEND_COUNT then
return true
elseif myFriendCount >= MAX_FRIEND_COUNT then
sendNotification("Cannot send friend request", "You are at the max friends limit.", "", 5, function() end)
return false
elseif theirFriendCount >= MAX_FRIEND_COUNT then
sendNotification("Cannot send friend request", otherPlayer.Name.." is at the max friends limit.", "", 5, function() end)
return false
end
end
--[[ Follower Functions ]]--
-- Returns whether followerUserId is following userId
local function isFollowing(userId, followerUserId)
local apiPath = "user/following-exists?userId="
local params = userId.."&followerUserId="..followerUserId
local success, result = pcall(function()
return HttpRbxApiService:GetAsync(apiPath..params, true)
end)
if not success then
print("isFollowing() failed because", result)
return false
end
-- can now parse web response
result = HttpService:JSONDecode(result)
return result["success"] and result["isFollowing"]
end
--[[ Functions for Blocking users ]]--
local BlockedList = {}
local MutedList = {}
local function GetBlockedPlayersAsync()
local userId = LocalPlayer.userId
local apiPath = "userblock/getblockedusers" .. "?" .. "userId=" .. tostring(userId) .. "&" .. "page=" .. "1"
if userId > 0 then
local blockList = nil
local success, msg = pcall(function()
local request = HttpRbxApiService:GetAsync(apiPath)
blockList = request and game:GetService('HttpService'):JSONDecode(request)
end)
if blockList and blockList['success'] == true and blockList['userList'] then
return blockList['userList']
end
end
return {}
end
spawn(function()
BlockedList = GetBlockedPlayersAsync()
end)
local function isBlocked(userId)
if (BlockedList[userId] ~= nil and BlockedList[userId] == true) then
return true
end
return false
end
local function isMuted(userId)
if (MutedList[userId] ~= nil and MutedList[userId] == true) then
return true
end
return false
end
local function BlockPlayerAsync(playerToBlock)
if playerToBlock and LocalPlayer ~= playerToBlock then
local blockUserId = playerToBlock.UserId
if blockUserId > 0 then
if not isBlocked(blockUserId) then
BlockedList[blockUserId] = true
BlockStatusChanged:fire(blockUserId, true)
pcall(function()
local success = PlayersService:BlockUser(LocalPlayer.userId, blockUserId)
end)
end
end
end
end
local function UnblockPlayerAsync(playerToUnblock)
if playerToUnblock then
local unblockUserId = playerToUnblock.userId
if isBlocked(unblockUserId) then
BlockedList[unblockUserId] = nil
BlockStatusChanged:fire(unblockUserId, false)
pcall(function()
local success = PlayersService:UnblockUser(LocalPlayer.userId, unblockUserId)
end)
end
end
end
local function MutePlayer(playerToMute)
if playerToMute and LocalPlayer ~= playerToMute then
local muteUserId = playerToMute.UserId
if muteUserId > 0 then
if not isMuted(muteUserId) then
MutedList[muteUserId] = true
end
end
end
end
local function UnmutePlayer(playerToUnmute)
if playerToUnmute then
local unmuteUserId = playerToUnmute.UserId
MutedList[unmuteUserId] = nil
end
end
--[[ Function to create DropDown class ]]--
function createPlayerDropDown()
local playerDropDown = {}
playerDropDown.Player = nil
playerDropDown.PopupFrame = nil
playerDropDown.HidePopupImmediately = false
playerDropDown.PopupFrameOffScreenPosition = nil -- if this is set the popup frame tweens to a different offscreen position than the default
playerDropDown.HiddenSignal = createSignal()
--[[ Functions for when options in the dropdown are pressed ]]--
local function onFriendButtonPressed()
if playerDropDown.Player then
local status = getFriendStatus(playerDropDown.Player)
if status == Enum.FriendStatus.Friend then
LocalPlayer:RevokeFriendship(playerDropDown.Player)
elseif status == Enum.FriendStatus.Unknown or status == Enum.FriendStatus.NotFriend then
-- cache and spawn
local cachedLastSelectedPlayer = playerDropDown.Player
spawn(function()
-- check for max friends before letting them send the request
if canSendFriendRequestAsync(cachedLastSelectedPlayer) then -- Yields
if cachedLastSelectedPlayer and cachedLastSelectedPlayer.Parent == PlayersService then
LocalPlayer:RequestFriendship(cachedLastSelectedPlayer)
end
end
end)
elseif status == Enum.FriendStatus.FriendRequestSent then
LocalPlayer:RevokeFriendship(playerDropDown.Player)
elseif status == Enum.FriendStatus.FriendRequestReceived then
LocalPlayer:RequestFriendship(playerDropDown.Player)
end
playerDropDown:Hide()
end
end
local function onDeclineFriendButonPressed()
if playerDropDown.Player then
LocalPlayer:RevokeFriendship(playerDropDown.Player)
playerDropDown:Hide()
end
end
-- Client unfollows followedUserId
local function onUnfollowButtonPressed()
if not playerDropDown.Player then return end
--
local apiPath = "user/unfollow"
local params = "followedUserId="..tostring(playerDropDown.Player.userId)
local success, result = pcall(function()
return HttpRbxApiService:PostAsync(apiPath, params, true, Enum.ThrottlingPriority.Default, Enum.HttpContentType.ApplicationUrlEncoded)
end)
if not success then
print("unfollowPlayer() failed because", result)
playerDropDown:Hide()
return
end
result = HttpService:JSONDecode(result)
if result["success"] then
if RemoteEvent_NewFollower then
RemoteEvent_NewFollower:FireServer(playerDropDown.Player, false)
end
moduleApiTable.FollowerStatusChanged:fire()
end
playerDropDown:Hide()
-- no need to send notification when someone unfollows
end
local function onBlockButtonPressed()
if playerDropDown.Player then
local cachedPlayer = playerDropDown.Player
spawn(function()
BlockPlayerAsync(cachedPlayer)
end)
playerDropDown:Hide()
end
end
local function onUnblockButtonPressed()
if playerDropDown.Player then
local cachedPlayer = playerDropDown.Player
spawn(function()
UnblockPlayerAsync(cachedPlayer)
end)
playerDropDown:Hide()
end
end
local function onReportButtonPressed()
if playerDropDown.Player then
reportAbuseMenu:ReportPlayer(playerDropDown.Player)
playerDropDown:Hide()
end
end
-- Client follows followedUserId
local function onFollowButtonPressed()
if not playerDropDown.Player then return end
--
local followedUserId = tostring(playerDropDown.Player.userId)
local apiPath = "user/follow"
local params = "followedUserId="..followedUserId
local success, result = pcall(function()
return HttpRbxApiService:PostAsync(apiPath, params, true, Enum.ThrottlingPriority.Default, Enum.HttpContentType.ApplicationUrlEncoded)
end)
if not success then
print("followPlayer() failed because", result)
playerDropDown:Hide()
return
end
result = HttpService:JSONDecode(result)
if result["success"] then
sendNotification("You are", "now following "..playerDropDown.Player.Name, FRIEND_IMAGE..followedUserId.."&x=48&y=48", 5, function() end)
if RemoteEvent_NewFollower then
RemoteEvent_NewFollower:FireServer(playerDropDown.Player, true)
end
moduleApiTable.FollowerStatusChanged:fire()
end
playerDropDown:Hide()
end
--[[ GUI Creation Functions ]]--
local function createPersonalServerDialog(buttons, selectedPlayer)
local showPersonalServerRanks = IsPersonalServer and LocalPlayer.PersonalServerRank >= PRIVILEGE_LEVEL.ADMIN and LocalPlayer.PersonalServerRank > selectedPlayer.PersonalServerRank
if showPersonalServerRanks then
table.insert(buttons, {
Name = "BanButton",
Text = "Ban",
OnPress = function()
playerDropDown:Hide()
onPrivilegeLevelSelect(selectedPlayer, PRIVILEGE_LEVEL.BANNED)
end,
})
table.insert(buttons, {
Name = "VistorButton",
Text = "Visitor",
OnPress = function()
onPrivilegeLevelSelect(selectedPlayer, PRIVILEGE_LEVEL.VISITOR)
end,
})
table.insert(buttons, {
Name = "MemberButton",
Text = "Member",
OnPress = function()
onPrivilegeLevelSelect(selectedPlayer, PRIVILEGE_LEVEL.MEMBER)
end,
})
table.insert(buttons, {
Name = "AdminButton",
Text = "Admin",
OnPress = function()
onPrivilegeLevelSelect(selectedPlayer, PRIVILEGE_LEVEL.ADMIN)
end,
})
end
end
local function createPopupFrame(buttons)
local frame = Instance.new('Frame')
frame.Name = "PopupFrame"
frame.Size = UDim2.new(1, 0, 0, (POPUP_ENTRY_SIZE_Y * #buttons) + (#buttons - ENTRY_PAD))
frame.Position = UDim2.new(1, 1, 0, 0)
frame.BackgroundTransparency = 1
for i,button in ipairs(buttons) do
local btn = Instance.new('TextButton')
btn.Name = button.Name
btn.Size = UDim2.new(1, 0, 0, POPUP_ENTRY_SIZE_Y)
btn.Position = UDim2.new(0, 0, 0, POPUP_ENTRY_SIZE_Y * (i - 1) + ((i - 1) * ENTRY_PAD))
btn.BackgroundTransparency = BG_TRANSPARENCY
btn.BackgroundColor3 = BG_COLOR
btn.BorderSizePixel = 0
btn.Text = button.Text
btn.Font = Enum.Font.SourceSans
btn.FontSize = Enum.FontSize.Size14
btn.TextColor3 = TEXT_COLOR
btn.TextStrokeTransparency = TEXT_STROKE_TRANSPARENCY
btn.TextStrokeColor3 = TEXT_STROKE_COLOR
btn.AutoButtonColor = true
btn.Parent = frame
btn.MouseButton1Click:connect(button.OnPress)
end
return frame
end
--[[ PlayerDropDown Functions ]]--
function playerDropDown:Hide()
if playerDropDown.PopupFrame then
local offscreenPosition = (playerDropDown.PopupFrameOffScreenPosition ~= nil and playerDropDown.PopupFrameOffScreenPosition or UDim2.new(1, 1, 0, playerDropDown.PopupFrame.Position.Y.Offset))
if not playerDropDown.HidePopupImmediately then
playerDropDown.PopupFrame:TweenPosition(offscreenPosition, Enum.EasingDirection.InOut,
Enum.EasingStyle.Quad, TWEEN_TIME, true, function()
if playerDropDown.PopupFrame then
playerDropDown.PopupFrame:Destroy()
playerDropDown.PopupFrame = nil
end
end)
else
playerDropDown.PopupFrame:Destroy()
playerDropDown.PopupFrame = nil
end
end
if playerDropDown.Player then
playerDropDown.Player = nil
end
playerDropDown.HiddenSignal:fire()
end
function playerDropDown:CreatePopup(Player)
playerDropDown.Player = Player
local buttons = {}
local status = getFriendStatus(playerDropDown.Player)
local friendText = ""
local canDeclineFriend = false
if status == Enum.FriendStatus.Friend then
friendText = "Unfriend Player"
elseif status == Enum.FriendStatus.Unknown or status == Enum.FriendStatus.NotFriend then
friendText = "Send Friend Request"
elseif status == Enum.FriendStatus.FriendRequestSent then
friendText = "Revoke Friend Request"
elseif status == Enum.FriendStatus.FriendRequestReceived then
friendText = "Accept Friend Request"
canDeclineFriend = true
end
local blocked = isBlocked(playerDropDown.Player.userId)
if not blocked then
table.insert(buttons, {
Name = "FriendButton",
Text = friendText,
OnPress = onFriendButtonPressed,
})
end
if canDeclineFriend and not blocked then
table.insert(buttons, {
Name = "DeclineFriend",
Text = "Decline Friend Request",
OnPress = onDeclineFriendButonPressed,
})
end
-- following status
if IsServerFollowers or IsFollowersEnabled then
local following = isFollowing(playerDropDown.Player.userId, LocalPlayer.userId)
local followerText = following and "Unfollow Player" or "Follow Player"
if not blocked then
table.insert(buttons, {
Name = "FollowerButton",
Text = followerText,
OnPress = following and onUnfollowButtonPressed or onFollowButtonPressed,
})
end
end
local blockedText = blocked and "Unblock Player" or "Block Player"
table.insert(buttons, {
Name = "BlockButton",
Text = blockedText,
OnPress = blocked and onUnblockButtonPressed or onBlockButtonPressed,
})
table.insert(buttons, {
Name = "ReportButton",
Text = "Report Abuse",
OnPress = onReportButtonPressed,
})
createPersonalServerDialog(buttons, playerDropDown.Player)
if playerDropDown.PopupFrame then
playerDropDown.PopupFrame:Destroy()
end
playerDropDown.PopupFrame = createPopupFrame(buttons)
return playerDropDown.PopupFrame
end
--[[ PlayerRemoving Connection ]]--
PlayersService.PlayerRemoving:connect(function(leavingPlayer)
if playerDropDown.Player == leavingPlayer then
playerDropDown:Hide()
end
end)
return playerDropDown
end
do
moduleApiTable.FollowerStatusChanged = createSignal()
function moduleApiTable:CreatePlayerDropDown()
return createPlayerDropDown()
end
function moduleApiTable:CreateBlockingUtility()
local blockingUtility = {}
function blockingUtility:BlockPlayerAsync(player)
return BlockPlayerAsync(player)
end
function blockingUtility:UnblockPlayerAsync(player)
return UnblockPlayerAsync(player)
end
function blockingUtility:MutePlayer(player)
return MutePlayer(player)
end
function blockingUtility:UnmutePlayer(player)
return UnmutePlayer(player)
end
function blockingUtility:IsPlayerBlockedByUserId(userId)
return isBlocked(userId)
end
function blockingUtility:GetBlockedStatusChangedEvent()
return BlockStatusChanged
end
function blockingUtility:IsPlayerMutedByUserId(userId)
return isMuted(userId)
end
return blockingUtility
end
end
return moduleApiTable
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,790 @@
--[[
Filename: GameSettings.lua
Written by: jeditkacheff
Version 1.1
Description: Takes care of the Game Settings Tab in Settings Menu
--]]
-------------- SERVICES --------------
local CoreGui = game:GetService("CoreGui")
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
local GuiService = game:GetService("GuiService")
local UserInputService = game:GetService("UserInputService")
local PlatformService = nil
pcall(function() PlatformService = game:GetService("PlatformService") end)
local ContextActionService = game:GetService("ContextActionService")
local StarterGui = game:GetService("StarterGui")
local Settings = UserSettings()
local GameSettings = Settings.GameSettings
-------------- CONSTANTS --------------
local GRAPHICS_QUALITY_LEVELS = 10
local GRAPHICS_QUALITY_TO_INT = {
["Enum.SavedQualitySetting.Automatic"] = 0,
["Enum.SavedQualitySetting.QualityLevel1"] = 1,
["Enum.SavedQualitySetting.QualityLevel2"] = 2,
["Enum.SavedQualitySetting.QualityLevel3"] = 3,
["Enum.SavedQualitySetting.QualityLevel4"] = 4,
["Enum.SavedQualitySetting.QualityLevel5"] = 5,
["Enum.SavedQualitySetting.QualityLevel6"] = 6,
["Enum.SavedQualitySetting.QualityLevel7"] = 7,
["Enum.SavedQualitySetting.QualityLevel8"] = 8,
["Enum.SavedQualitySetting.QualityLevel9"] = 9,
["Enum.SavedQualitySetting.QualityLevel10"] = 10,
}
local PC_CHANGED_PROPS = {
DevComputerMovementMode = true,
DevComputerCameraMode = true,
DevEnableMouseLock = true,
}
local TOUCH_CHANGED_PROPS = {
DevTouchMovementMode = true,
DevTouchCameraMode = true,
}
local CAMERA_MODE_DEFAULT_STRING = UserInputService.TouchEnabled and "Default (Follow)" or "Default (Classic)"
local MOVEMENT_MODE_DEFAULT_STRING = UserInputService.TouchEnabled and "Default (Thumbstick)" or "Default (Keyboard)"
local MOVEMENT_MODE_KEYBOARDMOUSE_STRING = "Keyboard + Mouse"
local MOVEMENT_MODE_CLICKTOMOVE_STRING = UserInputService.TouchEnabled and "Tap to Move" or "Click to Move"
----------- UTILITIES --------------
local utility = require(RobloxGui.Modules.Settings.Utility)
------------ Variables -------------------
RobloxGui:WaitForChild("Modules"):WaitForChild("TenFootInterface")
RobloxGui:WaitForChild("Modules"):WaitForChild("Settings"):WaitForChild("SettingsHub")
local isTenFootInterface = require(RobloxGui.Modules.TenFootInterface):IsEnabled()
local HasVRAPI = false
pcall(function() HasVRAPI = UserInputService.GetUserCFrame ~= nil end)
local PageInstance = nil
local LocalPlayer = game.Players.LocalPlayer
local platform = UserInputService:GetPlatform()
local overscanScreen = nil
----------- CLASS DECLARATION --------------
local function Initialize()
local settingsPageFactory = require(RobloxGui.Modules.Settings.SettingsPageFactory)
local this = settingsPageFactory:CreateNewPage()
----------- FUNCTIONS ---------------
local function createGraphicsOptions()
------------------ Fullscreen Selection GUI Setup ------------------
local fullScreenInit = 1
if not GameSettings:InFullScreen() then
fullScreenInit = 2
end
this.FullscreenFrame,
this.FullscreenLabel,
this.FullscreenEnabler = utility:AddNewRow(this, "Fullscreen", "Selector", {"On", "Off"}, fullScreenInit)
local fullScreenSelectionFrame = this.FullscreenEnabler.SliderFrame and this.FullscreenEnabler.SliderFrame or this.FullscreenEnabler.SelectorFrame
this.FullscreenEnabler.IndexChanged:connect(function(newIndex)
GuiService:ToggleFullscreen()
end)
------------------ Gfx Enabler Selection GUI Setup ------------------
local graphicsEnablerStart = 1
if GameSettings.SavedQualityLevel ~= Enum.SavedQualitySetting.Automatic then
graphicsEnablerStart = 2
end
this.GraphicsEnablerFrame,
this.GraphicsEnablerLabel,
this.GraphicsQualityEnabler = utility:AddNewRow(this, "Graphics Mode", "Selector", {"Automatic", "Manual"}, graphicsEnablerStart)
------------------ Gfx Slider GUI Setup ------------------
this.GraphicsQualityFrame,
this.GraphicsQualityLabel,
this.GraphicsQualitySlider = utility:AddNewRow(this, "Graphics Quality", "Slider", GRAPHICS_QUALITY_LEVELS, 1)
this.GraphicsQualitySlider:SetMinStep(1)
------------------------- Connection Setup ----------------------------
settings().Rendering.EnableFRM = true
function SetGraphicsQuality(newValue, automaticSettingAllowed)
local percentage = newValue/GRAPHICS_QUALITY_LEVELS
local newQualityLevel = math.floor((settings().Rendering:GetMaxQualityLevel() - 1) * percentage)
if newQualityLevel == 20 then
newQualityLevel = 21
elseif newValue == 1 then
newQualityLevel = 1
elseif newValue < 1 and not automaticSettingAllowed then
newValue = 1
newQualityLevel = 1
elseif newQualityLevel > settings().Rendering:GetMaxQualityLevel() then
newQualityLevel = settings().Rendering:GetMaxQualityLevel() - 1
end
GameSettings.SavedQualityLevel = newValue
settings().Rendering.QualityLevel = newQualityLevel
end
local function setGraphicsToAuto()
this.GraphicsQualitySlider:SetZIndex(1)
this.GraphicsQualityLabel.ZIndex = 1
this.GraphicsQualitySlider:SetInteractable(false)
SetGraphicsQuality(Enum.QualityLevel.Automatic.Value, true)
end
local function setGraphicsToManual(level)
this.GraphicsQualitySlider:SetZIndex(2)
this.GraphicsQualityLabel.ZIndex = 2
this.GraphicsQualitySlider:SetInteractable(true)
-- need to force the quality change if slider is already at this position
if this.GraphicsQualitySlider:GetValue() == level then
SetGraphicsQuality(level)
else
this.GraphicsQualitySlider:SetValue(level)
end
end
game.GraphicsQualityChangeRequest:connect(function(isIncrease)
if settings().Rendering.QualityLevel == Enum.QualityLevel.Automatic then return end
--
local currentGraphicsSliderValue = this.GraphicsQualitySlider:GetValue()
if isIncrease then
currentGraphicsSliderValue = currentGraphicsSliderValue + 1
else
currentGraphicsSliderValue = currentGraphicsSliderValue - 1
end
this.GraphicsQualitySlider:SetValue(currentGraphicsSliderValue)
end)
this.GraphicsQualitySlider.ValueChanged:connect(function(newValue)
SetGraphicsQuality(newValue)
end)
this.GraphicsQualityEnabler.IndexChanged:connect(function(newIndex)
if newIndex == 1 then
setGraphicsToAuto()
elseif newIndex == 2 then
setGraphicsToManual( this.GraphicsQualitySlider:GetValue() )
end
end)
-- initialize the slider position
if GameSettings.SavedQualityLevel == Enum.SavedQualitySetting.Automatic then
this.GraphicsQualitySlider:SetValue(5)
setGraphicsToAuto()
else
local graphicsLevel = tostring(GameSettings.SavedQualityLevel)
if GRAPHICS_QUALITY_TO_INT[graphicsLevel] then
graphicsLevel = GRAPHICS_QUALITY_TO_INT[graphicsLevel]
else
graphicsLevel = GRAPHICS_QUALITY_LEVELS
end
spawn(function()
this.GraphicsQualitySlider:SetValue(graphicsLevel)
end)
end
end
local function createCameraModeOptions(movementModeEnabled)
------------------------------------------------------
------------------
------------------ Shift Lock Switch -----------------
if UserInputService.MouseEnabled then
this.ShiftLockFrame,
this.ShiftLockLabel,
this.ShiftLockMode,
this.ShiftLockOverrideText = nil
if UserInputService.MouseEnabled and UserInputService.KeyboardEnabled then
local startIndex = 2
if GameSettings.ControlMode == Enum.ControlMode.MouseLockSwitch then
startIndex = 1
end
this.ShiftLockFrame,
this.ShiftLockLabel,
this.ShiftLockMode = utility:AddNewRow(this, "Shift Lock Switch", "Selector", {"On", "Off"}, startIndex)
this.ShiftLockOverrideText = utility:Create'TextLabel'
{
Name = "ShiftLockOverrideLabel",
Text = "Set by Developer",
TextColor3 = Color3.new(1,1,1),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size24,
BackgroundTransparency = 1,
Size = UDim2.new(0,200,1,0),
Position = UDim2.new(1,-350,0,0),
Visible = false,
ZIndex = 2,
Parent = this.ShiftLockFrame
};
this.ShiftLockMode.IndexChanged:connect(function(newIndex)
if newIndex == 1 then
GameSettings.ControlMode = Enum.ControlMode.MouseLockSwitch
else
GameSettings.ControlMode = Enum.ControlMode.Classic
end
end)
end
end
------------------------------------------------------
------------------
------------------ Camera Mode -----------------------
do
local enumItems = nil
local startingCameraEnumItem = 1
if UserInputService.TouchEnabled then
enumItems = Enum.TouchCameraMovementMode:GetEnumItems()
else
enumItems = Enum.ComputerCameraMovementMode:GetEnumItems()
end
local cameraEnumNames = {}
local cameraEnumNameToItem = {}
for i = 1, #enumItems do
local displayName = enumItems[i].Name
if displayName == 'Default' then
displayName = CAMERA_MODE_DEFAULT_STRING
end
if UserInputService.TouchEnabled then
if GameSettings.TouchCameraMovementMode == enumItems[i] then
startingCameraEnumItem = i
end
else
if GameSettings.ComputerCameraMovementMode == enumItems[i] then
startingCameraEnumItem = i
end
end
cameraEnumNames[i] = displayName
cameraEnumNameToItem[displayName] = enumItems[i].Value
end
this.CameraModeFrame,
this.CameraModeLabel,
this.CameraMode = utility:AddNewRow(this, "Camera Mode", "Selector", cameraEnumNames, startingCameraEnumItem)
this.CameraModeOverrideText = utility:Create'TextLabel'
{
Name = "CameraDevOverrideLabel",
Text = "Set by Developer",
TextColor3 = Color3.new(1,1,1),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size24,
BackgroundTransparency = 1,
Size = UDim2.new(0,200,1,0),
Position = UDim2.new(1,-350,0,0),
Visible = false,
ZIndex = 2,
Parent = this.CameraModeFrame
};
this.CameraMode.IndexChanged:connect(function(newIndex)
local newEnumSetting = cameraEnumNameToItem[cameraEnumNames[newIndex]]
if UserInputService.TouchEnabled then
GameSettings.TouchCameraMovementMode = newEnumSetting
else
GameSettings.ComputerCameraMovementMode = newEnumSetting
end
end)
end
------------------------------------------------------
------------------
------------------ VR Camera Mode -----------------------
if HasVRAPI and UserInputService.VREnabled then
local VR_ROTATION_INTENSITY_OPTIONS = {"Low", "High", "Smooth"}
if utility:IsSmallTouchScreen() then
this.VRRotationFrame,
this.VRRotationLabel,
this.VRRotationMode = utility:AddNewRow(this, "VR Camera Rotation", "Selector", VR_ROTATION_INTENSITY_OPTIONS, GameSettings.VRRotationIntensity)
else
this.VRRotationFrame,
this.VRRotationLabel,
this.VRRotationMode = utility:AddNewRow(this, "VR Camera Rotation", "Selector", VR_ROTATION_INTENSITY_OPTIONS, GameSettings.VRRotationIntensity, 3)
end
StarterGui:RegisterGetCore("VRRotationIntensity",
function()
return VR_ROTATION_INTENSITY_OPTIONS[GameSettings.VRRotationIntensity] or VR_ROTATION_INTENSITY_OPTIONS[1]
end)
this.VRRotationMode.IndexChanged:connect(function(newIndex)
GameSettings.VRRotationIntensity = newIndex
end)
end
------------------------------------------------------
------------------
------------------ Movement Mode ---------------------
if movementModeEnabled then
local movementEnumItems = nil
local startingMovementEnumItem = 1
if UserInputService.TouchEnabled then
movementEnumItems = Enum.TouchMovementMode:GetEnumItems()
else
movementEnumItems = Enum.ComputerMovementMode:GetEnumItems()
end
local movementEnumNames = {}
local movementEnumNameToItem = {}
for i = 1, #movementEnumItems do
local displayName = movementEnumItems[i].Name
if displayName == "Default" then
displayName = MOVEMENT_MODE_DEFAULT_STRING
elseif displayName == "KeyboardMouse" then
displayName = MOVEMENT_MODE_KEYBOARDMOUSE_STRING
elseif displayName == "ClickToMove" then
displayName = MOVEMENT_MODE_CLICKTOMOVE_STRING
end
if UserInputService.TouchEnabled then
if GameSettings.TouchMovementMode == movementEnumItems[i] then
startingMovementEnumItem = i
end
else
if GameSettings.ComputerMovementMode == movementEnumItems[i] then
startingMovementEnumItem = i
end
end
movementEnumNames[i] = displayName
movementEnumNameToItem[displayName] = movementEnumItems[i]
end
this.MovementModeFrame,
this.MovementModeLabel,
this.MovementMode = utility:AddNewRow(this, "Movement Mode", "Selector", movementEnumNames, startingMovementEnumItem)
this.MovementModeOverrideText = utility:Create'TextLabel'
{
Name = "MovementDevOverrideLabel",
Text = "Set by Developer",
TextColor3 = Color3.new(1,1,1),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size24,
BackgroundTransparency = 1,
Size = UDim2.new(0,200,1,0),
Position = UDim2.new(1,-350,0,0),
Visible = false,
ZIndex = 2,
Parent = this.MovementModeFrame
};
this.MovementMode.IndexChanged:connect(function(newIndex)
local newEnumSetting = movementEnumNameToItem[movementEnumNames[newIndex]]
if UserInputService.TouchEnabled then
GameSettings.TouchMovementMode = newEnumSetting
else
GameSettings.ComputerMovementMode = newEnumSetting
end
end)
end
------------------------------------------------------
------------------
------------------------- Connection Setup -----------
function setCameraModeVisible(visible)
if this.CameraMode then
this.CameraMode.SelectorFrame.Visible = visible
this.CameraMode:SetInteractable(visible)
end
end
function setMovementModeVisible(visible)
if this.MovementMode then
this.MovementMode.SelectorFrame.Visible = visible
this.MovementMode:SetInteractable(visible)
end
end
function setShiftLockVisible(visible)
if this.ShiftLockMode then
this.ShiftLockMode.SelectorFrame.Visible = visible
this.ShiftLockMode:SetInteractable(visible)
end
end
do -- initial set of dev vs user choice for guis
local isUserChoiceCamera = false
if UserInputService.TouchEnabled then
isUserChoiceCamera = LocalPlayer.DevTouchCameraMode == Enum.DevTouchCameraMovementMode.UserChoice
else
isUserChoiceCamera = LocalPlayer.DevComputerCameraMode == Enum.DevComputerCameraMovementMode.UserChoice
end
if not isUserChoiceCamera then
this.CameraModeOverrideText.Visible = true
setCameraModeVisible(false)
else
this.CameraModeOverrideText.Visible = false
setCameraModeVisible(true)
end
local isUserChoiceMovement = false
if UserInputService.TouchEnabled then
isUserChoiceMovement = LocalPlayer.DevTouchMovementMode == Enum.DevTouchMovementMode.UserChoice
else
isUserChoiceMovement = LocalPlayer.DevComputerMovementMode == Enum.DevComputerMovementMode.UserChoice
end
if this.MovementModeOverrideText then
if not isUserChoiceMovement then
this.MovementModeOverrideText.Visible = true
setMovementModeVisible(false)
else
this.MovementModeOverrideText.Visible = false
setMovementModeVisible(true)
end
end
if this.ShiftLockOverrideText then
this.ShiftLockOverrideText.Visible = not LocalPlayer.DevEnableMouseLock
setShiftLockVisible(LocalPlayer.DevEnableMouseLock)
end
end
local function updateUserSettingsMenu(property)
if this.ShiftLockOverrideText and property == "DevEnableMouseLock" then
this.ShiftLockOverrideText.Visible = not LocalPlayer.DevEnableMouseLock
setShiftLockVisible(LocalPlayer.DevEnableMouseLock)
elseif property == "DevComputerCameraMode" then
local isUserChoice = LocalPlayer.DevComputerCameraMode == Enum.DevComputerCameraMovementMode.UserChoice
setCameraModeVisible(isUserChoice)
this.CameraModeOverrideText.Visible = not isUserChoice
elseif property == "DevComputerMovementMode" then
local isUserChoice = LocalPlayer.DevComputerMovementMode == Enum.DevComputerMovementMode.UserChoice
setMovementModeVisible(isUserChoice)
if this.MovementModeOverrideText then
this.MovementModeOverrideText.Visible = not isUserChoice
end
-- TOUCH
elseif property == "DevTouchMovementMode" then
local isUserChoice = LocalPlayer.DevTouchMovementMode == Enum.DevTouchMovementMode.UserChoice
setMovementModeVisible(isUserChoice)
if this.MovementModeOverrideText then
this.MovementModeOverrideText.Visible = not isUserChoice
end
elseif property == "DevTouchCameraMode" then
local isUserChoice = LocalPlayer.DevTouchCameraMode == Enum.DevTouchCameraMovementMode.UserChoice
setCameraModeVisible(isUserChoice)
this.CameraModeOverrideText.Visible = not isUserChoice
end
end
LocalPlayer.Changed:connect(function(property)
if IsTouchClient then
if TOUCH_CHANGED_PROPS[property] then
updateUserSettingsMenu(property)
end
else
if PC_CHANGED_PROPS[property] then
updateUserSettingsMenu(property)
end
end
end)
end
local function createVolumeOptions()
local startVolumeLevel = math.floor(GameSettings.MasterVolume * 10)
this.VolumeFrame,
this.VolumeLabel,
this.VolumeSlider = utility:AddNewRow(this, "Volume", "Slider", 10, startVolumeLevel)
local volumeSound = Instance.new("Sound", game.CoreGui.RobloxGui.Sounds)
volumeSound.Name = "VolumeChangeSound"
volumeSound.SoundId = "rbxasset://sounds/metalstone2.mp3"
this.VolumeSlider.ValueChanged:connect(function(newValue)
local soundPercent = newValue/10
volumeSound.Volume = soundPercent
volumeSound:Play()
GameSettings.MasterVolume = soundPercent
end)
end
local function createMouseOptions()
local MouseSteps = 10
local MinMouseSensitivity = 0.2
local AdvancedSuccess, AdvancedValue = pcall(function() return settings():GetFFlag("AdvancedMouseSensitivityEnabled") end)
local AdvancedEnabled = AdvancedSuccess and AdvancedValue
-- equations below map a function to include points (0, 0.2) (5, 1) (10, 4)
-- where x is the slider position, y is the mouse sensitivity
local function translateEngineMouseSensitivityToGui(engineSensitivity)
return math.floor((2.0/3.0) * (math.sqrt(75.0 * engineSensitivity - 11.0) - 2))
end
local function translateGuiMouseSensitivityToEngine(guiSensitivity)
return 0.03 * math.pow(guiSensitivity,2) + (0.08 * guiSensitivity) + MinMouseSensitivity
end
local startMouseLevel = translateEngineMouseSensitivityToGui(GameSettings.MouseSensitivity)
------------------ Mouse Selection GUI Setup ------------------
-- switch between basic mode and advanced mode.
local MouseModeEnablerStart = 2
if GameSettings.UseBasicMouseSensitivity or not AdvancedEnabled then
MouseModeEnablerStart = 1
end
-- auto-detect mouse invert
local MouseInvertStart = 1
if GameSettings.MouseSensitivityFirstPerson.y < 0 then
MouseInvertStart = 2
end
if AdvancedEnabled then
this.MouseModeFrame,
this.MouseModeLabel,
this.MouseModeEnabler = utility:AddNewRow(this, "Mouse Sensitivity Mode", "Selector", {"Basic", "Advanced"}, MouseModeEnablerStart)
end
------------------ Basic Mouse Sensitivity Slider ------------------
-- basic quantized sensitivity with a weird number of settings.
local SliderLabel = "Basic Mouse Sensitivity"
if not AdvancedEnabled then
SliderLabel = "Mouse Sensitivity"
end
this.MouseSensitivityFrame,
this.MouseSensitivityLabel,
this.MouseSensitivitySlider = utility:AddNewRow(this, SliderLabel, "Slider", MouseSteps, startMouseLevel)
this.MouseSensitivitySlider:SetMinStep(1)
this.MouseSensitivitySlider.ValueChanged:connect(function(newValue)
GameSettings.MouseSensitivity = translateGuiMouseSensitivityToEngine(newValue)
end)
------------------ 3D Sensitivity ------------------
-- affects both first and third person.
if AdvancedEnabled then
local MouseAdvancedStart = tostring(GameSettings.MouseSensitivityFirstPerson.y)
this.MouseAdvancedFrame,
this.MouseAdvancedLabel,
this.MouseAdvancedEntry = utility:AddNewRow(this, "Advanced Mouse Sensitivity", "TextEntry", 1.0, 1.0, MouseAdvancedStart)
this.MouseAdvancedEntry.ValueChanged:connect(function(newValueText)
local currentFirstSensitivity = GameSettings.MouseSensitivityFirstPerson
local currentThirdSensitivity = GameSettings.MouseSensitivityThirdPerson
local newValue = tonumber(newValueText)
if not newValue then
this.MouseAdvancedEntry:SetValue(string.format("%.3f",currentFirstSensitivity.x))
return
end
-- inverted mouse will be handled later
if newValue < 0.0 then
newValue = -newValue
end
-- * assume a minimum that allows a 16000 dpi mouse a full 800mm travel for 360deg
-- ~0.0029: min of 0.001 seems ok.
-- * assume a max that allows a 400 dpi mouse a 360deg travel in 10mm
-- ~9.2: max of 10 seems ok, but users will want to have a bit of fun with crazy settings.
if newValue > 100.0 then
newValue = 100.0
elseif newValue < 0.001 then
newValue = 0.001
end
-- try to keep ratios the same, even though they aren't exposed to the GUI
local firstPersonX = newValue
local firstPersonY = newValue * (currentFirstSensitivity.y / currentFirstSensitivity.x)
local thirdPersonX = newValue * (currentFirstSensitivity.x / currentThirdSensitivity.x)
local thirdPersonY = thirdPersonX * (currentThirdSensitivity.y / currentThirdSensitivity.x)
-- handle invert
if currentFirstSensitivity.y < 0.0 then
firstPersonY = -firstPersonY
end
if currentThirdSensitivity.y < 0.0 then
thirdPersonY = -thirdPersonY
end
GameSettings.MouseSensitivityFirstPerson = Vector2.new(firstPersonX, firstPersonY)
GameSettings.MouseSensitivityThirdPerson = Vector2.new(thirdPersonX, thirdPersonY)
this.MouseAdvancedEntry:SetValue(string.format("%.3f",firstPersonX))
end)
end
------------------ Mouse Invert ------------------
-- This is a common setting in games, even if it is rare
if AdvancedEnabled then
this.MouseInvertFrame,
this.MouseInvertLabel,
this.MouseInvertEnabler = utility:AddNewRow(this, "Advanced Mouse Invert", "Selector", {"Normal", "Inverted"}, MouseInvertStart)
this.MouseInvertEnabler.IndexChanged:connect(function(newIndex)
local currentFirstSensitivity = GameSettings.MouseSensitivityFirstPerson
local currentThirdSensitivity = GameSettings.MouseSensitivityThirdPerson
if newIndex == 1 then
if currentFirstSensitivity.y < 0.0 then
currentFirstSensitivity = Vector2.new(currentFirstSensitivity.x, -currentFirstSensitivity.y)
currentThirdSensitivity = Vector2.new(currentThirdSensitivity.x, -currentThirdSensitivity.y)
end
elseif newIndex == 2 then
if currentFirstSensitivity.y > 0.0 then
currentFirstSensitivity = Vector2.new(currentFirstSensitivity.x, -currentFirstSensitivity.y)
currentThirdSensitivity = Vector2.new(currentThirdSensitivity.x, -currentThirdSensitivity.y)
end
end
GameSettings.MouseSensitivityFirstPerson = currentFirstSensitivity
GameSettings.MouseSensitivityThirdPerson = currentThirdSensitivity
end)
end
------------------ Init ------------------
if AdvancedEnabled then
local function setMouseModeToBasic()
this.MouseSensitivitySlider:SetZIndex(2)
this.MouseSensitivityLabel.ZIndex = 2
this.MouseSensitivitySlider:SetInteractable(true)
this.MouseSensitivitySlider:SetValue(translateEngineMouseSensitivityToGui(GameSettings.MouseSensitivity))
this.MouseAdvancedLabel.ZIndex = 1
this.MouseAdvancedEntry:SetInteractable(false)
this.MouseInvertLabel.ZIndex = 1
this.MouseInvertEnabler:SetInteractable(false)
end
local function setMouseModeToAdvanced()
this.MouseSensitivitySlider:SetZIndex(1)
this.MouseSensitivityLabel.ZIndex = 1
this.MouseSensitivitySlider:SetInteractable(false)
this.MouseAdvancedLabel.ZIndex = 2
this.MouseAdvancedEntry:SetInteractable(true)
local MouseSensitivity3d = GameSettings.MouseSensitivityFirstPerson
this.MouseAdvancedEntry:SetValue(tostring(MouseSensitivity3d.x));
this.MouseInvertLabel.ZIndex = 2
this.MouseInvertEnabler:SetInteractable(true)
end
this.MouseModeEnabler.IndexChanged:connect(function(newIndex)
if newIndex == 1 then
GameSettings.UseBasicMouseSensitivity = true
setMouseModeToBasic()
elseif newIndex == 2 then
GameSettings.UseBasicMouseSensitivity = false
setMouseModeToAdvanced()
end
end)
if GameSettings.UseBasicMouseSensitivity then
setMouseModeToBasic()
this.MouseAdvancedEntry:SetValue(tostring(MouseAdvancedStart))
else
setMouseModeToAdvanced()
end
end
end
local function createOverscanOption()
local showOverscanScreen = function()
if not overscanScreen then
local createOverscanFunc = require(RobloxGui.Modules.OverscanScreen)
overscanScreen = createOverscanFunc(RobloxGui)
overscanScreen:SetStyleForInGame()
end
local MenuModule = require(RobloxGui.Modules.Settings.SettingsHub)
MenuModule:SetVisibility(false, true)
local closedCon = nil
closedCon = overscanScreen.Closed:connect(function()
closedCon:disconnect()
pcall(function() PlatformService.BlurIntensity = 0 end)
ContextActionService:UnbindCoreAction("RbxStopOverscanMovement")
MenuModule:SetVisibility(true, true)
end)
pcall(function() PlatformService.BlurIntensity = 10 end)
local noOpFunc = function() end
ContextActionService:BindCoreAction("RbxStopOverscanMovement", noOpFunc, false,
Enum.UserInputType.Gamepad1, Enum.UserInputType.Gamepad2,
Enum.UserInputType.Gamepad3, Enum.UserInputType.Gamepad4)
local ScreenManager = require(RobloxGui.Modules.ScreenManager)
ScreenManager:OpenScreen(overscanScreen)
end
local adjustButton, adjustText, setButtonRowRef = utility:MakeStyledButton("AdjustButton", "Adjust", UDim2.new(0,300,1,-20), showOverscanScreen, this)
adjustText.Font = Enum.Font.SourceSans
adjustButton.Position = UDim2.new(1,-400,0,12)
local row = utility:AddNewRowObject(this, "Safe Zone", adjustButton)
setButtonRowRef(row)
end
createCameraModeOptions(not isTenFootInterface and
(UserInputService.TouchEnabled or UserInputService.MouseEnabled or UserInputService.KeyboardEnabled))
if UserInputService.MouseEnabled then
createMouseOptions()
end
createVolumeOptions()
if platform == Enum.Platform.Windows or platform == Enum.Platform.UWP or platform == Enum.Platform.OSX then
createGraphicsOptions()
end
if isTenFootInterface then
createOverscanOption()
end
------ TAB CUSTOMIZATION -------
this.TabHeader.Name = "GameSettingsTab"
this.TabHeader.Icon.Image = "rbxasset://textures/ui/Settings/MenuBarIcons/GameSettingsTab.png"
if utility:IsSmallTouchScreen() then
this.TabHeader.Icon.Size = UDim2.new(0,34,0,34)
this.TabHeader.Icon.Position = UDim2.new(this.TabHeader.Icon.Position.X.Scale,this.TabHeader.Icon.Position.X.Offset,0.5,-17)
this.TabHeader.Size = UDim2.new(0,125,1,0)
elseif isTenFootInterface then
this.TabHeader.Icon.Image = "rbxasset://textures/ui/Settings/MenuBarIcons/GameSettingsTab@2x.png"
this.TabHeader.Icon.Size = UDim2.new(0,90,0,90)
this.TabHeader.Icon.Position = UDim2.new(0,0,0.5,-43)
this.TabHeader.Size = UDim2.new(0,280,1,0)
else
this.TabHeader.Icon.Size = UDim2.new(0,45,0,45)
this.TabHeader.Icon.Position = UDim2.new(0,15,0.5,-22)
end
this.TabHeader.Icon.Title.Text = "Settings"
------ PAGE CUSTOMIZATION -------
this.Page.ZIndex = 5
return this
end
----------- Page Instantiation --------------
PageInstance = Initialize()
return PageInstance
@@ -0,0 +1,489 @@
--[[
Filename: Help.lua
Written by: jeditkacheff
Version 1.0
Description: Takes care of the help page in Settings Menu
--]]
-------------- CONSTANTS --------------
local KEYBOARD_MOUSE_TAG = "KeyboardMouse"
local TOUCH_TAG = "Touch"
local GAMEPAD_TAG = "Gamepad"
local PC_TABLE_SPACING = 4
-------------- SERVICES --------------
local CoreGui = game:GetService("CoreGui")
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
local UserInputService = game:GetService("UserInputService")
local GuiService = game:GetService("GuiService")
----------- UTILITIES --------------
local utility = require(RobloxGui.Modules.Settings.Utility)
------------ Variables -------------------
local PageInstance = nil
RobloxGui:WaitForChild("Modules"):WaitForChild("TenFootInterface")
local isTenFootInterface = require(RobloxGui.Modules.TenFootInterface):IsEnabled()
----------- CLASS DECLARATION --------------
local function Initialize()
local settingsPageFactory = require(RobloxGui.Modules.Settings.SettingsPageFactory)
local this = settingsPageFactory:CreateNewPage()
this.HelpPages = {}
-- TODO: Change dev console script to parent this to somewhere other than an engine created gui
local ControlFrame = RobloxGui:WaitForChild('ControlFrame')
local ToggleDevConsoleBindableFunc = ControlFrame:WaitForChild('ToggleDevConsole')
local lastInputType = nil
function this:GetCurrentInputType()
if lastInputType == nil then -- we don't know what controls the user has, just use reasonable defaults
local platform = UserInputService:GetPlatform()
if platform == Enum.Platform.XBoxOne or platform == Enum.Platform.WiiU then
return GAMEPAD_TAG
elseif platform == Enum.Platform.Windows or platform == Enum.Platform.OSX then
return KEYBOARD_MOUSE_TAG
else
return TOUCH_TAG
end
end
if lastInputType == Enum.UserInputType.Keyboard or lastInputType == Enum.UserInputType.MouseMovement or
lastInputType == Enum.UserInputType.MouseButton1 or lastInputType == Enum.UserInputType.MouseButton2 or
lastInputType == Enum.UserInputType.MouseButton3 or lastInputType == Enum.UserInputType.MouseWheel then
return KEYBOARD_MOUSE_TAG
elseif lastInputType == Enum.UserInputType.Touch then
return TOUCH_TAG
elseif lastInputType == Enum.UserInputType.Gamepad1 or lastInputType == Enum.UserInputType.Gamepad2 or
inputType == Enum.UserInputType.Gamepad3 or lastInputType == Enum.UserInputType.Gamepad4 then
return GAMEPAD_TAG
end
return KEYBOARD_MOUSE_TAG
end
local function createPCHelp(parentFrame)
local function createPCGroup(title, actionInputBindings)
local textIndent = 9
local pcGroupFrame = utility:Create'Frame'
{
Size = UDim2.new(1/3,-PC_TABLE_SPACING,1,0),
BackgroundTransparency = 1,
Name = "PCGroupFrame" .. tostring(title)
};
local pcGroupTitle = utility:Create'TextLabel'
{
Position = UDim2.new(0,textIndent,0,0),
Size = UDim2.new(1,-textIndent,0,30),
BackgroundTransparency = 1,
Text = title,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size18,
TextColor3 = Color3.new(1,1,1),
TextXAlignment = Enum.TextXAlignment.Left,
Name = "PCGroupTitle" .. tostring(title),
ZIndex = 2,
Parent = pcGroupFrame
};
local count = 0
local frameHeight = 42
local spacing = 2
local offset = pcGroupTitle.Size.Y.Offset
for i = 1, #actionInputBindings do
for actionName, inputName in pairs(actionInputBindings[i]) do
local actionInputFrame = utility:Create'Frame'
{
Size = UDim2.new(1,0,0,frameHeight),
Position = UDim2.new(0,0,0, offset + ((frameHeight + spacing) * count)),
BackgroundTransparency = 0.65,
BorderSizePixel = 0,
ZIndex = 2,
Name = "ActionInputBinding" .. tostring(actionName),
Parent = pcGroupFrame
};
local nameLabel = utility:Create'TextLabel'
{
Size = UDim2.new(0.4,-textIndent,0,frameHeight),
Position = UDim2.new(0,textIndent,0,0),
BackgroundTransparency = 1,
Text = actionName,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size18,
TextColor3 = Color3.new(1,1,1),
TextXAlignment = Enum.TextXAlignment.Left,
Name = actionName .. "Label",
ZIndex = 2,
Parent = actionInputFrame
};
local inputLabel = utility:Create'TextLabel'
{
Size = UDim2.new(0.6,0,0,frameHeight),
Position = UDim2.new(0.5,-4,0,0),
BackgroundTransparency = 1,
Text = inputName,
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size18,
TextColor3 = Color3.new(1,1,1),
TextXAlignment = Enum.TextXAlignment.Left,
Name = inputName .. "Label",
ZIndex = 2,
Parent = actionInputFrame
};
count = count + 1
end
end
pcGroupFrame.Size = UDim2.new(pcGroupFrame.Size.X.Scale,pcGroupFrame.Size.X.Offset,
0, offset + ((frameHeight + spacing) * count))
return pcGroupFrame
end
local rowOffset = 50
local isOSX = UserInputService:GetPlatform() == Enum.Platform.OSX
local charMoveFrame = createPCGroup( "Character Movement", {[1] = {["Move Forward"] = "W/Up Arrow"},
[2] = {["Move Backward"] = "S/Down Arrow"},
[3] = {["Move Left"] = "A/Left Arrow"},
[4] = {["Move Right"] = "D/Right Arrow"},
[5] = {["Jump"] = "Space"}} )
charMoveFrame.Parent = parentFrame
local accessoriesFrame = createPCGroup("Accessories", { [1] = {["Equip Tools"] = "1,2,3..."},
[2] = {["Unequip Tools"] = "1,2,3..."},
[3] = {["Drop Tool"] = "Backspace"},
[4] = {["Use Tool"] = "Left Mouse Button"},
[5] = {["Drop Hats"] = "+"} })
accessoriesFrame.Position = UDim2.new(1/3,PC_TABLE_SPACING,0,0)
accessoriesFrame.Parent = parentFrame
local miscFrame = nil
local hideHudSuccess, hideHudFlagValue = pcall(function() return settings():GetFFlag("AllowHideHudShortcut") end)
if (hideHudSuccess and hideHudFlagValue) then
miscFrame = createPCGroup("Misc", { [1] = {["Screenshot"] = "Print Screen"},
[2] = {["Record Video"] = isOSX and "F12/fn + F12" or "F12"},
[3] = {["Hide HUD"] = isOSX and "F7/fn + F7" or "F7"},
[4] = {["Dev Console"] = isOSX and "F9/fn + F9" or "F9"},
[5] = {["Mouselock"] = "Shift"},
[6] = {["Graphics Level"] = isOSX and "F10/fn + F10" or "F10"},
[7] = {["Fullscreen"] = isOSX and "F11/fn + F11" or "F11"} })
else
miscFrame = createPCGroup("Misc", { [1] = {["Screenshot"] = "Print Screen"},
[2] = {["Record Video"] = isOSX and "F12/fn + F12" or "F12"},
[3] = {["Dev Console"] = isOSX and "F9/fn + F9" or "F9"},
[4] = {["Mouselock"] = "Shift"},
[5] = {["Graphics Level"] = isOSX and "F10/fn + F10" or "F10"},
[6] = {["Fullscreen"] = isOSX and "F11/fn + F11" or "F11"} })
end
miscFrame.Position = UDim2.new(2/3,PC_TABLE_SPACING * 2,0,0)
miscFrame.Parent = parentFrame
local camFrame = createPCGroup("Camera Movement", { [1] = {["Rotate"] = "Right Mouse Button"},
[2] = {["Zoom In/Out"] = "Mouse Wheel"},
[3] = {["Zoom In"] = "I"},
[4] = {["Zoom Out"] = "O"} })
camFrame.Position = UDim2.new(0,0,charMoveFrame.Size.Y.Scale,charMoveFrame.Size.Y.Offset + rowOffset)
camFrame.Parent = parentFrame
local menuFrame = createPCGroup("Menu Items", { [1] = {["ROBLOX Menu"] = "ESC"},
[2] = {["Backpack"] = "~"},
[3] = {["Playerlist"] = "TAB"},
[4] = {["Chat"] = "/"} })
menuFrame.Position = UDim2.new(1/3,PC_TABLE_SPACING,charMoveFrame.Size.Y.Scale,charMoveFrame.Size.Y.Offset + rowOffset)
menuFrame.Parent = parentFrame
parentFrame.Size = UDim2.new(parentFrame.Size.X.Scale, parentFrame.Size.X.Offset, 0,
menuFrame.Size.Y.Offset + menuFrame.Position.Y.Offset)
end
local function createGamepadHelp(parentFrame)
local gamepadImage = "rbxasset://textures/ui/Settings/Help/GenericController.png"
local imageSize = UDim2.new(0,650,0,239)
local imagePosition = UDim2.new(0.5,-imageSize.X.Offset/2,0.5,-imageSize.Y.Offset/2)
if UserInputService:GetPlatform() == Enum.Platform.XBoxOne or UserInputService:GetPlatform() == Enum.Platform.XBox360 then
gamepadImage = "rbxasset://textures/ui/Settings/Help/XboxController.png"
imageSize = UDim2.new(0,1334,0,570)
imagePosition = UDim2.new(0.5, (-imageSize.X.Offset/2) - 50, 0.5, -imageSize.Y.Offset/2)
elseif UserInputService:GetPlatform() == Enum.Platform.PS4 or UserInputService:GetPlatform() == Enum.Platform.PS3 then
gamepadImage = "rbxasset://textures/ui/Settings/Help/PSController.png"
end
local gamepadImageLabel = utility:Create'ImageLabel'
{
Name = "GamepadImage",
Size = imageSize,
Position = imagePosition,
Image = gamepadImage,
BackgroundTransparency = 1,
ZIndex = 2,
Parent = parentFrame
};
parentFrame.Size = UDim2.new(parentFrame.Size.X.Scale, parentFrame.Size.X.Offset, 0, gamepadImageLabel.Size.Y.Offset + 100)
local gamepadFontSize = isTenFootInterface and Enum.FontSize.Size36 or Enum.FontSize.Size24
local function createGamepadLabel(text, position, size)
local nameLabel = utility:Create'TextLabel'
{
Position = position,
Size = size,
BackgroundTransparency = 1,
Text = text,
TextXAlignment = Enum.TextXAlignment.Left,
Font = Enum.Font.SourceSansBold,
FontSize = gamepadFontSize,
TextColor3 = Color3.new(1,1,1),
Name = text .. "Label",
ZIndex = 2,
Parent = gamepadImageLabel
};
end
local textVerticalSize = (gamepadFontSize == Enum.FontSize.Size36) and 36 or 24
if gamepadImage == "rbxasset://textures/ui/Settings/Help/XboxController.png" then
createGamepadLabel("Switch Tool", UDim2.new(0,50,0,-textVerticalSize/2), UDim2.new(0,100,0,textVerticalSize))
createGamepadLabel("Game Menu Toggle", UDim2.new(0,-38,0.15,-textVerticalSize/2), UDim2.new(0,164,0,textVerticalSize))
createGamepadLabel("Move", UDim2.new(0,-80,0.31,-textVerticalSize/2), UDim2.new(0,46,0,textVerticalSize))
createGamepadLabel("Menu Navigation", UDim2.new(0,-50,0.46,-textVerticalSize/2), UDim2.new(0,164,0,textVerticalSize))
createGamepadLabel("Use Tool", UDim2.new(0.96,0,0,-textVerticalSize/2), UDim2.new(0,73,0,textVerticalSize))
createGamepadLabel("ROBLOX Menu", UDim2.new(0.96,0,0.15,-textVerticalSize/2), UDim2.new(0,122,0,textVerticalSize))
createGamepadLabel("Back", UDim2.new(0.96,0,0.31,-textVerticalSize/2), UDim2.new(0,43,0,textVerticalSize))
createGamepadLabel("Jump", UDim2.new(0.96,0,0.46,-textVerticalSize/2), UDim2.new(0,49,0,textVerticalSize))
createGamepadLabel("Rotate Camera", UDim2.new(1,0,0.62,-textVerticalSize/2), UDim2.new(0,132,0,textVerticalSize))
createGamepadLabel("Camera Zoom", UDim2.new(1,0,0.77,-textVerticalSize/2), UDim2.new(0,122,0,textVerticalSize))
else
createGamepadLabel("Switch Tool", UDim2.new(-0.01,0,0,-textVerticalSize/2), UDim2.new(0,100,0,textVerticalSize))
createGamepadLabel("Game Menu Toggle", UDim2.new(-0.11,0,0.15,-textVerticalSize/2), UDim2.new(0,164,0,textVerticalSize))
createGamepadLabel("Move", UDim2.new(-0.08,0,0.31,-textVerticalSize/2), UDim2.new(0,46,0,textVerticalSize))
createGamepadLabel("Menu Navigation", UDim2.new(-0.125,0,0.46,-textVerticalSize/2), UDim2.new(0,164,0,textVerticalSize))
createGamepadLabel("Use Tool", UDim2.new(0.96,0,0,-textVerticalSize/2), UDim2.new(0,73,0,textVerticalSize))
createGamepadLabel("ROBLOX Menu", UDim2.new(0.9,0,0.15,-textVerticalSize/2), UDim2.new(0,122,0,textVerticalSize))
createGamepadLabel("Back", UDim2.new(1.01,0,0.31,-textVerticalSize/2), UDim2.new(0,43,0,textVerticalSize))
createGamepadLabel("Jump", UDim2.new(0.91,0,0.46,-textVerticalSize/2), UDim2.new(0,49,0,textVerticalSize))
createGamepadLabel("Rotate Camera", UDim2.new(0.91,0,0.62,-textVerticalSize/2), UDim2.new(0,132,0,textVerticalSize))
createGamepadLabel("Camera Zoom", UDim2.new(0.91,0,0.77,-textVerticalSize/2), UDim2.new(0,122,0,textVerticalSize))
end
-- todo: turn on dev console button when dev console is ready
--[[local openDevConsoleFunc = function()
this.HubRef:SetVisibility(false)
ToggleDevConsoleBindableFunc:Invoke()
end
local devConsoleButton = utility:MakeStyledButton("ConsoleButton", " Toggle Dev Console", UDim2.new(0,300,0,44), openDevConsoleFunc)
devConsoleButton.Size = UDim2.new(devConsoleButton.Size.X.Scale, devConsoleButton.Size.X.Offset, 0, 60)
devConsoleButton.Position = UDim2.new(1,-300,1,30)
if UserInputService.GamepadEnabled and not UserInputService.TouchEnabled and not UserInputService.MouseEnabled and not UserInputService.KeyboardEnabled then
devConsoleButton.ImageTransparency = 1
end
devConsoleButton.Parent = gamepadImageLabel
local aButtonImage = utility:Create'ImageLabel'
{
Name = "AButtonImage",
Size = UDim2.new(0,55,0,55),
Position = UDim2.new(0,5,0.5,-28),
Image = "rbxasset://textures/ui/Settings/Help/AButtonDark.png",
BackgroundTransparency = 1,
ZIndex = 2,
Parent = devConsoleButton
};
this:AddRow(nil, nil, devConsoleButton, 340)]]
end
local function createTouchHelp(parentFrame)
local smallScreen = utility:IsSmallTouchScreen()
local ySize = GuiService:GetScreenResolution().y - 350
if smallScreen then
ySize = GuiService:GetScreenResolution().y - 100
end
parentFrame.Size = UDim2.new(1,0,0,ySize)
local function createTouchLabel(text, position, size, parent)
local nameLabel = utility:Create'TextLabel'
{
Position = position,
Size = size,
BackgroundTransparency = 1,
Text = text,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size14,
TextColor3 = Color3.new(1,1,1),
Name = text .. "Label",
ZIndex = 2,
Parent = parent
};
if not smallScreen then
nameLabel.FontSize = Enum.FontSize.Size18
nameLabel.Size = UDim2.new(nameLabel.Size.X.Scale, nameLabel.Size.X.Offset, nameLabel.Size.Y.Scale, nameLabel.Size.Y.Offset + 4)
end
local nameBackgroundImage = utility:Create'ImageLabel'
{
Name = text .. "BackgroundImage",
Size = UDim2.new(1,0,1,0),
Position = UDim2.new(0,0,0,2),
BackgroundTransparency = 1,
Image = "rbxasset://textures/ui/Settings/Radial/RadialLabel.png",
ScaleType = Enum.ScaleType.Slice,
SliceCenter = Rect.new(12,2,65,21),
ZIndex = 2,
Parent = nameLabel
};
return nameLabel
end
local function createTouchGestureImage(name, image, position, size, parent)
local gestureImage = utility:Create'ImageLabel'
{
Name = name,
Size = size,
Position = position,
BackgroundTransparency = 1,
Image = image,
ZIndex = 2,
Parent = parent
};
return gestureImage
end
local xSizeOffset = 30
local ySize = 25
if smallScreen then xSizeOffset = 0 end
local moveLabel = createTouchLabel("Move", UDim2.new(0.06,0,0.58,0), UDim2.new(0,77 + xSizeOffset,0,ySize), parentFrame)
if not smallScreen then moveLabel.Position = UDim2.new(-0.03,0,0.7,0) end
local jumpLabel = createTouchLabel("Jump", UDim2.new(0.8,0,0.58,0), UDim2.new(0,77 + xSizeOffset,0,ySize), parentFrame)
if not smallScreen then jumpLabel.Position = UDim2.new(0.85,0,0.7,0) end
local equipLabel = createTouchLabel("Equip/Unequip Tools", UDim2.new(0.5,-60,0.64,0), UDim2.new(0,120 + xSizeOffset,0,ySize), parentFrame)
if not smallScreen then equipLabel.Position = UDim2.new(0.5,-60,0.95,0) end
local zoomLabel = createTouchLabel("Zoom In/Out", UDim2.new(0.15,-60,0.02,0), UDim2.new(0,120,0,ySize), parentFrame)
createTouchGestureImage("ZoomImage", "rbxasset://textures/ui/Settings/Help/ZoomGesture.png", UDim2.new(0.5,-26,1,3), UDim2.new(0,53,0,59), zoomLabel)
local rotateLabel = createTouchLabel("Rotate Camera", UDim2.new(0.5,-60,0.02,0), UDim2.new(0,120,0,ySize), parentFrame)
createTouchGestureImage("RotateImage", "rbxasset://textures/ui/Settings/Help/RotateCameraGesture.png", UDim2.new(0.5,-32,1,3), UDim2.new(0,65,0,48), rotateLabel)
local useToolLabel = createTouchLabel("Use Tool", UDim2.new(0.85,-60,0.02,0), UDim2.new(0,120,0,ySize), parentFrame)
createTouchGestureImage("ToolImage", "rbxasset://textures/ui/Settings/Help/UseToolGesture.png", UDim2.new(0.5,-19,1,3), UDim2.new(0,38,0,52), useToolLabel)
end
local function createHelpDisplay(typeOfHelp)
local helpFrame = utility:Create'Frame'
{
Size = UDim2.new(1,0,1,0),
BackgroundTransparency = 1,
Name = "HelpFrame" .. tostring(typeOfHelp)
};
if typeOfHelp == KEYBOARD_MOUSE_TAG then
createPCHelp(helpFrame)
elseif typeOfHelp == GAMEPAD_TAG then
createGamepadHelp(helpFrame)
elseif typeOfHelp == TOUCH_TAG then
createTouchHelp(helpFrame)
end
return helpFrame
end
local function displayHelp(currentPage)
for i, helpPage in pairs(this.HelpPages) do
if helpPage == currentPage then
helpPage.Parent = this.Page
this.Page.Size = helpPage.Size
else
helpPage.Parent = nil
end
end
if UserInputService:GetPlatform() == Enum.Platform.XBoxOne then
this.HubRef.PageViewClipper.ClipsDescendants = false
this.HubRef.PageView.ClipsDescendants = false
end
end
local function switchToHelp(typeOfHelp)
local helpPage = this.HelpPages[typeOfHelp]
if helpPage then
displayHelp(helpPage)
else
this.HelpPages[typeOfHelp] = createHelpDisplay(typeOfHelp)
switchToHelp(typeOfHelp)
end
end
local function showTypeOfHelp()
switchToHelp(this:GetCurrentInputType())
end
------ TAB CUSTOMIZATION -------
this.TabHeader.Name = "HelpTab"
this.TabHeader.Icon.Image = "rbxasset://textures/ui/Settings/MenuBarIcons/HelpTab.png"
if utility:IsSmallTouchScreen() then
this.TabHeader.Icon.Size = UDim2.new(0,33,0,33)
this.TabHeader.Icon.Position = UDim2.new(this.TabHeader.Icon.Position.X.Scale,this.TabHeader.Icon.Position.X.Offset,0.5,-16)
this.TabHeader.Size = UDim2.new(0,100,1,0)
elseif isTenFootInterface then
this.TabHeader.Icon.Image = "rbxasset://textures/ui/Settings/MenuBarIcons/HelpTab@2x.png"
this.TabHeader.Icon.Size = UDim2.new(0,90,0,90)
this.TabHeader.Icon.Position = UDim2.new(0,0,0.5,-43)
this.TabHeader.Size = UDim2.new(0,210,1,0)
else
this.TabHeader.Icon.Size = UDim2.new(0,44,0,44)
this.TabHeader.Icon.Position = UDim2.new(this.TabHeader.Icon.Position.X.Scale,this.TabHeader.Icon.Position.X.Offset,0.5,-22)
this.TabHeader.Size = UDim2.new(0,130,1,0)
end
this.TabHeader.Icon.Title.Text = "Help"
------ PAGE CUSTOMIZATION -------
this.Page.Name = "Help"
UserInputService.InputBegan:connect(function(inputObject)
local inputType = inputObject.UserInputType
if inputType ~= Enum.UserInputType.Focus and inputType ~= Enum.UserInputType.None then
lastInputType = inputObject.UserInputType
showTypeOfHelp()
end
end)
return this
end
----------- Public Facing API Additions --------------
do
PageInstance = Initialize()
PageInstance.Displayed.Event:connect(function()
if PageInstance:GetCurrentInputType() == TOUCH_TAG then
if PageInstance.HubRef.BottomButtonFrame and not utility:IsSmallTouchScreen() then
PageInstance.HubRef.BottomButtonFrame.Visible = false
end
end
end)
PageInstance.Hidden.Event:connect(function()
PageInstance.HubRef.PageViewClipper.ClipsDescendants = true
PageInstance.HubRef.PageView.ClipsDescendants = true
PageInstance.HubRef:ShowShield()
if PageInstance:GetCurrentInputType() == TOUCH_TAG then
PageInstance.HubRef.BottomButtonFrame.Visible = true
end
end)
end
return PageInstance
@@ -0,0 +1,124 @@
--[[
Filename: LeaveGame.lua
Written by: jeditkacheff
Version 1.0
Description: Takes care of the leave game in Settings Menu
--]]
-------------- CONSTANTS -------------
local LEAVE_GAME_ACTION = "LeaveGameCancelAction"
-------------- SERVICES --------------
local CoreGui = game:GetService("CoreGui")
local ContextActionService = game:GetService("ContextActionService")
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
local GuiService = game:GetService("GuiService")
----------- UTILITIES --------------
local utility = require(RobloxGui.Modules.Settings.Utility)
------------ Variables -------------------
local PageInstance = nil
RobloxGui:WaitForChild("Modules"):WaitForChild("TenFootInterface")
local isTenFootInterface = require(RobloxGui.Modules.TenFootInterface):IsEnabled()
----------- CLASS DECLARATION --------------
local function Initialize()
local settingsPageFactory = require(RobloxGui.Modules.Settings.SettingsPageFactory)
local this = settingsPageFactory:CreateNewPage()
this.DontLeaveFunc = function(isUsingGamepad)
if this.HubRef then
this.HubRef:PopMenu(isUsingGamepad, true)
end
end
this.DontLeaveFromHotkey = function(name, state, input)
if state == Enum.UserInputState.Begin then
local isUsingGamepad = input.UserInputType == Enum.UserInputType.Gamepad1 or input.UserInputType == Enum.UserInputType.Gamepad2
or input.UserInputType == Enum.UserInputType.Gamepad3 or input.UserInputType == Enum.UserInputType.Gamepad4
this.DontLeaveFunc(isUsingGamepad)
end
end
this.DontLeaveFromButton = function(isUsingGamepad)
this.DontLeaveFunc(isUsingGamepad)
end
------ TAB CUSTOMIZATION -------
this.TabHeader = nil -- no tab for this page
------ PAGE CUSTOMIZATION -------
this.Page.Name = "LeaveGamePage"
local leaveGameText = utility:Create'TextLabel'
{
Name = "LeaveGameText",
Text = "Are you sure you want to leave the game?",
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size36,
TextColor3 = Color3.new(1,1,1),
BackgroundTransparency = 1,
Size = UDim2.new(1,0,0,200),
TextWrapped = true,
ZIndex = 2,
Parent = this.Page
};
if utility:IsSmallTouchScreen() then
leaveGameText.FontSize = Enum.FontSize.Size24
leaveGameText.Size = UDim2.new(1,0,0,100)
elseif isTenFootInterface then
leaveGameText.FontSize = Enum.FontSize.Size48
end
local buttonSpacing = 20
local buttonSize = UDim2.new(0, 200, 0, 50)
if isTenFootInterface then
leaveGameText.Position = UDim2.new(0,0,0,100)
buttonSize = UDim2.new(0, 300, 0, 80)
end
this.LeaveGameButton = utility:MakeStyledButton("LeaveGame", "Leave", buttonSize)
this.LeaveGameButton.NextSelectionRight = nil
this.LeaveGameButton:SetVerb("Exit")
if utility:IsSmallTouchScreen() then
this.LeaveGameButton.Position = UDim2.new(0.5, -buttonSize.X.Offset - buttonSpacing, 1, 0)
else
this.LeaveGameButton.Position = UDim2.new(0.5, -buttonSize.X.Offset - buttonSpacing, 1, -30)
end
this.LeaveGameButton.Parent = leaveGameText
------------- Init ----------------------------------
local dontleaveGameButton = utility:MakeStyledButton("DontLeaveGame", "Don't Leave", buttonSize, this.DontLeaveFromButton)
dontleaveGameButton.NextSelectionLeft = nil
if utility:IsSmallTouchScreen() then
dontleaveGameButton.Position = UDim2.new(0.5, buttonSpacing, 1, 0)
else
dontleaveGameButton.Position = UDim2.new(0.5, buttonSpacing, 1, -30)
end
dontleaveGameButton.Parent = leaveGameText
this.Page.Size = UDim2.new(1,0,0,dontleaveGameButton.AbsolutePosition.Y + dontleaveGameButton.AbsoluteSize.Y)
return this
end
----------- Public Facing API Additions --------------
PageInstance = Initialize()
PageInstance.Displayed.Event:connect(function()
GuiService.SelectedCoreObject = PageInstance.LeaveGameButton
ContextActionService:BindCoreAction(LEAVE_GAME_ACTION, PageInstance.DontLeaveFromHotkey, false, Enum.KeyCode.ButtonB)
end)
PageInstance.Hidden.Event:connect(function()
ContextActionService:UnbindCoreAction(LEAVE_GAME_ACTION)
end)
return PageInstance
@@ -0,0 +1,170 @@
--[[r
Filename: Record.lua
Written by: jeditkacheff
Version 1.0
Description: Takes care of the Record Tab in Settings Menu
--]]
-------------- SERVICES --------------
local CoreGui = game:GetService("CoreGui")
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
local GuiService = game:GetService("GuiService")
local Settings = UserSettings()
local GameSettings = Settings.GameSettings
----------- UTILITIES --------------
RobloxGui:WaitForChild("Modules"):WaitForChild("TenFootInterface")
local utility = require(RobloxGui.Modules.Settings.Utility)
local isTenFootInterface = require(RobloxGui.Modules.TenFootInterface):IsEnabled()
------------ Variables -------------------
local PageInstance = nil
----------- CLASS DECLARATION --------------
local function Initialize()
local settingsPageFactory = require(RobloxGui.Modules.Settings.SettingsPageFactory)
local this = settingsPageFactory:CreateNewPage()
local isRecordingVideo = false
local recordingEvent = Instance.new("BindableEvent")
recordingEvent.Name = "RecordingEvent"
this.RecordingChanged = recordingEvent.Event
function this:IsRecording()
return isRecordingVideo
end
------ TAB CUSTOMIZATION -------
this.TabHeader.Name = "RecordTab"
this.TabHeader.Icon.Image = "rbxasset://textures/ui/Settings/MenuBarIcons/RecordTab.png"
this.TabHeader.Icon.Size = UDim2.new(0,41,0,40)
this.TabHeader.Icon.Position = UDim2.new(0,5,0.5,-20)
this.TabHeader.Icon.Title.Text = "Record"
this.TabHeader.Size = UDim2.new(0,130,1,0)
------ PAGE CUSTOMIZATION -------
this.Page.Name = "Record"
local function makeTextLabel(name, text, bold, size, pos, parent)
local textLabel = utility:Create'TextLabel'
{
Name = name,
BackgroundTransparency = 1,
Text = text,
TextWrapped = true,
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size24,
TextColor3 = Color3.new(1,1,1),
Size = size,
Position = pos,
TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Top,
ZIndex = 2,
Parent = parent
};
if bold then textLabel.Font = Enum.Font.SourceSansBold end
return textLabel
end
-- need to override this function from SettingsPageFactory
-- DropDown menus require hub to to be set when they are initialized
function this:SetHub(newHubRef)
this.HubRef = newHubRef
local recordEnumNames = {}
recordEnumNames[1] = "Save To Disk"
recordEnumNames[2] = "Upload to YouTube"
local startSetting = 2
if GameSettings.VideoUploadPromptBehavior == Enum.UploadSetting["Never"] then
startSetting = 1
end
---------------------------------- SCREENSHOT -------------------------------------
local screenshotTitle = makeTextLabel("ScreenshotTitle",
"Screenshot",
true, UDim2.new(1,0,0,36), UDim2.new(0,10,0.05,0), this.Page)
screenshotTitle.FontSize = Enum.FontSize.Size36
local screenshotBody = makeTextLabel("ScreenshotBody",
"By clicking the 'Take Screenshot' button, the menu will close and take a screenshot and save it to your computer.",
false, UDim2.new(1,-10,0,70), UDim2.new(0,0,1,0), screenshotTitle)
local closeSettingsFunc = function()
this.HubRef:SetVisibility(false, true)
end
this.ScreenshotButton = utility:MakeStyledButton("ScreenshotButton", "Take Screenshot", UDim2.new(0,300,0,44), closeSettingsFunc, this)
this.ScreenshotButton.Position = UDim2.new(0,400,1,0)
this.ScreenshotButton.Parent = screenshotBody
---------------------------------- VIDEO -------------------------------------
local videoTitle = makeTextLabel("VideoTitle",
"Video",
true, UDim2.new(1,0,0,36), UDim2.new(0,10,0.5,0), this.Page)
videoTitle.FontSize = Enum.FontSize.Size36
local videoBody = makeTextLabel("VideoBody",
"By clicking the 'Record Video' button, the menu will close and start recording your screen.",
false, UDim2.new(1,-10,0,70), UDim2.new(0,0,1,0), videoTitle)
this.VideoSettingsFrame,
this.VideoSettingsLabel,
this.VideoSettingsMode = utility:AddNewRow(this, "Video Settings", "Selector", recordEnumNames, startSetting, 270)
this.VideoSettingsMode.IndexChanged:connect(function(newIndex)
if newIndex == 1 then
GameSettings.VideoUploadPromptBehavior = Enum.UploadSetting.Never
elseif newIndex == 2 then
GameSettings.VideoUploadPromptBehavior = Enum.UploadSetting.Always
end
end)
local recordButton = utility:MakeStyledButton("RecordButton", "Record Video", UDim2.new(0,300,0,44), closeSettingsFunc, this)
recordButton.Position = UDim2.new(0,410,1,10)
recordButton.Parent = this.VideoSettingsMode.SelectorFrame.Parent
recordButton.MouseButton1Click:connect(function()
recordingEvent:Fire(not isRecordingVideo)
end)
local gameOptions = settings():FindFirstChild("Game Options")
if gameOptions then
gameOptions.VideoRecordingChangeRequest:connect(function(recording)
isRecordingVideo = recording
if recording then
recordButton.RecordButtonTextLabel.Text = "Stop Recording"
else
recordButton.RecordButtonTextLabel.Text = "Record Video"
end
end)
end
recordButton:SetVerb("RecordToggle")
this.ScreenshotButton:SetVerb("Screenshot")
this.Page.Size = UDim2.new(1,0,0,400)
end
return this
end
----------- Public Facing API Additions --------------
PageInstance = Initialize()
PageInstance.Displayed.Event:connect(function(switchedFromGamepadInput)
if switchedFromGamepadInput then
GuiService.SelectedCoreObject = PageInstance.ScreenshotButton
end
end)
return PageInstance
@@ -0,0 +1,311 @@
--[[
Filename: ReportAbuseMenu.lua
Written by: jeditkacheff
Version 1.0
Description: Takes care of the report abuse page in Settings Menu
--]]
-------------- SERVICES --------------
local CoreGui = game:GetService("CoreGui")
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
local GuiService = game:GetService("GuiService")
local PlayersService = game:GetService("Players")
----------- UTILITIES --------------
local utility = require(RobloxGui.Modules.Settings.Utility)
------------ CONSTANTS -------------------
local ABUSE_TYPES_PLAYER = {
"Swearing",
"Inappropriate Username",
"Bullying",
"Scamming",
"Dating",
"Cheating/Exploiting",
"Personal Question",
"Offsite Links",
}
local ABUSE_TYPES_GAME = {
"Inappropriate Content",
"Bad Model or Script",
"Offsite Link",
}
local DEFAULT_ABUSE_DESC_TEXT = " Short Description (Optional)"
if utility:IsSmallTouchScreen() then
DEFAULT_ABUSE_DESC_TEXT = " (Optional)"
end
------------ VARIABLES -------------------
local PageInstance = nil
----------- CLASS DECLARATION --------------
local function Initialize()
local settingsPageFactory = require(RobloxGui.Modules.Settings.SettingsPageFactory)
local this = settingsPageFactory:CreateNewPage()
local playerNames = {}
local nameToRbxPlayer = {}
function this:GetPlayerFromIndex(index)
local playerName = playerNames[index]
if playerName then
return nameToRbxPlayer[nameToRbxPlayer]
end
return nil
end
function this:UpdatePlayerDropDown()
playerNames = {}
nameToRbxPlayer = {}
local players = PlayersService:GetPlayers()
local index = 1
for i = 1, #players do
local player = players[i]
if player ~= PlayersService.LocalPlayer and player.UserId > 0 then
playerNames[index] = player.Name
nameToRbxPlayer[player.Name] = player
index = index + 1
end
end
this.WhichPlayerMode:UpdateDropDownList(playerNames)
if index == 1 then
this.GameOrPlayerMode:SetSelectionIndex(1)
this.TypeOfAbuseMode:UpdateDropDownList(ABUSE_TYPES_GAME)
end
this.WhichPlayerMode:SetInteractable(index > 1 and this.GameOrPlayerMode.CurrentIndex ~= 1)
this.GameOrPlayerMode:SetInteractable(index > 1)
end
------ TAB CUSTOMIZATION -------
this.TabHeader.Name = "ReportAbuseTab"
this.TabHeader.Icon.Image = "rbxasset://textures/ui/Settings/MenuBarIcons/ReportAbuseTab.png"
if utility:IsSmallTouchScreen() then
this.TabHeader.Icon.Size = UDim2.new(0,27,0,32)
this.TabHeader.Size = UDim2.new(0,120,1,0)
else
this.TabHeader.Size = UDim2.new(0,150,1,0)
this.TabHeader.Icon.Size = UDim2.new(0,36,0,43)
end
this.TabHeader.Icon.Position = UDim2.new(this.TabHeader.Icon.Position.X.Scale, this.TabHeader.Icon.Position.X.Offset + 10, 0.5,-this.TabHeader.Icon.Size.Y.Offset/2)
this.TabHeader.Icon.Title.Text = "Report"
------ PAGE CUSTOMIZATION -------
this.Page.Name = "ReportAbusePage"
-- need to override this function from SettingsPageFactory
-- DropDown menus require hub to to be set when they are initialized
function this:SetHub(newHubRef)
this.HubRef = newHubRef
if utility:IsSmallTouchScreen() then
this.GameOrPlayerFrame,
this.GameOrPlayerLabel,
this.GameOrPlayerMode = utility:AddNewRow(this, "Game or Player?", "Selector", {"Game", "Player"}, 1)
else
this.GameOrPlayerFrame,
this.GameOrPlayerLabel,
this.GameOrPlayerMode = utility:AddNewRow(this, "Game or Player?", "Selector", {"Game", "Player"}, 1, 3)
end
this.WhichPlayerFrame,
this.WhichPlayerLabel,
this.WhichPlayerMode = utility:AddNewRow(this, "Which Player?", "DropDown", {"update me"})
this.WhichPlayerMode:SetInteractable(false)
this.WhichPlayerLabel.ZIndex = 1
this.TypeOfAbuseFrame,
this.TypeOfAbuseLabel,
this.TypeOfAbuseMode = utility:AddNewRow(this, "Type Of Abuse", "DropDown", ABUSE_TYPES_GAME)
if utility:IsSmallTouchScreen() then
this.AbuseDescriptionFrame,
this.AbuseDescriptionLabel,
this.AbuseDescription = utility:AddNewRow(this, DEFAULT_ABUSE_DESC_TEXT, "TextBox", nil, nil)
else
this.AbuseDescriptionFrame,
this.AbuseDescriptionLabel,
this.AbuseDescription = utility:AddNewRow(this, DEFAULT_ABUSE_DESC_TEXT, "TextBox", nil, nil, 5)
end
if utility:IsSmallTouchScreen() then
this.AbuseDescription.Selection.Size = UDim2.new(0, 290, 0, 30)
this.AbuseDescription.Selection.Position = UDim2.new(1,-345,this.AbuseDescription.Selection.Position.Y.Scale, this.AbuseDescription.Selection.Position.Y.Offset)
this.AbuseDescriptionLabel = this.TypeOfAbuseLabel:clone()
this.AbuseDescriptionLabel.Text = "Abuse Description"
this.AbuseDescriptionLabel.Position = UDim2.new(this.AbuseDescriptionLabel.Position.X.Scale, this.AbuseDescriptionLabel.Position.X.Offset,
0,50)
this.AbuseDescriptionLabel.Parent = this.Page
end
local SelectionOverrideObject = utility:Create'ImageLabel'
{
Image = "",
BackgroundTransparency = 1
};
local submitButton, submitText = nil, nil
local function makeSubmitButtonActive()
submitButton.ZIndex = 2
submitButton.Selectable = true
submitText.ZIndex = 2
end
local function makeSubmitButtonInactive()
submitButton.ZIndex = 1
submitButton.Selectable = false
submitText.ZIndex = 1
end
local function updateAbuseDropDown()
this.WhichPlayerMode:ResetSelectionIndex()
this.TypeOfAbuseMode:ResetSelectionIndex()
if this.GameOrPlayerMode.CurrentIndex == 1 then
this.TypeOfAbuseMode:UpdateDropDownList(ABUSE_TYPES_GAME)
this.WhichPlayerMode:SetInteractable(false)
this.WhichPlayerLabel.ZIndex = 1
this.GameOrPlayerMode.SelectorFrame.NextSelectionDown = this.TypeOfAbuseMode.DropDownFrame
else
this.TypeOfAbuseMode:UpdateDropDownList(ABUSE_TYPES_PLAYER)
this.WhichPlayerMode:SetInteractable(true)
this.WhichPlayerLabel.ZIndex = 2
this.GameOrPlayerMode.SelectorFrame.NextSelectionDown = this.WhichPlayerMode.DropDownFrame
end
makeSubmitButtonInactive()
end
local function cleanupReportAbuseMenu()
updateAbuseDropDown()
this.AbuseDescription.Selection.Text = DEFAULT_ABUSE_DESC_TEXT
this.HubRef:SetVisibility(false, true)
end
local function onReportSubmitted()
local abuseReason = nil
if this.GameOrPlayerMode.CurrentIndex == 2 then
abuseReason = ABUSE_TYPES_PLAYER[this.TypeOfAbuseMode.CurrentIndex]
local currentAbusingPlayer = this:GetPlayerFromIndex(this.WhichPlayerMode.CurrentIndex)
if currentAbusingPlayer and abuseReason then
spawn(function()
game.Players:ReportAbuse(currentAbusingPlayer, abuseReason, this.AbuseDescription.Selection.Text)
end)
end
else
abuseReason = ABUSE_TYPES_GAME[this.TypeOfAbuseMode.CurrentIndex]
if abuseReason then
spawn(function()
game.Players:ReportAbuse(nil, abuseReason, this.AbuseDescription.Selection.Text)
end)
end
end
if abuseReason then
local alertText = "Thanks for your report! Our moderators will review the chat logs and evaluate what happened."
if abuseReason == 'Cheating/Exploiting' then
alertText = "Thanks for your report! We've recorded your report for evaluation."
elseif abuseReason == 'Inappropriate Username' then
alertText = "Thanks for your report! Our moderators will evaluate the username."
elseif abuseReason == "Bad Model or Script" or abuseReason == "Inappropriate Content" or abuseReason == "Offsite Link" or abuseReason == "Offsite Links" then
alertText = "Thanks for your report! Our moderators will review the place and make a determination."
end
utility:ShowAlert(alertText, "Ok", this.HubRef, cleanupReportAbuseMenu)
this.LastSelectedObject = nil
end
end
submitButton, submitText = utility:MakeStyledButton("SubmitButton", "Submit", UDim2.new(0,198,0,50), onReportSubmitted, this)
if utility:IsSmallTouchScreen() then
submitButton.Position = UDim2.new(1,-220,1,5)
else
submitButton.Position = UDim2.new(1,-194,1,5)
end
submitButton.Selectable = false
submitButton.ZIndex = 1
submitText.ZIndex = 1
submitButton.Parent = this.AbuseDescription.Selection
local function playerSelectionChanged(newIndex)
if newIndex ~= nil and this.TypeOfAbuseMode:GetSelectedIndex() ~= nil then
makeSubmitButtonActive()
else
makeSubmitButtonInactive()
end
end
this.WhichPlayerMode.IndexChanged:connect(playerSelectionChanged)
local function typeOfAbuseChanged(newIndex)
if newIndex ~= nil then
if this.GameOrPlayerMode.CurrentIndex == 1 or this.WhichPlayerMode:GetSelectedIndex() ~= nil then
makeSubmitButtonActive()
else
makeSubmitButtonInactive()
end
else
makeSubmitButtonInactive()
end
end
this.TypeOfAbuseMode.IndexChanged:connect(typeOfAbuseChanged)
this.GameOrPlayerMode.IndexChanged:connect(updateAbuseDropDown)
this:AddRow(nil, nil, this.AbuseDescription)
this.Page.Size = UDim2.new(1,0,0,submitButton.AbsolutePosition.Y + submitButton.AbsoluteSize.Y)
end
return this
end
----------- Public Facing API Additions --------------
do
PageInstance = Initialize()
PageInstance.Displayed.Event:connect(function()
PageInstance:UpdatePlayerDropDown()
end)
function PageInstance:ReportPlayer(player)
if player then
local setReportPlayerConnection = nil
setReportPlayerConnection = PageInstance.Displayed.Event:connect(function()
-- When we change the SelectionIndex of GameOrPlayerMode it waits until the tween is done
-- before it fires the IndexChanged signal. The WhichPlayerMode dropdown listens to this signal
-- and resets when it is fired. Therefore we need to listen to this signal and set the player we want
-- to report the frame after the dropdown is reset
local indexChangedConnection = nil
indexChangedConnection = PageInstance.GameOrPlayerMode.IndexChanged:connect(function()
if indexChangedConnection then
indexChangedConnection:disconnect()
indexChangedConnection = nil
end
PageInstance.WhichPlayerMode:SetSelectionByValue(player.Name)
end)
PageInstance.GameOrPlayerMode:SetSelectionIndex(2)
if setReportPlayerConnection then
setReportPlayerConnection:disconnect()
setReportPlayerConnection = nil
end
end)
PageInstance.HubRef:SetVisibility(true, false, PageInstance)
end
end
end
return PageInstance
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+345
View File
@@ -0,0 +1,345 @@
--[[
Filename: TenFootInterface.lua
Written by: jeditkacheff
Version 1.0
Description: Setups up some special UI for ROBLOX TV gaming
--]]
-------------- CONSTANTS --------------
local HEALTH_GREEN_COLOR = Color3.new(27/255, 252/255, 107/255)
local DISPLAY_POS_INIT_INSET = 0
local DISPLAY_ITEM_OFFSET = 4
local FORCE_TEN_FOOT_INTERFACE = false
-------------- SERVICES --------------
local CoreGui = game:GetService("CoreGui")
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
local UserInputService = game:GetService("UserInputService")
local GuiService = game:GetService("GuiService")
------------------ VARIABLES --------------------
local tenFootInterfaceEnabled = false
do
local platform = UserInputService:GetPlatform()
tenFootInterfaceEnabled = (platform == Enum.Platform.XBoxOne or platform == Enum.Platform.WiiU or platform == Enum.Platform.PS4 or
platform == Enum.Platform.AndroidTV or platform == Enum.Platform.XBox360 or platform == Enum.Platform.PS3 or
platform == Enum.Platform.Ouya or platform == Enum.Platform.SteamOS)
end
if FORCE_TEN_FOOT_INTERFACE then
tenFootInterfaceEnabled = true
end
local Util = {}
do
function Util.Create(instanceType)
return function(data)
local obj = Instance.new(instanceType)
for k, v in pairs(data) do
if type(k) == 'number' then
v.Parent = obj
else
obj[k] = v
end
end
return obj
end
end
end
local function CreateModule()
local this = {}
local nextObjectDisplayYPos = DISPLAY_POS_INIT_INSET
local displayStack = {}
-- setup base gui
local function createContainer()
if not this.Container then
this.Container = Util.Create'ImageButton'
{
Name = "TopRightContainer";
Size = UDim2.new(0, 350, 0, 100);
Position = UDim2.new(1,-360,0,10);
AutoButtonColor = false;
Image = "";
Active = false;
BackgroundTransparency = 1;
Parent = RobloxGui;
};
end
end
function removeFromDisplayStack(displayObject)
local moveUpFromHere = nil
for i = 1, #displayStack do
if displayStack[i] == displayObject then
moveUpFromHere = i + 1
break
end
end
local prevObject = displayObject
for i = moveUpFromHere, #displayStack do
local objectToMoveUp = displayStack[i]
objectToMoveUp.Position = UDim2.new(objectToMoveUp.Position.X.Scale, objectToMoveUp.Position.X.Offset,
objectToMoveUp.Position.Y.Scale, prevObject.AbsolutePosition.Y)
prevObject = objectToMoveUp
end
end
function addBackToDisplayStack(displayObject)
for i = 1, #displayStack do
if displayStack[i] == displayObject then
moveDownFromHere = i + 1
break
end
end
local prevObject = displayObject
for i = moveDownFromHere, #displayStack do
local objectToMoveDown = displayStack[i]
local nextDisplayPos = prevObject.AbsolutePosition.Y + prevObject.AbsoluteSize.Y + DISPLAY_ITEM_OFFSET
objectToMoveDown.Position = UDim2.new(objectToMoveDown.Position.X.Scale, objectToMoveDown.Position.X.Offset,
objectToMoveDown.Position.Y.Scale, nextDisplayPos)
prevObject = objectToMoveDown
end
end
function addToDisplayStack(displayObject)
local lastDisplayed = nil
if #displayStack > 0 then
lastDisplayed = displayStack[#displayStack]
end
displayStack[#displayStack + 1] = displayObject
local nextDisplayPos = DISPLAY_POS_INIT_INSET
if lastDisplayed then
nextDisplayPos = lastDisplayed.AbsolutePosition.Y + lastDisplayed.AbsoluteSize.Y + DISPLAY_ITEM_OFFSET
end
displayObject.Position = UDim2.new(displayObject.Position.X.Scale, displayObject.Position.X.Offset,
displayObject.Position.Y.Scale, nextDisplayPos)
createContainer()
displayObject.Parent = this.Container
displayObject.Changed:connect(function(prop)
if prop == "Visible" then
if not displayObject.Visible then
removeFromDisplayStack(displayObject)
else
addBackToDisplayStack(displayObject)
end
end
end)
end
function this:CreateHealthBar()
this.HealthContainer = Util.Create'Frame'{
Name = "HealthContainer";
Size = UDim2.new(1, -86, 0, 50);
Position = UDim2.new(0, 92, 0, 0);
BorderSizePixel = 0;
BackgroundColor3 = Color3.new(0,0,0);
BackgroundTransparency = 0.5;
};
local healthFillHolder = Util.Create'Frame'{
Name = "HealthFillHolder";
Size = UDim2.new(1, -10, 1, -10);
Position = UDim2.new(0, 5, 0, 5);
BorderSizePixel = 0;
BackgroundColor3 = Color3.new(1,1,1);
BackgroundTransparency = 1.0;
Parent = this.HealthContainer;
};
local healthFill = Util.Create'Frame'{
Name = "HealthFill";
Size = UDim2.new(1, 0, 1, 0);
Position = UDim2.new(0, 0, 0, 0);
BorderSizePixel = 0;
BackgroundTransparency = 0.0;
BackgroundColor3 = HEALTH_GREEN_COLOR;
Parent = healthFillHolder;
};
local healthText = Util.Create'TextLabel'{
Name = "HealthText";
Size = UDim2.new(0, 98, 0, 50);
Position = UDim2.new(0, -100, 0, 0);
BackgroundTransparency = 0.5;
BackgroundColor3 = Color3.new(0,0,0);
Font = Enum.Font.SourceSans;
FontSize = Enum.FontSize.Size36;
Text = "Health";
TextColor3 = Color3.new(1,1,1);
BorderSizePixel = 0;
Parent = this.HealthContainer;
};
local username = Util.Create'TextLabel'{
Visible = false
}
addToDisplayStack(this.HealthContainer)
createContainer()
return this.Container, username, this.HealthContainer, healthFill
end
function this:SetupTopStat()
local topStatEnabled = true
local displayedStat = nil
local displayedStatChangedCon = nil
local displayedStatParentedCon = nil
local leaderstatsChildAddedCon = nil
local tenFootInterfaceStat = nil
local function makeTenFootInterfaceStat()
if tenFootInterfaceStat then return end
tenFootInterfaceStat = Util.Create'Frame'{
Name = "OneStatFrame";
Size = UDim2.new(1, 0, 0, 36);
Position = UDim2.new(0, 0, 0, 0);
BorderSizePixel = 0;
BackgroundTransparency = 1;
};
local statName = Util.Create'TextLabel'{
Name = "StatName";
Size = UDim2.new(0.5,0,0,36);
BackgroundTransparency = 1;
Font = Enum.Font.SourceSans;
FontSize = Enum.FontSize.Size36;
TextStrokeColor3 = Color3.new(104/255, 104/255, 104/255);
TextStrokeTransparency = 0;
Text = " StatName:";
TextColor3 = Color3.new(1,1,1);
TextXAlignment = Enum.TextXAlignment.Left;
BorderSizePixel = 0;
ClipsDescendants = true;
Parent = tenFootInterfaceStat;
};
local statValue = statName:clone()
statValue.Position = UDim2.new(0.5,0,0,0)
statValue.Name = "StatValue"
statValue.Text = "123,643,231"
statValue.TextXAlignment = Enum.TextXAlignment.Right
statValue.Parent = tenFootInterfaceStat
addToDisplayStack(tenFootInterfaceStat)
end
local function setDisplayedStat(newStat)
if displayedStatChangedCon then displayedStatChangedCon:disconnect() displayedStatChangedCon = nil end
if displayedStatParentedCon then displayedStatParentedCon:disconnect() displayedStatParentedCon = nil end
displayedStat = newStat
if displayedStat then
makeTenFootInterfaceStat()
updateTenFootStat(displayedStat)
displayedStatParentedCon = displayedStat.AncestryChanged:connect(function() updateTenFootStat(displayedStat, "Parent") end)
displayedStatChangedCon = displayedStat.Changed:connect(function(prop) updateTenFootStat(displayedStat, prop) end)
end
end
function updateTenFootStat(statObj, property)
if property and property == "Parent" then
tenFootInterfaceStat.StatName.Text = ""
tenFootInterfaceStat.StatValue.Text = ""
setDisplayedStat(nil)
tenFootInterfaceChanged()
else
if topStatEnabled then
tenFootInterfaceStat.StatName.Text = " " .. tostring(statObj.Name) .. ":"
tenFootInterfaceStat.StatValue.Text = tostring(statObj.Value)
else
tenFootInterfaceStat.StatName.Text = ""
tenFootInterfaceStat.StatValue.Text = ""
end
end
end
local function isValidStat(obj)
return obj:IsA('StringValue') or obj:IsA('IntValue') or obj:IsA('BoolValue') or obj:IsA('NumberValue') or
obj:IsA('DoubleConstrainedValue') or obj:IsA('IntConstrainedValue')
end
local function tenFootInterfaceNewStat( newStat )
if not displayedStat and isValidStat(newStat) then
setDisplayedStat(newStat)
end
end
function tenFootInterfaceChanged()
game:WaitForChild("Players")
while not game.Players.LocalPlayer do
wait()
end
local leaderstats = game.Players.LocalPlayer:FindFirstChild('leaderstats')
if leaderstats then
local statChildren = leaderstats:GetChildren()
for i = 1, #statChildren do
tenFootInterfaceNewStat(statChildren[i])
end
if leaderstatsChildAddedCon then leaderstatsChildAddedCon:disconnect() end
leaderstatsChildAddedCon = leaderstats.ChildAdded:connect(function(newStat)
tenFootInterfaceNewStat(newStat)
end)
end
end
game:WaitForChild("Players")
while not game.Players.LocalPlayer do
wait()
end
local leaderstats = game.Players.LocalPlayer:FindFirstChild('leaderstats')
if leaderstats then
tenFootInterfaceChanged()
else
game.Players.LocalPlayer.ChildAdded:connect(tenFootInterfaceChanged)
end
--Top Stat Public API
local topStatApiTable = {}
function topStatApiTable:SetTopStatEnabled(value)
topStatEnabled = value
if displayedStat then
updateTenFootStat(displayedStat, "")
end
end
return topStatApiTable
end
return this
end
-- Public API
local moduleApiTable = {}
local TenFootInterfaceModule = CreateModule()
function moduleApiTable:IsEnabled()
return tenFootInterfaceEnabled
end
function moduleApiTable:CreateHealthBar()
return TenFootInterfaceModule:CreateHealthBar()
end
function moduleApiTable:SetupTopStat()
return TenFootInterfaceModule:SetupTopStat()
end
return moduleApiTable
+808
View File
@@ -0,0 +1,808 @@
--Panel3D: 3D GUI panels for VR
--written by 0xBAADF00D
--revised/refactored 5/11/16
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local GuiService = game:GetService("GuiService")
local CoreGui = game:GetService("CoreGui")
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
local PlayersService = game.Players
--Util
local Util = {}
do
function Util.Create(instanceType)
return function(data)
local obj = Instance.new(instanceType)
for k, v in pairs(data) do
if type(k) == 'number' then
v.Parent = obj
else
obj[k] = v
end
end
return obj
end
end
-- RayPlaneIntersection (shortened)
-- http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm
function Util.RayPlaneIntersection(ray, planeNormal, pointOnPlane)
planeNormal = planeNormal.unit
ray = ray.Unit
local Vd = planeNormal:Dot(ray.Direction)
if Vd == 0 then -- parallel, no intersection
return nil
end
local V0 = planeNormal:Dot(pointOnPlane - ray.Origin)
local t = V0 / Vd
if t < 0 then --plane is behind ray origin, and thus there is no intersection
return nil
end
return ray.Origin + ray.Direction * t
end
end
--End of Util
--Panel3D State variables
local renderStepName = "Panel3DRenderStep-" .. game:GetService("HttpService"):GenerateGUID()
local defaultPixelsPerStud = 64
local pointUpCF = CFrame.Angles(math.rad(-90), math.rad(180), 0)
local zeroVector = Vector3.new(0, 0, 0)
local zeroVector2 = Vector2.new(0, 0)
local turnAroundCF = CFrame.Angles(0, math.rad(180), 0)
local fullyOpaqueAtPixelsFromEdge = 10
local fullyTransparentAtPixelsFromEdge = 80
local partThickness = 0.2
local cursorHidden = false
local cursorHideTime = 2.5
local currentModal = nil
local lastModal = nil
local currentMaxDist = math.huge
local currentClosest = nil
local lastClosest = nil
local currentHeadScale = 1
local panels = {}
local floorRotation = CFrame.new()
local cursor = Util.Create "ImageLabel" {
Image = "rbxasset://textures/Cursors/Gamepad/Pointer.png",
Size = UDim2.new(0, 8, 0, 8),
BackgroundTransparency = 1,
ZIndex = 10
}
--End of Panel3D State variables
--Panel3D Declaration and enumerations
local Panel3D = {}
Panel3D.Type = {
None = 0,
Floor = 1,
Fixed = 2,
HorizontalFollow = 3,
FixedToHead = 4
}
Panel3D.OnPanelClosed = Util.Create 'BindableEvent' {
Name = 'OnPanelClosed'
}
function Panel3D.GetHeadLookXZ(withTranslation)
local userHeadCF = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)
local headLook = userHeadCF.lookVector
local headYaw = math.atan2(-headLook.Z, headLook.X) + math.rad(90)
local cf = CFrame.Angles(0, headYaw, 0)
if withTranslation then
cf = cf + userHeadCF.p
end
return cf
end
function Panel3D.FindContainerOf(element)
for i, v in pairs(panels) do
if v.gui and v.gui:IsAncestorOf(element) then
return v
end
end
return nil
end
function Panel3D.SetModalPanel(panel)
if currentModal == panel then
return
end
if currentModal then
currentModal:OnModalChanged(false)
end
if panel then
panel:OnModalChanged(true)
end
lastModal = currentModal
currentModal = panel
end
--End of Panel3D Declaration and enumerations
--Cursor autohiding methods
local cursorHidden = false
local hasTool = false
local lastMouseActivity = tick()
local lastMouseBehavior = Enum.MouseBehavior.Default
local function OnCharacterAdded(character)
hasTool = false
for i, v in ipairs(character:GetChildren()) do
if v:IsA("Tool") then
hasTool = true
end
end
character.ChildAdded:connect(function(child)
if child:IsA("Tool") then
hasTool = true
lastMouseActivity = tick() --kick the mouse when a tool is equipped
end
end)
character.ChildRemoved:connect(function(child)
if child:IsA("Tool") then
hasTool = false
end
end)
end
spawn(function()
while not PlayersService.LocalPlayer do wait() end
PlayersService.LocalPlayer.CharacterAdded:connect(OnCharacterAdded)
if PlayersService.LocalPlayer.Character then OnCharacterAdded(PlayersService.LocalPlayer.Character) end
end)
local function autoHideCursor(hide)
if not UserInputService.VREnabled then
cursorHidden = false
return
end
if hide then
--don't hide if there's a tool in the character
local character = PlayersService.LocalPlayer.Character
if character and hasTool then
return
end
cursorHidden = true
UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.ForceHide
else
cursorHidden = false
UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.None
end
end
local function isCursorVisible()
--if ForceShow, the cursor is definitely visible at all times
if UserInputService.OverrideMouseIconBehavior == Enum.OverrideMouseIconBehavior.ForceShow then
return true
end
--if ForceHide, the cursor is definitely NOT visible
if UserInputService.OverrideMouseIconBehavior == Enum.OverrideMouseIconBehavior.ForceHide then
return false
end
--Otherwise, we need to check if the developer set MouseIconEnabled=false
if UserInputService.MouseIconEnabled and UserInputService.OverrideMouseIconBehavior == Enum.OverrideMouseIconBehavior.None then
return true
end
return false
end
--End of cursor autohiding methods
--Panel class implementation
local Panel = {}
Panel.mt = { __index = Panel }
function Panel.new(name)
local instance = {
name = name,
part = nil,
gui = nil,
width = 1,
height = 1,
isVisible = false,
isEnabled = false,
panelType = Panel3D.Type.None,
pixelScale = 1,
showCursor = true,
canFade = true,
shouldFindLookAtGuiElement = false,
ignoreModal = false,
linkedTo = nil,
subpanels = {},
transparency = 1,
forceShowUntilLookedAt = false,
isLookedAt = false,
isOffscreen = true,
lookAtPixel = Vector2.new(-1, -1),
lookAtDistance = math.huge,
lookAtGuiElement = nil,
isClosest = true
}
if panels[name] then
error("A panel by the name of " .. name .. " already exists.")
end
panels[name] = instance
return setmetatable(instance, Panel.mt)
end
--Panel accessor methods
function Panel:GetPart()
if not self.part then
self.part = Util.Create "Part" {
Name = self.name,
Parent = nil,
Transparency = 1,
CanCollide = false,
Anchored = true,
Archivable = false,
Size = Vector3.new(1, 1, partThickness)
}
end
return self.part
end
function Panel:GetGUI()
if not self.gui then
local part = self:GetPart()
self.gui = Util.Create "SurfaceGui" {
Parent = CoreGui,
Adornee = part,
Active = true,
ToolPunchThroughDistance = 1000,
CanvasSize = Vector2.new(0, 0),
Enabled = self.isEnabled,
AlwaysOnTop = true
}
end
return self.gui
end
function Panel:FindHoveredGuiElement(elements)
local x, y = self.lookAtPixel.X, self.lookAtPixel.Y
for i, v in pairs(elements) do
local minPt = v.AbsolutePosition
local maxPt = v.AbsolutePosition + v.AbsoluteSize
if minPt.X <= x and maxPt.X >= x and
minPt.Y <= y and maxPt.Y >= y then
return v, i
end
end
end
--End of panel accessor methods
--Panel update methods
function Panel:SetPartCFrame(cframe)
self:GetPart().CFrame = cframe * CFrame.new(0, 0, -0.5 * partThickness)
end
function Panel:SetEnabled(enabled)
if self.isEnabled == enabled then
return
end
self.isEnabled = enabled
if enabled then
self:GetPart().Parent = workspace.CurrentCamera --todo: Perhaps this can change soon.
self:GetGUI().Enabled = true
for i, v in pairs(self.subpanels) do
v:GetPart().Parent = workspace.CurrentCamera
v:GetGUI().Enabled = true
end
else
self:GetPart().Parent = nil
self:GetGUI().Enabled = false
for i, v in pairs(self.subpanels) do
v:GetPart().Parent = nil
v:GetGUI().Enabled = false
end
end
self:OnEnabled(enabled)
end
function Panel:EvaluatePositioning(cameraCF, cameraRenderCF, userHeadCF)
if self.panelType == Panel3D.Type.Floor then
--Floor panels simply... go on the floor.
--Panel will be in camera's local space (which is assumed to be horizontal),
--and floorRotation is derived from the user's head rotation (yaw only)
local floorCF = cameraCF * CFrame.new(0, -headHeightFromFloor * currentHeadScale, 0) * floorRotation
self:SetPartCFrame(floorCF * pointUpCF)
elseif self.panelType == Panel3D.Type.Fixed then
--Places the panel in the camera's local space, but doesn't follow the user's head.
--Useful if you know what you're doing. localCF can be updated in PreUpdate for animation.
local cf = self.localCF - self.localCF.p
cf = cf + (self.localCF.p * currentHeadScale)
self:SetPartCFrame(cameraCF * cf)
elseif self.panelType == Panel3D.Type.HorizontalFollow then
local headLook = userHeadCF.lookVector
local headYaw = math.atan2(-headLook.Z, headLook.X) + math.rad(90)
local headForwardCF = CFrame.Angles(0, headYaw, 0) + userHeadCF.p
local localCF = (headForwardCF * self.angleFromForward) * --Rotate about Y (left-right)
self.angleFromHorizon * --Rotate about X (up-down)
(currentHeadScale * self.distance) * --Move into scene
turnAroundCF --Turn around to face character
self:SetPartCFrame(cameraCF * localCF)
elseif self.panelType == Panel3D.Type.FixedToHead then
--Places the panel in the user's head local space. localCF can be updated in PreUpdate for animation.
local cf = self.localCF - self.localCF.p
cf = cf + (self.localCF.p * currentHeadScale)
self:SetPartCFrame(cameraRenderCF * cf)
end
end
function Panel:EvaluateGaze(cameraCF, cameraRenderCF, userHeadCF, lookRay)
--reset distance data
self.isClosest = false
self.lookAtPixel = zeroVector2
self.lookAtDistance = math.huge
--Evaluate the lookRay versus this panel
local planeCF = self:GetPart().CFrame
local planeNormal = planeCF.lookVector
local pointOnPlane = planeCF.p + (planeNormal * partThickness * 0.5) --Move the point out by half the thickness of the part
local worldIntersectPoint = Util.RayPlaneIntersection(lookRay, planeNormal, pointOnPlane)
if worldIntersectPoint then
self.isOffscreen = false
--transform worldIntersectPoint to gui space
local gui = self:GetGUI()
local guiWidth, guiHeight = gui.AbsoluteSize.X, gui.AbsoluteSize.Y
local localIntersectPoint = (planeCF:pointToObjectSpace(worldIntersectPoint) / currentHeadScale) * Vector3.new(-1, 1, 1) + Vector3.new(self.width / 2, -self.height / 2, 0)
self.lookAtPixel = Vector2.new((localIntersectPoint.X / self.width) * gui.AbsoluteSize.X, (localIntersectPoint.Y / self.height) * -gui.AbsoluteSize.Y)
--fire mouse enter/leave events if necessary
local guiX, guiY = self.lookAtPixel.X, self.lookAtPixel.Y
if guiX >= 0 and guiX <= guiWidth and
guiY >= 0 and guiY <= guiHeight then
if not self.isLookedAt then
self.isLookedAt = true
self:OnMouseEnter(guiX, guiY)
if self.forceShowUntilLookedAt then
self.forceShowUntilLookedAt = false
end
end
else
if self.isLookedAt then
self.isLookedAt = false
self:OnMouseLeave(guiX, guiY)
end
end
--evaluate distance
self.lookAtDistance = (worldIntersectPoint - cameraRenderCF.p).magnitude
if self.isLookedAt and self.lookAtDistance < currentMaxDist and self.showCursor then
currentMaxDist = self.lookAtDistance
currentClosest = self
end
else
self.isOffscreen = true
--Not looking at the plane at all, so fire off mouseleave if necessary.
if self.isLookedAt then
self.isLookedAt = false
self:OnMouseLeave(self.lookAtPixel.X, self.lookAtPixel.Y)
end
end
end
function Panel:EvaluateTransparency()
--Early exit if force shown
if self.forceShowUntilLookedAt then
self.transparency = 0
return
end
--Early exit if we're looking at the panel (no transparency!)
if self.isLookedAt then
self.transparency = 0
return
end
--Similarly, exit if we can't possibly see the panel.
if self.isOffscreen then
self.transparency = 1
return
end
--Otherwise, we'll want to calculate the transparency.
self.transparency = self:CalculateTransparency()
end
function Panel:Update(cameraCF, cameraRenderCF, userHeadCF, lookRay)
if self.forceShowUntilLookedAt and not self.part then
self:GetPart()
self:GetGUI()
end
if not self.part then
return
end
local isModal = (currentModal == self)
if not isModal and self.linkedTo and self.linkedTo == currentModal then
isModal = true
end
if currentModal and not isModal then
self:SetEnabled(false)
return
end
self:PreUpdate(cameraCF, cameraRenderCF, userHeadCF, lookRay)
if self.isVisible then
self:EvaluatePositioning(cameraCF, cameraRenderCF, userHeadCF)
self:EvaluateGaze(cameraCF, cameraRenderCF, userHeadCF, lookRay)
self:EvaluateTransparency(cameraCF, cameraRenderCF)
end
end
--End of Panel update methods
--Panel virtual methods
function Panel:PreUpdate() --virtual: handle positioning here
end
function Panel:OnUpdate() --virtual: handle transparency here
end
function Panel:OnMouseEnter(x, y) --virtual
end
function Panel:OnMouseLeave(x, y) --virtual
end
function Panel:OnEnabled(enabled) --virtual
end
function Panel:OnModalChanged(isModal) --virtual
end
function Panel:OnVisibilityChanged(visible) --virtual
end
function Panel:CalculateTransparency() --virtual
if not self.canFade then
return 0
end
local guiWidth, guiHeight = self.gui.AbsoluteSize.X, self.gui.AbsoluteSize.Y
local lookX, lookY = self.lookAtPixel.X, self.lookAtPixel.Y
--Determine the distance from the edge;
--if x is negative it's on the left side, meaning the distance is just absolute value
--if x is positive it's on the right side, meaning the distance is x minus the width
local xEdgeDist = lookX < 0 and -lookX or (lookX - guiWidth)
local yEdgeDist = lookY < 0 and -lookY or (lookY - guiHeight)
if lookX > 0 and lookX < guiWidth then
xEdgeDist = 0
end
if lookY > 0 and lookY < guiHeight then
yEdgeDist = 0
end
local edgeDist = math.sqrt(xEdgeDist ^ 2 + yEdgeDist ^ 2)
--since transparency is 0-1, we know how many pixels will give us 0 and how many will give us 1.
local offset = fullyOpaqueAtPixelsFromEdge
local interval = fullyTransparentAtPixelsFromEdge
--then we just clamp between 0 and 1.
return math.max(0, math.min(1, (edgeDist - offset) / interval))
end
--End of Panel virtual methods
--Panel configuration methods
function Panel:ResizeStuds(width, height, pixelsPerStud)
pixelsPerStud = pixelsPerStud or defaultPixelsPerStud
self.width = width
self.height = height
self.pixelScale = pixelsPerStud / defaultPixelsPerStud
local part = self:GetPart()
part.Size = Vector3.new(self.width * currentHeadScale, self.height * currentHeadScale, partThickness)
local gui = self:GetGUI()
gui.CanvasSize = Vector2.new(pixelsPerStud * self.width, pixelsPerStud * self.height)
end
function Panel:ResizePixels(width, height, pixelsPerStud)
pixelsPerStud = pixelsPerStud or defaultPixelsPerStud
local widthInStuds = width / pixelsPerStud
local heightInStuds = height / pixelsPerStud
self:ResizeStuds(widthInStuds, heightInStuds, pixelsPerStud)
end
function Panel:OnHeadScaleChanged(newHeadScale)
local pixelsPerStud = self.pixelScale * defaultPixelsPerStud
self:ResizeStuds(self.width, self.height, pixelsPerStud)
end
function Panel:SetType(panelType, config)
self.panelType = panelType
--clear out old type-specific members
self.floorPos = nil
self.localCF = nil
self.angleFromHorizon = nil
self.angleFromForward = nil
self.distance = nil
if not config then
config = {}
end
if panelType == Panel3D.Type.None then
--nothing to do
return
elseif panelType == Panel3D.Type.Floor then
self.floorPos = config.FloorPosition or Vector3.new(0, 0, 0)
elseif panelType == Panel3D.Type.Fixed then
self.localCF = config.CFrame or CFrame.new()
elseif panelType == Panel3D.Type.HorizontalFollow then
self.angleFromHorizon = CFrame.Angles(config.angleFromHorizon or 0, 0, 0)
self.angleFromForward = CFrame.Angles(0, config.angleFromForward or 0, 0)
self.distance = CFrame.new(0, 0, config.distance or 5)
elseif panelType == Panel3D.Type.FixedToHead then
self.localCF = config.CFrame or CFrame.new()
else
error("Invalid Panel type")
end
end
function Panel:SetVisible(visible, modal)
if visible ~= self.isVisible then
self:OnVisibilityChanged(visible)
if not visible then
Panel3D.OnPanelClosed:Fire(self.name)
end
end
self.isVisible = visible
self:SetEnabled(visible)
if visible and modal then
Panel3D.SetModalPanel(self)
end
if not visible and currentModal == self then
if modal and not doNotRestore then
--restore last modal panel
Panel3D.SetModalPanel(lastModal)
else
Panel3D.SetModalPanel(nil)
--if the coder explicitly wanted to hide this modal panel,
--it follows that they don't want it to be restored when the next
--modal panel is hidden.
if lastModal == self then
lastModal = nil
end
end
end
if not visible and self.forceShowUntilLookedAt then
self.forceShowUntilLookedAt = false
end
end
function Panel:LinkTo(panelName)
if type(panelName) == "string" then
self.linkedTo = Panel3D.Get(panelName)
else
self.linkedTo = panelName
end
end
function Panel:ForceShowUntilLookedAt(makeModal)
--ensure the part exists
self:GetPart()
self:GetGUI()
self:SetVisible(true, makeModal)
self.forceShowUntilLookedAt = true
end
function Panel:SetCanFade(canFade)
self.canFade = canFade
end
--Child class, Subpanel
local Subpanel = {}
local Subpanel_mt = {}
function Subpanel.new(guiElement)
local instance = {
guiElement = guiElement
}
return setmetatable(instance, Subpanel_mt)
end
function Subpanel:GetPart()
warn("Subpanel:GetPart() not yet implemented")
return nil
end
function Subpanel:GetGUI()
warn("Subpanel:GetGUI() not yet implemented")
return nil
end
function Panel:AddSubpanel(guiElement)
local subpanel = Subpanel.new(guiElement)
self.subpanels[guiElement] = subpanel
end
function Panel:RemoveSubpanel(guiElement)
self.subpanels[guiElement] = nil
end
--End of Panel configuration methods
--End of Panel class implementation
--Panel3D API
function Panel3D.Get(name)
local panel = panels[name]
if not panels[name] then
panels[name] = Panel.new(name)
panel = panels[name]
end
return panel
end
--End of Panel3D API
--Panel3D Setup
local function onRenderStep()
if not UserInputService.VREnabled then
return
end
--reset distance info
currentClosest = nil
currentMaxDist = math.huge
--figure out some useful stuff
local camera = workspace.CurrentCamera
local cameraCF = camera.CFrame
local cameraRenderCF = camera:GetRenderCFrame()
local userHeadCF = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)
local lookRay = Ray.new(cameraRenderCF.p, cameraRenderCF.lookVector)
--allow all panels to run their own update code
for i, v in pairs(panels) do
v:Update(cameraCF, cameraRenderCF, userHeadCF, lookRay)
end
--evaluate linked panels
local processed = {}
for i, v in pairs(panels) do
if not processed[v] and v.linkedTo and v.isVisible and v.linkedTo.isVisible then
processed[v] = true
processed[v.linkedTo] = true
local minTransparency = math.min(v.transparency, v.linkedTo.transparency)
v.transparency = minTransparency
v.linkedTo.transparency = minTransparency
end
end
--run post update because the distance information hasn't been
--finalized until now.
for i, v in pairs(panels) do
--If the part is fully transparent, we don't want to keep it around in the workspace.
if v.part and v.gui then
--check if this panel is the current modal panel
local isModal = (currentModal == v)
--but also check if this panel is linked to the current modal panel
if not isModal and v.linkedTo and v.linkedTo == currentModal then
isModal = true
end
local show = v.isVisible
if not isModal and currentModal then
show = false
end
if v.transparency >= 1 then
show = false
end
if v.forceShowUntilLookedAt then
show = true
end
if not v.canFade and v.isVisible then
show = true
end
v:SetEnabled(show)
end
v:OnUpdate()
end
--place the cursor on the closest panel (for now)
if not currentClosest and lastClosest then
UserInputService.MouseBehavior = lastMouseBehavior
elseif currentClosest and not lastClosest then
lastMouseBehavior = UserInputService.MouseBehavior
end
if currentClosest then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.ForceHide
cursor.Parent = currentClosest:GetGUI()
local x, y = currentClosest.lookAtPixel.X, currentClosest.lookAtPixel.Y
cursor.Size = UDim2.new(0, 8 * currentClosest.pixelScale, 0, 8 * currentClosest.pixelScale)
cursor.Position = UDim2.new(0, x - cursor.AbsoluteSize.x * 0.5, 0, y - cursor.AbsoluteSize.y * 0.5)
else
cursor.Parent = nil
end
lastClosest = currentClosest
end
RunService:BindToRenderStep(renderStepName, Enum.RenderPriority.Last.Value, onRenderStep)
--Implement cursor autohide functionality
UserInputService.InputChanged:connect(function(inputObj, processed)
if inputObj.UserInputType == Enum.UserInputType.MouseMovement then
lastMouseActivity = tick()
autoHideCursor(false)
end
end)
local function onHeartbeat()
if isCursorVisible() then
cursorHidden = false
end
if lastMouseActivity + cursorHideTime < tick() and not GuiService.MenuIsOpen and not cursorHidden then
autoHideCursor(true)
end
end
RunService.Heartbeat:connect(onHeartbeat)
--Handle camera changes
local cameraChangedConnection = nil
local function onCameraChanged(prop)
if prop == "HeadScale" then
pcall(function()
currentHeadScale = workspace.CurrentCamera.HeadScale
end)
for i, v in pairs(panels) do
v:OnHeadScaleChanged(currentHeadScale)
end
end
end
local function onWorkspaceChanged(prop)
if prop == "CurrentCamera" then
onCameraChanged("HeadScale")
if cameraChangedConnection then
cameraChangedConnection:disconnect()
end
cameraChangedConnection = workspace.CurrentCamera.Changed:connect(onCameraChanged)
end
end
if workspace.CurrentCamera then
onWorkspaceChanged("CurrentCamera")
end
workspace.Changed:connect(onWorkspaceChanged)
return Panel3D
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+815
View File
@@ -0,0 +1,815 @@
--rbxsig%hm7SbDaf0GHizpUYxb6qQAHuUU7LfsWX8bgPnc64hv1MnSJFX+Komih+acv/5vqLxpzxHNtvBCnuAwN6l63fYukZ0Yat7mDBHBx0w0CPTaWSCs2P5WDx/W7P+L8AkqpaowXKgCKST9VBErgwqTlUySsi0r9+HfExO+cl3h2lXig=%
--rbxassetid%158948138%
-- Creates the generic "ROBLOX" loading screen on startup
-- Written by ArceusInator & Ben Tkacheff, 2014
--
-- Constants
local PLACEID = Game.PlaceId
local MPS = Game:GetService 'MarketplaceService'
local CP = Game:GetService 'ContentProvider'
local COLORS = {
BLACK = Color3.new(0, 0, 0),
DARK = Color3.new(35/255, 35/255, 38/255),
DARKMED = Color3.new(61/255, 61/255, 67/255),
DARKMED2 = Color3.new(75/255, 76/255, 85/255),
MED = Color3.new(118/255, 118/255, 129/255),
LIGHTMED = Color3.new(190/255, 192/255, 212/255),
LIGHT = Color3.new(217/255, 218/255, 231/255),
ERROR = Color3.new(253/255,68/255,72/255)
}
local IMAGES = {
BACKGROUND_THUMBNAIL_VIGNETTE = 'rbxasset://textures/loading/loadingvignette.png',
ROBLOX_LOGO_256 = 'rbxasset://textures/loading/robloxlogo.png',
GAME_THUMBNAIL = 'http://www.roblox.com/Thumbs/Asset.ashx?format=png&width=420&height=230&assetId=',
GAME_BACKGROUND = 'rbxasset://textures/loading/loadingTexture.png'
}
local VALID_TEXT_SIZES = {
12,
14,
18,
24,
36,
48
}
--
-- Variables
local GameAssetInfo -- loaded by InfoProvider:LoadAssets()
local currScreenGui = nil
local renderSteppedConnection = nil
--
-- Utility functions
local create = function(className, defaultParent)
return function(propertyList)
local object = Instance.new(className)
for index, value in next, propertyList do
if type(index) == 'string' then
object[index] = value
else
if type(value) == 'function' then
value(object)
elseif type(value) == 'userdata' then
value.Parent = object
end
end
end
if object.Parent == nil then
object.Parent = defaultParent
end
return object
end
end
--
-- Create objects
local MainGui = {}
local InfoProvider = {}
function InfoProvider:GetGameName()
if GameAssetInfo ~= nil then
return GameAssetInfo.Name
else
return ''
end
end
function InfoProvider:GetCreatorName()
if GameAssetInfo ~= nil then
return GameAssetInfo.Creator.Name
else
return ''
end
end
function InfoProvider:LoadAssets()
Spawn(function()
if PLACEID <= 0 then
while Game.PlaceId <= 0 do
wait()
end
PLACEID = Game.PlaceId
end
IMAGES.GAME_THUMBNAIL = IMAGES.GAME_THUMBNAIL .. tostring(PLACEID)
-- load game asset info
coroutine.resume(coroutine.create(function() GameAssetInfo = MPS:GetProductInfo(PLACEID) end))
while not currScreenGui do
wait()
end
currScreenGui.ThumbnailContainer.Thumbnail.Image = IMAGES.GAME_THUMBNAIL
-- load images
for imageName, imageContent in next, IMAGES do
CP:Preload(imageContent)
end
end)
end
--
-- Declare member functions
function MainGui:GenerateMain()
local screenGui = create 'ScreenGui' {
Name = 'RobloxLoadingGui'
}
--
-- create descendant frames
local mainBackgroundContainer = create 'Frame' {
Name = 'MainBackgroundContainer',
BackgroundColor3 = COLORS.DARK,
Size = UDim2.new(1, 0, 1, 0),
Active = true,
create 'Frame' {
Name = 'TopBar',
BackgroundColor3 = COLORS.DARKMED,
BorderColor3 = COLORS.MED,
BorderSizePixel = 3,
Position = UDim2.new(0, -220, 0, -205),
Rotation = -10,
Size = UDim2.new(0, 1000, 0, 220),
ZIndex = 5,
create 'ImageLabel' {
Name = 'RobloxLogo',
BackgroundTransparency = 1,
Image = IMAGES.ROBLOX_LOGO_256,
Position = UDim2.new(0, 214, 1, -80),
Rotation = 2,
Size = UDim2.new(0, 128, 0, 128),
ZIndex = 6,
create 'TextLabel' {
Name = 'PoweredBy',
BackgroundTransparency = 1,
Position = UDim2.new(0.5, -60, 0, 30),
Size = UDim2.new(0, 80, 0, 18),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size18,
TextColor3 = Color3.new(1,1,1),
Text = "Powered By",
ZIndex = 6
}
}
},
create 'ImageButton' {
Name = 'CloseButton',
Image = 'rbxasset://textures/ui/CloseButton.png',
BackgroundTransparency = 1,
Position = UDim2.new(1, -27, 0, 5),
Size = UDim2.new(0, 22, 0, 22),
Active = true,
ZIndex = 10
},
create 'Frame' {
Name = 'ErrorFrame',
BackgroundColor3 = COLORS.ERROR,
BorderSizePixel = 0,
Position = UDim2.new(0.25,0,0,0),
Size = UDim2.new(0.5, 0, 0, 80),
ZIndex = 5,
Visible = false,
create 'TextLabel' {
Name = "ErrorText",
BackgroundTransparency = 1,
ZIndex = 6,
Position = UDim2.new(0,5,0,5),
Size = UDim2.new(1,-10,1,-10),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size18,
Text = "",
TextColor3 = Color3.new(1,1,1),
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Center,
TextWrap = true
}
},
create 'Frame' {
Name = 'BottomBar',
BorderSizePixel = 0,
BackgroundTransparency = 1,
Position = UDim2.new(0, 0, 1, -150),
Size = UDim2.new(1, 0, 0, 300),
ZIndex = 5,
create 'Frame' {
Name = 'BottomBarActual',
BackgroundColor3 = COLORS.DARKMED,
BorderColor3 = COLORS.MED,
BorderSizePixel = 3,
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 5,
create 'Frame' {
Name = 'TextContainer',
BackgroundTransparency = 1,
Position = UDim2.new(0, -5, 0, 5),
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 8,
create 'TextLabel' {
Name = 'CreatorName',
BackgroundTransparency = 1,
Position = UDim2.new(0, 0, 0, 70),
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size48,
Text = InfoProvider:GetCreatorName(),
TextColor3 = COLORS.LIGHT,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Right,
TextYAlignment = Enum.TextYAlignment.Top
},
create 'TextLabel' {
Name = 'GameName',
BackgroundTransparency = 1,
Position = UDim2.new(0, 0, 0, 30),
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size48,
Text = InfoProvider:GetGameName(),
TextColor3 = COLORS.LIGHT,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Right,
TextYAlignment = Enum.TextYAlignment.Top
},
create 'TextLabel' {
Name = 'CreatorNamePrefix',
BackgroundTransparency = 1,
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 9,
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size48,
Text = 'By',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Right,
TextYAlignment = Enum.TextYAlignment.Top
},
create 'TextLabel' {
Name = 'OnYourWay',
BackgroundTransparency = 1,
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 9,
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size36,
Text = 'You\'re on your way to',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Right,
TextYAlignment = Enum.TextYAlignment.Top
}
}
}
},
create 'ImageLabel' {
Name = 'BackgroundThumbnailVignette',
BackgroundTransparency = 1,
Image = IMAGES.BACKGROUND_THUMBNAIL_VIGNETTE,
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 3
},
create 'ImageLabel' {
Name = 'BackgroundThumbnail',
BackgroundTransparency = 1,
Image = IMAGES.GAME_BACKGROUND,
Size = UDim2.new(1.5, 0, 1.5, 0),
Position = UDim2.new(-0.5,0,0,0),
ZIndex = 2
},
Parent = screenGui
}
local thumbnailContainer = create 'Frame' {
Name = 'ThumbnailContainer',
BackgroundColor3 = COLORS.BLACK,
BorderColor3 = COLORS.MED,
BorderSizePixel = 4,
Position = UDim2.new(0.5, -210, 0.5, -115),
Size = UDim2.new(0, 420, 0, 230),
ZIndex = 8,
create 'ImageLabel' {
Name = 'Thumbnail',
BorderColor3 = COLORS.DARKMED2,
BorderSizePixel = 3,
Image = "",
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 8
},
create 'Frame' {
Name = 'LoadingInfoContainer',
BorderColor3 = COLORS.MED,
BackgroundColor3 = COLORS.DARKMED,
BorderSizePixel = 2,
Position = UDim2.new(0,20,1,0),
Size = UDim2.new(1,-40,0,40),
ZIndex = 7,
create 'TextLabel' {
Name = 'InstancesLabel',
BackgroundTransparency = 1,
Position = UDim2.new(0,0,0,5),
Size = UDim2.new(0.25, 0, 1, -10),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size14,
Text = 'Instances',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Top
},
create 'TextLabel' {
Name = 'InstancesValue',
BackgroundTransparency = 1,
Position = UDim2.new(0,0,0,5),
Size = UDim2.new(0.25, 0, 1, -10),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size14,
Text = '0',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Bottom
},
create 'TextLabel' {
Name = 'VoxelsLabel',
BackgroundTransparency = 1,
Position = UDim2.new(0.75,0,0,5),
Size = UDim2.new(0.25, 0, 1, -10),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size14,
Text = 'Voxels',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Top
},
create 'TextLabel' {
Name = 'VoxelsValue',
BackgroundTransparency = 1,
Position = UDim2.new(0.75,0,0,5),
Size = UDim2.new(0.25, 0, 1, -10),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size14,
Text = '0',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Bottom
},
create 'TextLabel' {
Name = 'ConnectorsLabel',
BackgroundTransparency = 1,
Position = UDim2.new(0.5,0,0,5),
Size = UDim2.new(0.25, 0, 1, -10),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size14,
Text = 'Connectors',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Top
},
create 'TextLabel' {
Name = 'ConnectorsValue',
BackgroundTransparency = 1,
Position = UDim2.new(0.5,0,0,5),
Size = UDim2.new(0.25, 0, 1, -10),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size14,
Text = '0',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Bottom
},
create 'TextLabel' {
Name = 'BricksLabel',
BackgroundTransparency = 1,
Position = UDim2.new(0.25,0,0,5),
Size = UDim2.new(0.25, 0, 1, -10),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size14,
Text = 'Bricks',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Top
},
create 'TextLabel' {
Name = 'BricksValue',
BackgroundTransparency = 1,
Position = UDim2.new(0.25,0,0,5),
Size = UDim2.new(0.25, 0, 1, -10),
ZIndex = 9,
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size14,
Text = '0',
TextColor3 = COLORS.LIGHTMED,
TextStrokeColor3 = COLORS.DARKMED2,
TextStrokeTransparency = 0,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Bottom
},
},
Parent = screenGui
}
--
-- recalculate everything
while not Game:GetService("CoreGui") do
wait()
end
screenGui.Parent = Game.CoreGui
MainGui:RecalculateSizes(screenGui)
--
-- return generated gui
return screenGui
end
function MainGui:RecalculateTextSize(screenGui)
local screenSize = screenGui.AbsoluteSize
local textSizeScale = math.min(screenSize.y/800, 1)
local closestValidSizePrevIndex = math.floor(textSizeScale*#VALID_TEXT_SIZES)-1
local closestValidSizePrevIndex2 = closestValidSizePrevIndex-1
local closestValidTextSize
local closestValidTextSizePrev
-- next can't take a 0 because it's a total wuss
if closestValidSizePrevIndex > 0 then
_, closestValidTextSize = next(VALID_TEXT_SIZES, closestValidSizePrevIndex)
if closestValidSizePrevIndex2 > 0 then
_, closestValidTextSizePrev = next(VALID_TEXT_SIZES, closestValidSizePrevIndex2)
else
_, closestValidTextSizePrev = next(VALID_TEXT_SIZES) -- not doing t[1] because this looks cleaner
end
else
_, closestValidTextSize = next(VALID_TEXT_SIZES)
_, closestValidTextSizePrev = next(VALID_TEXT_SIZES)
end
local textSizeEnum = Enum.FontSize['Size'..closestValidTextSize]
local textSizePrevEnum = Enum.FontSize['Size'..closestValidTextSizePrev]
if not screenGui:FindFirstChild("MainBackgroundContainer") then return end
local TextContainer = screenGui.MainBackgroundContainer.BottomBar.BottomBarActual.TextContainer
local currentYBumpDistance = 0
TextContainer.OnYourWay.FontSize = textSizePrevEnum
currentYBumpDistance = currentYBumpDistance + closestValidTextSizePrev*(40/48)
TextContainer.GameName.Position = UDim2.new(0, 0, 0, currentYBumpDistance)
TextContainer.GameName.FontSize = textSizeEnum
currentYBumpDistance = currentYBumpDistance + closestValidTextSize*(40/48)
TextContainer.CreatorName.Position = UDim2.new(0, 0, 0, currentYBumpDistance)
TextContainer.CreatorName.FontSize = textSizeEnum
local currentXBumpDistance = -(TextContainer.CreatorName.TextBounds.X+5)
TextContainer.CreatorNamePrefix.Position = UDim2.new(0, currentXBumpDistance, 0, currentYBumpDistance)
TextContainer.CreatorNamePrefix.FontSize = textSizeEnum
-- recalculate bottom bar size
local sizeScale = closestValidTextSize/48
screenGui.MainBackgroundContainer.BottomBar.Size = UDim2.new(1, 0, 0, 300 * sizeScale)
screenGui.MainBackgroundContainer.BottomBar.Position = UDim2.new(0, 0, 1, -150 * sizeScale)
screenGui.MainBackgroundContainer.BottomBar.BottomBarActual.Position = UDim2.new(0, -130 * sizeScale,0,0)
end
function MainGui:RecalculateSizes(screenGui)
local screenSize = screenGui.AbsoluteSize
-- recalculate thumbnail size
local thumbnailSizeScale = math.min(math.max(screenSize.y/630, 50/230), 1)
local thumbnailSize = UDim2.new(0, thumbnailSizeScale*420, 0, thumbnailSizeScale*230)
local thumbnailPosition = UDim2.new(0.5, -thumbnailSizeScale*420/2, 0.5, -20 - thumbnailSizeScale*230/2 )
screenGui.ThumbnailContainer.Size = thumbnailSize
screenGui.ThumbnailContainer.Position = thumbnailPosition
screenGui.ThumbnailContainer.LoadingInfoContainer.Visible = (screenSize.Y > 500)
-- update names
-- if we don't have a name yet, keep trying!
if InfoProvider:GetCreatorName() == '' or InfoProvider:GetGameName() == '' then
Spawn(function()
while InfoProvider and InfoProvider:GetCreatorName() == '' or InfoProvider:GetGameName() == '' do
wait()
end
if screenGui and screenGui:FindFirstChild("MainBackgroundContainer") then
screenGui.MainBackgroundContainer.BottomBar.BottomBarActual.TextContainer.CreatorName.Text = InfoProvider:GetCreatorName()
screenGui.MainBackgroundContainer.BottomBar.BottomBarActual.TextContainer.GameName.Text = InfoProvider:GetGameName()
end
MainGui:RecalculateTextSize(screenGui)
end)
else
screenGui.MainBackgroundContainer.BottomBar.BottomBarActual.TextContainer.CreatorName.Text = InfoProvider:GetCreatorName()
screenGui.MainBackgroundContainer.BottomBar.BottomBarActual.TextContainer.GameName.Text = InfoProvider:GetGameName()
end
MainGui:RecalculateTextSize(screenGui)
end
function MainGui:Show()
currScreenGui = MainGui:GenerateMain()
currScreenGui.MainBackgroundContainer.Visible = true
currScreenGui.ThumbnailContainer.Visible = true
currScreenGui.Changed:connect(function(prop)
if prop == "AbsoluteSize" then
MainGui:RecalculateSizes(currScreenGui)
end
end)
end
---------------------------------------------------------
-- Main Script (show something now + setup connections)
-- start loading assets asap
InfoProvider:LoadAssets()
MainGui:Show()
local guiService = Game:GetService("GuiService")
local instanceCount = 0
local voxelCount = 0
local brickCount = 0
local connectorCount = 0
local setVerb = true
renderSteppedConnection = Game:GetService("RunService").RenderStepped:connect(function()
instanceCount = guiService:GetInstanceCount()
voxelCount = guiService:GetVoxelCount()
brickCount = guiService:GetBrickCount()
connectorCount = guiService:GetConnectorCount()
if not currScreenGui then return end
if setVerb then
currScreenGui.MainBackgroundContainer.CloseButton:SetVerb("Exit")
setVerb = false
end
currScreenGui.ThumbnailContainer.LoadingInfoContainer.InstancesValue.Text = tostring(instanceCount)
currScreenGui.ThumbnailContainer.LoadingInfoContainer.BricksValue.Text = tostring(brickCount)
currScreenGui.ThumbnailContainer.LoadingInfoContainer.ConnectorsValue.Text = tostring(connectorCount)
if voxelCount <= 0 then
currScreenGui.ThumbnailContainer.LoadingInfoContainer.VoxelsValue.Text = "0"
else
currScreenGui.ThumbnailContainer.LoadingInfoContainer.VoxelsValue.Text = tostring(voxelCount) .." million"
end
end)
guiService.ErrorMessageChanged:connect(function()
if guiService:GetErrorMessage() ~= '' then
currScreenGui.MainBackgroundContainer.ErrorFrame.ErrorText.Text = guiService:GetErrorMessage()
currScreenGui.MainBackgroundContainer.ErrorFrame.Visible = true
else
currScreenGui.MainBackgroundContainer.ErrorFrame.Visible = false
end
end)
if guiService:GetErrorMessage() ~= '' then
currScreenGui.MainBackgroundContainer.ErrorFrame.ErrorText.Text = guiService:GetErrorMessage()
currScreenGui.MainBackgroundContainer.ErrorFrame.Visible = true
end
local forceRemovalTime = 5
local destroyed = false
function removeLoadingScreen()
if renderSteppedConnection then
renderSteppedConnection:disconnect()
end
if currScreenGui then
currScreenGui:Destroy()
currScreenGui = nil
end
if script then script:Destroy() end
destroyed = true
end
function startForceLoadingDoneTimer()
wait(forceRemovalTime)
removeLoadingScreen()
end
function gameIsLoaded()
if Game.ReplicatedFirst:IsDefaultLoadingGuiRemoved() then
removeLoadingScreen()
else
startForceLoadingDoneTimer()
end
end
Game.ReplicatedFirst.RemoveDefaultLoadingGuiSignal:connect(function()
removeLoadingScreen()
end)
if Game.ReplicatedFirst:IsDefaultLoadingGuiRemoved() then
removeLoadingScreen()
return
end
Game.Loaded:connect(function()
gameIsLoaded()
end)
if Game:IsLoaded() then
gameIsLoaded()
end
--------------------------------------------------------------------------
--
-- Animation (make the stuff we are showing look cool)
local blockSize = 10
local blockColor = Color3.new(33/255,66/255,209/255)
local yPosScale = 0
local yPosOffset = -blockSize * 3.5
local tweenStyle = Enum.EasingStyle.Sine
local tweenVelocity = 1500
local tweenTime = (currScreenGui.AbsoluteSize.X/2)/tweenVelocity
function createBlock()
local initBlock = Instance.new("Frame")
initBlock.ZIndex = 5
initBlock.Size = UDim2.new(0,blockSize,0,blockSize)
initBlock.BackgroundColor3 = COLORS.DARK
initBlock.BorderSizePixel = 0
initBlock.Position = UDim2.new(0,-blockSize,yPosScale,yPosOffset)
initBlock.Parent = currScreenGui.MainBackgroundContainer.BottomBar
return initBlock
end
local blocks = {}
for i = 1,6 do
blocks[i] = createBlock()
end
function getYOffset(newSize)
return yPosOffset - (newSize/3)
end
function rightScreenExit()
wait(tweenTime * 3)
if not currScreenGui then return end
local regSize = blocks[6].Size
local regPos = blocks[6].Position
blocks[6].Size = blocks[1].Size
blocks[6].Position = blocks[1].Position
blocks[1].Size = regSize
blocks[1].Position = regPos
wait()
for i = 1,6 do
local delayTime = tweenTime * (i - 1) * 0.5
Delay(delayTime, function()
if not currScreenGui then return end
local blockIndex = i
local blockSizeMultiplier = 4 - (i * 0.5)
blocks[blockIndex]:TweenPosition(UDim2.new(1,0,yPosScale,yPosOffset),
Enum.EasingDirection.Out,tweenStyle,
tweenTime,true)
if i == 6 then
blocks[6]:TweenSizeAndPosition(UDim2.new(0,blockSize,0,blockSize),
UDim2.new(1,0,yPosScale,yPosOffset),
Enum.EasingDirection.InOut,tweenStyle,
tweenTime,true)
wait(tweenTime * 1.1)
leftScreenEntrance()
else
local newSize = blockSize * blockSizeMultiplier
blocks[6]:TweenSizeAndPosition(UDim2.new(0,newSize,0,newSize),
UDim2.new(0.5,-newSize/2,yPosScale,getYOffset(newSize)),
Enum.EasingDirection.InOut,tweenStyle,
tweenTime * 0.75,true)
end
end)
end
end
function leftScreenEntrance()
if not currScreenGui then return end
for i = 1,6 do
blocks[i].Size = UDim2.new(0,blockSize,0,blockSize)
blocks[i].Position = UDim2.new(0,-blockSize,yPosScale,yPosOffset)
end
blocks[1]:TweenPosition(UDim2.new(0.5,-blockSize/2,yPosScale,yPosOffset),Enum.EasingDirection.Out,tweenStyle,tweenTime,true,function()
for i = 1, 6 do
local delayTime = tweenTime * (i - 1) * 0.5
Delay(delayTime, function()
if not currScreenGui then return end
local blockIndex = i
local blockSizeMultiplier = 1 + (i * 0.5)
blocks[blockIndex]:TweenPosition(UDim2.new(0.5,-blockSize/2,yPosScale,yPosOffset),
Enum.EasingDirection.Out,tweenStyle,
tweenTime,true)
local newSize = blockSize * blockSizeMultiplier
blocks[1]:TweenSizeAndPosition(UDim2.new(0,newSize,0,newSize),
UDim2.new(0.5,-newSize/2,yPosScale,getYOffset(newSize)),
Enum.EasingDirection.InOut,tweenStyle,
tweenTime * 0.75,true)
if i == 4 then
rightScreenExit()
end
end)
end
end)
end
function startLoadingAnimation()
currScreenGui.MainBackgroundContainer.BackgroundThumbnail:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Linear,20,true)
leftScreenEntrance()
end
----------------------------------
-- Animation Begin
startLoadingAnimation()
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+102
View File
@@ -0,0 +1,102 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Part" referent="RBX0">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">3</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">3</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">23</int>
<CoordinateFrame name="CFrame">
<X>-0.5</X>
<Y>0.5</Y>
<Z>0</Z>
<R00>-1.1920929e-007</R00>
<R01>1.00000012</R01>
<R02>0</R02>
<R10>1.00000012</R10>
<R11>-1.1920929e-007</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>-1.00000024</R22>
</CoordinateFrame>
<bool name="CanCollide">true</bool>
<bool name="CastsShadows">true</bool>
<token name="Controller">0</token>
<bool name="ControllerFlagShown">true</bool>
<bool name="Cullable">true</bool>
<float name="Elasticity">0.5</float>
<token name="FormFactor">0</token>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">3</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">3</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">false</bool>
<string name="Name">Rocket</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">3</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>1</Y>
<Z>4</Z>
</Vector3>
</Properties>
<Item class="Sound">
<Properties>
<bool name="Looped">true</bool>
<string name="Name">Swoosh</string>
<int name="PlayCount">0</int>
<bool name="PlayOnRemove">false</bool>
<Content name="SoundId"><url>rbxasset://sounds\Rocket whoosh 01.wav</url></Content>
<float name="Volume">0.699999988</float>
</Properties>
</Item>
<Item class="Sound">
<Properties>
<bool name="Looped">false</bool>
<string name="Name">Explosion</string>
<int name="PlayCount">0</int>
<bool name="PlayOnRemove">true</bool>
<Content name="SoundId"><url>rbxasset://sounds\collide.wav</url></Content>
<float name="Volume">1</float>
</Properties>
</Item>
<Item class="Script">
<Properties>
<string name="Name">Script</string>
<string name="Source">r = game:service(&quot;RunService&quot;)&#13;&#10;&#13;&#10;shaft = script.Parent&#13;&#10;position = Vector3.new(0,0,0)&#13;&#10;&#13;&#10;function fly()&#13;&#10;&#9;direction = shaft.CFrame.lookVector&#13;&#10;&#9;position = position + direction&#13;&#10;&#9;error = position - shaft.Position&#13;&#10;&#9;shaft.Velocity = 7*error&#13;&#10;end&#13;&#10;&#13;&#10;function blow()&#13;&#10;&#9;swoosh:Stop()&#13;&#10;&#9;explosion = Instance.new(&quot;Explosion&quot;)&#13;&#10;&#9;explosion.Position = shaft.Position&#13;&#10;&#9;explosion.Parent = game.Workspace&#13;&#10;&#9;connection:disconnect()&#13;&#10;&#9;shaft:remove()&#13;&#10;end&#13;&#10;&#13;&#10;t, s = r.Stepped:wait()&#13;&#10;&#13;&#10;swoosh = script.Parent.Swoosh&#13;&#10;swoosh:Play()&#13;&#10;&#13;&#10;position = shaft.Position&#13;&#10;d = t + 10.0 - s&#13;&#10;connection = shaft.Touched:connect(blow)&#13;&#10;&#13;&#10;while t &lt; d do&#13;&#10;&#9;fly()&#13;&#10;&#9;t = r.Stepped:wait()&#13;&#10;end&#13;&#10;&#13;&#10;script.Parent.Explosion.PlayOnRemove = false&#13;&#10;swoosh:Stop()&#13;&#10;shaft:remove()&#13;&#10;</string>
</Properties>
</Item>
</Item>
</roblox>
Binary file not shown.
+82
View File
@@ -0,0 +1,82 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Part" referent="RBX0">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">194</int>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>6.4000001</Y>
<Z>-8</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<bool name="CanCollide">true</bool>
<bool name="CastsShadows">true</bool>
<token name="Controller">0</token>
<bool name="ControllerFlagShown">true</bool>
<bool name="Cullable">true</bool>
<float name="Elasticity">0.5</float>
<token name="FormFactor">0</token>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">false</bool>
<string name="Name">Pellet</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="shape">0</token>
<Vector3 name="size">
<X>2</X>
<Y>2</Y>
<Z>2</Z>
</Vector3>
</Properties>
<Item class="Script">
<Properties>
<string name="Name">Script</string>
<string name="Source">&#13;&#10;pellet = script.Parent&#13;&#10;damage = 8&#13;&#10;&#13;&#10;function onTouched(hit)&#13;&#10;&#9;humanoid = hit.Parent:findFirstChild(&quot;Humanoid&quot;)&#13;&#10;&#9;if humanoid~=nil then&#13;&#10;&#9;&#9;humanoid.Health = humanoid.Health - damage&#13;&#10;&#9;&#9;connection:disconnect()&#13;&#10;&#9;else&#13;&#10;&#9;&#9;damage = damage / 2&#13;&#10;&#9;&#9;if damage &lt; 0.1 then&#13;&#10;&#9;&#9;&#9;connection:disconnect()&#13;&#10;&#9;&#9;end&#13;&#10;&#9;end&#13;&#10;end&#13;&#10;&#13;&#10;connection = pellet.Touched:connect(onTouched)&#13;&#10;&#13;&#10;r = game:service(&quot;RunService&quot;)&#13;&#10;t, s = r.Stepped:wait()&#13;&#10;d = t + 1.0 - s&#13;&#10;while t &lt; d do&#13;&#10;&#9;t = r.Stepped:wait()&#13;&#10;end&#13;&#10;&#13;&#10;pellet.Parent = nil</string>
</Properties>
</Item>
</Item>
</roblox>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+850
View File
@@ -0,0 +1,850 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Model" referent="RBX0">
<Properties>
<CoordinateFrame name="ModelInPrimary">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">erik.cassel</string>
<Ref name="PrimaryPart">RBX1</Ref>
</Properties>
<Item class="Part" referent="RBX1">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">194</int>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>19.5</Y>
<Z>22.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">true</bool>
<PhysicalProperties name="CustomPhysicalProperties">
<CustomPhysics>false</CustomPhysics>
</PhysicalProperties>
<float name="Elasticity">0.5</float>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<token name="Material">256</token>
<string name="Name">Head</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">0</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">0</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>2</X>
<Y>1</Y>
<Z>1</Z>
</Vector3>
</Properties>
<Item class="SpecialMesh" referent="RBX2">
<Properties>
<token name="LODX">2</token>
<token name="LODY">2</token>
<Content name="MeshId"><null></null></Content>
<token name="MeshType">0</token>
<string name="Name">Mesh</string>
<Vector3 name="Offset">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<Vector3 name="Scale">
<X>1.25</X>
<Y>1.25</Y>
<Z>1.25</Z>
</Vector3>
<Content name="TextureId"><null></null></Content>
<Vector3 name="VertexColor">
<X>1</X>
<Y>1</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>
<Item class="Decal" referent="RBX3">
<Properties>
<token name="Face">5</token>
<string name="Name">face</string>
<Content name="Texture"><url>rbxasset://textures/face.png</url></Content>
<float name="Transparency">0</float>
</Properties>
</Item>
<Item class="Attachment" referent="RBX94E86BA569B64785B5D8F3F9C1C9D4F8">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>0.600000024</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">HairAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBX378A74DCC4AA4A2598AA40FF503FD481">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>0.600000024</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">HatAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBX99DFBABC62D2465A8C279BF27A84727A">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>0</Y>
<Z>-0.600000024</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">FaceFrontAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBX1D688DF966C84BC7B8EA35A8C51B3A3E">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">FaceCenterAttachment</string>
</Properties>
</Item>
</Item>
<Item class="Part" referent="RBX4">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">194</int>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>18</Y>
<Z>22.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>-0</R02>
<R10>-0</R10>
<R11>1</R11>
<R12>-0</R12>
<R20>-0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">true</bool>
<PhysicalProperties name="CustomPhysicalProperties">
<CustomPhysics>false</CustomPhysics>
</PhysicalProperties>
<float name="Elasticity">0.5</float>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">0</float>
<float name="LeftParamB">0</float>
<token name="LeftSurface">2</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<token name="Material">256</token>
<string name="Name">Torso</string>
<float name="Reflectance">0</float>
<float name="RightParamA">0</float>
<float name="RightParamB">0</float>
<token name="RightSurface">2</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">0</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>2</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
<Item class="Decal" referent="RBX5">
<Properties>
<token name="Face">5</token>
<string name="Name">roblox</string>
<Content name="Texture"><null></null></Content>
<float name="Transparency">0</float>
</Properties>
</Item>
<Item class="Attachment" referent="RBXF18642A6731741EB965F132B28EAF1DC">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>1</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">NeckAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBXE4C1D4019C4A40DA86329D0548957CE3">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>0</Y>
<Z>-0.5</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">BodyFrontAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBX9A29D0ACFCB045FE95734B1973F9F3DA">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>0</Y>
<Z>0.5</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">BodyBackAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBXB02E7106C39E485995A68DB8B3662D6A">
<Properties>
<CoordinateFrame name="CFrame">
<X>-1</X>
<Y>1</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">LeftCollarAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBX68757F07EBFA45A8BBC77405BF28AD4A">
<Properties>
<CoordinateFrame name="CFrame">
<X>1</X>
<Y>1</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">RightCollarAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBXAE8F55F8248748C0B3B008E176195348">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>-1</Y>
<Z>-0.5</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">WaistFrontAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBXDBB757C86A6948EE86DA6F8B9A4CBDC0">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>-1</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">WaistCenterAttachment</string>
</Properties>
</Item>
<Item class="Attachment" referent="RBX0CD5ED23664D4ECABBB224F0DAE8542E">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>-1</Y>
<Z>0.5</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">WaistBackAttachment</string>
</Properties>
</Item>
</Item>
<Item class="Part" referent="RBX6">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">194</int>
<CoordinateFrame name="CFrame">
<X>1.5</X>
<Y>18</Y>
<Z>22.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">false</bool>
<PhysicalProperties name="CustomPhysicalProperties">
<CustomPhysics>false</CustomPhysics>
</PhysicalProperties>
<float name="Elasticity">0.5</float>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<token name="Material">256</token>
<string name="Name">Left Arm</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">0</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
<Item class="Attachment" referent="RBX32AAED8CBEAA432B93549F57A8CD264F">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>1.0</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">LeftShoulderAttachment</string>
</Properties>
</Item>
</Item>
<Item class="Part" referent="RBX7">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">194</int>
<CoordinateFrame name="CFrame">
<X>-1.5</X>
<Y>18</Y>
<Z>22.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">false</bool>
<PhysicalProperties name="CustomPhysicalProperties">
<CustomPhysics>false</CustomPhysics>
</PhysicalProperties>
<float name="Elasticity">0.5</float>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<token name="Material">256</token>
<string name="Name">Right Arm</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">0</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
<Item class="Attachment" referent="RBX1442A14CF3BB469E8B8A84AEF3ACBA23">
<Properties>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>1.0</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">RightShoulderAttachment</string>
</Properties>
</Item>
</Item>
<Item class="Part" referent="RBX8">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">0</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">194</int>
<CoordinateFrame name="CFrame">
<X>0.5</X>
<Y>16</Y>
<Z>22.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>-0</R02>
<R10>-0</R10>
<R11>1</R11>
<R12>-0</R12>
<R20>-0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">false</bool>
<PhysicalProperties name="CustomPhysicalProperties">
<CustomPhysics>false</CustomPhysics>
</PhysicalProperties>
<float name="Elasticity">0.5</float>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<token name="Material">256</token>
<string name="Name">Left Leg</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">0</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>
<Item class="Part" referent="RBX9">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">0</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">194</int>
<CoordinateFrame name="CFrame">
<X>-0.5</X>
<Y>16</Y>
<Z>22.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>-0</R02>
<R10>-0</R10>
<R11>1</R11>
<R12>-0</R12>
<R20>-0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">false</bool>
<PhysicalProperties name="CustomPhysicalProperties">
<CustomPhysics>false</CustomPhysics>
</PhysicalProperties>
<float name="Elasticity">0.5</float>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<token name="Material">256</token>
<string name="Name">Right Leg</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">0</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>
<Item class="Humanoid" referent="RBX10">
<Properties>
<token name="DisplayDistanceType">0</token>
<float name="HealthDisplayDistance">100</float>
<float name="Health_XML">100</float>
<float name="HipHeight">0</float>
<float name="JumpPower">50</float>
<float name="MaxHealth">100</float>
<float name="MaxSlopeAngle">89</float>
<string name="Name">Humanoid</string>
<float name="NameDisplayDistance">100</float>
<token name="NameOcclusion">2</token>
<float name="WalkSpeed">16</float>
</Properties>
</Item>
<Item class="Part" referent="RBX11">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">0</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">194</int>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>18</Y>
<Z>22.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>-0</R02>
<R10>-0</R10>
<R11>1</R11>
<R12>-0</R12>
<R20>-0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">false</bool>
<PhysicalProperties name="CustomPhysicalProperties">
<CustomPhysics>false</CustomPhysics>
</PhysicalProperties>
<float name="Elasticity">0.5</float>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">0</float>
<float name="LeftParamB">0</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<token name="Material">256</token>
<string name="Name">HumanoidRootPart</string>
<float name="Reflectance">0</float>
<float name="RightParamA">0</float>
<float name="RightParamB">0</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">0</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">1</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">0</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>2</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>
</Item>
</roblox>
+527
View File
@@ -0,0 +1,527 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Model" referent="RBX0">
<Properties>
<token name="Controller">7</token>
<bool name="ControllerFlagShown">true</bool>
<CoordinateFrame name="ModelInPrimary">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">erik.cassel</string>
<Ref name="PrimaryPart">RBX1</Ref>
<bool name="archivable">true</bool>
</Properties>
<Item class="Part" referent="RBX1">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">24</int>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>4.5</Y>
<Z>25.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">true</bool>
<token name="Controller">0</token>
<bool name="ControllerFlagShown">true</bool>
<bool name="DraggingV1">false</bool>
<float name="Elasticity">0.5</float>
<token name="FormFactor">0</token>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<string name="Name">Head</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">0</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<bool name="archivable">true</bool>
<token name="shape">1</token>
<Vector3 name="size">
<X>2</X>
<Y>1</Y>
<Z>1</Z>
</Vector3>
</Properties>
<Item class="SpecialMesh" referent="RBX2">
<Properties>
<Content name="MeshId"><null></null></Content>
<token name="MeshType">0</token>
<string name="Name">Mesh</string>
<Vector3 name="Scale">
<X>1.25</X>
<Y>1.25</Y>
<Z>1.25</Z>
</Vector3>
<Content name="TextureId"><null></null></Content>
<Vector3 name="VertexColor">
<X>1</X>
<Y>1</Y>
<Z>1</Z>
</Vector3>
<bool name="archivable">true</bool>
</Properties>
</Item>
<Item class="Decal" referent="RBX3">
<Properties>
<token name="Face">5</token>
<string name="Name">face</string>
<float name="Shiny">20</float>
<float name="Specular">0</float>
<Content name="Texture"><url>rbxasset://textures/face.png</url></Content>
<bool name="archivable">true</bool>
</Properties>
</Item>
</Item>
<Item class="Part" referent="RBX4">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">23</int>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>3</Y>
<Z>25.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>-0</R02>
<R10>-0</R10>
<R11>1</R11>
<R12>-0</R12>
<R20>-0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">true</bool>
<token name="Controller">0</token>
<bool name="ControllerFlagShown">true</bool>
<bool name="DraggingV1">false</bool>
<float name="Elasticity">0.5</float>
<token name="FormFactor">0</token>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">0</float>
<float name="LeftParamB">0</float>
<token name="LeftSurface">2</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<string name="Name">Torso</string>
<float name="Reflectance">0</float>
<float name="RightParamA">0</float>
<float name="RightParamB">0</float>
<token name="RightSurface">2</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<bool name="archivable">true</bool>
<token name="shape">1</token>
<Vector3 name="size">
<X>2</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
<Item class="Decal" referent="RBX5">
<Properties>
<token name="Face">5</token>
<string name="Name">roblox</string>
<float name="Shiny">20</float>
<float name="Specular">0</float>
<Content name="Texture">
<null></null>
</Content>
<bool name="archivable">true</bool>
</Properties>
</Item>
</Item>
<Item class="Part" referent="RBX6">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">24</int>
<CoordinateFrame name="CFrame">
<X>1.5</X>
<Y>3</Y>
<Z>25.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">false</bool>
<token name="Controller">0</token>
<bool name="ControllerFlagShown">true</bool>
<bool name="DraggingV1">false</bool>
<float name="Elasticity">0.5</float>
<token name="FormFactor">0</token>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<string name="Name">Left Arm</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<bool name="archivable">true</bool>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>
<Item class="Part" referent="RBX7">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">24</int>
<CoordinateFrame name="CFrame">
<X>-1.5</X>
<Y>3</Y>
<Z>25.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">false</bool>
<token name="Controller">0</token>
<bool name="ControllerFlagShown">true</bool>
<bool name="DraggingV1">false</bool>
<float name="Elasticity">0.5</float>
<token name="FormFactor">0</token>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<string name="Name">Right Arm</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<bool name="archivable">true</bool>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>
<Item class="Part" referent="RBX8">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">0</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">119</int>
<CoordinateFrame name="CFrame">
<X>0.5</X>
<Y>1</Y>
<Z>25.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">false</bool>
<token name="Controller">0</token>
<bool name="ControllerFlagShown">true</bool>
<bool name="DraggingV1">false</bool>
<float name="Elasticity">0.5</float>
<token name="FormFactor">0</token>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<string name="Name">Left Leg</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<bool name="archivable">true</bool>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>
<Item class="Part" referent="RBX9">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">0</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">119</int>
<CoordinateFrame name="CFrame">
<X>-0.5</X>
<Y>1</Y>
<Z>25.5</Z>
<R00>-1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>-1</R22>
</CoordinateFrame>
<bool name="CanCollide">false</bool>
<token name="Controller">0</token>
<bool name="ControllerFlagShown">true</bool>
<bool name="DraggingV1">false</bool>
<float name="Elasticity">0.5</float>
<token name="FormFactor">0</token>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<string name="Name">Right Leg</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<bool name="archivable">true</bool>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>2</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>
<Item class="Humanoid" referent="RBX10">
<Properties>
<float name="Health">100</float>
<bool name="Jump">false</bool>
<float name="MaxHealth">100</float>
<string name="Name">Humanoid</string>
<bool name="Sit">false</bool>
<Vector3 name="TargetPoint">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<Vector3 name="WalkDirection">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="WalkRotationalVelocity">0</float>
<Ref name="WalkToPart">null</Ref>
<Vector3 name="WalkToPoint">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<bool name="archivable">true</bool>
</Properties>
</Item>
</Item>
</roblox>
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+366
View File
@@ -0,0 +1,366 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Script" referent="RBXf11428b7b777457c8d872c64386aa070">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Sound</string>
<string name="ScriptGuid"></string>
<ProtectedString name="Source"><![CDATA[--[[
Author: @spotco
This script creates sounds which are placed under the character head.
These sounds are used by the "LocalSound" script.
To modify this script, copy it to your "StarterPlayer/StarterCharacterScripts" folder keeping the same script name ("Sound").
The default Sound script loaded for every character will then be replaced with your copy of the script.
]]--
function CreateNewSound(name, id, looped, pitch, parent)
local sound = Instance.new("Sound")
sound.SoundId = id
sound.Name = name
sound.archivable = false
sound.Parent = parent
sound.Pitch = pitch
sound.Looped = looped
sound.MinDistance = 5
sound.MaxDistance = 150
sound.Volume = 0.65
return sound
end
local head = script.Parent:FindFirstChild("Head")
if head == nil then
error("Sound script parent has no child Head.")
return
end
CreateNewSound("GettingUp", "rbxasset://sounds/action_get_up.mp3", false, 1, head)
CreateNewSound("Died", "rbxasset://sounds/uuhhh.mp3", false, 1, head)
CreateNewSound("FreeFalling", "rbxasset://sounds/action_falling.mp3", true, 1, head)
CreateNewSound("Jumping", "rbxasset://sounds/action_jump.mp3", false, 1, head)
CreateNewSound("Landing", "rbxasset://sounds/action_jump_land.mp3", false, 1, head)
CreateNewSound("Splash", "rbxasset://sounds/impact_water.mp3", false, 1, head)
CreateNewSound("Running", "rbxasset://sounds/action_footsteps_plastic.mp3", true, 1.85, head)
CreateNewSound("Swimming", "rbxasset://sounds/action_swim.mp3", true, 1.6, head)
CreateNewSound("Climbing", "rbxasset://sounds/action_footsteps_plastic.mp3", true, 1, head)]]></ProtectedString>
</Properties>
<Item class="LocalScript" referent="RBXcf674087fdd94888aaa89ff050d72c40">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">LocalSound</string>
<string name="ScriptGuid"></string>
<ProtectedString name="Source"><![CDATA[--[[
Author: @spotco
This script runs locally for the player of the given humanoid.
This script triggers humanoid sound play/pause actions locally.
The Playing/TimePosition properties of Sound objects bypass FilteringEnabled, so this triggers the sound
immediately for the player and is replicated to all other players.
This script is optimized to reduce network traffic through minimizing the amount of property replication.
]]--
--All sounds are referenced by this ID
local SFX = {
Died = 0;
Running = 1;
Swimming = 2;
Climbing = 3,
Jumping = 4;
GettingUp = 5;
FreeFalling = 6;
FallingDown = 7;
Landing = 8;
Splash = 9;
}
local Humanoid = nil
local Head = nil
--SFX ID to Sound object
local Sounds = {}
do
local Figure = script.Parent.Parent
Head = Figure:WaitForChild("Head")
while not Humanoid do
for _,NewHumanoid in pairs(Figure:GetChildren()) do
if NewHumanoid:IsA("Humanoid") then
Humanoid = NewHumanoid
break
end
end
Figure.ChildAdded:wait()
end
Sounds[SFX.Died] = Head:WaitForChild("Died")
Sounds[SFX.Running] = Head:WaitForChild("Running")
Sounds[SFX.Swimming] = Head:WaitForChild("Swimming")
Sounds[SFX.Climbing] = Head:WaitForChild("Climbing")
Sounds[SFX.Jumping] = Head:WaitForChild("Jumping")
Sounds[SFX.GettingUp] = Head:WaitForChild("GettingUp")
Sounds[SFX.FreeFalling] = Head:WaitForChild("FreeFalling")
Sounds[SFX.Landing] = Head:WaitForChild("Landing")
Sounds[SFX.Splash] = Head:WaitForChild("Splash")
end
local Util
Util = {
--Define linear relationship between (pt1x,pt2x) and (pt2x,pt2y). Evaluate this at x.
YForLineGivenXAndTwoPts = function(x,pt1x,pt1y,pt2x,pt2y)
--(y - y1)/(x - x1) = m
local m = (pt1y - pt2y) / (pt1x - pt2x)
--float b = pt1.y - m * pt1.x;
local b = (pt1y - m * pt1x)
return m * x + b
end;
--Clamps the value of "val" between the "min" and "max"
Clamp = function(val,min,max)
return math.min(max,math.max(min,val))
end;
--Gets the horizontal (x,z) velocity magnitude of the given part
HorizontalSpeed = function(Head)
local hVel = Head.Velocity + Vector3.new(0,-Head.Velocity.Y,0)
return hVel.magnitude
end;
--Gets the vertical (y) velocity magnitude of the given part
VerticalSpeed = function(Head)
return math.abs(Head.Velocity.Y)
end;
--Setting Playing/TimePosition values directly result in less network traffic than Play/Pause/Resume/Stop
--If these properties are enabled, use them.
Play = function(sound)
if sound.TimePosition ~= 0 then
sound.TimePosition = 0
end
if not sound.IsPlaying then
sound.Playing = true
end
end;
Pause = function(sound)
if sound.IsPlaying then
sound.Playing = false
end
end;
Resume = function(sound)
if not sound.IsPlaying then
sound.Playing = true
end
end;
Stop = function(sound)
if sound.IsPlaying then
sound.Playing = false
end
if sound.TimePosition ~= 0 then
sound.TimePosition = 0
end
end;
}
do
-- List of all active Looped sounds
local playingLoopedSounds = {}
-- Last seen Enum.HumanoidStateType
local activeState = nil
-- Verify and set that "sound" is in "playingLoopedSounds".
function setSoundInPlayingLoopedSounds(sound)
for i=1, #playingLoopedSounds do
if playingLoopedSounds[i] == sound then
return
end
end
table.insert(playingLoopedSounds,sound)
end
-- Stop all active looped sounds except parameter "except". If "except" is not passed, all looped sounds will be stopped.
function stopPlayingLoopedSoundsExcept(except)
for i=#playingLoopedSounds,1,-1 do
if playingLoopedSounds[i] ~= except then
Util.Pause(playingLoopedSounds[i])
table.remove(playingLoopedSounds,i)
end
end
end
-- Table of Enum.HumanoidStateType to handling function
local stateUpdateHandler = {
[Enum.HumanoidStateType.Dead] = function()
stopPlayingLoopedSoundsExcept()
local sound = Sounds[SFX.Died]
Util.Play(sound)
end;
[Enum.HumanoidStateType.RunningNoPhysics] = function()
stateUpdated(Enum.HumanoidStateType.Running)
end;
[Enum.HumanoidStateType.Running] = function()
local sound = Sounds[SFX.Running]
stopPlayingLoopedSoundsExcept(sound)
if Util.HorizontalSpeed(Head) > 0.5 then
Util.Resume(sound)
setSoundInPlayingLoopedSounds(sound)
else
stopPlayingLoopedSoundsExcept()
end
end;
[Enum.HumanoidStateType.Swimming] = function()
if activeState ~= Enum.HumanoidStateType.Swimming and Util.VerticalSpeed(Head) > 0.1 then
local splashSound = Sounds[SFX.Splash]
splashSound.Volume = Util.Clamp(
Util.YForLineGivenXAndTwoPts(
Util.VerticalSpeed(Head),
100, 0.28,
350, 1),
0,1)
Util.Play(splashSound)
end
do
local sound = Sounds[SFX.Swimming]
stopPlayingLoopedSoundsExcept(sound)
Util.Resume(sound)
setSoundInPlayingLoopedSounds(sound)
end
end;
[Enum.HumanoidStateType.Climbing] = function()
local sound = Sounds[SFX.Climbing]
if Util.VerticalSpeed(Head) > 0.1 then
Util.Resume(sound)
stopPlayingLoopedSoundsExcept(sound)
else
stopPlayingLoopedSoundsExcept()
end
setSoundInPlayingLoopedSounds(sound)
end;
[Enum.HumanoidStateType.Jumping] = function()
if activeState == Enum.HumanoidStateType.Jumping then
return
end
stopPlayingLoopedSoundsExcept()
local sound = Sounds[SFX.Jumping]
Util.Play(sound)
end;
[Enum.HumanoidStateType.GettingUp] = function()
stopPlayingLoopedSoundsExcept()
local sound = Sounds[SFX.GettingUp]
Util.Play(sound)
end;
[Enum.HumanoidStateType.Freefall] = function()
if activeState == Enum.HumanoidStateType.Freefall then
return
end
local sound = Sounds[SFX.FreeFalling]
sound.Volume = 0
stopPlayingLoopedSoundsExcept()
end;
[Enum.HumanoidStateType.FallingDown] = function()
stopPlayingLoopedSoundsExcept()
end;
[Enum.HumanoidStateType.Landed] = function()
stopPlayingLoopedSoundsExcept()
if Util.VerticalSpeed(Head) > 75 then
local landingSound = Sounds[SFX.Landing]
landingSound.Volume = Util.Clamp(
Util.YForLineGivenXAndTwoPts(
Util.VerticalSpeed(Head),
50, 0,
100, 1),
0,1)
Util.Play(landingSound)
end
end;
[Enum.HumanoidStateType.Seated] = function()
stopPlayingLoopedSoundsExcept()
end;
}
-- Handle state event fired or OnChange fired
function stateUpdated(state)
if stateUpdateHandler[state] ~= nil then
stateUpdateHandler[state]()
end
activeState = state
end
Humanoid.Died:connect( function() stateUpdated(Enum.HumanoidStateType.Dead) end)
Humanoid.Running:connect( function() stateUpdated(Enum.HumanoidStateType.Running) end)
Humanoid.Swimming:connect( function() stateUpdated(Enum.HumanoidStateType.Swimming) end)
Humanoid.Climbing:connect( function() stateUpdated(Enum.HumanoidStateType.Climbing) end)
Humanoid.Jumping:connect( function() stateUpdated(Enum.HumanoidStateType.Jumping) end)
Humanoid.GettingUp:connect( function() stateUpdated(Enum.HumanoidStateType.GettingUp) end)
Humanoid.FreeFalling:connect( function() stateUpdated(Enum.HumanoidStateType.Freefall) end)
Humanoid.FallingDown:connect( function() stateUpdated(Enum.HumanoidStateType.FallingDown) end)
-- required for proper handling of Landed event
Humanoid.StateChanged:connect(function(old, new)
stateUpdated(new)
end)
function onUpdate(stepDeltaSeconds, tickSpeedSeconds)
local stepScale = stepDeltaSeconds / tickSpeedSeconds
do
local sound = Sounds[SFX.FreeFalling]
if activeState == Enum.HumanoidStateType.Freefall then
if Head.Velocity.Y < 0 and Util.VerticalSpeed(Head) > 75 then
Util.Resume(sound)
--Volume takes 1.1 seconds to go from volume 0 to 1
local ANIMATION_LENGTH_SECONDS = 1.1
local normalizedIncrement = tickSpeedSeconds / ANIMATION_LENGTH_SECONDS
sound.Volume = Util.Clamp(sound.Volume + normalizedIncrement * stepScale, 0, 1)
else
sound.Volume = 0
end
else
Util.Pause(sound)
end
end
do
local sound = Sounds[SFX.Running]
if activeState == Enum.HumanoidStateType.Running then
if Util.HorizontalSpeed(Head) < 0.5 then
Util.Pause(sound)
end
end
end
end
local lastTick = tick()
local TICK_SPEED_SECONDS = 0.25
while true do
onUpdate(tick() - lastTick,TICK_SPEED_SECONDS)
lastTick = tick()
wait(TICK_SPEED_SECONDS)
end
end
]]></ProtectedString>
</Properties>
</Item>
</Item>
</roblox>
Binary file not shown.
+356
View File
@@ -0,0 +1,356 @@
a 6>
4=:90
4;499,
4; &
4&=:90
4&=:90&
4&&=:90
4&&=:90&
4&&><&&0'
704&!<49<!,
704&!<9<!,
70&!<49<!,
7<6=
7<6=0&
7<6!=
7<!6
7<!6=
7<!6=0'
7<!6=0'&
7<!6=0&
7<!6=<;
7<!6=<;2
7<!6=&
79:"?:7
79:"?:7&
7:;0'
7 99&=<!
7 9&=<!
7 !!3 6>
7 !!3 6>0'
7 !!=4<'
7 !!&0-
7 !!&06&
7 !!&0>&
6=<;>
6<'690?0'>
69<!
6e;1e8&
6:;1e8&
6e;1:8&
6:6>
6:6>{
6:6>&
6:6>& 6>
6:6>& 6>01
6:6>& 6>0'
6:6>& 6><;2
6:6>& 6>&
6:>
6:;1:8
6:;1:8&
6::!0'
6 8
6 880'
6 88<;2
6 8&
6 8&=:!
6 8&=:!
6 ;<9<;2 &
6 ;<99<;2 &
6 ;;<9<;2 &
6 ;!
6 ;!9<6>
6 ;!9<6>0'
6 ;!9<6><;2
6 ;!&
6,70'3 6
6,70'3 6>
6,70'3 6>01
6,70'3 6>0'
6,70'3 6>0'&
6,70'3 6><;2
1<6>
1<6>&
1<>0
1<91:
1<91:
1<91:&
1<91:&
1<%&=<!
1: 6=0
1: 6=0742
1,>0
0?46 94!0
0?46 94!01
0?46 94!0&
0?46 94!<;2
0?46 94!<;2&
0?46 94!<:;
30'
3<;2
342
3420!
3422
34220!
3422<;2
3422<!
3422:!
3422&
342<!
342:!
342:!&
342&
34%%0'
34%%<;2
34%%<;
34">
36><;2
3094!<:
3094!<:
30994!<:
3<;20'74;2
3<;20'3 6>
3<;20'3 6>01
3<;20'3 6>0'
3<;20'3 6>0'&
3<;20'3 6><;2
3<;20'3 6>&
3<&!3 6>
3<&!3 6>01
3<&!3 6>0'
3<&!3 6>0'&
3<&!3 6><;2
3<&!3 6><;2&
3<&!3 6>&
3:6><;2
3 6>
3 6>t
3 6>0
3 6>01
3 6>0;
3 6>0'
3 6>0'&
3 6><;
3 6><;2
3 6><;2&
3 6>>>>>>>>>>>>>>>>>
3 6>80
3 6>&
3 6>!4'1
3 6>,:
3 >
3 >0'
3 ><;
3 ><;2
3 >>
3 >&
3 '7 '20'
24;274;2
24;274;201
24;274;2&
24,
24,&0-
24/:;24&
24/:;20'&
2:;41&
2::>
=4'16:'0&0-
=4'1:;
=:8:
=::>0'
=:';<0&!
=:';,
=:!&0-
= 8%
?46>4&&
?46><;2:33
?46>:33
?46>x:33
?4%
?0'>x:33
?0"
?<&8
?</
?</8
?<//
><>0
>>>
>:6>
>:;1 8
>:;1 8&
> 8
> 880'
> 88<;2
> 8&
> ;<9<;2 &
90&7<4;
90&7:
9 &!<;2
80'10
8:90&!
8:!=43 6>
8:!=43 6>
8:!=43 6>4
8:!=43 6>4
8:!=43 6>4&
8:!=43 6>4&
8:!=43 6>4/
8:!=43 6>4/
8:!=43 6>01
8:!=43 6>01
8:!=43 6>0'
8:!=43 6>0'
8:!=43 6>0'&
8:!=43 6>0'&
8:!=43 6><;
8:!=43 6><;
8:!=43 6><;2
8:!=43 6><;2
8:!=43 6><;2&
8:!=43 6><;2&
8:!=43 6>&
8:!=43 6>&
8:!=0'3 6>
8:!=0'3 6>
8:!=0'3 6>01
8:!=0'3 6>0'
8:!=0'3 6>0'
8:!=0'3 6>0'&
8:!=0'3 6>0'&
8:!=0'3 6><;
8:!=0'3 6><;
8:!=0'3 6><;2
8:!=0'3 6><;2
8:!=0'3 6><;2&
8:!=0'3 6><;2&
8:!=0'3 6>&
8:!=0'3 6>&
;4/<
;<20'
;<224
;<224&
;<220'
;<220'
;<220'&
;<220'&
:'24&<8
:'24&<8&
:'24&8
:'24&8&
%06>0'
%0;<&
%=:;0&0-
%= >01
%= ><;2
%= >>01
%= >><;2
%= >
%= >&
%= $
%<8%
%<&&:33
%:';
%:';:
%:';:2'4%=,
%:';:&
%'<6>
%'<6>&
%':&!<! !0
% &<0&
% &&<0&
% &&,
% &&,&
% &,
% &,&
$ 00'
'%0
'%01
'4%0
'4%01
&6=9:;2
&0-
&0--
&0---
&=<!3 99
&=<!<;2
&=<!<;2&
&=<!&
&=<!!01
&=<!!0'
&=<!!0'&
&=<!!<;2
&=<!!<;2&
&=<!!,
&=<!,
&9 !
&9 !&
&8 !
&;4!6=
&:1:8<!0
&:1:8</0
&:1:8</0'
&:1:8,
&% ;>
& 6>
!'48%
!"4!
#42<;4
#<7'4!:'
"4;2
"4;>
"4;>0'
"0!746>
"=:'0
":%
Binary file not shown.
+89
View File
@@ -0,0 +1,89 @@
# Windows - DINPUT
8f0e1200000000000000504944564944,Acme,platform:Windows,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,
341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,
25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,
4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,platform:Windows,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,
36280100000000000000504944564944,OUYA Controller,platform:Windows,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13,
4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Windows,
00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,
00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,
28040140000000000000504944564944,GamePad Pro USB,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,
ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9,
8f0e0300000000000000504944564944,Piranha xtreme,platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,
8f0e0d31000000000000504944564944,Multilaser JS071 USB,platform:Windows,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,
10080300000000000000504944564944,PS2 USB,platform:Windows,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5,
79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows,
4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,platform:Windows,
d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,
a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows,
8f0e0300000000000000504944564944,Trust GTX 28,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,
4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,platform:Windows,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,
# OS X
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,Platform:Mac OS X,
5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Mac OS X,
4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Mac OS X,
8f0e0000000000000300000000000000,Piranha xtreme,platform:Mac OS X,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,
0d0f0000000000004d00000000000000,HORI Gem Pad 3,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,
79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,
4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,platform:Mac OS X,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,
# Linux
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Linux,
03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,
03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Linux,
030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,y:b3,x:b1,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux,
030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,
030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,
030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,
030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
030000006d04000016c2000010010000,Logitech Logitech Dual Action,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,
03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Linux,
030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,y:b4,x:b3,start:b8,guide:b5,back:b2,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b9,righttrigger:b10,platform:Linux,
030000006d04000018c2000010010000,Logitech Logitech RumblePad 2 USB,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,
05000000d6200000ad0d000001000000,Moga Pro,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,
030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,
030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,
0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux,
0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux,
030000006f0e00001f01000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,
03000000280400000140000000010000,Gravis GamePad Pro USB ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,
030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,
030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,
03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,platform:Linux,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,
030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux,
03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
050000004c050000c405000000010000,PS4 Controller (Bluetooth),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux,
03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,
03000000666600000488000000010000,Super Joy Box 5 Pro,platform:Linux,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,
05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,
05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,
030000008916000001fd000024010000,Razer Onza Classic Edition,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,
030000005e040000d102000001010000,Microsoft X-Box One pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+296
View File
@@ -0,0 +1,296 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Script" referent="RBX0">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Animate</string>
<string name="Source">-- Now with exciting TeamColors HACK!
function waitForChild(parent, childName)
local child = parent:findFirstChild(childName)
if child then return child end
while true do
child = parent.ChildAdded:wait()
if child.Name==childName then return child end
end
end
-- TEAM COLORS
function onTeamChanged(player)
wait(1)
local char = player.Character
if char == nil then return end
if player.Neutral then
-- Replacing the current BodyColor object will force a reset
local old = char:findFirstChild(&quot;Body Colors&quot;)
if not old then return end
old:clone().Parent = char
old.Parent = nil
else
local head = char:findFirstChild(&quot;Head&quot;)
local torso = char:findFirstChild(&quot;Torso&quot;)
local left_arm = char:findFirstChild(&quot;Left Arm&quot;)
local right_arm = char:findFirstChild(&quot;Right Arm&quot;)
local left_leg = char:findFirstChild(&quot;Left Leg&quot;)
local right_leg = char:findFirstChild(&quot;Right Leg&quot;)
if head then head.BrickColor = BrickColor.new(24) end
if torso then torso.BrickColor = player.TeamColor end
if left_arm then left_arm.BrickColor = BrickColor.new(26) end
if right_arm then right_arm.BrickColor = BrickColor.new(26) end
if left_leg then left_leg.BrickColor = BrickColor.new(26) end
if right_leg then right_leg.BrickColor = BrickColor.new(26) end
end
end
function onPlayerPropChanged(property, player)
if property == &quot;Character&quot; then
onTeamChanged(player)
end
if property== &quot;TeamColor&quot; or property == &quot;Neutral&quot; then
onTeamChanged(player)
end
end
local cPlayer = game.Players:GetPlayerFromCharacter(script.Parent)
cPlayer.Changed:connect(function(property) onPlayerPropChanged(property, cPlayer) end )
onTeamChanged(cPlayer)
-- ANIMATION
-- declarations
local Figure = script.Parent
local Torso = waitForChild(Figure, &quot;Torso&quot;)
local RightShoulder = waitForChild(Torso, &quot;Right Shoulder&quot;)
local LeftShoulder = waitForChild(Torso, &quot;Left Shoulder&quot;)
local RightHip = waitForChild(Torso, &quot;Right Hip&quot;)
local LeftHip = waitForChild(Torso, &quot;Left Hip&quot;)
local Neck = waitForChild(Torso, &quot;Neck&quot;)
local Humanoid = waitForChild(Figure, &quot;Humanoid&quot;)
local pose = &quot;Standing&quot;
local toolAnim = &quot;None&quot;
local toolAnimTime = 0
-- functions
function onRunning(speed)
if speed&gt;0 then
pose = &quot;Running&quot;
else
pose = &quot;Standing&quot;
end
end
function onDied()
pose = &quot;Dead&quot;
end
function onJumping()
pose = &quot;Jumping&quot;
end
function onClimbing()
pose = &quot;Climbing&quot;
end
function onGettingUp()
pose = &quot;GettingUp&quot;
end
function onFreeFall()
pose = &quot;FreeFall&quot;
end
function onFallingDown()
pose = &quot;FallingDown&quot;
end
function onSeated()
pose = &quot;Seated&quot;
end
function onPlatformStanding()
pose = &quot;PlatformStanding&quot;
end
function moveJump()
RightShoulder.MaxVelocity = 0.5
LeftShoulder.MaxVelocity = 0.5
RightShoulder:SetDesiredAngle(3.14)
LeftShoulder:SetDesiredAngle(-3.14)
RightHip:SetDesiredAngle(0)
LeftHip:SetDesiredAngle(0)
end
-- same as jump for now
function moveFreeFall()
RightShoulder.MaxVelocity = 0.5
LeftShoulder.MaxVelocity = 0.5
RightShoulder:SetDesiredAngle(3.14)
LeftShoulder:SetDesiredAngle(-3.14)
RightHip:SetDesiredAngle(0)
LeftHip:SetDesiredAngle(0)
end
function moveSit()
RightShoulder.MaxVelocity = 0.15
LeftShoulder.MaxVelocity = 0.15
RightShoulder:SetDesiredAngle(3.14 /2)
LeftShoulder:SetDesiredAngle(-3.14 /2)
RightHip:SetDesiredAngle(3.14 /2)
LeftHip:SetDesiredAngle(-3.14 /2)
end
function getTool()
for _, kid in ipairs(Figure:GetChildren()) do
if kid.className == &quot;Tool&quot; then return kid end
end
return nil
end
function getToolAnim(tool)
for _, c in ipairs(tool:GetChildren()) do
if c.Name == &quot;toolanim&quot; and c.className == &quot;StringValue&quot; then
return c
end
end
return nil
end
function animateTool()
if (toolAnim == &quot;None&quot;) then
RightShoulder:SetDesiredAngle(1.57)
return
end
if (toolAnim == &quot;Slash&quot;) then
RightShoulder.MaxVelocity = 0.5
RightShoulder:SetDesiredAngle(0)
return
end
if (toolAnim == &quot;Lunge&quot;) then
RightShoulder.MaxVelocity = 0.5
LeftShoulder.MaxVelocity = 0.5
RightHip.MaxVelocity = 0.5
LeftHip.MaxVelocity = 0.5
RightShoulder:SetDesiredAngle(1.57)
LeftShoulder:SetDesiredAngle(1.0)
RightHip:SetDesiredAngle(1.57)
LeftHip:SetDesiredAngle(1.0)
return
end
end
function move(time)
local amplitude
local frequency
if (pose == &quot;Jumping&quot;) then
moveJump()
return
end
if (pose == &quot;FreeFall&quot;) then
moveFreeFall()
return
end
if (pose == &quot;Seated&quot;) then
moveSit()
return
end
local climbFudge = 0
if (pose == &quot;Running&quot;) then
RightShoulder.MaxVelocity = 0.15
LeftShoulder.MaxVelocity = 0.15
amplitude = 1
frequency = 9
elseif (pose == &quot;Climbing&quot;) then
RightShoulder.MaxVelocity = 0.5
LeftShoulder.MaxVelocity = 0.5
amplitude = 1
frequency = 9
climbFudge = 3.14
else
amplitude = 0.1
frequency = 1
end
desiredAngle = amplitude * math.sin(time*frequency)
RightShoulder:SetDesiredAngle(desiredAngle + climbFudge)
LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge)
RightHip:SetDesiredAngle(-desiredAngle)
LeftHip:SetDesiredAngle(-desiredAngle)
local tool = getTool()
if tool then
animStringValueObject = getToolAnim(tool)
if animStringValueObject then
toolAnim = animStringValueObject.Value
-- message recieved, delete StringValue
animStringValueObject.Parent = nil
toolAnimTime = time + .3
end
if time &gt; toolAnimTime then
toolAnimTime = 0
toolAnim = &quot;None&quot;
end
animateTool()
else
toolAnim = &quot;None&quot;
toolAnimTime = 0
end
end
-- connect events
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)
-- main program
local runService = game:service(&quot;RunService&quot;);
while Figure.Parent~=nil do
local _, time = wait(0.1)
move(time)
end
</string>
<bool name="archivable">true</bool>
</Properties>
</Item>
</roblox>
@@ -0,0 +1,336 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="LocalScript" referent="RBX0">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Animate</string>
<string name="Source">
function waitForChild(parent, childName)
local child = parent:findFirstChild(childName)
if child then return child end
while true do
child = parent.ChildAdded:wait()
if child.Name==childName then return child end
end
end
-- ANIMATION
-- declarations
local Figure = script.Parent
local Torso = waitForChild(Figure, &quot;Torso&quot;)
local RightShoulder = waitForChild(Torso, &quot;Right Shoulder&quot;)
local LeftShoulder = waitForChild(Torso, &quot;Left Shoulder&quot;)
local RightHip = waitForChild(Torso, &quot;Right Hip&quot;)
local LeftHip = waitForChild(Torso, &quot;Left Hip&quot;)
local Neck = waitForChild(Torso, &quot;Neck&quot;)
local Humanoid = waitForChild(Figure, &quot;Humanoid&quot;)
local pose = &quot;Standing&quot;
local toolAnim = &quot;None&quot;
local toolAnimTime = 0
local jumpMaxLimbVelocity = 0.75
-- functions
function onRunning(speed)
if speed&gt;0 then
pose = &quot;Running&quot;
else
pose = &quot;Standing&quot;
end
end
function onDied()
pose = &quot;Dead&quot;
end
function onJumping()
pose = &quot;Jumping&quot;
end
function onClimbing()
pose = &quot;Climbing&quot;
end
function onGettingUp()
pose = &quot;GettingUp&quot;
end
function onFreeFall()
pose = &quot;FreeFall&quot;
end
function onFallingDown()
pose = &quot;FallingDown&quot;
end
function onSeated()
pose = &quot;Seated&quot;
end
function onPlatformStanding()
pose = &quot;PlatformStanding&quot;
end
function onSwimming(speed)
if speed&gt;0 then
pose = &quot;Running&quot;
else
pose = &quot;Standing&quot;
end
end
function moveJump()
RightShoulder.MaxVelocity = jumpMaxLimbVelocity
LeftShoulder.MaxVelocity = jumpMaxLimbVelocity
RightShoulder:SetDesiredAngle(3.14)
LeftShoulder:SetDesiredAngle(-3.14)
RightHip:SetDesiredAngle(0)
LeftHip:SetDesiredAngle(0)
end
-- same as jump for now
function moveFreeFall()
RightShoulder.MaxVelocity = jumpMaxLimbVelocity
LeftShoulder.MaxVelocity = jumpMaxLimbVelocity
RightShoulder:SetDesiredAngle(3.14)
LeftShoulder:SetDesiredAngle(-3.14)
RightHip:SetDesiredAngle(0)
LeftHip:SetDesiredAngle(0)
end
function moveSit()
RightShoulder.MaxVelocity = 0.15
LeftShoulder.MaxVelocity = 0.15
RightShoulder:SetDesiredAngle(3.14 /2)
LeftShoulder:SetDesiredAngle(-3.14 /2)
RightHip:SetDesiredAngle(3.14 /2)
LeftHip:SetDesiredAngle(-3.14 /2)
end
function getTool()
for _, kid in ipairs(Figure:GetChildren()) do
if kid.className == &quot;Tool&quot; then return kid end
end
return nil
end
function getToolAnim(tool)
for _, c in ipairs(tool:GetChildren()) do
if c.Name == &quot;toolanim&quot; and c.className == &quot;StringValue&quot; then
return c
end
end
return nil
end
function animateTool()
if (toolAnim == &quot;None&quot;) then
RightShoulder:SetDesiredAngle(1.57)
return
end
if (toolAnim == &quot;Slash&quot;) then
RightShoulder.MaxVelocity = 0.5
RightShoulder:SetDesiredAngle(0)
return
end
if (toolAnim == &quot;Lunge&quot;) then
RightShoulder.MaxVelocity = 0.5
LeftShoulder.MaxVelocity = 0.5
RightHip.MaxVelocity = 0.5
LeftHip.MaxVelocity = 0.5
RightShoulder:SetDesiredAngle(1.57)
LeftShoulder:SetDesiredAngle(1.0)
RightHip:SetDesiredAngle(1.57)
LeftHip:SetDesiredAngle(1.0)
return
end
end
function move(time)
local amplitude
local frequency
if (pose == &quot;Jumping&quot;) then
moveJump()
return
end
if (pose == &quot;FreeFall&quot;) then
moveFreeFall()
return
end
if (pose == &quot;Seated&quot;) then
moveSit()
return
end
local climbFudge = 0
if (pose == &quot;Running&quot;) then
if (RightShoulder.CurrentAngle &gt; 1.5 or RightShoulder.CurrentAngle &lt; -1.5) then
RightShoulder.MaxVelocity = jumpMaxLimbVelocity
else
RightShoulder.MaxVelocity = 0.15
end
if (LeftShoulder.CurrentAngle &gt; 1.5 or LeftShoulder.CurrentAngle &lt; -1.5) then
LeftShoulder.MaxVelocity = jumpMaxLimbVelocity
else
LeftShoulder.MaxVelocity = 0.15
end
amplitude = 1
frequency = 9
elseif (pose == &quot;Climbing&quot;) then
RightShoulder.MaxVelocity = 0.5
LeftShoulder.MaxVelocity = 0.5
amplitude = 1
frequency = 9
climbFudge = 3.14
else
amplitude = 0.1
frequency = 1
end
desiredAngle = amplitude * math.sin(time*frequency)
RightShoulder:SetDesiredAngle(desiredAngle + climbFudge)
LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge)
RightHip:SetDesiredAngle(-desiredAngle)
LeftHip:SetDesiredAngle(-desiredAngle)
local tool = getTool()
if tool then
animStringValueObject = getToolAnim(tool)
if animStringValueObject then
toolAnim = animStringValueObject.Value
-- message recieved, delete StringValue
animStringValueObject.Parent = nil
toolAnimTime = time + .3
end
if time &gt; toolAnimTime then
toolAnimTime = 0
toolAnim = &quot;None&quot;
end
animateTool()
else
toolAnim = &quot;None&quot;
toolAnimTime = 0
end
end
-- connect events
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)
-- main program
local runService = game:service(&quot;RunService&quot;);
while Figure.Parent~=nil do
local _, time = wait(0.1)
move(time)
end
</string>
<bool name="archivable">true</bool>
</Properties>
</Item>
<Item class="Script" referent="RBX1">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource">
<null></null>
</Content>
<string name="Name">RobloxTeam</string>
<string name="Source">
-- Now with exciting TeamColors HACK!
function waitForChild(parent, childName)
local child = parent:findFirstChild(childName)
if child then return child end
while true do
child = parent.ChildAdded:wait()
if child.Name==childName then return child end
end
end
-- TEAM COLORS
function onTeamChanged(player)
wait(1)
local char = player.Character
if char == nil then return end
if player.Neutral then
-- Replacing the current BodyColor object will force a reset
local old = char:findFirstChild(&quot;Body Colors&quot;)
if not old then return end
old:clone().Parent = char
old.Parent = nil
else
local head = char:findFirstChild(&quot;Head&quot;)
local torso = char:findFirstChild(&quot;Torso&quot;)
local left_arm = char:findFirstChild(&quot;Left Arm&quot;)
local right_arm = char:findFirstChild(&quot;Right Arm&quot;)
local left_leg = char:findFirstChild(&quot;Left Leg&quot;)
local right_leg = char:findFirstChild(&quot;Right Leg&quot;)
if head then head.BrickColor = BrickColor.new(24) end
if torso then torso.BrickColor = player.TeamColor end
if left_arm then left_arm.BrickColor = BrickColor.new(26) end
if right_arm then right_arm.BrickColor = BrickColor.new(26) end
if left_leg then left_leg.BrickColor = BrickColor.new(26) end
if right_leg then right_leg.BrickColor = BrickColor.new(26) end
end
end
function onPlayerPropChanged(property, player)
if property == &quot;Character&quot; then
onTeamChanged(player)
end
if property== &quot;TeamColor&quot; or property == &quot;Neutral&quot; then
onTeamChanged(player)
end
end
local cPlayer = game.Players:GetPlayerFromCharacter(script.Parent)
cPlayer.Changed:connect(function(property) onPlayerPropChanged(property, cPlayer) end )
onTeamChanged(cPlayer)
</string>
<bool name="archivable">true</bool>
</Properties>
</Item>
</roblox>
@@ -0,0 +1,649 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="LocalScript" referent="RBX715229BE23804EB781837156DFCBE808">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Animate</string>
<ProtectedString name="Source">function waitForChild(parent, childName)
&#9;local child = parent:findFirstChild(childName)
&#9;if child then return child end
&#9;while true do
&#9;&#9;child = parent.ChildAdded:wait()
&#9;&#9;if child.Name==childName then return child end
&#9;end
end
local Figure = script.Parent
local Torso = waitForChild(Figure, &quot;Torso&quot;)
local RightShoulder = waitForChild(Torso, &quot;Right Shoulder&quot;)
local LeftShoulder = waitForChild(Torso, &quot;Left Shoulder&quot;)
local RightHip = waitForChild(Torso, &quot;Right Hip&quot;)
local LeftHip = waitForChild(Torso, &quot;Left Hip&quot;)
local Neck = waitForChild(Torso, &quot;Neck&quot;)
local Humanoid = waitForChild(Figure, &quot;Humanoid&quot;)
local pose = &quot;Standing&quot;
local currentAnim = &quot;&quot;
local currentAnimTrack = nil
local currentAnimKeyframeHandler = nil
local currentAnimSpeed = 1.0
local animTable = {}
local animNames = {
&#9;idle = &#9;{&#9;
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=125750544&quot;, weight = 9 },
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=125750618&quot;, weight = 1 }
&#9;&#9;&#9;},
&#9;walk = &#9;{ &#9;
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=125749145&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;run = &#9;{
&#9;&#9;&#9;&#9;{ id = &quot;run.xml&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;jump = &#9;{
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=125750702&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;fall = &#9;{
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=125750759&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;climb = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=125750800&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;sit = &#9;{
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=178130996&quot;, weight = 10 }
&#9;&#9;&#9;},&#9;
&#9;toolnone = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=125750867&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;toolslash = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=129967390&quot;, weight = 10 }
--&#9;&#9;&#9;&#9;{ id = &quot;slash.xml&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;toollunge = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=129967478&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;wave = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=128777973&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;point = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=128853357&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;dance = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=130018893&quot;, weight = 10 },
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=132546839&quot;, weight = 10 },
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=132546884&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;dance2 = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=160934142&quot;, weight = 10 },
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=160934298&quot;, weight = 10 },
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=160934376&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;dance3 = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=160934458&quot;, weight = 10 },
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=160934530&quot;, weight = 10 },
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=160934593&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;laugh = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=129423131&quot;, weight = 10 }
&#9;&#9;&#9;},
&#9;cheer = {
&#9;&#9;&#9;&#9;{ id = &quot;http://www.roblox.com/asset/?id=129423030&quot;, weight = 10 }
&#9;&#9;&#9;},
}
-- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote
local emoteNames = { wave = false, point = false, dance = true, dance2 = true, dance3 = true, laugh = false, cheer = false}
math.randomseed(tick())
function configureAnimationSet(name, fileList)
&#9;if (animTable[name] ~= nil) then
&#9;&#9;for _, connection in pairs(animTable[name].connections) do
&#9;&#9;&#9;connection:disconnect()
&#9;&#9;end
&#9;end
&#9;animTable[name] = {}
&#9;animTable[name].count = 0
&#9;animTable[name].totalWeight = 0&#9;
&#9;animTable[name].connections = {}
&#9;-- check for config values
&#9;local config = script:FindFirstChild(name)
&#9;if (config ~= nil) then
--&#9;&#9;print(&quot;Loading anims &quot; .. name)
&#9;&#9;table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
&#9;&#9;table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))
&#9;&#9;local idx = 1
&#9;&#9;for _, childPart in pairs(config:GetChildren()) do
&#9;&#9;&#9;if (childPart:IsA(&quot;Animation&quot;)) then
&#9;&#9;&#9;&#9;table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
&#9;&#9;&#9;&#9;animTable[name][idx] = {}
&#9;&#9;&#9;&#9;animTable[name][idx].anim = childPart
&#9;&#9;&#9;&#9;local weightObject = childPart:FindFirstChild(&quot;Weight&quot;)
&#9;&#9;&#9;&#9;if (weightObject == nil) then
&#9;&#9;&#9;&#9;&#9;animTable[name][idx].weight = 1
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;animTable[name][idx].weight = weightObject.Value
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;animTable[name].count = animTable[name].count + 1
&#9;&#9;&#9;&#9;animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
&#9;--&#9;&#9;&#9;print(name .. &quot; [&quot; .. idx .. &quot;] &quot; .. animTable[name][idx].anim.AnimationId .. &quot; (&quot; .. animTable[name][idx].weight .. &quot;)&quot;)
&#9;&#9;&#9;&#9;idx = idx + 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;-- fallback to defaults
&#9;if (animTable[name].count &lt;= 0) then
&#9;&#9;for idx, anim in pairs(fileList) do
&#9;&#9;&#9;animTable[name][idx] = {}
&#9;&#9;&#9;animTable[name][idx].anim = Instance.new(&quot;Animation&quot;)
&#9;&#9;&#9;animTable[name][idx].anim.Name = name
&#9;&#9;&#9;animTable[name][idx].anim.AnimationId = anim.id
&#9;&#9;&#9;animTable[name][idx].weight = anim.weight
&#9;&#9;&#9;animTable[name].count = animTable[name].count + 1
&#9;&#9;&#9;animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
--&#9;&#9;&#9;print(name .. &quot; [&quot; .. idx .. &quot;] &quot; .. anim.id .. &quot; (&quot; .. anim.weight .. &quot;)&quot;)
&#9;&#9;end
&#9;end
end
-- Setup animation objects
function scriptChildModified(child)
&#9;local fileList = animNames[child.Name]
&#9;if (fileList ~= nil) then
&#9;&#9;configureAnimationSet(child.Name, fileList)
&#9;end&#9;
end
script.ChildAdded:connect(scriptChildModified)
script.ChildRemoved:connect(scriptChildModified)
for name, fileList in pairs(animNames) do
&#9;configureAnimationSet(name, fileList)
end&#9;
-- ANIMATION
-- declarations
local toolAnim = &quot;None&quot;
local toolAnimTime = 0
local jumpAnimTime = 0
local jumpAnimDuration = 0.3
local toolTransitionTime = 0.1
local fallTransitionTime = 0.3
local jumpMaxLimbVelocity = 0.75
-- functions
function stopAllAnimations()
&#9;local oldAnim = currentAnim
&#9;-- return to idle if finishing an emote
&#9;if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then
&#9;&#9;oldAnim = &quot;idle&quot;
&#9;end
&#9;currentAnim = &quot;&quot;
&#9;if (currentAnimKeyframeHandler ~= nil) then
&#9;&#9;currentAnimKeyframeHandler:disconnect()
&#9;end
&#9;if (currentAnimTrack ~= nil) then
&#9;&#9;currentAnimTrack:Stop()
&#9;&#9;currentAnimTrack:Destroy()
&#9;&#9;currentAnimTrack = nil
&#9;end
&#9;return oldAnim
end
function setAnimationSpeed(speed)
&#9;if speed ~= currentAnimSpeed then
&#9;&#9;currentAnimSpeed = speed
&#9;&#9;currentAnimTrack:AdjustSpeed(currentAnimSpeed)
&#9;end
end
function keyFrameReachedFunc(frameName)
&#9;if (frameName == &quot;End&quot;) then
--&#9;&#9;print(&quot;Keyframe : &quot;.. frameName)
&#9;&#9;local repeatAnim = stopAllAnimations()
&#9;&#9;local animSpeed = currentAnimSpeed
&#9;&#9;playAnimation(repeatAnim, 0.0, Humanoid)
&#9;&#9;setAnimationSpeed(animSpeed)
&#9;end
end
-- Preload animations
function playAnimation(animName, transitionTime, humanoid)
&#9;local idleFromEmote = (animName == &quot;idle&quot; and emoteNames[currentAnim] ~= nil)
&#9;if (animName ~= currentAnim and not idleFromEmote) then&#9;&#9;
&#9;&#9;
&#9;&#9;if (currentAnimTrack ~= nil) then
&#9;&#9;&#9;currentAnimTrack:Stop(transitionTime)
&#9;&#9;&#9;currentAnimTrack:Destroy()
&#9;&#9;end
&#9;&#9;currentAnimSpeed = 1.0
&#9;&#9;local roll = math.random(1, animTable[animName].totalWeight)
&#9;&#9;local origRoll = roll
&#9;&#9;local idx = 1
&#9;&#9;while (roll &gt; animTable[animName][idx].weight) do
&#9;&#9;&#9;roll = roll - animTable[animName][idx].weight
&#9;&#9;&#9;idx = idx + 1
&#9;&#9;end
--&#9;&#9;print(animName .. &quot; &quot; .. idx .. &quot; [&quot; .. origRoll .. &quot;]&quot;)
&#9;&#9;local anim = animTable[animName][idx].anim
&#9;&#9;-- load it to the humanoid; get AnimationTrack
&#9;&#9;currentAnimTrack = humanoid:LoadAnimation(anim)
&#9;&#9;
&#9;&#9;-- play the animation
&#9;&#9;currentAnimTrack:Play(transitionTime)
&#9;&#9;currentAnim = animName
&#9;&#9;-- set up keyframe name triggers
&#9;&#9;if (currentAnimKeyframeHandler ~= nil) then
&#9;&#9;&#9;currentAnimKeyframeHandler:disconnect()
&#9;&#9;end
&#9;&#9;currentAnimKeyframeHandler = currentAnimTrack.KeyframeReached:connect(keyFrameReachedFunc)
&#9;end
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
local toolAnimName = &quot;&quot;
local toolAnimTrack = nil
local currentToolAnimKeyframeHandler = nil
function toolKeyFrameReachedFunc(frameName)
&#9;if (frameName == &quot;End&quot;) then
--&#9;&#9;print(&quot;Keyframe : &quot;.. frameName)
&#9;&#9;local repeatAnim = stopToolAnimations()
&#9;&#9;playToolAnimation(repeatAnim, 0.0, Humanoid)
&#9;end
end
function playToolAnimation(animName, transitionTime, humanoid)
&#9;if (animName ~= toolAnimName) then&#9;&#9;
&#9;&#9;
&#9;&#9;if (toolAnimTrack ~= nil) then
&#9;&#9;&#9;toolAnimTrack:Stop()
&#9;&#9;&#9;toolAnimTrack:Destroy()
&#9;&#9;&#9;transitionTime = 0
&#9;&#9;end
&#9;&#9;local roll = math.random(1, animTable[animName].totalWeight)
&#9;&#9;local origRoll = roll
&#9;&#9;local idx = 1
&#9;&#9;while (roll &gt; animTable[animName][idx].weight) do
&#9;&#9;&#9;roll = roll - animTable[animName][idx].weight
&#9;&#9;&#9;idx = idx + 1
&#9;&#9;end
--&#9;&#9;print(animName .. &quot; * &quot; .. idx .. &quot; [&quot; .. origRoll .. &quot;]&quot;)
&#9;&#9;local anim = animTable[animName][idx].anim
&#9;&#9;-- load it to the humanoid; get AnimationTrack
&#9;&#9;toolAnimTrack = humanoid:LoadAnimation(anim)
&#9;&#9;
&#9;&#9;-- play the animation
&#9;&#9;toolAnimTrack:Play(transitionTime)
&#9;&#9;toolAnimName = animName
&#9;&#9;currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc)
&#9;end
end
function stopToolAnimations()
&#9;local oldAnim = toolAnimName
&#9;if (currentToolAnimKeyframeHandler ~= nil) then
&#9;&#9;currentToolAnimKeyframeHandler:disconnect()
&#9;end
&#9;toolAnimName = &quot;&quot;
&#9;if (toolAnimTrack ~= nil) then
&#9;&#9;toolAnimTrack:Stop()
&#9;&#9;toolAnimTrack:Destroy()
&#9;&#9;toolAnimTrack = nil
&#9;end
&#9;return oldAnim
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
function onRunning(speed)
&#9;if speed&gt;0.5 then
&#9;&#9;playAnimation(&quot;walk&quot;, 0.1, Humanoid)
&#9;&#9;pose = &quot;Running&quot;
&#9;else
&#9;&#9;playAnimation(&quot;idle&quot;, 0.1, Humanoid)
&#9;&#9;pose = &quot;Standing&quot;
&#9;end
end
function onDied()
&#9;pose = &quot;Dead&quot;
end
function onJumping()
&#9;playAnimation(&quot;jump&quot;, 0.1, Humanoid)
&#9;jumpAnimTime = jumpAnimDuration
&#9;pose = &quot;Jumping&quot;
end
function onClimbing(speed)
&#9;playAnimation(&quot;climb&quot;, 0.1, Humanoid)
&#9;setAnimationSpeed(speed / 12.0)
&#9;pose = &quot;Climbing&quot;
end
function onGettingUp()
&#9;pose = &quot;GettingUp&quot;
end
function onFreeFall()
&#9;if (jumpAnimTime &lt;= 0) then
&#9;&#9;playAnimation(&quot;fall&quot;, fallTransitionTime, Humanoid)
&#9;end
&#9;pose = &quot;FreeFall&quot;
end
function onFallingDown()
&#9;pose = &quot;FallingDown&quot;
end
function onSeated()
&#9;pose = &quot;Seated&quot;
end
function onPlatformStanding()
&#9;pose = &quot;PlatformStanding&quot;
end
function onSwimming(speed)
&#9;if speed&gt;0 then
&#9;&#9;pose = &quot;Running&quot;
&#9;else
&#9;&#9;pose = &quot;Standing&quot;
&#9;end
end
function getTool()&#9;
&#9;for _, kid in ipairs(Figure:GetChildren()) do
&#9;&#9;if kid.className == &quot;Tool&quot; then return kid end
&#9;end
&#9;return nil
end
function getToolAnim(tool)
&#9;for _, c in ipairs(tool:GetChildren()) do
&#9;&#9;if c.Name == &quot;toolanim&quot; and c.className == &quot;StringValue&quot; then
&#9;&#9;&#9;return c
&#9;&#9;end
&#9;end
&#9;return nil
end
function animateTool()
&#9;
&#9;if (toolAnim == &quot;None&quot;) then
&#9;&#9;playToolAnimation(&quot;toolnone&quot;, toolTransitionTime, Humanoid)
&#9;&#9;return
&#9;end
&#9;if (toolAnim == &quot;Slash&quot;) then
&#9;&#9;playToolAnimation(&quot;toolslash&quot;, 0, Humanoid)
&#9;&#9;return
&#9;end
&#9;if (toolAnim == &quot;Lunge&quot;) then
&#9;&#9;playToolAnimation(&quot;toollunge&quot;, 0, Humanoid)
&#9;&#9;return
&#9;end
end
function moveSit()
&#9;RightShoulder.MaxVelocity = 0.15
&#9;LeftShoulder.MaxVelocity = 0.15
&#9;RightShoulder:SetDesiredAngle(3.14 /2)
&#9;LeftShoulder:SetDesiredAngle(-3.14 /2)
&#9;RightHip:SetDesiredAngle(3.14 /2)
&#9;LeftHip:SetDesiredAngle(-3.14 /2)
end
local lastTick = 0
function move(time)
&#9;local amplitude = 1
&#9;local frequency = 1
&#9;local deltaTime = time - lastTick
&#9;lastTick = time
&#9;local climbFudge = 0
&#9;local setAngles = false
&#9;if (jumpAnimTime &gt; 0) then
&#9;&#9;jumpAnimTime = jumpAnimTime - deltaTime
&#9;end
&#9;if (pose == &quot;FreeFall&quot; and jumpAnimTime &lt;= 0) then
&#9;&#9;playAnimation(&quot;fall&quot;, fallTransitionTime, Humanoid)
&#9;elseif (pose == &quot;Seated&quot;) then
&#9;&#9;playAnimation(&quot;sit&quot;, 0.5, Humanoid)
&#9;&#9;return
&#9;elseif (pose == &quot;Running&quot;) then
&#9;&#9;playAnimation(&quot;walk&quot;, 0.1, Humanoid)
&#9;elseif (pose == &quot;Dead&quot; or pose == &quot;GettingUp&quot; or pose == &quot;FallingDown&quot; or pose == &quot;Seated&quot; or pose == &quot;PlatformStanding&quot;) then
--&#9;&#9;print(&quot;Wha &quot; .. pose)
&#9;&#9;stopAllAnimations()
&#9;&#9;amplitude = 0.1
&#9;&#9;frequency = 1
&#9;&#9;setAngles = true
&#9;end
&#9;if (setAngles) then
&#9;&#9;desiredAngle = amplitude * math.sin(time * frequency)
&#9;&#9;RightShoulder:SetDesiredAngle(desiredAngle + climbFudge)
&#9;&#9;LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge)
&#9;&#9;RightHip:SetDesiredAngle(-desiredAngle)
&#9;&#9;LeftHip:SetDesiredAngle(-desiredAngle)
&#9;end
&#9;-- Tool Animation handling
&#9;local tool = getTool()
&#9;if tool then
&#9;
&#9;&#9;animStringValueObject = getToolAnim(tool)
&#9;&#9;if animStringValueObject then
&#9;&#9;&#9;toolAnim = animStringValueObject.Value
&#9;&#9;&#9;-- message recieved, delete StringValue
&#9;&#9;&#9;animStringValueObject.Parent = nil
&#9;&#9;&#9;toolAnimTime = time + .3
&#9;&#9;end
&#9;&#9;if time &gt; toolAnimTime then
&#9;&#9;&#9;toolAnimTime = 0
&#9;&#9;&#9;toolAnim = &quot;None&quot;
&#9;&#9;end
&#9;&#9;animateTool()&#9;&#9;
&#9;else
&#9;&#9;stopToolAnimations()
&#9;&#9;toolAnim = &quot;None&quot;
&#9;&#9;toolAnimTime = 0
&#9;end
end
-- connect events
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.Players.LocalPlayer.Chatted:connect(function(msg)
&#9;local emote = &quot;&quot;
&#9;if (string.sub(msg, 1, 3) == &quot;/e &quot;) then
&#9;&#9;emote = string.sub(msg, 4)
&#9;elseif (string.sub(msg, 1, 7) == &quot;/emote &quot;) then
&#9;&#9;emote = string.sub(msg, 8)
&#9;end
&#9;
&#9;if (pose == &quot;Standing&quot; and emoteNames[emote] ~= nil) then
&#9;&#9;playAnimation(emote, 0.1, Humanoid)
&#9;end
--&#9;print(&quot;===&gt; &quot; .. string.sub(msg, 1, 3) .. &quot;(&quot; .. emote .. &quot;)&quot;)
end)
-- main program
local runService = game:service(&quot;RunService&quot;);
-- initialize to idle
playAnimation(&quot;idle&quot;, 0.1, Humanoid)
pose = &quot;Standing&quot;
while Figure.Parent~=nil do
&#9;local _, time = wait(0.1)
&#9;move(time)
end
</ProtectedString>
</Properties>
<Item class="StringValue" referent="RBXB9F94AC9C8714EE9B8DC5AC6394A39D8">
<Properties>
<string name="Name">idle</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX00CF3DBBF6A44ED5BBC717359071CB44">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=125750544</url></Content>
<string name="Name">Animation1</string>
</Properties>
<Item class="NumberValue" referent="RBX5B18FB5697DC46F69374CB1D7236BD8C">
<Properties>
<string name="Name">Weight</string>
<double name="Value">9</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBX4FDE2C9CBC2245C18F7583D18E8FA849">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=125750618</url></Content>
<string name="Name">Animation2</string>
</Properties>
<Item class="NumberValue" referent="RBX52104EA5D6A54AF19E439A7E4F5D2874">
<Properties>
<string name="Name">Weight</string>
<double name="Value">1</double>
</Properties>
</Item>
</Item>
</Item>
<Item class="StringValue" referent="RBX3C93974F58884058B4A4E6B086D58272">
<Properties>
<string name="Name">walk</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX038BF3EC9C3E4F06B2F24E69A20F347C">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=125749145</url></Content>
<string name="Name">WalkAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX2755DD130F8B4D69AC40662FF9F5E27B">
<Properties>
<string name="Name">run</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX8755FB1F0AB24E028CD877AC4266F885">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=125749145</url></Content>
<string name="Name">RunAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXDE338122B8944CB4BBF75A4869F808D4">
<Properties>
<string name="Name">jump</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX94F8E8E31C3B4343A24D76E4721CA64F">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=125750702</url></Content>
<string name="Name">JumpAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXF5D613DC6F6B44E789F7AAB2ED845805">
<Properties>
<string name="Name">climb</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX7CB10265BA4B4488A67823BF80A77DC0">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=125750800</url></Content>
<string name="Name">ClimbAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX6E21A99A8A89468F9D60E1A2005C68A3">
<Properties>
<string name="Name">toolnone</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX8210E414C2DD416BAFD78558576B7955">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=125750867</url></Content>
<string name="Name">ToolNoneAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXC92C8796E26C411984CCB70BA8E39107">
<Properties>
<string name="Name">fall</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX9A2EC4B488454C1ABEEEF09689D5BD33">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=125750759</url></Content>
<string name="Name">FallAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX70F38631790D415F950C39166423D8AA">
<Properties>
<string name="Name">sit</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX7A130B7EFF964AFDB81E41B6BF7A0FC7">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=178130996</url></Content>
<string name="Name">SitAnim</string>
</Properties>
</Item>
</Item>
</Item>
</roblox>
@@ -0,0 +1,673 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="LocalScript" referent="RBXC49238CC391A40B0B08D3C0989F85A53">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Animate</string>
<ProtectedString name="Source"><![CDATA[function waitForChild(parent, childName)
local child = parent:findFirstChild(childName)
if child then return child end
while true do
child = parent.ChildAdded:wait()
if child.Name==childName then return child end
end
end
local Figure = script.Parent
local Torso = waitForChild(Figure, "Torso")
local RightShoulder = waitForChild(Torso, "Right Shoulder")
local LeftShoulder = waitForChild(Torso, "Left Shoulder")
local RightHip = waitForChild(Torso, "Right Hip")
local LeftHip = waitForChild(Torso, "Left Hip")
local Neck = waitForChild(Torso, "Neck")
local Humanoid = waitForChild(Figure, "Humanoid")
local pose = "Standing"
local currentAnim = ""
local currentAnimInstance = nil
local currentAnimTrack = nil
local currentAnimKeyframeHandler = nil
local currentAnimSpeed = 1.0
local animTable = {}
local animNames = {
idle = {
{ id = "http://www.roblox.com/asset/?id=180435571", weight = 9 },
{ id = "http://www.roblox.com/asset/?id=180435792", weight = 1 }
},
walk = {
{ id = "http://www.roblox.com/asset/?id=180426354", weight = 10 }
},
run = {
{ id = "run.xml", weight = 10 }
},
jump = {
{ id = "http://www.roblox.com/asset/?id=125750702", weight = 10 }
},
fall = {
{ id = "http://www.roblox.com/asset/?id=180436148", weight = 10 }
},
climb = {
{ id = "http://www.roblox.com/asset/?id=180436334", weight = 10 }
},
sit = {
{ id = "http://www.roblox.com/asset/?id=178130996", weight = 10 }
},
toolnone = {
{ id = "http://www.roblox.com/asset/?id=182393478", weight = 10 }
},
toolslash = {
{ id = "http://www.roblox.com/asset/?id=129967390", weight = 10 }
-- { id = "slash.xml", weight = 10 }
},
toollunge = {
{ id = "http://www.roblox.com/asset/?id=129967478", weight = 10 }
},
wave = {
{ id = "http://www.roblox.com/asset/?id=128777973", weight = 10 }
},
point = {
{ id = "http://www.roblox.com/asset/?id=128853357", weight = 10 }
},
dance1 = {
{ id = "http://www.roblox.com/asset/?id=182435998", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=182491037", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=182491065", weight = 10 }
},
dance2 = {
{ id = "http://www.roblox.com/asset/?id=182436842", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=182491248", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=182491277", weight = 10 }
},
dance3 = {
{ id = "http://www.roblox.com/asset/?id=11669649889", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=11669649889", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=11669649889", weight = 10 }
},
laugh = {
{ id = "http://www.roblox.com/asset/?id=129423131", weight = 10 }
},
cheer = {
{ id = "http://www.roblox.com/asset/?id=129423030", weight = 10 }
},
gmod = {
{ id = "http://www.roblox.com/asset/?id=11669649889", weight = 10 }
},
}
local dances = {"dance1", "dance2", "dance3", "gmod"}
-- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote
local emoteNames = { wave = false, point = false, dance1 = true, dance2 = true, dance3 = true, laugh = false, cheer = false}
function configureAnimationSet(name, fileList)
if (animTable[name] ~= nil) then
for _, connection in pairs(animTable[name].connections) do
connection:disconnect()
end
end
animTable[name] = {}
animTable[name].count = 0
animTable[name].totalWeight = 0
animTable[name].connections = {}
-- check for config values
local config = script:FindFirstChild(name)
if (config ~= nil) then
-- print("Loading anims " .. name)
table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))
local idx = 1
for _, childPart in pairs(config:GetChildren()) do
if (childPart:IsA("Animation")) then
table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
animTable[name][idx] = {}
animTable[name][idx].anim = childPart
local weightObject = childPart:FindFirstChild("Weight")
if (weightObject == nil) then
animTable[name][idx].weight = 1
else
animTable[name][idx].weight = weightObject.Value
end
animTable[name].count = animTable[name].count + 1
animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
-- print(name .. " [" .. idx .. "] " .. animTable[name][idx].anim.AnimationId .. " (" .. animTable[name][idx].weight .. ")")
idx = idx + 1
end
end
end
-- fallback to defaults
if (animTable[name].count <= 0) then
for idx, anim in pairs(fileList) do
animTable[name][idx] = {}
animTable[name][idx].anim = Instance.new("Animation")
animTable[name][idx].anim.Name = name
animTable[name][idx].anim.AnimationId = anim.id
animTable[name][idx].weight = anim.weight
animTable[name].count = animTable[name].count + 1
animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
-- print(name .. " [" .. idx .. "] " .. anim.id .. " (" .. anim.weight .. ")")
end
end
end
-- Setup animation objects
function scriptChildModified(child)
local fileList = animNames[child.Name]
if (fileList ~= nil) then
configureAnimationSet(child.Name, fileList)
end
end
script.ChildAdded:connect(scriptChildModified)
script.ChildRemoved:connect(scriptChildModified)
for name, fileList in pairs(animNames) do
configureAnimationSet(name, fileList)
end
-- ANIMATION
-- declarations
local toolAnim = "None"
local toolAnimTime = 0
local jumpAnimTime = 0
local jumpAnimDuration = 0.3
local toolTransitionTime = 0.1
local fallTransitionTime = 0.3
local jumpMaxLimbVelocity = 0.75
-- functions
function stopAllAnimations()
local oldAnim = currentAnim
-- return to idle if finishing an emote
if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then
oldAnim = "idle"
end
currentAnim = ""
currentAnimInstance = nil
if (currentAnimKeyframeHandler ~= nil) then
currentAnimKeyframeHandler:disconnect()
end
if (currentAnimTrack ~= nil) then
currentAnimTrack:Stop()
currentAnimTrack:Destroy()
currentAnimTrack = nil
end
return oldAnim
end
function setAnimationSpeed(speed)
if speed ~= currentAnimSpeed then
currentAnimSpeed = speed
currentAnimTrack:AdjustSpeed(currentAnimSpeed)
end
end
function keyFrameReachedFunc(frameName)
if (frameName == "End") then
local repeatAnim = currentAnim
-- return to idle if finishing an emote
if (emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false) then
repeatAnim = "idle"
end
local animSpeed = currentAnimSpeed
playAnimation(repeatAnim, 0.0, Humanoid)
setAnimationSpeed(animSpeed)
end
end
-- Preload animations
function playAnimation(animName, transitionTime, humanoid)
local roll = math.random(1, animTable[animName].totalWeight)
local origRoll = roll
local idx = 1
while (roll > animTable[animName][idx].weight) do
roll = roll - animTable[animName][idx].weight
idx = idx + 1
end
-- print(animName .. " " .. idx .. " [" .. origRoll .. "]")
local anim = animTable[animName][idx].anim
-- switch animation
if (anim ~= currentAnimInstance) then
if (currentAnimTrack ~= nil) then
currentAnimTrack:Stop(transitionTime)
currentAnimTrack:Destroy()
end
currentAnimSpeed = 1.0
-- load it to the humanoid; get AnimationTrack
currentAnimTrack = humanoid:LoadAnimation(anim)
-- 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)
end
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
local toolAnimName = ""
local toolAnimTrack = nil
local toolAnimInstance = nil
local currentToolAnimKeyframeHandler = nil
function toolKeyFrameReachedFunc(frameName)
if (frameName == "End") then
-- print("Keyframe : ".. frameName)
playToolAnimation(toolAnimName, 0.0, Humanoid)
end
end
function playToolAnimation(animName, transitionTime, humanoid)
local roll = math.random(1, animTable[animName].totalWeight)
local origRoll = roll
local idx = 1
while (roll > animTable[animName][idx].weight) do
roll = roll - animTable[animName][idx].weight
idx = idx + 1
end
-- print(animName .. " * " .. idx .. " [" .. origRoll .. "]")
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)
-- 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
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
function onRunning(speed)
if speed>0.01 then
playAnimation("walk", 0.1, Humanoid)
if currentAnimInstance and currentAnimInstance.AnimationId == "http://www.roblox.com/asset/?id=180426354" then
setAnimationSpeed(speed / 14.5)
end
pose = "Running"
else
playAnimation("idle", 0.1, Humanoid)
pose = "Standing"
end
end
function onDied()
pose = "Dead"
end
function onJumping()
playAnimation("jump", 0.1, Humanoid)
jumpAnimTime = jumpAnimDuration
pose = "Jumping"
end
function onClimbing(speed)
playAnimation("climb", 0.1, Humanoid)
setAnimationSpeed(speed / 12.0)
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>0 then
pose = "Running"
else
pose = "Standing"
end
end
function getTool()
for _, kid in ipairs(Figure:GetChildren()) do
if kid.className == "Tool" then return kid end
end
return nil
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
function animateTool()
if (toolAnim == "None") then
playToolAnimation("toolnone", toolTransitionTime, Humanoid)
return
end
if (toolAnim == "Slash") then
playToolAnimation("toolslash", 0, Humanoid)
return
end
if (toolAnim == "Lunge") then
playToolAnimation("toollunge", 0, Humanoid)
return
end
end
function moveSit()
RightShoulder.MaxVelocity = 0.15
LeftShoulder.MaxVelocity = 0.15
RightShoulder:SetDesiredAngle(3.14 /2)
LeftShoulder:SetDesiredAngle(-3.14 /2)
RightHip:SetDesiredAngle(3.14 /2)
LeftHip:SetDesiredAngle(-3.14 /2)
end
local lastTick = 0
function move(time)
local amplitude = 1
local frequency = 1
local deltaTime = time - lastTick
lastTick = time
local climbFudge = 0
local setAngles = false
if (jumpAnimTime > 0) then
jumpAnimTime = jumpAnimTime - deltaTime
end
if (pose == "FreeFall" and jumpAnimTime <= 0) then
playAnimation("fall", fallTransitionTime, Humanoid)
elseif (pose == "Seated") then
playAnimation("sit", 0.5, Humanoid)
return
elseif (pose == "Running") then
playAnimation("walk", 0.1, Humanoid)
elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then
-- print("Wha " .. pose)
stopAllAnimations()
amplitude = 0.1
frequency = 1
setAngles = true
end
if (setAngles) then
desiredAngle = amplitude * math.sin(time * frequency)
RightShoulder:SetDesiredAngle(desiredAngle + climbFudge)
LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge)
RightHip:SetDesiredAngle(-desiredAngle)
LeftHip:SetDesiredAngle(-desiredAngle)
end
-- Tool Animation handling
local tool = getTool()
if tool and tool:FindFirstChild("Handle") then
animStringValueObject = getToolAnim(tool)
if animStringValueObject then
toolAnim = animStringValueObject.Value
-- message recieved, delete StringValue
animStringValueObject.Parent = nil
toolAnimTime = time + .3
end
if time > toolAnimTime then
toolAnimTime = 0
toolAnim = "None"
end
animateTool()
else
stopToolAnimations()
toolAnim = "None"
toolAnimInstance = nil
toolAnimTime = 0
end
end
-- connect events
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.Players.LocalPlayer.Chatted:connect(function(msg)
local emote = ""
if msg == "/e dance" then
emote = dances[math.random(1, #dances)]
elseif (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)
-- main program
local runService = game:service("RunService");
-- initialize to idle
playAnimation("idle", 0.1, Humanoid)
pose = "Standing"
while Figure.Parent~=nil do
local _, time = wait(0.1)
move(time)
end
]]></ProtectedString>
</Properties>
<Item class="StringValue" referent="RBX3D115054235C475E9E23460AF948BD6F">
<Properties>
<string name="Name">idle</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXDB67065FB85E4931999CB515B5F2012A">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=180435571</url></Content>
<string name="Name">Animation1</string>
</Properties>
<Item class="NumberValue" referent="RBX9C1D89D976924979BDD8B81DA97BE114">
<Properties>
<string name="Name">Weight</string>
<double name="Value">9</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBXEEE171AA4C1C4802A98EA849C0B0A8AC">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=180435792</url></Content>
<string name="Name">Animation2</string>
</Properties>
<Item class="NumberValue" referent="RBX37B140D9414C4473A5F27F7880B0EC4E">
<Properties>
<string name="Name">Weight</string>
<double name="Value">1</double>
</Properties>
</Item>
</Item>
</Item>
<Item class="StringValue" referent="RBX6B0595F7D6464E039C6C20310AF91669">
<Properties>
<string name="Name">walk</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX45D6152C54FA4EF7B0F9CBF069550557">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=180426354</url></Content>
<string name="Name">WalkAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX304A801B2F904AA59F892145C3DA51F4">
<Properties>
<string name="Name">run</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXA37336981B6E454C90E45A7F01515966">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=180426354</url></Content>
<string name="Name">RunAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX992310CD075D4083AA3FC397200F0E12">
<Properties>
<string name="Name">jump</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXDB0FB6EAF0A94640AD7C222F7E4E39F4">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=125750702</url></Content>
<string name="Name">JumpAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXE784B068E17041EDBE1C80F73A8FB305">
<Properties>
<string name="Name">climb</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX94C1F5C954294A889B341487BAC89356">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=180436334</url></Content>
<string name="Name">ClimbAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX40FB7BAC1B514D918FD0D59D70A13401">
<Properties>
<string name="Name">toolnone</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX6B27C35810754C93915CA4FE34E8EB95">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=182393478</url></Content>
<string name="Name">ToolNoneAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX9D56FC8B85B240089A73C4C0BF994681">
<Properties>
<string name="Name">fall</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX0766704DC00944A88D7F0204B7AD2177">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=180436148</url></Content>
<string name="Name">FallAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXCE77F4BD43F74ECE8CEC4CB497927D27">
<Properties>
<string name="Name">sit</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXBEBAA19B49FE45FB9D852B2290377C2C">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=178130996</url></Content>
<string name="Name">SitAnim</string>
</Properties>
</Item>
</Item>
</Item>
</roblox>
+669
View File
@@ -0,0 +1,669 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="LocalScript" referent="RBX6FAEF2BC81AC4B2A86AB109BC483D22E">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Animate</string>
<ProtectedString name="Source"><![CDATA[function waitForChild(parent, childName)
local child = parent:findFirstChild(childName)
if child then return child end
while true do
child = parent.ChildAdded:wait()
if child.Name==childName then return child end
end
end
local Figure = script.Parent
local Humanoid = waitForChild(Figure, "Humanoid")
local pose = "Standing"
local currentAnim = ""
local currentAnimInstance = nil
local currentAnimTrack = nil
local currentAnimKeyframeHandler = nil
local currentAnimSpeed = 1.0
local animTable = {}
local animNames = {
idle = {
{ id = "rbxasset://R15021216/idle_stretch.xml", weight = 1 },
{ id = "rbxasset://R15021216/idle_look.xml", weight = 1 },
{ id = "rbxasset://R15021216/idle.xml", weight = 9 }
},
walk = {
{ id = "rbxasset://R15021216/run.xml", weight = 10 }
},
run = {
{ id = "rbxasset://R15021216/run.xml", weight = 10 }
},
jump = {
{ id = "rbxasset://R15021216/jump.xml", weight = 10 }
},
fall = {
{ id = "rbxasset://R15021216/falling.xml", weight = 10 }
},
climb = {
{ id = "rbxasset://R15021216/climb.xml", weight = 10 }
},
sit = {
{ id = "http://www.roblox.com/asset/?id=434419018", weight = 10 }
},
toolnone = {
{ id = "http://www.roblox.com/asset/?id=434419638", weight = 10 }
},
toolslash = {
{ id = "http://www.roblox.com/asset/?id=434419638", weight = 10 }
-- { id = "slash.xml", weight = 10 }
},
toollunge = {
{ id = "http://www.roblox.com/asset/?id=434419638", weight = 10 }
},
wave = {
{ id = "http://www.roblox.com/asset/?id=434420105", weight = 10 }
},
point = {
{ id = "http://www.roblox.com/asset/?id=434420378", weight = 10 }
},
dance = {
{ id = "http://www.roblox.com/asset/?id=434422187", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=434422809", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=434423133", weight = 10 }
},
dance2 = {
{ id = "http://www.roblox.com/asset/?id=434423431", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=434424210", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=434424519", weight = 10 }
},
dance3 = {
{ id = "http://www.roblox.com/asset/?id=434424825", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=434425108", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=434425599", weight = 10 }
},
laugh = {
{ id = "http://www.roblox.com/asset/?id=434421799", weight = 10 }
},
cheer = {
{ id = "http://www.roblox.com/asset/?id=434421226", weight = 10 }
},
}
-- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote
local emoteNames = { wave = false, point = false, dance = true, dance2 = true, dance3 = true, laugh = false, cheer = false}
math.randomseed(tick())
function configureAnimationSet(name, fileList)
if (animTable[name] ~= nil) then
for _, connection in pairs(animTable[name].connections) do
connection:disconnect()
end
end
animTable[name] = {}
animTable[name].count = 0
animTable[name].totalWeight = 0
animTable[name].connections = {}
-- check for config values
local config = script:FindFirstChild(name)
if (config ~= nil) then
-- print("Loading anims " .. name)
table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))
local idx = 1
for _, childPart in pairs(config:GetChildren()) do
if (childPart:IsA("Animation")) then
table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
animTable[name][idx] = {}
animTable[name][idx].anim = childPart
local weightObject = childPart:FindFirstChild("Weight")
if (weightObject == nil) then
animTable[name][idx].weight = 1
else
animTable[name][idx].weight = weightObject.Value
end
animTable[name].count = animTable[name].count + 1
animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
-- print(name .. " [" .. idx .. "] " .. animTable[name][idx].anim.AnimationId .. " (" .. animTable[name][idx].weight .. ")")
idx = idx + 1
end
end
end
-- fallback to defaults
if (animTable[name].count <= 0) then
for idx, anim in pairs(fileList) do
animTable[name][idx] = {}
animTable[name][idx].anim = Instance.new("Animation")
animTable[name][idx].anim.Name = name
animTable[name][idx].anim.AnimationId = anim.id
animTable[name][idx].weight = anim.weight
animTable[name].count = animTable[name].count + 1
animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
-- print(name .. " [" .. idx .. "] " .. anim.id .. " (" .. anim.weight .. ")")
end
end
end
-- Setup animation objects
function scriptChildModified(child)
local fileList = animNames[child.Name]
if (fileList ~= nil) then
configureAnimationSet(child.Name, fileList)
end
end
script.ChildAdded:connect(scriptChildModified)
script.ChildRemoved:connect(scriptChildModified)
for name, fileList in pairs(animNames) do
configureAnimationSet(name, fileList)
end
-- ANIMATION
-- declarations
local toolAnim = "None"
local toolAnimTime = 0
local jumpAnimTime = 0
local jumpAnimDuration = 0.31
local toolTransitionTime = 0.1
local fallTransitionTime = 0.2
-- functions
function stopAllAnimations()
local oldAnim = currentAnim
-- return to idle if finishing an emote
if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then
oldAnim = "idle"
end
currentAnim = ""
currentAnimInstance = nil
if (currentAnimKeyframeHandler ~= nil) then
currentAnimKeyframeHandler:disconnect()
end
if (currentAnimTrack ~= nil) then
currentAnimTrack:Stop()
currentAnimTrack:Destroy()
currentAnimTrack = nil
end
return oldAnim
end
function setAnimationSpeed(speed)
if speed ~= currentAnimSpeed then
currentAnimSpeed = speed
currentAnimTrack:AdjustSpeed(currentAnimSpeed)
end
end
function keyFrameReachedFunc(frameName)
if (frameName == "End") then
-- print("Keyframe : ".. frameName)
local repeatAnim = currentAnim
-- return to idle if finishing an emote
if (emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false) then
repeatAnim = "idle"
end
local animSpeed = currentAnimSpeed
playAnimation(repeatAnim, 0.15, Humanoid)
setAnimationSpeed(animSpeed)
end
end
-- Preload animations
function playAnimation(animName, transitionTime, humanoid)
local roll = math.random(1, animTable[animName].totalWeight)
local origRoll = roll
local idx = 1
while (roll > animTable[animName][idx].weight) do
roll = roll - animTable[animName][idx].weight
idx = idx + 1
end
-- print(animName .. " " .. idx .. " [" .. origRoll .. "]")
local anim = animTable[animName][idx].anim
-- switch animation
if (anim ~= currentAnimInstance) then
if (currentAnimTrack ~= nil) then
currentAnimTrack:Stop(transitionTime)
currentAnimTrack:Destroy()
end
currentAnimSpeed = 1.0
-- load it to the humanoid; get AnimationTrack
currentAnimTrack = humanoid:LoadAnimation(anim)
-- 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)
end
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
local toolAnimName = ""
local toolAnimTrack = nil
local toolAnimInstance = nil
local currentToolAnimKeyframeHandler = nil
function toolKeyFrameReachedFunc(frameName)
if (frameName == "End") then
-- print("Keyframe : ".. frameName)
playToolAnimation(toolAnimName, 0.0, Humanoid)
end
end
function playToolAnimation(animName, transitionTime, humanoid)
local roll = math.random(1, animTable[animName].totalWeight)
local origRoll = roll
local idx = 1
while (roll > animTable[animName][idx].weight) do
roll = roll - animTable[animName][idx].weight
idx = idx + 1
end
-- print(animName .. " * " .. idx .. " [" .. origRoll .. "]")
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)
-- 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
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
function onRunning(speed)
if speed>0.01 then
local scale = 15.0
playAnimation("walk", 0.1, Humanoid)
setAnimationSpeed(speed / scale)
pose = "Running"
else
playAnimation("idle", 0.1, Humanoid)
pose = "Standing"
end
end
function onDied()
pose = "Dead"
end
function onJumping()
playAnimation("jump", 0.1, Humanoid)
jumpAnimTime = jumpAnimDuration
pose = "Jumping"
end
function onClimbing(speed)
local scale = 2.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>0 then
pose = "Running"
else
pose = "Standing"
end
end
function getTool()
for _, kid in ipairs(Figure:GetChildren()) do
if kid.className == "Tool" then return kid end
end
return nil
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
function animateTool()
if (toolAnim == "None") then
playToolAnimation("toolnone", toolTransitionTime, Humanoid)
return
end
if (toolAnim == "Slash") then
playToolAnimation("toolslash", 0, Humanoid)
return
end
if (toolAnim == "Lunge") then
playToolAnimation("toollunge", 0, Humanoid)
return
end
end
function moveSit()
RightShoulder.MaxVelocity = 0.15
LeftShoulder.MaxVelocity = 0.15
RightShoulder:SetDesiredAngle(3.14 /2)
LeftShoulder:SetDesiredAngle(-3.14 /2)
RightHip:SetDesiredAngle(3.14 /2)
LeftHip:SetDesiredAngle(-3.14 /2)
end
local lastTick = 0
function move(time)
local amplitude = 1
local frequency = 1
local deltaTime = time - lastTick
lastTick = time
local climbFudge = 0
local setAngles = false
if (jumpAnimTime > 0) then
jumpAnimTime = jumpAnimTime - deltaTime
end
if (pose == "FreeFall" and jumpAnimTime <= 0) then
playAnimation("fall", fallTransitionTime, Humanoid)
elseif (pose == "Seated") then
playAnimation("sit", 0.5, Humanoid)
return
elseif (pose == "Running") then
playAnimation("walk", 0.1, 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 = getTool()
if tool then
animStringValueObject = getToolAnim(tool)
if animStringValueObject then
toolAnim = animStringValueObject.Value
-- message recieved, delete StringValue
animStringValueObject.Parent = nil
toolAnimTime = time + .3
end
if time > toolAnimTime then
toolAnimTime = 0
toolAnim = "None"
end
animateTool()
else
stopToolAnimations()
toolAnim = "None"
toolAnimInstance = nil
toolAnimTime = 0
end
end
-- connect events
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.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
-- print("===> " .. string.sub(msg, 1, 3) .. "(" .. emote .. ")")
end)
-- main program
local runService = game:service("RunService");
-- print("bottom")
-- initialize to idle
playAnimation("idle", 0.1, Humanoid)
pose = "Standing"
while Figure.Parent~=nil do
local _, time = wait(0.1)
move(time)
end
]]></ProtectedString>
</Properties>
<Item class="StringValue" referent="RBX46E2E332A429402F82B8165A9C0274B5">
<Properties>
<string name="Name">climb</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX86915EC08DCE4F59ACD120FD238F349A">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=434415851</url></Content>
<string name="Name">ClimbAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX7A1F8B88C13549A5AF2CBF28C9EF4611">
<Properties>
<string name="Name">fall</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX6EC39B2515BB452D84D31E6CF36ACFDB">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=434418643</url></Content>
<string name="Name">FallAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXC26C332F48294D14897B7BB010302641">
<Properties>
<string name="Name">idle</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXDF0B3CD69EE54DA1B7B732D9B92C3FAB">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=434416649</url></Content>
<string name="Name">Animation1</string>
</Properties>
<Item class="NumberValue" referent="RBX61087E7864744B418198C8290A603722">
<Properties>
<string name="Name">Weight</string>
<double name="Value">9</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBX3BC5344B91AB441F9CFE58BDD1A8DC6A">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=434417169</url></Content>
<string name="Name">Animation2</string>
</Properties>
<Item class="NumberValue" referent="RBXDD7D9684AACE428B905F512A95F5ADAA">
<Properties>
<string name="Name">Weight</string>
<double name="Value">1</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBXAF93B9583F91430DA4CC77653CB25B25">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=434417655</url></Content>
<string name="Name">Animation3</string>
</Properties>
<Item class="NumberValue" referent="RBX8F359BD385614039BCCD8BA3195A33C6">
<Properties>
<string name="Name">Weight</string>
<double name="Value">1</double>
</Properties>
</Item>
</Item>
</Item>
<Item class="StringValue" referent="RBXFF6E3B718B0748CEBC9263C1E5F29A50">
<Properties>
<string name="Name">jump</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX606D26FE17D343DFB970F328093A7BBC">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=434415339</url></Content>
<string name="Name">JumpAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX0ABEAC8348CA49D0B7C7B996BE8538E8">
<Properties>
<string name="Name">run</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX2E15FFA1141F46E49B530ADEEBF24EEE">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=434418038</url></Content>
<string name="Name">RunAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX4F16A850E4334F29A5A17E6E1C0B3721">
<Properties>
<string name="Name">sit</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX91144ECEDB034748B333C8621651A523">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=434419018</url></Content>
<string name="Name">SitAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXAD10A4020BA64B93AFC152DA9195F531">
<Properties>
<string name="Name">toolnone</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX0A920533C1844D779D82A499930C6B10">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=434419638</url></Content>
<string name="Name">ToolNoneAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX3F4DCB146EB642F7B866DE4B65DDFD7A">
<Properties>
<string name="Name">walk</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXCECB9B1E254F4A7293C0327AB396AA27">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=387947975</url></Content>
<string name="Name">WalkAnim</string>
</Properties>
</Item>
</Item>
</Item>
</roblox>
@@ -0,0 +1,694 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="LocalScript" referent="RBX81CCF0D8D0524CB6BEE9B255C92169B0">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Animate</string>
<string name="ScriptGuid"></string>
<ProtectedString name="Source"><![CDATA[function waitForChild(parent, childName)
local child = parent:findFirstChild(childName)
if child then return child end
while true do
child = parent.ChildAdded:wait()
if child.Name==childName then return child end
end
end
local Figure = script.Parent
local Humanoid = waitForChild(Figure, "Humanoid")
local pose = "Standing"
local currentAnim = ""
local currentAnimInstance = nil
local currentAnimTrack = nil
local currentAnimKeyframeHandler = nil
local currentAnimSpeed = 1.0
local animTable = {}
local animNames = {
idle = {
{ id = "http://www.roblox.com/asset/?id=507766666", weight = 1 },
{ id = "http://www.roblox.com/asset/?id=507766951", weight = 1 },
{ id = "http://www.roblox.com/asset/?id=507766388", weight = 9 }
},
walk = {
{ id = "http://www.roblox.com/asset/?id=507777826", weight = 10 }
},
run = {
{ id = "http://www.roblox.com/asset/?id=507767714", weight = 10 }
},
swim = {
{ id = "http://www.roblox.com/asset/?id=507784897", weight = 10 }
},
swimidle = {
{ id = "http://www.roblox.com/asset/?id=507785072", weight = 10 }
},
jump = {
{ id = "http://www.roblox.com/asset/?id=507765000", weight = 10 }
},
fall = {
{ id = "http://www.roblox.com/asset/?id=507767968", weight = 10 }
},
climb = {
{ id = "http://www.roblox.com/asset/?id=507765644", weight = 10 }
},
sit = {
{ id = "http://www.roblox.com/asset/?id=507768133", weight = 10 }
},
toolnone = {
{ id = "http://www.roblox.com/asset/?id=507768375", weight = 10 }
},
toolslash = {
{ id = "http://www.roblox.com/asset/?id=507768375", weight = 10 }
-- { id = "slash.xml", weight = 10 }
},
toollunge = {
{ id = "http://www.roblox.com/asset/?id=507768375", weight = 10 }
},
wave = {
{ id = "http://www.roblox.com/asset/?id=507770239", weight = 10 }
},
point = {
{ id = "http://www.roblox.com/asset/?id=507770453", weight = 10 }
},
dance = {
{ id = "http://www.roblox.com/asset/?id=507771019", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507771955", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507772104", weight = 10 }
},
dance2 = {
{ id = "http://www.roblox.com/asset/?id=507776043", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507776720", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507776879", weight = 10 }
},
dance3 = {
{ id = "http://www.roblox.com/asset/?id=507777268", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507777451", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507777623", weight = 10 }
},
laugh = {
{ id = "http://www.roblox.com/asset/?id=507770818", weight = 10 }
},
cheer = {
{ id = "http://www.roblox.com/asset/?id=507770677", weight = 10 }
},
}
-- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote
local emoteNames = { wave = false, point = false, dance = true, dance2 = true, dance3 = true, laugh = false, cheer = false}
math.randomseed(tick())
function configureAnimationSet(name, fileList)
if (animTable[name] ~= nil) then
for _, connection in pairs(animTable[name].connections) do
connection:disconnect()
end
end
animTable[name] = {}
animTable[name].count = 0
animTable[name].totalWeight = 0
animTable[name].connections = {}
-- check for config values
local config = script:FindFirstChild(name)
if (config ~= nil) then
-- print("Loading anims " .. name)
table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))
local idx = 1
for _, childPart in pairs(config:GetChildren()) do
if (childPart:IsA("Animation")) then
table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
animTable[name][idx] = {}
animTable[name][idx].anim = childPart
local weightObject = childPart:FindFirstChild("Weight")
if (weightObject == nil) then
animTable[name][idx].weight = 1
else
animTable[name][idx].weight = weightObject.Value
end
animTable[name].count = animTable[name].count + 1
animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
-- print(name .. " [" .. idx .. "] " .. animTable[name][idx].anim.AnimationId .. " (" .. animTable[name][idx].weight .. ")")
idx = idx + 1
end
end
end
-- fallback to defaults
if (animTable[name].count <= 0) then
for idx, anim in pairs(fileList) do
animTable[name][idx] = {}
animTable[name][idx].anim = Instance.new("Animation")
animTable[name][idx].anim.Name = name
animTable[name][idx].anim.AnimationId = anim.id
animTable[name][idx].weight = anim.weight
animTable[name].count = animTable[name].count + 1
animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
-- print(name .. " [" .. idx .. "] " .. anim.id .. " (" .. anim.weight .. ")")
end
end
end
-- Setup animation objects
function scriptChildModified(child)
local fileList = animNames[child.Name]
if (fileList ~= nil) then
configureAnimationSet(child.Name, fileList)
end
end
script.ChildAdded:connect(scriptChildModified)
script.ChildRemoved:connect(scriptChildModified)
for name, fileList in pairs(animNames) do
configureAnimationSet(name, fileList)
end
-- ANIMATION
-- declarations
local toolAnim = "None"
local toolAnimTime = 0
local jumpAnimTime = 0
local jumpAnimDuration = 0.31
local toolTransitionTime = 0.1
local fallTransitionTime = 0.2
-- functions
function stopAllAnimations()
local oldAnim = currentAnim
-- return to idle if finishing an emote
if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then
oldAnim = "idle"
end
currentAnim = ""
currentAnimInstance = nil
if (currentAnimKeyframeHandler ~= nil) then
currentAnimKeyframeHandler:disconnect()
end
if (currentAnimTrack ~= nil) then
currentAnimTrack:Stop()
currentAnimTrack:Destroy()
currentAnimTrack = nil
end
return oldAnim
end
function setAnimationSpeed(speed)
if speed ~= currentAnimSpeed then
currentAnimSpeed = speed
currentAnimTrack:AdjustSpeed(currentAnimSpeed)
end
end
function keyFrameReachedFunc(frameName)
if (frameName == "End") then
-- print("Keyframe : ".. frameName)
local repeatAnim = currentAnim
-- return to idle if finishing an emote
if (emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false) then
repeatAnim = "idle"
end
local animSpeed = currentAnimSpeed
playAnimation(repeatAnim, 0.15, Humanoid)
setAnimationSpeed(animSpeed)
end
end
-- Preload animations
function playAnimation(animName, transitionTime, humanoid)
local roll = math.random(1, animTable[animName].totalWeight)
local origRoll = roll
local idx = 1
while (roll > animTable[animName][idx].weight) do
roll = roll - animTable[animName][idx].weight
idx = idx + 1
end
-- print(animName .. " " .. idx .. " [" .. origRoll .. "]")
local anim = animTable[animName][idx].anim
-- switch animation
if (anim ~= currentAnimInstance) then
if (currentAnimTrack ~= nil) then
currentAnimTrack:Stop(transitionTime)
currentAnimTrack:Destroy()
end
currentAnimSpeed = 1.0
-- load it to the humanoid; get AnimationTrack
currentAnimTrack = humanoid:LoadAnimation(anim)
-- 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)
end
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
local toolAnimName = ""
local toolAnimTrack = nil
local toolAnimInstance = nil
local currentToolAnimKeyframeHandler = nil
function toolKeyFrameReachedFunc(frameName)
if (frameName == "End") then
-- print("Keyframe : ".. frameName)
playToolAnimation(toolAnimName, 0.0, Humanoid)
end
end
function playToolAnimation(animName, transitionTime, humanoid)
local roll = math.random(1, animTable[animName].totalWeight)
local origRoll = roll
local idx = 1
while (roll > animTable[animName][idx].weight) do
roll = roll - animTable[animName][idx].weight
idx = idx + 1
end
-- print(animName .. " * " .. idx .. " [" .. origRoll .. "]")
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)
-- 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
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
function onRunning(speed)
if speed > 0.01 then
local scale = 15.0
playAnimation("walk", 0.1, Humanoid)
setAnimationSpeed(speed / scale)
pose = "Running"
else
if emoteNames[currentAnim] == nil then
playAnimation("idle", 0.1, 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 getTool()
for _, kid in ipairs(Figure:GetChildren()) do
if kid.className == "Tool" then return kid end
end
return nil
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
function animateTool()
if (toolAnim == "None") then
playToolAnimation("toolnone", toolTransitionTime, Humanoid)
return
end
if (toolAnim == "Slash") then
playToolAnimation("toolslash", 0, Humanoid)
return
end
if (toolAnim == "Lunge") then
playToolAnimation("toollunge", 0, Humanoid)
return
end
end
function moveSit()
RightShoulder.MaxVelocity = 0.15
LeftShoulder.MaxVelocity = 0.15
RightShoulder:SetDesiredAngle(3.14 /2)
LeftShoulder:SetDesiredAngle(-3.14 /2)
RightHip:SetDesiredAngle(3.14 /2)
LeftHip:SetDesiredAngle(-3.14 /2)
end
local lastTick = 0
function move(time)
local amplitude = 1
local frequency = 1
local deltaTime = time - lastTick
lastTick = time
local climbFudge = 0
local setAngles = false
if (jumpAnimTime > 0) then
jumpAnimTime = jumpAnimTime - deltaTime
end
if (pose == "FreeFall" and jumpAnimTime <= 0) then
playAnimation("fall", fallTransitionTime, Humanoid)
elseif (pose == "Seated") then
playAnimation("sit", 0.5, Humanoid)
return
elseif (pose == "Running") then
playAnimation("walk", 0.1, 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 = getTool()
if tool and (tool.RequiresHandle or tool:FindFirstChild("Handle")) then
animStringValueObject = getToolAnim(tool)
if animStringValueObject then
toolAnim = animStringValueObject.Value
-- message recieved, delete StringValue
animStringValueObject.Parent = nil
toolAnimTime = time + .3
end
if time > toolAnimTime then
toolAnimTime = 0
toolAnim = "None"
end
animateTool()
else
stopToolAnimations()
toolAnim = "None"
toolAnimInstance = nil
toolAnimTime = 0
end
end
-- connect events
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.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
-- print("===> " .. string.sub(msg, 1, 3) .. "(" .. emote .. ")")
end)
-- main program
local runService = game:service("RunService");
-- print("bottom")
-- initialize to idle
playAnimation("idle", 0.1, Humanoid)
pose = "Standing"
while Figure.Parent~=nil do
local _, time = wait(0.1)
move(time)
end
]]></ProtectedString>
</Properties>
<Item class="StringValue" referent="RBX90D2310F3499411E93EB705C595332F9">
<Properties>
<string name="Name">climb</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX751435404EDA413F989EFDB61AEF83F7">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507765644</url></Content>
<string name="Name">ClimbAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX4122099F3058463B8CDC84F8F14A4DE8">
<Properties>
<string name="Name">fall</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX01328E496CA74035ABDDB9ABDBAAE17E">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507767968</url></Content>
<string name="Name">FallAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXEA4D0413A91A40A9ADEFA6C743F90AE6">
<Properties>
<string name="Name">idle</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX413BED0D35534B4793F4941F3F252FD1">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507766388</url></Content>
<string name="Name">Animation1</string>
</Properties>
<Item class="NumberValue" referent="RBX79C9D1CBC12148508B2E98CEF424F7DA">
<Properties>
<string name="Name">Weight</string>
<double name="Value">9</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBXB64911DB20F2424684C3C387151F94F5">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507766666</url></Content>
<string name="Name">Animation2</string>
</Properties>
<Item class="NumberValue" referent="RBX398CD5B511D1422CA1BAAA4265B163F0">
<Properties>
<string name="Name">Weight</string>
<double name="Value">1</double>
</Properties>
</Item>
</Item>
</Item>
<Item class="StringValue" referent="RBX158746ACDD45430AAF15FE4577B348C7">
<Properties>
<string name="Name">jump</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXC751033764264CA994C549E8E36BD20E">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507765000</url></Content>
<string name="Name">JumpAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXE3EC2CBB21DB4724B90E26E7DA569406">
<Properties>
<string name="Name">run</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXE0AB7B279EAF4E0DA8FD148C57A5A3C8">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=5077677142</url></Content>
<string name="Name">RunAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX8A1B8319AEB349469497F7943F9ACBB7">
<Properties>
<string name="Name">sit</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX867339DE035842B4AD88EFAF3625BB49">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507768133</url></Content>
<string name="Name">SitAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXBC54151A25964CED8370B5C005DD8954">
<Properties>
<string name="Name">toolnone</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXD27FB2FCA91E477385E032E6EAD5BD0E">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507768375</url></Content>
<string name="Name">ToolNoneAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX28DA1B6A565F47459169C87D967D6BEC">
<Properties>
<string name="Name">walk</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX51AA2F25CCAB4C4AB610DBE6A384431F">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507777826</url></Content>
<string name="Name">RunAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX37CBFD72FD56488795BD5EB96194EC7F">
<Properties>
<string name="Name">swimidle</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXE057EB1ABC264C799380EB10C18B6E7B">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=481825862</url></Content>
<string name="Name">SwimIdle</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX6589FFEFB5CD453A9CC3C3943029E170">
<Properties>
<string name="Name">swim</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX6FC3A2465C0D41BDBB1DAE559068EDE7">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507784897</url></Content>
<string name="Name">Swim</string>
</Properties>
</Item>
</Item>
</Item>
</roblox>
@@ -0,0 +1,942 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="LocalScript" referent="RBX980D00D6910F408F981BBC8F0BA9B344">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Animate</string>
<string name="ScriptGuid"></string>
<ProtectedString name="Source"><![CDATA[function waitForChild(parent, childName)
local child = parent:findFirstChild(childName)
if child then return child end
while true do
child = parent.ChildAdded:wait()
if child.Name==childName then return child end
end
end
local Figure = script.Parent
local Humanoid = waitForChild(Figure, "Humanoid")
local pose = "Standing"
local currentAnim = ""
local currentAnimInstance = nil
local currentAnimTrack = nil
local currentAnimKeyframeHandler = nil
local currentAnimSpeed = 1.0
local runAnimTrack = nil
local runAnimKeyframeHandler = nil
local animTable = {}
local animNames = {
idle = {
{ id = "http://www.roblox.com/asset/?id=507766666", weight = 1 },
{ id = "http://www.roblox.com/asset/?id=507766951", weight = 1 },
{ id = "http://www.roblox.com/asset/?id=507766388", weight = 9 }
},
walk = {
{ id = "http://www.roblox.com/asset/?id=507777826", weight = 10 }
},
run = {
{ id = "http://www.roblox.com/asset/?id=507767714", weight = 10 }
},
swim = {
{ id = "http://www.roblox.com/asset/?id=507784897", weight = 10 }
},
swimidle = {
{ id = "http://www.roblox.com/asset/?id=507785072", weight = 10 }
},
jump = {
{ id = "http://www.roblox.com/asset/?id=507765000", weight = 10 }
},
fall = {
{ id = "http://www.roblox.com/asset/?id=507767968", weight = 10 }
},
climb = {
{ id = "http://www.roblox.com/asset/?id=507765644", weight = 10 }
},
sit = {
{ id = "http://www.roblox.com/asset/?id=507768133", weight = 10 }
},
toolnone = {
{ id = "http://www.roblox.com/asset/?id=507768375", weight = 10 }
},
toolslash = {
{ id = "http://www.roblox.com/asset/?id=507768375", weight = 10 }
-- { id = "slash.xml", weight = 10 }
},
toollunge = {
{ id = "http://www.roblox.com/asset/?id=507768375", weight = 10 }
},
wave = {
{ id = "http://www.roblox.com/asset/?id=507770239", weight = 10 }
},
point = {
{ id = "http://www.roblox.com/asset/?id=507770453", weight = 10 }
},
dance = {
{ id = "http://www.roblox.com/asset/?id=507771019", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507771955", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507772104", weight = 10 }
},
dance2 = {
{ id = "http://www.roblox.com/asset/?id=507776043", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507776720", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507776879", weight = 10 }
},
dance3 = {
{ id = "http://www.roblox.com/asset/?id=507777268", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507777451", weight = 10 },
{ id = "http://www.roblox.com/asset/?id=507777623", weight = 10 }
},
laugh = {
{ id = "http://www.roblox.com/asset/?id=507770818", weight = 10 }
},
cheer = {
{ id = "http://www.roblox.com/asset/?id=507770677", weight = 10 }
},
}
-- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote
local emoteNames = { wave = false, point = false, dance = true, dance2 = true, dance3 = true, laugh = false, cheer = false}
math.randomseed(tick())
function configureAnimationSet(name, fileList)
if (animTable[name] ~= nil) then
for _, connection in pairs(animTable[name].connections) do
connection:disconnect()
end
end
animTable[name] = {}
animTable[name].count = 0
animTable[name].totalWeight = 0
animTable[name].connections = {}
-- check for config values
local config = script:FindFirstChild(name)
if (config ~= nil) then
-- print("Loading anims " .. name)
table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))
local idx = 1
for _, childPart in pairs(config:GetChildren()) do
if (childPart:IsA("Animation")) then
table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
animTable[name][idx] = {}
animTable[name][idx].anim = childPart
local weightObject = childPart:FindFirstChild("Weight")
if (weightObject == nil) then
animTable[name][idx].weight = 1
else
animTable[name][idx].weight = weightObject.Value
end
animTable[name].count = animTable[name].count + 1
animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
-- print(name .. " [" .. idx .. "] " .. animTable[name][idx].anim.AnimationId .. " (" .. animTable[name][idx].weight .. ")")
idx = idx + 1
end
end
end
-- fallback to defaults
if (animTable[name].count <= 0) then
for idx, anim in pairs(fileList) do
animTable[name][idx] = {}
animTable[name][idx].anim = Instance.new("Animation")
animTable[name][idx].anim.Name = name
animTable[name][idx].anim.AnimationId = anim.id
animTable[name][idx].weight = anim.weight
animTable[name].count = animTable[name].count + 1
animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
-- print(name .. " [" .. idx .. "] " .. anim.id .. " (" .. anim.weight .. ")")
end
end
end
-- Setup animation objects
function scriptChildModified(child)
local fileList = animNames[child.Name]
if (fileList ~= nil) then
configureAnimationSet(child.Name, fileList)
end
end
script.ChildAdded:connect(scriptChildModified)
script.ChildRemoved:connect(scriptChildModified)
for name, fileList in pairs(animNames) do
configureAnimationSet(name, fileList)
end
-- ANIMATION
-- declarations
local toolAnim = "None"
local toolAnimTime = 0
local jumpAnimTime = 0
local jumpAnimDuration = 0.31
local toolTransitionTime = 0.1
local fallTransitionTime = 0.2
-- functions
function stopAllAnimations()
local oldAnim = currentAnim
-- return to idle if finishing an emote
if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then
oldAnim = "idle"
end
currentAnim = ""
currentAnimInstance = nil
if (currentAnimKeyframeHandler ~= nil) then
currentAnimKeyframeHandler:disconnect()
end
if (currentAnimTrack ~= nil) then
currentAnimTrack:Stop()
currentAnimTrack:Destroy()
currentAnimTrack = nil
end
-- clean up walk if there is one
if (runAnimKeyframeHandler ~= nil) then
runAnimKeyframeHandler:disconnect()
end
if (runAnimTrack ~= nil) then
runAnimTrack:Stop()
runAnimTrack:Destroy()
runAnimTrack = nil
end
return oldAnim
end
local smallButNotZero = 0.0001
function setRunSpeed(speed)
if speed < 0.33 then
currentAnimTrack:AdjustWeight(1.0)
runAnimTrack:AdjustWeight(smallButNotZero)
elseif speed < 0.66 then
local weight = ((speed - 0.33) / 0.33)
currentAnimTrack:AdjustWeight(1.0 - weight + smallButNotZero)
runAnimTrack:AdjustWeight(weight + smallButNotZero)
else
currentAnimTrack:AdjustWeight(smallButNotZero)
runAnimTrack:AdjustWeight(1.0)
end
local speedScaled = speed * 1.25
runAnimTrack:AdjustSpeed(speedScaled)
currentAnimTrack:AdjustSpeed(speedScaled)
end
function setAnimationSpeed(speed)
if speed ~= currentAnimSpeed then
currentAnimSpeed = speed
if currentAnim == "walk" then
setRunSpeed(speed)
else
currentAnimTrack:AdjustSpeed(currentAnimSpeed)
end
end
end
function keyFrameReachedFunc(frameName)
-- print("CurrentAnim ", currentAnim, " ", frameName)
if (frameName == "End") then
if currentAnim == "walk" then
runAnimTrack.TimePosition = 0.0
currentAnimTrack.TimePosition = 0.0
else
-- print("Keyframe : ".. frameName)
local repeatAnim = currentAnim
-- return to idle if finishing an emote
if (emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false) then
repeatAnim = "idle"
end
local animSpeed = currentAnimSpeed
playAnimation(repeatAnim, 0.15, Humanoid)
setAnimationSpeed(animSpeed)
end
end
end
function rollAnimation(animName)
local roll = math.random(1, animTable[animName].totalWeight)
local origRoll = roll
local idx = 1
while (roll > animTable[animName][idx].weight) do
roll = roll - animTable[animName][idx].weight
idx = idx + 1
end
return idx
end
function playAnimation(animName, transitionTime, humanoid)
local idx = rollAnimation(animName)
-- print(animName .. " " .. idx .. " [" .. origRoll .. "]")
local anim = animTable[animName][idx].anim
-- switch animation
if (anim ~= currentAnimInstance) then
if (currentAnimTrack ~= nil) then
currentAnimTrack:Stop(transitionTime)
currentAnimTrack:Destroy()
end
if (runAnimTrack ~= nil) then
runAnimTrack:Stop(transitionTime)
runAnimTrack:Destroy()
end
currentAnimSpeed = 1.0
-- load it to the humanoid; get AnimationTrack
currentAnimTrack = humanoid:LoadAnimation(anim)
-- 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: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
-- print("Keyframe : ".. frameName)
playToolAnimation(toolAnimName, 0.0, Humanoid)
end
end
function playToolAnimation(animName, transitionTime, humanoid)
local idx = rollAnimation(animName)
-- print(animName .. " * " .. idx .. " [" .. origRoll .. "]")
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)
-- 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
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
function onRunning(speed)
if speed > 0.01 then
local scale = 16.0
playAnimation("walk", 0.1, Humanoid)
setAnimationSpeed(speed / scale)
pose = "Running"
else
if emoteNames[currentAnim] == nil then
playAnimation("idle", 0.1, 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 getTool()
for _, kid in ipairs(Figure:GetChildren()) do
if kid.className == "Tool" then return kid end
end
return nil
end
function animateTool()
if (toolAnim == "None") then
playToolAnimation("toolnone", toolTransitionTime, Humanoid)
return
end
if (toolAnim == "Slash") then
playToolAnimation("toolslash", 0, Humanoid)
return
end
if (toolAnim == "Lunge") then
playToolAnimation("toollunge", 0, Humanoid)
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 move(time)
local amplitude = 1
local frequency = 1
local deltaTime = time - lastTick
lastTick = time
local climbFudge = 0
local setAngles = false
if (jumpAnimTime > 0) then
jumpAnimTime = jumpAnimTime - deltaTime
end
if (pose == "FreeFall" and jumpAnimTime <= 0) then
playAnimation("fall", fallTransitionTime, Humanoid)
elseif (pose == "Seated") then
playAnimation("sit", 0.5, Humanoid)
return
elseif (pose == "Running") then
playAnimation("walk", 0.1, 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 = getTool()
if tool then
local animStringValueObject = getToolAnim(tool)
if animStringValueObject then
toolAnim = animStringValueObject.Value
-- message recieved, delete StringValue
animStringValueObject.Parent = nil
toolAnimTime = time + .3
end
if time > toolAnimTime then
toolAnimTime = 0
toolAnim = "None"
end
animateTool()
else
stopToolAnimations()
toolAnim = "None"
toolAnimInstance = nil
toolAnimTime = 0
end
end
-- connect events
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.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
-- print("===> " .. string.sub(msg, 1, 3) .. "(" .. emote .. ")")
end)
-- initialize to idle
playAnimation("idle", 0.1, Humanoid)
pose = "Standing"
-- loop to handle timed state transitions and tool animations
while Figure.Parent~=nil do
local _, time = wait(0.1)
move(time)
end
]]></ProtectedString>
</Properties>
<Item class="StringValue" referent="RBX8B778A72BCBF4ACB8696D8C5A38B6E83">
<Properties>
<string name="Name">climb</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXD74196C64A4A414E85E1862FB322BCAC">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507765644</url></Content>
<string name="Name">ClimbAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX928CEDB1BFED487AA543BA482976A985">
<Properties>
<string name="Name">fall</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX031D73ED004E4A33927224B4919609F0">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507767968</url></Content>
<string name="Name">FallAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXA494D4E93F9847F89A9402026287C007">
<Properties>
<string name="Name">idle</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX1D83AA3674B5426E917DE58F21AD87B6">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507766388</url></Content>
<string name="Name">Animation1</string>
</Properties>
<Item class="NumberValue" referent="RBXC51E8CA58EBB4E2FBE6C29AC7CB459EA">
<Properties>
<string name="Name">Weight</string>
<double name="Value">9</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBX370A7EC91BE94BFEA920D6DD82B5DBBD">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507766666</url></Content>
<string name="Name">Animation2</string>
</Properties>
<Item class="NumberValue" referent="RBX558D7AA1389F4C6F8DE31F704F8C4575">
<Properties>
<string name="Name">Weight</string>
<double name="Value">1</double>
</Properties>
</Item>
</Item>
</Item>
<Item class="StringValue" referent="RBX6B204E5BF017427C8149141368DF0CCF">
<Properties>
<string name="Name">jump</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX2EC0C03F466D4763B69F30C89FCF2B47">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507765000</url></Content>
<string name="Name">JumpAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX62F3FD55984848F1A96A7DB1913CF17E">
<Properties>
<string name="Name">run</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX658DCBD687FC42AAB1FCF76F46730A8C">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507767714</url></Content>
<string name="Name">RunAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX2FE204914EE043A89D62442E82365571">
<Properties>
<string name="Name">sit</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXAB6D8B0D7C9249F6B4D472B5F2267200">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507768133</url></Content>
<string name="Name">SitAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX9457B9D2E87D40B89760E538A71F3039">
<Properties>
<string name="Name">toollunge</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXCF6FEED13778435BAB1847FB03DF8AD8">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507768375</url></Content>
<string name="Name">ToolLungeAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBXE60446BE714E4BBDBC4CE151F5212861">
<Properties>
<string name="Name">walk</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX7EA30331FA0B479C9BDB302BA01F2419">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=540798782</url></Content>
<string name="Name">WalkAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX5EA7F5420B9E4B4CA7E3730B24262BAF">
<Properties>
<string name="Name">swimidle</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX5FD148051EF5456FA4E349FB28AC0C22">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=481825862</url></Content>
<string name="Name">SwimIdle</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX6FDDF6C9EEF6406C8D7282785DFB78CD">
<Properties>
<string name="Name">swim</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXDB64D8D3F7054C00868C8A5B596BA6DA">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507784897</url></Content>
<string name="Name">Swim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX86C7EBEDF2D841A88347669EB61C0DAA">
<Properties>
<string name="Name">toolslash</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXB6069EFEDD074A1E8950D252CD0BEDAC">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507768375</url></Content>
<string name="Name">ToolSlashAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX74C535A97ACC43E7A0D6496268E02A21">
<Properties>
<string name="Name">toolnone</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX235A33030B114950B95F9A803CE18011">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507768375</url></Content>
<string name="Name">ToolNoneAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX22E0A32FB67744DC8ADE68FFC73E14A8">
<Properties>
<string name="Name">wave</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX289607FF40264B5283CBE52A0968D369">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507770239</url></Content>
<string name="Name">WaveAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX15A7BD9A74634E038B3D3809D1B8E03F">
<Properties>
<string name="Name">laugh</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXC1F3C6BE473E463B831DF758C6E33E7B">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507770818</url></Content>
<string name="Name">LaughAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX0CC63179A9FA41FD8171BC4CE7ACEB04">
<Properties>
<string name="Name">point</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX97A5E04897324DC29B502AD151492628">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507770453</url></Content>
<string name="Name">PointAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX52BC1CDE71CF44F9B6E26A5C13944A26">
<Properties>
<string name="Name">cheer</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX1FBCD816A95947FD92F88F27A2742E76">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507770677</url></Content>
<string name="Name">CheerAnim</string>
</Properties>
</Item>
</Item>
<Item class="StringValue" referent="RBX905B92DD4E8C4EE1A0C229538FCCB4A8">
<Properties>
<string name="Name">dance</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXBB51D8D1C8964CAEBF72AFF33CC3F86B">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507771019</url></Content>
<string name="Name">Animation1</string>
</Properties>
<Item class="NumberValue" referent="RBXE1D01798DA734F9ABD349136360AC0F7">
<Properties>
<string name="Name">Weight</string>
<double name="Value">10</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBXBF61451CF15640B69CA86ADC9A485D22">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507771955</url></Content>
<string name="Name">Animation2</string>
</Properties>
<Item class="NumberValue" referent="RBX07011263539F410298682B0E484E6DD6">
<Properties>
<string name="Name">Weight</string>
<double name="Value">10</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBXEC4EDF3394E942239DE459CE0F6311F7">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507772104</url></Content>
<string name="Name">Animation3</string>
</Properties>
<Item class="NumberValue" referent="RBXDE3167369F184A6B88AE3F70209F930B">
<Properties>
<string name="Name">Weight</string>
<double name="Value">10</double>
</Properties>
</Item>
</Item>
</Item>
<Item class="StringValue" referent="RBXE8C147C2797A463683EB841E6E574E72">
<Properties>
<string name="Name">dance2</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBX5D79C48B4507452A86A34CCCC944BB6C">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507776043</url></Content>
<string name="Name">Animation1</string>
</Properties>
<Item class="NumberValue" referent="RBX0B464F16C3C94E54AF92B58A72FE1DBC">
<Properties>
<string name="Name">Weight</string>
<double name="Value">10</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBX67E70DEFF3774D689E6DEADA7AFB2869">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507776720</url></Content>
<string name="Name">Animation2</string>
</Properties>
<Item class="NumberValue" referent="RBX899591DBFD3B4E7DACE3AB4919A6D6C1">
<Properties>
<string name="Name">Weight</string>
<double name="Value">10</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBX214E40E9BEAA4681B7F79F886FE40302">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507776879</url></Content>
<string name="Name">Animation3</string>
</Properties>
<Item class="NumberValue" referent="RBXD8E0FDD9DA374312BA56E29B080FF00C">
<Properties>
<string name="Name">Weight</string>
<double name="Value">10</double>
</Properties>
</Item>
</Item>
</Item>
<Item class="StringValue" referent="RBXD9DFE6D5CB80438AB23F31F67882BF25">
<Properties>
<string name="Name">dance3</string>
<string name="Value"></string>
</Properties>
<Item class="Animation" referent="RBXAE6D13EFDDE54BECA02633C646419F2B">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507777268</url></Content>
<string name="Name">Animation1</string>
</Properties>
<Item class="NumberValue" referent="RBX77AD6AF4C51E40538099193C6C9151D6">
<Properties>
<string name="Name">Weight</string>
<double name="Value">10</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBXDF0B79AAB82B4A5CADFFB202FF54D6EB">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507777451</url></Content>
<string name="Name">Animation2</string>
</Properties>
<Item class="NumberValue" referent="RBXF795075B6A07440E91F02457A02CBE47">
<Properties>
<string name="Name">Weight</string>
<double name="Value">10</double>
</Properties>
</Item>
</Item>
<Item class="Animation" referent="RBX6244AB050AA84D8599A87CC474E12288">
<Properties>
<Content name="AnimationId"><url>http://www.roblox.com/asset/?id=507777623</url></Content>
<string name="Name">Animation3</string>
</Properties>
<Item class="NumberValue" referent="RBX1EB4653C0987454F8E77A57DEBC68C9B">
<Properties>
<string name="Name">Weight</string>
<double name="Value">10</double>
</Properties>
</Item>
</Item>
</Item>
</Item>
</roblox>
+11
View File
@@ -0,0 +1,11 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Script">
<Properties>
<bool name="Disabled">false</bool>
<string name="Name">Script</string>
<string name="Source">&#13;&#10;while script.Parent.Head==nil do&#13;&#10;&#9;wait(0.05)&#13;&#10;end&#13;&#10;&#13;&#10;function newSound(id)&#13;&#10;&#9;local sound = Instance.new(&quot;Sound&quot;)&#13;&#10;&#9;sound.SoundId = id&#13;&#10;&#9;sound.Parent = script.Parent.Head&#13;&#10;&#9;return sound&#13;&#10;end&#13;&#10;&#13;&#10;sDied = newSound(&quot;rbxasset://sounds/uuhhh.wav&quot;)&#13;&#10;sFallingDown = newSound(&quot;rbxasset://sounds/splat.wav&quot;)&#13;&#10;sFreeFalling = newSound(&quot;rbxasset://sounds/swoosh.wav&quot;)&#13;&#10;sGettingUp = newSound(&quot;rbxasset://sounds/hit.wav&quot;)&#13;&#10;sJumping = newSound(&quot;rbxasset://sounds/button.wav&quot;)&#13;&#10;sRunning = newSound(&quot;rbxasset://sounds/bfsl-minifigfoots1.mp3&quot;)&#13;&#10;sRunning.Looped = true&#13;&#10;&#13;&#10;function onDied()&#13;&#10;&#9;sDied:play()&#13;&#10;end&#13;&#10;&#13;&#10;function onState(state, sound)&#13;&#10;&#9;if state then&#13;&#10;&#9;&#9;sound:play()&#13;&#10;&#9;else&#13;&#10;&#9;&#9;sound:pause()&#13;&#10;&#9;end&#13;&#10;end&#13;&#10;&#13;&#10;function onRunning(speed)&#13;&#10;&#9;if speed&gt;0 then&#13;&#10;&#9;&#9;sRunning:play()&#13;&#10;&#9;else&#13;&#10;&#9;&#9;sRunning:pause()&#13;&#10;&#9;end&#13;&#10;end&#13;&#10;&#13;&#10;while script.Parent.Humanoid==nil do&#13;&#10;&#9;wait(0.05)&#13;&#10;end&#13;&#10;&#13;&#10;h = script.Parent.Humanoid&#13;&#10;h.Died:connect(onDied)&#13;&#10;h.Running:connect(onRunning)&#13;&#10;h.Jumping:connect(function(state) onState(state, sJumping) end)&#13;&#10;h.GettingUp:connect(function(state) onState(state, sGettingUp) end)&#13;&#10;h.FreeFalling:connect(function(state) onState(state, sFreeFalling) end)&#13;&#10;h.FallingDown:connect(function(state) onState(state, sFallingDown) end)&#13;&#10;&#13;&#10;-- regeneration&#13;&#10;while true do&#13;&#10;&#9;local s = wait(1)&#13;&#10;&#9;local health=h.Health&#13;&#10;&#9;if health&gt;0 and health&lt;h.MaxHealth then&#13;&#10;&#9;&#9;health = health + 0.01*s*h.MaxHealth&#13;&#10;&#9;&#9;if health*1.05 &lt; h.MaxHealth then&#13;&#10;&#9;&#9;&#9;h.Health = health&#13;&#10;&#9;&#9;else&#13;&#10;&#9;&#9;&#9;h.Health = h.MaxHealth&#13;&#10;&#9;&#9;end&#13;&#10;&#9;end&#13;&#10;end&#13;&#10;</string>
</Properties>
</Item>
</roblox>
@@ -0,0 +1,191 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Script" referent="RBX440EE2113E074565A1C69E447652B15D">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Sound</string>
<ProtectedString name="Source"><![CDATA[---This server script creates the sounds and also exists so that it can be easily copied into an NPC and create sounds for that NPC.
--Remove the local script if you copy this into an NPC.
--humanoidSoundNewLocal.rbxmx--
function newSound(name, id)
local sound = Instance.new("Sound")
sound.SoundId = id
sound.Name = name
sound.archivable = false
sound.Parent = script.Parent.Head
return sound
end
-- declarations
local sGettingUp = newSound("GettingUp", "rbxasset://sounds/action_get_up.mp3")
local sDied = newSound("Died", "rbxasset://sounds/uuhhh.mp3")
local sFreeFalling = newSound("FreeFalling", "rbxasset://sounds/action_falling.mp3")
local sJumping = newSound("Jumping", "rbxasset://sounds/action_jump.mp3")
local sLanding = newSound("Landing", "rbxasset://sounds/action_jump_land.mp3")
local sSplash = newSound("Splash", "rbxasset://sounds/impact_water.mp3")
local sRunning = newSound("Running", "rbxasset://sounds/action_footsteps_plastic.mp3")
sRunning.Looped = true
local sSwimming = newSound("Swimming", "rbxasset://sounds/action_swim.mp3")
sSwimming.Looped = true
local sClimbing = newSound("Climbing", "rbxasset://sounds/action_footsteps_plastic.mp3")
sClimbing.Looped = true
]]></ProtectedString>
</Properties>
<Item class="LocalScript" referent="RBXACC3E7AAF68642CC9341039CBCE06F78">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">LocalSound</string>
<ProtectedString name="Source"><![CDATA[--This local script will run only for the player whos character it is in. It's changes to the sounds will replicate as they are changes to the character.
-- util
function waitForChild(parent, childName)
local child = parent:findFirstChild(childName)
if child then return child end
while true do
child = parent.ChildAdded:wait()
if child.Name==childName then return child end
end
end
-- declarations
local Figure = script.Parent.Parent
local Head = waitForChild(Figure, "Head")
local Humanoid = waitForChild(Figure, "Humanoid")
local sGettingUp = waitForChild(Head, "GettingUp")
local sDied = waitForChild(Head, "Died")
local sFreeFalling = waitForChild(Head, "FreeFalling")
local sJumping = waitForChild(Head, "Jumping")
local sLanding = waitForChild(Head, "Landing")
local sSplash = waitForChild(Head, "Splash")
local sRunning = waitForChild(Head, "Running")
sRunning.Looped = true
local sSwimming = waitForChild(Head, "Swimming")
sSwimming.Looped = true
local sClimbing =waitForChild(Head, "Climbing")
sClimbing.Looped = true
local prevState = "None"
-- functions
function onDied()
stopLoopedSounds()
sDied:Play()
end
local fallCount = 0
local fallSpeed = 0
function onStateFall(state, sound)
fallCount = fallCount + 1
if state then
sound.Volume = 0
sound:Play()
Spawn( function()
local t = 0
local thisFall = fallCount
while t < 1.5 and fallCount == thisFall do
local vol = math.max(t - 0.3 , 0)
sound.Volume = vol
wait(0.1)
t = t + 0.1
end
end)
else
sound:Stop()
end
fallSpeed = math.max(fallSpeed, math.abs(Head.Velocity.Y))
end
function onStateNoStop(state, sound)
if state then
sound:Play()
end
end
function onRunning(speed)
sClimbing:Stop()
sSwimming:Stop()
if (prevState == "FreeFall" and fallSpeed > 0.1) then
local vol = math.min(1.0, math.max(0.0, (fallSpeed - 50) / 110))
sLanding.Volume = vol
sLanding:Play()
fallSpeed = 0
end
if speed>0.5 then
sRunning:Resume()
sRunning.Pitch = speed / 8.0
else
sRunning:Pause()
end
prevState = "Run"
end
function onSwimming(speed)
if (prevState ~= "Swim" and speed > 0.1) then
local volume = math.min(1.0, speed / 350)
sSplash.Volume = volume
sSplash:Play()
prevState = "Swim"
end
sClimbing:Stop()
sRunning:Stop()
sSwimming.Pitch = 1.6
sSwimming:Resume()
end
function onClimbing(speed)
sRunning:Stop()
sSwimming:Stop()
if speed>0.01 then
sClimbing:Resume()
sClimbing.Pitch = speed / 5.5
else
sClimbing:Pause()
end
prevState = "Climb"
end
-- connect up
function stopLoopedSounds()
sRunning:Stop()
sClimbing:Stop()
sSwimming:Stop()
end
Humanoid.Died:connect(onDied)
Humanoid.Running:connect(onRunning)
Humanoid.Swimming:connect(onSwimming)
Humanoid.Climbing:connect(onClimbing)
Humanoid.Jumping:connect(function(state) onStateNoStop(state, sJumping) prevState = "Jump" end)
Humanoid.GettingUp:connect(function(state) stopLoopedSounds() onStateNoStop(state, sGettingUp) prevState = "GetUp" end)
Humanoid.FreeFalling:connect(function(state) stopLoopedSounds() onStateFall(state, sFreeFalling) prevState = "FreeFall" end)
Humanoid.FallingDown:connect(function(state) stopLoopedSounds() end)
Humanoid.StateChanged:connect(function(old, new)
if not (new.Name == "Dead" or
new.Name == "Running" or
new.Name == "RunningNoPhysics" or
new.Name == "Swimming" or
new.Name == "Jumping" or
new.Name == "GettingUp" or
new.Name == "Freefall" or
new.Name == "FallingDown") then
stopLoopedSounds()
end
end)
]]></ProtectedString>
</Properties>
</Item>
</Item>
</roblox>
+12
View File
@@ -0,0 +1,12 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Script">
<Properties>
<bool name="Disabled">false</bool>
<string name="Name">Static</string>
<string name="Source">local Figure = script.Parent&#13;&#10;&#13;&#10;local Torso = Figure:findFirstChild(&quot;Torso&quot;)&#13;&#10;&#13;&#10;Torso:makeJoints()</string>
<bool name="archivable">true</bool>
</Properties>
</Item>
</roblox>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More