add
This commit is contained in:
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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.
Binary file not shown.
@@ -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.
@@ -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("RunService") shaft = script.Parent position = Vector3.new(0,0,0) function fly() 	direction = shaft.CFrame.lookVector 	position = position + direction 	error = position - shaft.Position 	shaft.Velocity = 7*error end function blow() 	swoosh:Stop() 	explosion = Instance.new("Explosion") 	explosion.Position = shaft.Position 	explosion.Parent = game.Workspace 	connection:disconnect() 	shaft:remove() end t, s = r.Stepped:wait() swoosh = script.Parent.Swoosh swoosh:Play() position = shaft.Position d = t + 10.0 - s connection = shaft.Touched:connect(blow) while t < d do 	fly() 	t = r.Stepped:wait() end script.Parent.Explosion.PlayOnRemove = false swoosh:Stop() shaft:remove() </string>
|
||||
</Properties>
|
||||
</Item>
|
||||
</Item>
|
||||
</roblox>
|
||||
Binary file not shown.
@@ -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"> pellet = script.Parent damage = 8 function onTouched(hit) 	humanoid = hit.Parent:findFirstChild("Humanoid") 	if humanoid~=nil then 		humanoid.Health = humanoid.Health - damage 		connection:disconnect() 	else 		damage = damage / 2 		if damage < 0.1 then 			connection:disconnect() 		end 	end end connection = pellet.Touched:connect(onTouched) r = game:service("RunService") t, s = r.Stepped:wait() d = t + 1.0 - s while t < d do 	t = r.Stepped:wait() end 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.
@@ -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>
|
||||
@@ -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
@@ -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.
@@ -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.
@@ -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.
@@ -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("Body Colors")
|
||||
if not old then return end
|
||||
old:clone().Parent = char
|
||||
old.Parent = nil
|
||||
else
|
||||
local head = char:findFirstChild("Head")
|
||||
local torso = char:findFirstChild("Torso")
|
||||
local left_arm = char:findFirstChild("Left Arm")
|
||||
local right_arm = char:findFirstChild("Right Arm")
|
||||
local left_leg = char:findFirstChild("Left Leg")
|
||||
local right_leg = char:findFirstChild("Right Leg")
|
||||
|
||||
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 == "Character" then
|
||||
onTeamChanged(player)
|
||||
end
|
||||
if property== "TeamColor" or property == "Neutral" 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, "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 toolAnim = "None"
|
||||
local toolAnimTime = 0
|
||||
|
||||
-- functions
|
||||
|
||||
function onRunning(speed)
|
||||
if speed>0 then
|
||||
pose = "Running"
|
||||
else
|
||||
pose = "Standing"
|
||||
end
|
||||
end
|
||||
|
||||
function onDied()
|
||||
pose = "Dead"
|
||||
end
|
||||
|
||||
function onJumping()
|
||||
pose = "Jumping"
|
||||
end
|
||||
|
||||
function onClimbing()
|
||||
pose = "Climbing"
|
||||
end
|
||||
|
||||
function onGettingUp()
|
||||
pose = "GettingUp"
|
||||
end
|
||||
|
||||
function onFreeFall()
|
||||
pose = "FreeFall"
|
||||
end
|
||||
|
||||
function onFallingDown()
|
||||
pose = "FallingDown"
|
||||
end
|
||||
|
||||
function onSeated()
|
||||
pose = "Seated"
|
||||
end
|
||||
|
||||
function onPlatformStanding()
|
||||
pose = "PlatformStanding"
|
||||
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 == "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
|
||||
RightShoulder:SetDesiredAngle(1.57)
|
||||
return
|
||||
end
|
||||
|
||||
if (toolAnim == "Slash") then
|
||||
RightShoulder.MaxVelocity = 0.5
|
||||
RightShoulder:SetDesiredAngle(0)
|
||||
return
|
||||
end
|
||||
|
||||
if (toolAnim == "Lunge") 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 == "Jumping") then
|
||||
moveJump()
|
||||
return
|
||||
end
|
||||
|
||||
if (pose == "FreeFall") then
|
||||
moveFreeFall()
|
||||
return
|
||||
end
|
||||
|
||||
if (pose == "Seated") then
|
||||
moveSit()
|
||||
return
|
||||
end
|
||||
|
||||
local climbFudge = 0
|
||||
|
||||
if (pose == "Running") then
|
||||
RightShoulder.MaxVelocity = 0.15
|
||||
LeftShoulder.MaxVelocity = 0.15
|
||||
amplitude = 1
|
||||
frequency = 9
|
||||
elseif (pose == "Climbing") 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 > toolAnimTime then
|
||||
toolAnimTime = 0
|
||||
toolAnim = "None"
|
||||
end
|
||||
|
||||
animateTool()
|
||||
|
||||
|
||||
else
|
||||
toolAnim = "None"
|
||||
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("RunService");
|
||||
|
||||
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, "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 toolAnim = "None"
|
||||
local toolAnimTime = 0
|
||||
|
||||
local jumpMaxLimbVelocity = 0.75
|
||||
|
||||
-- functions
|
||||
|
||||
function onRunning(speed)
|
||||
if speed>0 then
|
||||
pose = "Running"
|
||||
else
|
||||
pose = "Standing"
|
||||
end
|
||||
end
|
||||
|
||||
function onDied()
|
||||
pose = "Dead"
|
||||
end
|
||||
|
||||
function onJumping()
|
||||
pose = "Jumping"
|
||||
end
|
||||
|
||||
function onClimbing()
|
||||
pose = "Climbing"
|
||||
end
|
||||
|
||||
function onGettingUp()
|
||||
pose = "GettingUp"
|
||||
end
|
||||
|
||||
function onFreeFall()
|
||||
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 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 == "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
|
||||
RightShoulder:SetDesiredAngle(1.57)
|
||||
return
|
||||
end
|
||||
|
||||
if (toolAnim == "Slash") then
|
||||
RightShoulder.MaxVelocity = 0.5
|
||||
RightShoulder:SetDesiredAngle(0)
|
||||
return
|
||||
end
|
||||
|
||||
if (toolAnim == "Lunge") 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 == "Jumping") then
|
||||
moveJump()
|
||||
return
|
||||
end
|
||||
|
||||
if (pose == "FreeFall") then
|
||||
moveFreeFall()
|
||||
return
|
||||
end
|
||||
|
||||
if (pose == "Seated") then
|
||||
moveSit()
|
||||
return
|
||||
end
|
||||
|
||||
local climbFudge = 0
|
||||
|
||||
if (pose == "Running") then
|
||||
if (RightShoulder.CurrentAngle > 1.5 or RightShoulder.CurrentAngle < -1.5) then
|
||||
RightShoulder.MaxVelocity = jumpMaxLimbVelocity
|
||||
else
|
||||
RightShoulder.MaxVelocity = 0.15
|
||||
end
|
||||
if (LeftShoulder.CurrentAngle > 1.5 or LeftShoulder.CurrentAngle < -1.5) then
|
||||
LeftShoulder.MaxVelocity = jumpMaxLimbVelocity
|
||||
else
|
||||
LeftShoulder.MaxVelocity = 0.15
|
||||
end
|
||||
amplitude = 1
|
||||
frequency = 9
|
||||
elseif (pose == "Climbing") 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 > toolAnimTime then
|
||||
toolAnimTime = 0
|
||||
toolAnim = "None"
|
||||
end
|
||||
|
||||
animateTool()
|
||||
|
||||
|
||||
else
|
||||
toolAnim = "None"
|
||||
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("RunService");
|
||||
|
||||
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("Body Colors")
|
||||
if not old then return end
|
||||
old:clone().Parent = char
|
||||
old.Parent = nil
|
||||
else
|
||||
local head = char:findFirstChild("Head")
|
||||
local torso = char:findFirstChild("Torso")
|
||||
local left_arm = char:findFirstChild("Left Arm")
|
||||
local right_arm = char:findFirstChild("Right Arm")
|
||||
local left_leg = char:findFirstChild("Left Leg")
|
||||
local right_leg = char:findFirstChild("Right Leg")
|
||||
|
||||
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 == "Character" then
|
||||
onTeamChanged(player)
|
||||
end
|
||||
if property== "TeamColor" or property == "Neutral" 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)
|
||||
	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 currentAnimTrack = nil
|
||||
local currentAnimKeyframeHandler = nil
|
||||
local currentAnimSpeed = 1.0
|
||||
local animTable = {}
|
||||
local animNames = {
|
||||
	idle = 	{	
|
||||
				{ id = "http://www.roblox.com/asset/?id=125750544", weight = 9 },
|
||||
				{ id = "http://www.roblox.com/asset/?id=125750618", weight = 1 }
|
||||
			},
|
||||
	walk = 	{ 	
|
||||
				{ id = "http://www.roblox.com/asset/?id=125749145", 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=125750759", weight = 10 }
|
||||
			},
|
||||
	climb = {
|
||||
				{ id = "http://www.roblox.com/asset/?id=125750800", weight = 10 }
|
||||
			},
|
||||
	sit = 	{
|
||||
				{ id = "http://www.roblox.com/asset/?id=178130996", weight = 10 }
|
||||
			},	
|
||||
	toolnone = {
|
||||
				{ id = "http://www.roblox.com/asset/?id=125750867", 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 }
|
||||
			},
|
||||
	dance = {
|
||||
				{ id = "http://www.roblox.com/asset/?id=130018893", weight = 10 },
|
||||
				{ id = "http://www.roblox.com/asset/?id=132546839", weight = 10 },
|
||||
				{ id = "http://www.roblox.com/asset/?id=132546884", weight = 10 }
|
||||
			},
|
||||
	dance2 = {
|
||||
				{ id = "http://www.roblox.com/asset/?id=160934142", weight = 10 },
|
||||
				{ id = "http://www.roblox.com/asset/?id=160934298", weight = 10 },
|
||||
				{ id = "http://www.roblox.com/asset/?id=160934376", weight = 10 }
|
||||
			},
|
||||
	dance3 = {
|
||||
				{ id = "http://www.roblox.com/asset/?id=160934458", weight = 10 },
|
||||
				{ id = "http://www.roblox.com/asset/?id=160934530", weight = 10 },
|
||||
				{ id = "http://www.roblox.com/asset/?id=160934593", weight = 10 }
|
||||
			},
|
||||
	laugh = {
|
||||
				{ id = "http://www.roblox.com/asset/?id=129423131", weight = 10 }
|
||||
			},
|
||||
	cheer = {
|
||||
				{ id = "http://www.roblox.com/asset/?id=129423030", 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.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 = ""
|
||||
	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 = stopAllAnimations()
|
||||
		local animSpeed = currentAnimSpeed
|
||||
		playAnimation(repeatAnim, 0.0, Humanoid)
|
||||
		setAnimationSpeed(animSpeed)
|
||||
	end
|
||||
end
|
||||
|
||||
-- Preload animations
|
||||
function playAnimation(animName, transitionTime, humanoid)
|
||||
	local idleFromEmote = (animName == "idle" and emoteNames[currentAnim] ~= nil)
|
||||
	if (animName ~= currentAnim and not idleFromEmote) then		
|
||||
		
|
||||
		if (currentAnimTrack ~= nil) then
|
||||
			currentAnimTrack:Stop(transitionTime)
|
||||
			currentAnimTrack:Destroy()
|
||||
		end
|
||||
|
||||
		currentAnimSpeed = 1.0
|
||||
		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
|
||||
|
||||
		-- load it to the humanoid; get AnimationTrack
|
||||
		currentAnimTrack = humanoid:LoadAnimation(anim)
|
||||
		
|
||||
		-- play the animation
|
||||
		currentAnimTrack:Play(transitionTime)
|
||||
		currentAnim = animName
|
||||
|
||||
		-- 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 currentToolAnimKeyframeHandler = nil
|
||||
|
||||
function toolKeyFrameReachedFunc(frameName)
|
||||
	if (frameName == "End") then
|
||||
--		print("Keyframe : ".. frameName)
|
||||
		local repeatAnim = stopToolAnimations()
|
||||
		playToolAnimation(repeatAnim, 0.0, Humanoid)
|
||||
	end
|
||||
end
|
||||
|
||||
|
||||
function playToolAnimation(animName, transitionTime, humanoid)
|
||||
	if (animName ~= toolAnimName) then		
|
||||
		
|
||||
		if (toolAnimTrack ~= nil) then
|
||||
			toolAnimTrack:Stop()
|
||||
			toolAnimTrack:Destroy()
|
||||
			transitionTime = 0
|
||||
		end
|
||||
|
||||
		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
|
||||
|
||||
		-- load it to the humanoid; get AnimationTrack
|
||||
		toolAnimTrack = humanoid:LoadAnimation(anim)
|
||||
		
|
||||
		-- play the animation
|
||||
		toolAnimTrack:Play(transitionTime)
|
||||
		toolAnimName = animName
|
||||
|
||||
		currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc)
|
||||
	end
|
||||
end
|
||||
|
||||
function stopToolAnimations()
|
||||
	local oldAnim = toolAnimName
|
||||
|
||||
	if (currentToolAnimKeyframeHandler ~= nil) then
|
||||
		currentToolAnimKeyframeHandler:disconnect()
|
||||
	end
|
||||
|
||||
	toolAnimName = ""
|
||||
	if (toolAnimTrack ~= nil) then
|
||||
		toolAnimTrack:Stop()
|
||||
		toolAnimTrack:Destroy()
|
||||
		toolAnimTrack = nil
|
||||
	end
|
||||
|
||||
|
||||
	return oldAnim
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
function onRunning(speed)
|
||||
	if speed>0.5 then
|
||||
		playAnimation("walk", 0.1, Humanoid)
|
||||
		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 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"
|
||||
		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");
|
||||
|
||||
-- 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="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>
|
||||
@@ -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>
|
||||
@@ -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"> while script.Parent.Head==nil do 	wait(0.05) end function newSound(id) 	local sound = Instance.new("Sound") 	sound.SoundId = id 	sound.Parent = script.Parent.Head 	return sound end sDied = newSound("rbxasset://sounds/uuhhh.wav") sFallingDown = newSound("rbxasset://sounds/splat.wav") sFreeFalling = newSound("rbxasset://sounds/swoosh.wav") sGettingUp = newSound("rbxasset://sounds/hit.wav") sJumping = newSound("rbxasset://sounds/button.wav") sRunning = newSound("rbxasset://sounds/bfsl-minifigfoots1.mp3") sRunning.Looped = true function onDied() 	sDied:play() end function onState(state, sound) 	if state then 		sound:play() 	else 		sound:pause() 	end end function onRunning(speed) 	if speed>0 then 		sRunning:play() 	else 		sRunning:pause() 	end end while script.Parent.Humanoid==nil do 	wait(0.05) end h = script.Parent.Humanoid h.Died:connect(onDied) h.Running:connect(onRunning) h.Jumping:connect(function(state) onState(state, sJumping) end) h.GettingUp:connect(function(state) onState(state, sGettingUp) end) h.FreeFalling:connect(function(state) onState(state, sFreeFalling) end) h.FallingDown:connect(function(state) onState(state, sFallingDown) end) -- regeneration while true do 	local s = wait(1) 	local health=h.Health 	if health>0 and health<h.MaxHealth then 		health = health + 0.01*s*h.MaxHealth 		if health*1.05 < h.MaxHealth then 			h.Health = health 		else 			h.Health = h.MaxHealth 		end 	end end </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>
|
||||
@@ -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 local Torso = Figure:findFirstChild("Torso") 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
Reference in New Issue
Block a user