Initial commit

This commit is contained in:
2025-12-17 16:47:48 +00:00
commit 13813f3363
4964 changed files with 1079753 additions and 0 deletions

View File

@@ -0,0 +1,618 @@
-- This script creates almost all gui elements found in the backpack (warning: there are a lot!)
-- TODO: automate this process
-- if game.CoreGui.Version < 3 then return end -- peace out if we aren't using the right client
local gui = script.Parent
-- A couple of necessary functions
local function waitForChild(instance, name)
while not instance:FindFirstChild(name) do
instance.ChildAdded:wait()
end
end
local function waitForProperty(instance, property)
while not instance[property] do
instance.Changed:wait()
end
end
local function IsTouchDevice()
-- local touchEnabled = false
-- pcall(function() touchEnabled = Game:GetService('UserInputService').TouchEnabled end)
return false -- touchEnabled
end
local function IsPhone()
--[[
if gui.AbsoluteSize.Y <= 320 then
return true
end
]]--
return false
end
waitForChild(game,"Players")
waitForProperty(game.Players,"LocalPlayer")
local player = game.Players.LocalPlayer
-- First up is the current loadout
local CurrentLoadout = Instance.new("Frame")
CurrentLoadout.Name = "CurrentLoadout"
CurrentLoadout.Position = UDim2.new(0.5, -300, 1, -85)
CurrentLoadout.Size = UDim2.new(0, 600, 0, 54)
CurrentLoadout.BackgroundTransparency = 1
CurrentLoadout.RobloxLocked = true
CurrentLoadout.Parent = gui
local CLBackground = Instance.new('ImageLabel')
CLBackground.Name = 'Background';
CLBackground.Size = UDim2.new(1.2, 0, 1.2, 0);
CLBackground.Image = "ayaasset://textures/2015/BackpackBuilder/CLBackground.png"
CLBackground.BackgroundTransparency = 1.0;
CLBackground.Position = UDim2.new(-0.1, 0, -0.1, 0);
CLBackground.ZIndex = 0.0;
CLBackground.Parent = CurrentLoadout
CLBackground.Visible = false
local BackgroundUp = Instance.new('ImageLabel')
BackgroundUp.Size = UDim2.new(1, 0, 0.025, 1)
BackgroundUp.Position = UDim2.new(0, 0, 0, 0)
BackgroundUp.Image = 'ayaasset://textures/2013/BackpackBuilder/BackgroundUp.png'
BackgroundUp.BackgroundTransparency = 1.0
BackgroundUp.Parent = CLBackground
local Debounce = Instance.new("BoolValue")
Debounce.Name = "Debounce"
Debounce.RobloxLocked = true
Debounce.Parent = CurrentLoadout
local BackpackButton = Instance.new("ImageButton")
BackpackButton.RobloxLocked = true
BackpackButton.Visible = false
BackpackButton.Name = "BackpackButton"
BackpackButton.BackgroundTransparency = 1
BackpackButton.Image = "ayaasset://textures/2013/BackpackBuilder/BackpackButton.png"
BackpackButton.Position = UDim2.new(0.5, -60, 1, -108)
BackpackButton.Size = UDim2.new(0, 120, 0, 18)
waitForChild(gui,"ControlFrame")
BackpackButton.Parent = gui.ControlFrame
local NumSlots = 9
if IsPhone() then
NumSlots = 3
CurrentLoadout.Size = UDim2.new(0, 180, 0, 54)
CurrentLoadout.Position = UDim2.new(0.5, -90, 1, -85)
end
for i = 0, NumSlots do
local slotFrame = Instance.new("Frame")
slotFrame.RobloxLocked = true
slotFrame.BackgroundColor3 = Color3.new(0,0,0)
slotFrame.BackgroundTransparency = 1
slotFrame.BorderColor3 = Color3.new(1, 1, 1)
slotFrame.Name = "Slot" .. tostring(i)
slotFrame.ZIndex = 4.0
if i == 0 then
slotFrame.Position = UDim2.new(0.9, 0, 0, 0)
else
slotFrame.Position = UDim2.new((i - 1) * 0.1, (i-1)* 6,0,0)
end
slotFrame.Size = UDim2.new(0, 54, 1, 0)
slotFrame.Parent = CurrentLoadout
--[[
if gui.AbsoluteSize.Y <= 320 then
slotFrame.Position = UDim2.new(0, (i-1)* 60, 0, -50)
print('Well got here', slotFrame, slotFrame.Position.X.Scale, slotFrame.Position.X.Offset)
end
if gui.AbsoluteSize.Y <= 320 and i == 0 then
slotFrame:Destroy()
end ]]--
end
local TempSlot = Instance.new("ImageButton")
TempSlot.Name = "TempSlot"
TempSlot.Active = true
TempSlot.Size = UDim2.new(1,0,1,0)
TempSlot.BackgroundTransparency = 1.0
TempSlot.Style = 'Custom'
TempSlot.Visible = false
TempSlot.RobloxLocked = true
TempSlot.Parent = CurrentLoadout
TempSlot.ZIndex = 4.0
local slotBackground = Instance.new('ImageLabel')
slotBackground.Name = 'Background'
slotBackground.BackgroundTransparency = 1.0
slotBackground.Image = 'ayaasset://textures/2013/BackpackBuilder/SlotBackground.png'
slotBackground.Size = UDim2.new(1, 0, 1, 0)
slotBackground.Parent = TempSlot
local HighLight = Instance.new('ImageLabel')
HighLight.Name = 'Highlight'
HighLight.BackgroundTransparency = 1.0
HighLight.Image = 'ayaasset://textures/2015/BackpackBuilder/HighLight.png'
HighLight.Size = UDim2.new(1, 0, 1, 0)
--HighLight.Parent = TempSlot
HighLight.Visible = false
-- TempSlot Children
local GearReference = Instance.new("ObjectValue")
GearReference.Name = "GearReference"
GearReference.RobloxLocked = true
GearReference.Parent = TempSlot
local ToolTipLabel = Instance.new("TextLabel")
ToolTipLabel.Name = "ToolTipLabel"
ToolTipLabel.RobloxLocked = true
ToolTipLabel.Text = ""
ToolTipLabel.BackgroundTransparency = 0.5
ToolTipLabel.BorderSizePixel = 0
ToolTipLabel.Visible = false
ToolTipLabel.TextColor3 = Color3.new(1,1,1)
ToolTipLabel.BackgroundColor3 = Color3.new(0,0,0)
ToolTipLabel.TextStrokeTransparency = 0
ToolTipLabel.Font = Enum.Font.ArialBold
ToolTipLabel.FontSize = Enum.FontSize.Size14
--ToolTipLabel.TextWrap = true
ToolTipLabel.Size = UDim2.new(1,60,0,20)
ToolTipLabel.Position = UDim2.new(0,-30,0,-30)
ToolTipLabel.Parent = TempSlot
local Kill = Instance.new("BoolValue")
Kill.Name = "Kill"
Kill.RobloxLocked = true
Kill.Parent = TempSlot
local GearImage = Instance.new("ImageLabel")
GearImage.Name = "GearImage"
GearImage.BackgroundTransparency = 1
GearImage.Position = UDim2.new(0, 0, 0, 0)
GearImage.Size = UDim2.new(1, 0, 1, 0)
GearImage.ZIndex = 5.0
GearImage.RobloxLocked = true
GearImage.Parent = TempSlot
local SlotNumber = Instance.new("TextLabel")
SlotNumber.Name = "SlotNumber"
SlotNumber.BackgroundTransparency = 1
SlotNumber.BorderSizePixel = 0
SlotNumber.Font = Enum.Font.ArialBold
SlotNumber.FontSize = Enum.FontSize.Size18
SlotNumber.Position = UDim2.new(0, 0, 0, 0)
SlotNumber.Size = UDim2.new(0,10,0,15)
SlotNumber.TextColor3 = Color3.new(1,1,1)
SlotNumber.TextTransparency = 0
SlotNumber.TextXAlignment = Enum.TextXAlignment.Left
SlotNumber.TextYAlignment = Enum.TextYAlignment.Bottom
SlotNumber.RobloxLocked = true
SlotNumber.Parent = TempSlot
SlotNumber.ZIndex = 5
if IsTouchDevice() then
SlotNumber.Visible = false
end
local SlotNumberDownShadow = SlotNumber:Clone()
SlotNumberDownShadow.Name = "SlotNumberDownShadow"
SlotNumberDownShadow.TextColor3 = Color3.new(0,0,0)
SlotNumberDownShadow.Position = UDim2.new(0, 1, 0, -1)
SlotNumberDownShadow.Parent = TempSlot
SlotNumberDownShadow.ZIndex = 2
local SlotNumberUpShadow = SlotNumberDownShadow:Clone()
SlotNumberUpShadow.Name = "SlotNumberUpShadow"
SlotNumberUpShadow.Position = UDim2.new(0, -1, 0, -1)
SlotNumberUpShadow.Parent = TempSlot
local GearText = Instance.new("TextLabel")
GearText.RobloxLocked = true
GearText.Name = "GearText"
GearText.BackgroundTransparency = 1
GearText.Font = Enum.Font.Arial
GearText.FontSize = Enum.FontSize.Size14
GearText.Position = UDim2.new(0,-8,0,-8)
GearText.Size = UDim2.new(1,16,1,16)
GearText.Text = ""
GearText.TextColor3 = Color3.new(1,1,1)
GearText.TextWrap = true
GearText.Parent = TempSlot
GearText.ZIndex = 5.0
--- Great, now lets make the inventory!
local Backpack = Instance.new("Frame")
Backpack.RobloxLocked = true
Backpack.Visible = false
Backpack.Name = "Backpack"
Backpack.Position = UDim2.new(0.5, 0, 0.5, 0)
Backpack.BackgroundColor3 = Color3.new(32/255, 32/255, 32/255)
Backpack.BackgroundTransparency = 0.0
Backpack.BorderSizePixel = 0
Backpack.Parent = gui
Backpack.Active = true
-- Backpack Children
local SwapSlot = Instance.new("BoolValue")
SwapSlot.RobloxLocked = true
SwapSlot.Name = "SwapSlot"
SwapSlot.Parent = Backpack
-- SwapSlot Children
local Slot = Instance.new("IntValue")
Slot.RobloxLocked = true
Slot.Name = "Slot"
Slot.Parent = SwapSlot
local GearButton = Instance.new("ObjectValue")
GearButton.RobloxLocked = true
GearButton.Name = "GearButton"
GearButton.Parent = SwapSlot
local Tabs = Instance.new("Frame")
Tabs.Name = "Tabs"
Tabs.Visible = false
Tabs.Active = false
Tabs.RobloxLocked = true
Tabs.BackgroundColor3 = Color3.new(0,0,0)
Tabs.BackgroundTransparency = 0.08
Tabs.BorderSizePixel = 0
Tabs.Position = UDim2.new(0,0,-0.1,-4)
Tabs.Size = UDim2.new(1,0,0.1,4)
Tabs.Parent = Backpack
-- Tabs Children
local tabLine = Instance.new("Frame")
tabLine.RobloxLocked = true
tabLine.Name = "TabLine"
tabLine.BackgroundColor3 = Color3.new(53/255, 53/255, 53/255)
tabLine.BorderSizePixel = 0
tabLine.Position = UDim2.new(0,5,1,-4)
tabLine.Size = UDim2.new(1,-10,0,4)
tabLine.ZIndex = 2
tabLine.Parent = Tabs
local InventoryButton = Instance.new("TextButton")
InventoryButton.RobloxLocked = true
InventoryButton.Name = "InventoryButton"
InventoryButton.Size = UDim2.new(0,60,0,30)
InventoryButton.Position = UDim2.new(0,7,1,-31)
InventoryButton.BackgroundColor3 = Color3.new(1,1,1)
InventoryButton.BorderColor3 = Color3.new(1,1,1)
InventoryButton.Font = Enum.Font.ArialBold
InventoryButton.FontSize = Enum.FontSize.Size18
InventoryButton.Text = "Gear"
InventoryButton.AutoButtonColor = false
InventoryButton.TextColor3 = Color3.new(0,0,0)
InventoryButton.Selected = true
InventoryButton.Active = true
InventoryButton.ZIndex = 3
InventoryButton.Parent = Tabs
--[[
if game.CoreGui.Version >= 8 then
local WardrobeButton = Instance.new("TextButton")
WardrobeButton.RobloxLocked = true
WardrobeButton.Name = "WardrobeButton"
WardrobeButton.Size = UDim2.new(0,90,0,30)
WardrobeButton.Position = UDim2.new(0,77,1,-31)
WardrobeButton.BackgroundColor3 = Color3.new(0,0,0)
WardrobeButton.BorderColor3 = Color3.new(1,1,1)
WardrobeButton.Font = Enum.Font.ArialBold
WardrobeButton.FontSize = Enum.FontSize.Size18
WardrobeButton.Text = "Wardrobe"
WardrobeButton.AutoButtonColor = false
WardrobeButton.TextColor3 = Color3.new(1,1,1)
WardrobeButton.Selected = false
WardrobeButton.Active = true
WardrobeButton.Parent = Tabs
end]]--
local closeButton = Instance.new("TextButton")
closeButton.RobloxLocked = true
closeButton.Name = "CloseButton"
closeButton.Font = Enum.Font.ArialBold
closeButton.FontSize = Enum.FontSize.Size24
closeButton.Position = UDim2.new(1,-33,0,4)
closeButton.Size = UDim2.new(0,30,0,30)
closeButton.Style = Enum.ButtonStyle.RobloxButton
closeButton.Text = ""
closeButton.TextColor3 = Color3.new(1,1,1)
closeButton.Parent = Tabs
closeButton.Modal = true
--closeButton child
local XImage = Instance.new("ImageLabel")
XImage.RobloxLocked = true
XImage.Name = "XImage"
XImage.Image = "ayaasset://textures/2015/BackpackBuilder/XImage.png" --TODO: move to ayaasset
XImage.BackgroundTransparency = 1
XImage.Position = UDim2.new(-.25,-1,-.25,-1)
XImage.Size = UDim2.new(1.5,2,1.5,2)
XImage.ZIndex = 2
XImage.Parent = closeButton
-- Generic Search gui used across backpack
local SearchFrame = Instance.new("Frame")
SearchFrame.RobloxLocked = true
SearchFrame.Name = "SearchFrame"
SearchFrame.BackgroundTransparency = 1
SearchFrame.Position = UDim2.new(1,-220,0,2)
SearchFrame.Size = UDim2.new(0,220,0,24)
SearchFrame.Parent = Backpack
-- SearchFrame Children
local SearchButton = Instance.new("ImageButton")
SearchButton.RobloxLocked = true
SearchButton.Name = "SearchButton"
SearchButton.Size = UDim2.new(0,25,0,25)
SearchButton.BackgroundTransparency = 1
SearchButton.Image = "ayaasset://textures/ui/SearchIcon.png"
SearchButton.Parent = SearchFrame
local SearchBoxFrame = Instance.new("TextButton")
SearchBoxFrame.RobloxLocked = true
SearchBoxFrame.Position = UDim2.new(0,25,0,0)
SearchBoxFrame.Size = UDim2.new(1,-28,0,26)
SearchBoxFrame.Name = "SearchBoxFrame"
SearchBoxFrame.Text = ""
SearchBoxFrame.Style = Enum.ButtonStyle.RobloxButton
SearchBoxFrame.Parent = SearchFrame
-- SearchBoxFrame Children
local SearchBox = Instance.new("TextBox")
SearchBox.RobloxLocked = true
SearchBox.Name = "SearchBox"
SearchBox.BackgroundTransparency = 1
SearchBox.Font = Enum.Font.ArialBold
SearchBox.FontSize = Enum.FontSize.Size12
SearchBox.Position = UDim2.new(0,-5,0,-5)
SearchBox.Size = UDim2.new(1,10,1,10)
SearchBox.TextColor3 = Color3.new(1,1,1)
SearchBox.TextXAlignment = Enum.TextXAlignment.Left
SearchBox.ZIndex = 2
SearchBox.TextWrap = true
SearchBox.Text = "Search..."
SearchBox.Parent = SearchBoxFrame
local ResetButton = Instance.new("TextButton")
ResetButton.RobloxLocked = true
ResetButton.Visible = false
ResetButton.Name = "ResetButton"
ResetButton.Position = UDim2.new(1,-26,0,3)
ResetButton.Size = UDim2.new(0,20,0,20)
ResetButton.Style = Enum.ButtonStyle.RobloxButtonDefault
ResetButton.Text = "X"
ResetButton.TextColor3 = Color3.new(1,1,1)
ResetButton.Font = Enum.Font.ArialBold
ResetButton.FontSize = Enum.FontSize.Size18
ResetButton.ZIndex = 3
ResetButton.Parent = SearchFrame
------------------------------- GEAR -------------------------------------------------------
local Gear = Instance.new("Frame")
Gear.Name = "Gear"
Gear.RobloxLocked = true
Gear.BackgroundTransparency = 1
Gear.Size = UDim2.new(1,0,1,0)
Gear.Parent = Backpack
-- Gear Children
local AssetsList = Instance.new("Frame")
AssetsList.RobloxLocked = true
AssetsList.Name = "AssetsList"
AssetsList.BackgroundTransparency = 1
AssetsList.Size = UDim2.new(0.2,0,1,0)
AssetsList.Style = Enum.FrameStyle.RobloxSquare
AssetsList.Visible = false
AssetsList.Parent = Gear
local GearGrid = Instance.new("Frame")
GearGrid.RobloxLocked = true
GearGrid.Name = "GearGrid"
GearGrid.Size = UDim2.new(0.95, 0, 1, 0)
GearGrid.BackgroundTransparency = 1
GearGrid.Parent = Gear
local GearButton = Instance.new("ImageButton")
GearButton.RobloxLocked = true
GearButton.Visible = false
GearButton.Name = "GearButton"
GearButton.Size = UDim2.new(0, 54, 0, 54)
GearButton.Style = 'Custom'
GearButton.Parent = GearGrid
GearButton.BackgroundTransparency = 1.0
local slotBackground = Instance.new('ImageLabel')
slotBackground.Name = 'Background'
slotBackground.BackgroundTransparency = 1.0
slotBackground.Image = 'ayaasset://textures/2013/BackpackBuilder/SlotBackground.png'
slotBackground.Size = UDim2.new(1, 0, 1, 0)
slotBackground.Parent = GearButton
-- GearButton Children
local GearReference = Instance.new("ObjectValue")
GearReference.RobloxLocked = true
GearReference.Name = "GearReference"
GearReference.Parent = GearButton
local GreyOutButton = Instance.new("Frame")
GreyOutButton.RobloxLocked = true
GreyOutButton.Name = "GreyOutButton"
GreyOutButton.BackgroundTransparency = 0.5
GreyOutButton.Size = UDim2.new(1,0,1,0)
GreyOutButton.Active = true
GreyOutButton.Visible = false
GreyOutButton.ZIndex = 3
GreyOutButton.Parent = GearButton
local GearText = Instance.new("TextLabel")
GearText.RobloxLocked = true
GearText.Name = "GearText"
GearText.BackgroundTransparency = 1
GearText.Font = Enum.Font.Arial
GearText.FontSize = Enum.FontSize.Size14
GearText.Position = UDim2.new(0,-8,0,-8)
GearText.Size = UDim2.new(1,16,1,16)
GearText.Text = ""
GearText.ZIndex = 2
GearText.TextColor3 = Color3.new(1,1,1)
GearText.TextWrap = true
GearText.Parent = GearButton
local GearGridScrollingArea = Instance.new("Frame")
GearGridScrollingArea.RobloxLocked = true
GearGridScrollingArea.Name = "GearGridScrollingArea"
GearGridScrollingArea.Position = UDim2.new(1, -19, 0, 35)
GearGridScrollingArea.Size = UDim2.new(0, 17, 1, -45)
GearGridScrollingArea.BackgroundTransparency = 1
GearGridScrollingArea.Parent = Gear
local GearLoadouts = Instance.new("Frame")
GearLoadouts.RobloxLocked = true
GearLoadouts.Name = "GearLoadouts"
GearLoadouts.BackgroundTransparency = 1
GearLoadouts.Position = UDim2.new(0.7,23,0.5,1)
GearLoadouts.Size = UDim2.new(0.3,-23,0.5,-1)
GearLoadouts.Parent = Gear
GearLoadouts.Visible = false
-- GearLoadouts Children
local GearLoadoutsHeader = Instance.new("Frame")
GearLoadoutsHeader.RobloxLocked = true
GearLoadoutsHeader.Name = "GearLoadoutsHeader"
GearLoadoutsHeader.BackgroundColor3 = Color3.new(0,0,0)
GearLoadoutsHeader.BackgroundTransparency = 0.2
GearLoadoutsHeader.BorderColor3 = Color3.new(1,0,0)
GearLoadoutsHeader.Size = UDim2.new(1,2,0.15,-1)
GearLoadoutsHeader.Parent = GearLoadouts
-- GearLoadoutsHeader Children
local LoadoutsHeaderText = Instance.new("TextLabel")
LoadoutsHeaderText.RobloxLocked = true
LoadoutsHeaderText.Name = "LoadoutsHeaderText"
LoadoutsHeaderText.BackgroundTransparency = 1
LoadoutsHeaderText.Font = Enum.Font.ArialBold
LoadoutsHeaderText.FontSize = Enum.FontSize.Size18
LoadoutsHeaderText.Size = UDim2.new(1,0,1,0)
LoadoutsHeaderText.Text = "Loadouts"
LoadoutsHeaderText.TextColor3 = Color3.new(1,1,1)
LoadoutsHeaderText.Parent = GearLoadoutsHeader
local GearLoadoutsScrollingArea = GearGridScrollingArea:clone()
GearLoadoutsScrollingArea.RobloxLocked = true
GearLoadoutsScrollingArea.Name = "GearLoadoutsScrollingArea"
GearLoadoutsScrollingArea.Position = UDim2.new(1,-15,0.15,2)
GearLoadoutsScrollingArea.Size = UDim2.new(0,17,0.85,-2)
GearLoadoutsScrollingArea.Parent = GearLoadouts
local LoadoutsList = Instance.new("Frame")
LoadoutsList.RobloxLocked = true
LoadoutsList.Name = "LoadoutsList"
LoadoutsList.Position = UDim2.new(0,0,0.15,2)
LoadoutsList.Size = UDim2.new(1,-17,0.85,-2)
LoadoutsList.Style = Enum.FrameStyle.RobloxSquare
LoadoutsList.Parent = GearLoadouts
local GearPreview = Instance.new("Frame")
GearPreview.RobloxLocked = true
GearPreview.Name = "GearPreview"
GearPreview.Position = UDim2.new(0.7,23,0,0)
GearPreview.Size = UDim2.new(0.3,-28,0.5,-1)
GearPreview.BackgroundTransparency = 1
GearPreview.ZIndex = 7
GearPreview.Parent = Gear
-- GearPreview Children
local GearStats = Instance.new("Frame")
GearStats.RobloxLocked = true
GearStats.Name = "GearStats"
GearStats.BackgroundTransparency = 1
GearStats.Position = UDim2.new(0,0,0.75,0)
GearStats.Size = UDim2.new(1,0,0.25,0)
GearStats.ZIndex = 8
GearStats.Parent = GearPreview
-- GearStats Children
local GearName = Instance.new("TextLabel")
GearName.RobloxLocked = true
GearName.Name = "GearName"
GearName.BackgroundTransparency = 1
GearName.Font = Enum.Font.ArialBold
GearName.FontSize = Enum.FontSize.Size18
GearName.Position = UDim2.new(0,-3,0,0)
GearName.Size = UDim2.new(1,6,1,5)
GearName.Text = ""
GearName.TextColor3 = Color3.new(1,1,1)
GearName.TextWrap = true
GearName.ZIndex = 9
GearName.Parent = GearStats
local GearImage = Instance.new("ImageLabel")
GearImage.RobloxLocked = true
GearImage.Name = "GearImage"
GearImage.Image = ""
GearImage.BackgroundTransparency = 1
GearImage.Position = UDim2.new(0.125,0,0,0)
GearImage.Size = UDim2.new(0.75,0,0.75,0)
GearImage.ZIndex = 8
GearImage.Parent = GearPreview
--GearImage Children
local GearIcons = Instance.new("Frame")
GearIcons.BackgroundColor3 = Color3.new(0,0,0)
GearIcons.BackgroundTransparency = 0.5
GearIcons.BorderSizePixel = 0
GearIcons.RobloxLocked = true
GearIcons.Name = "GearIcons"
GearIcons.Position = UDim2.new(0.4,2,0.85,-2)
GearIcons.Size = UDim2.new(0.6,0,0.15,0)
GearIcons.Visible = false
GearIcons.ZIndex = 9
GearIcons.Parent = GearImage
-- GearIcons Children
local GenreImage = Instance.new("ImageLabel")
GenreImage.RobloxLocked = true
GenreImage.Name = "GenreImage"
GenreImage.BackgroundColor3 = Color3.new(102/255,153/255,1)
GenreImage.BackgroundTransparency = 0.5
GenreImage.BorderSizePixel = 0
GenreImage.Size = UDim2.new(0.25,0,1,0)
GenreImage.Parent = GearIcons
local AttributeOneImage = GenreImage:clone()
AttributeOneImage.RobloxLocked = true
AttributeOneImage.Name = "AttributeOneImage"
AttributeOneImage.BackgroundColor3 = Color3.new(1,51/255,0)
AttributeOneImage.Position = UDim2.new(0.25,0,0,0)
AttributeOneImage.Parent = GearIcons
local AttributeTwoImage = GenreImage:clone()
AttributeTwoImage.RobloxLocked = true
AttributeTwoImage.Name = "AttributeTwoImage"
AttributeTwoImage.BackgroundColor3 = Color3.new(153/255,1,153/255)
AttributeTwoImage.Position = UDim2.new(0.5,0,0,0)
AttributeTwoImage.Parent = GearIcons
local AttributeThreeImage = GenreImage:clone()
AttributeThreeImage.RobloxLocked = true
AttributeThreeImage.Name = "AttributeThreeImage"
AttributeThreeImage.BackgroundColor3 = Color3.new(0,0.5,0.5)
AttributeThreeImage.Position = UDim2.new(0.75,0,0,0)
AttributeThreeImage.Parent = GearIcons
-- no need for this to stick around
script:Destroy()

View File

@@ -0,0 +1,876 @@
-- A couple of necessary functions
local function waitForChild(instance, name)
assert(instance)
assert(name)
while not instance:FindFirstChild(name) do
print('Waiting for ...', instance, name)
instance.ChildAdded:wait()
end
return instance:FindFirstChild(name)
end
local function waitForProperty(instance, property)
assert(instance)
assert(property)
while not instance[property] do
instance.Changed:wait()
end
end
local function IsTouchDevice()
local touchEnabled = false
pcall(function() touchEnabled = Game:GetService('UserInputService').TouchEnabled end)
return touchEnabled
end
waitForChild(game,"Players")
waitForProperty(game.Players,"LocalPlayer")
local player = game.Players.LocalPlayer
local RbxGui, msg = LoadLibrary("RbxGui")
if not RbxGui then print("could not find RbxGui!") return end
--- Begin Locals
local StaticTabName = "gear"
local backpack = script.Parent
local screen = script.Parent.Parent
local backpackItems = {}
local buttons = {}
local debounce = false
local browsingMenu = false
local mouseEnterCons = {}
local mouseClickCons = {}
local characterChildAddedCon = nil
local characterChildRemovedCon = nil
local backpackAddCon = nil
local playerBackpack = waitForChild(player,"Backpack")
waitForChild(backpack,"Tabs")
waitForChild(backpack,"Gear")
local gearPreview = waitForChild(backpack.Gear,"GearPreview")
local scroller = waitForChild(backpack.Gear,"GearGridScrollingArea")
local currentLoadout = waitForChild(backpack.Parent,"CurrentLoadout")
local grid = waitForChild(backpack.Gear,"GearGrid")
local gearButton = waitForChild(grid,"GearButton")
local swapSlot = waitForChild(script.Parent,"SwapSlot")
local backpackManager = waitForChild(script.Parent,"CoreScripts/2013/BackpackManager")
local backpackOpenEvent = waitForChild(backpackManager,"BackpackOpenEvent")
local backpackCloseEvent = waitForChild(backpackManager,"BackpackCloseEvent")
local tabClickedEvent = waitForChild(backpackManager,"TabClickedEvent")
local resizeEvent = waitForChild(backpackManager,"ResizeEvent")
local searchRequestedEvent = waitForChild(backpackManager,"SearchRequestedEvent")
local tellBackpackReadyFunc = waitForChild(backpackManager,"BackpackReady")
-- creating scroll bar early as to make sure items get placed correctly
local scrollFrame, scrollUp, scrollDown, recalculateScroll = RbxGui.CreateScrollingFrame(nil, "grid", Vector2.new(6, 6))
scrollFrame.Position = UDim2.new(0,0,0,30)
scrollFrame.Size = UDim2.new(1,0,1,-30)
scrollFrame.Parent = backpack.Gear.GearGrid
local scrollBar = Instance.new("Frame")
scrollBar.Name = "ScrollBar"
scrollBar.BackgroundTransparency = 0.9
scrollBar.BackgroundColor3 = Color3.new(1,1,1)
scrollBar.BorderSizePixel = 0
scrollBar.Size = UDim2.new(0, 17, 1, -36)
scrollBar.Position = UDim2.new(0,0,0,18)
scrollBar.Parent = scroller
scrollDown.Position = UDim2.new(0,0,1,-17)
scrollUp.Parent = scroller
scrollDown.Parent = scroller
local scrollFrameLoadout, scrollUpLoadout, scrollDownLoadout, recalculateScrollLoadout = RbxGui.CreateScrollingFrame()
scrollFrameLoadout.Position = UDim2.new(0,0,0,0)
scrollFrameLoadout.Size = UDim2.new(1,0,1,0)
scrollFrameLoadout.Parent = backpack.Gear.GearLoadouts.LoadoutsList
local LoadoutButton = Instance.new("TextButton")
LoadoutButton.RobloxLocked = true
LoadoutButton.Name = "LoadoutButton"
LoadoutButton.Font = Enum.Font.ArialBold
LoadoutButton.FontSize = Enum.FontSize.Size14
LoadoutButton.Position = UDim2.new(0,0,0,0)
LoadoutButton.Size = UDim2.new(1,0,0,32)
LoadoutButton.Style = Enum.ButtonStyle.RobloxButton
LoadoutButton.Text = "Loadout #1"
LoadoutButton.TextColor3 = Color3.new(1,1,1)
LoadoutButton.Parent = scrollFrameLoadout
local LoadoutButtonTwo = LoadoutButton:clone()
LoadoutButtonTwo.Text = "Loadout #2"
LoadoutButtonTwo.Parent = scrollFrameLoadout
local LoadoutButtonThree = LoadoutButton:clone()
LoadoutButtonThree.Text = "Loadout #3"
LoadoutButtonThree.Parent = scrollFrameLoadout
local LoadoutButtonFour = LoadoutButton:clone()
LoadoutButtonFour.Text = "Loadout #4"
LoadoutButtonFour.Parent = scrollFrameLoadout
local scrollBarLoadout = Instance.new("Frame")
scrollBarLoadout.Name = "ScrollBarLoadout"
scrollBarLoadout.BackgroundTransparency = 0.9
scrollBarLoadout.BackgroundColor3 = Color3.new(1,1,1)
scrollBarLoadout.BorderSizePixel = 0
scrollBarLoadout.Size = UDim2.new(0, 17, 1, -36)
scrollBarLoadout.Position = UDim2.new(0,0,0,18)
scrollBarLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
scrollDownLoadout.Position = UDim2.new(0,0,1,-17)
scrollUpLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
scrollDownLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
-- Begin Functions
function removeFromMap(map,object)
for i = 1, #map do
if map[i] == object then
table.remove(map,i)
break
end
end
end
function robloxLock(instance)
instance.RobloxLocked = true
children = instance:GetChildren()
if children then
for i, child in ipairs(children) do
robloxLock(child)
end
end
end
function resize()
local size = 0
if gearPreview.AbsoluteSize.Y > gearPreview.AbsoluteSize.X then
size = gearPreview.AbsoluteSize.X * 0.75
else
size = gearPreview.AbsoluteSize.Y * 0.75
end
waitForChild(gearPreview,"GearImage")
gearPreview.GearImage.Size = UDim2.new(0,size,0,size)
gearPreview.GearImage.Position = UDim2.new(0,gearPreview.AbsoluteSize.X/2 - size/2,0.75,-size)
resizeGrid()
end
function addToGrid(child)
if not child:IsA("Tool") then
if not child:IsA("HopperBin") then
return
end
end
if child:FindFirstChild("RobloxBuildTool") then return end
for i,v in pairs(backpackItems) do -- check to see if we already have this gear registered
if v == child then return end
end
table.insert(backpackItems,child)
local changeCon = child.Changed:connect(function(prop)
if prop == "Name" then
if buttons[child] then
if buttons[child].Image == "" then
buttons[child].GearText.Text = child.Name
end
end
end
end)
local ancestryCon = nil
ancestryCon = child.AncestryChanged:connect(function(theChild,theParent)
local thisObject = nil
for k,v in pairs(backpackItems) do
if v == child then
thisObject = v
break
end
end
waitForProperty(player,"Character")
waitForChild(player,"Backpack")
if (child.Parent ~= player.Backpack and child.Parent ~= player.Character) then
if ancestryCon then ancestryCon:disconnect() end
if changeCon then changeCon:disconnect() end
for k,v in pairs(backpackItems) do
if v == thisObject then
if mouseEnterCons[buttons[v]] then mouseEnterCons[buttons[v]]:disconnect() end
if mouseClickCons[buttons[v]] then mouseClickCons[buttons[v]]:disconnect() end
buttons[v].Parent = nil
buttons[v] = nil
break
end
end
removeFromMap(backpackItems,thisObject)
resizeGrid()
else
resizeGrid()
end
updateGridActive()
end)
resizeGrid()
end
function buttonClick(button)
if button:FindFirstChild("UnequipContextMenu") and not button.Active then
button.UnequipContextMenu.Visible = true
browsingMenu = true
end
end
function previewGear(button)
if not browsingMenu then
gearPreview.Visible = false
gearPreview.GearImage.Image = button.Image
gearPreview.GearStats.GearName.Text = button.GearReference.Value.Name
end
end
function findEmptySlot()
local smallestNum = nil
local loadout = currentLoadout:GetChildren()
for i = 1, #loadout do
if loadout[i]:IsA("Frame") and #loadout[i]:GetChildren() <= 0 then
local frameNum = tonumber(string.sub(loadout[i].Name,5))
if frameNum == 0 then frameNum = 10 end
if not smallestNum or (smallestNum > frameNum) then
smallestNum = frameNum
end
end
end
if smallestNum == 10 then smallestNum = 0 end
return smallestNum
end
function checkForSwap(button,x,y)
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name,"Slot") then
if x >= loadoutChildren[i].AbsolutePosition.x and x <= (loadoutChildren[i].AbsolutePosition.x + loadoutChildren[i].AbsoluteSize.x) then
if y >= loadoutChildren[i].AbsolutePosition.y and y <= (loadoutChildren[i].AbsolutePosition.y + loadoutChildren[i].AbsoluteSize.y) then
local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
swapGearSlot(slot,button)
return true
end
end
end
end
return false
end
function resizeGrid()
for k,v in pairs(backpackItems) do
if not v:FindFirstChild("RobloxBuildTool") then
if not buttons[v] then
local buttonClone = gearButton:clone()
buttonClone.Parent = grid.ScrollingFrame
buttonClone.Visible = true
buttonClone.Image = v.TextureId
if buttonClone.Image == "" then
buttonClone.GearText.Text = v.Name
end
buttonClone.GearReference.Value = v
buttonClone.Draggable = true
buttons[v] = buttonClone
if not IsTouchDevice() then
local unequipMenu = getGearContextMenu()
unequipMenu.Visible = false
unequipMenu.Parent = buttonClone
end
local beginPos = nil
buttonClone.DragBegin:connect(function(value)
waitForChild(buttonClone, 'Background')
buttonClone['Background'].ZIndex = 10
buttonClone.ZIndex = 10
beginPos = value
end)
buttonClone.DragStopped:connect(function(x,y)
waitForChild(buttonClone, 'Background')
buttonClone['Background'].ZIndex = 1.0
buttonClone.ZIndex = 2
if beginPos ~= buttonClone.Position then
if not checkForSwap(buttonClone,x,y) then
buttonClone:TweenPosition(beginPos,Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true)
buttonClone.Draggable = false
delay(0.5,function()
buttonClone.Draggable = true
end)
else
buttonClone.Position = beginPos
end
end
end)
local clickTime = tick()
mouseEnterCons[buttonClone] = buttonClone.MouseEnter:connect(function() previewGear(buttonClone) end)
mouseClickCons[buttonClone] = buttonClone.MouseButton1Click:connect(function()
local newClickTime = tick()
if buttonClone.Active and (newClickTime - clickTime) < 0.5 then
local slot = findEmptySlot()
if slot then
buttonClone.ZIndex = 1
swapGearSlot(slot,buttonClone)
end
else
buttonClick(buttonClone)
end
clickTime = newClickTime
end)
end
end
end
recalculateScroll()
end
function showPartialGrid(subset)
for k,v in pairs(buttons) do
v.Parent = nil
end
if subset then
for k,v in pairs(subset) do
v.Parent = grid.ScrollingFrame
end
end
recalculateScroll()
end
function showEntireGrid()
for k,v in pairs(buttons) do
v.Parent = grid.ScrollingFrame
end
recalculateScroll()
end
function inLoadout(gear)
local children = currentLoadout:GetChildren()
for i = 1, #children do
if children[i]:IsA("Frame") then
local button = children[i]:GetChildren()
if #button > 0 then
if button[1].GearReference.Value and button[1].GearReference.Value == gear then
return true
end
end
end
end
return false
end
function updateGridActive()
for k,v in pairs(backpackItems) do
if buttons[v] then
local gear = nil
local gearRef = buttons[v]:FindFirstChild("GearReference")
if gearRef then gear = gearRef.Value end
if not gear then
buttons[v].Active = false
elseif inLoadout(gear) then
buttons[v].Active = false
else
buttons[v].Active = true
end
end
end
end
function centerGear(loadoutChildren)
local gearButtons = {}
local lastSlotAdd = nil
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") and #loadoutChildren[i]:GetChildren() > 0 then
if loadoutChildren[i].Name == "Slot0" then
lastSlotAdd = loadoutChildren[i]
else
table.insert(gearButtons, loadoutChildren[i])
end
end
end
if lastSlotAdd then table.insert(gearButtons,lastSlotAdd) end
local startPos = ( 1 - (#gearButtons * 0.1) ) / 2
for i = 1, #gearButtons do
gearButtons[i]:TweenPosition(UDim2.new(startPos + ((i - 1) * 0.1),0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
end
end
function tabClickHandler(tabName)
if tabName == StaticTabName then
backpackOpenHandler(tabName)
else
backpackCloseHandler(tabName)
end
end
function backpackOpenHandler(currentTab)
if currentTab and currentTab ~= StaticTabName then
backpack.Gear.Visible = false
return
end
backpack.Gear.Visible = true
updateGridActive()
resizeGrid()
resize()
tellBackpackReadyFunc:Invoke()
end
function backpackCloseHandler(currentTab)
if currentTab and currentTab ~= StaticTabName then
backpack.Gear.Visible = false
return
end
backpack.Gear.Visible = false
resizeGrid()
resize()
tellBackpackReadyFunc:Invoke()
end
function loadoutCheck(child, selectState)
if not child:IsA("ImageButton") then return end
for k,v in pairs(backpackItems) do
if buttons[v] then
if child:FindFirstChild("GearReference") and buttons[v]:FindFirstChild("GearReference") then
if buttons[v].GearReference.Value == child.GearReference.Value then
buttons[v].Active = selectState
break
end
end
end
end
end
function clearPreview()
gearPreview.GearImage.Image = ""
gearPreview.GearStats.GearName.Text = ""
end
function removeAllEquippedGear(physGear)
local stuff = player.Character:GetChildren()
for i = 1, #stuff do
if ( stuff[i]:IsA("Tool") or stuff[i]:IsA("HopperBin") ) and stuff[i] ~= physGear then
stuff[i].Parent = playerBackpack
end
end
end
function equipGear(physGear)
removeAllEquippedGear(physGear)
physGear.Parent = player.Character
updateGridActive()
end
function unequipGear(physGear)
physGear.Parent = playerBackpack
updateGridActive()
end
function highlight(button)
button.TextColor3 = Color3.new(0,0,0)
button.BackgroundColor3 = Color3.new(0.8,0.8,0.8)
end
function clearHighlight(button)
button.TextColor3 = Color3.new(1,1,1)
button.BackgroundColor3 = Color3.new(0,0,0)
end
function swapGearSlot(slot,gearButton)
if not swapSlot.Value then -- signal loadout to swap a gear out
swapSlot.Slot.Value = slot
swapSlot.GearButton.Value = gearButton
swapSlot.Value = true
updateGridActive()
end
end
local UnequipGearMenuClick = function(element, menu)
if type(element.Action) ~= "number" then return end
local num = element.Action
if num == 1 then -- remove from loadout
unequipGear(menu.Parent.GearReference.Value)
local inventoryButton = menu.Parent
local gearToUnequip = inventoryButton.GearReference.Value
local loadoutChildren = currentLoadout:GetChildren()
local slot = -1
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") then
local button = loadoutChildren[i]:GetChildren()
if button[1] and button[1].GearReference.Value == gearToUnequip then
slot = button[1].SlotNumber.Text
break
end
end
end
swapGearSlot(slot,nil)
end
end
function setupCharacterConnections()
if backpackAddCon then backpackAddCon:disconnect() end
backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
-- make sure we get all the children
local backpackChildren = game.Players.LocalPlayer.Backpack:GetChildren()
for i = 1, #backpackChildren do
addToGrid(backpackChildren[i])
end
if characterChildAddedCon then characterChildAddedCon:disconnect() end
characterChildAddedCon =
game.Players.LocalPlayer.Character.ChildAdded:connect(function(child)
addToGrid(child)
updateGridActive()
end)
if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
characterChildRemovedCon =
game.Players.LocalPlayer.Character.ChildRemoved:connect(function(child)
updateGridActive()
end)
wait()
centerGear(currentLoadout:GetChildren())
end
function removeCharacterConnections()
if characterChildAddedCon then characterChildAddedCon:disconnect() end
if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
if backpackAddCon then backpackAddCon:disconnect() end
end
function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
function filterGear(terms)
local filteredGear = {}
for k,v in pairs(backpackItems) do
if buttons[v] then
local gearString = string.lower(buttons[v].GearReference.Value.Name)
gearString = trim(gearString)
for i = 1, #terms do
if string.match(gearString,terms[i]) then
table.insert(filteredGear,buttons[v])
break
end
end
end
end
return filteredGear
end
function splitByWhitespace(text)
if type(text) ~= "string" then return nil end
local terms = {}
for token in string.gmatch(text, "[^%s]+") do
if string.len(token) > 0 then
table.insert(terms,token)
end
end
return terms
end
function showSearchGear(searchTerms)
if not backpack.Gear.Visible then return end -- currently not active tab
local searchTermTable = splitByWhitespace(searchTerms)
if searchTermTable and (#searchTermTable > 0) then
currSearchTerms = searchTermTable
else
currSearchTerms = nil
end
if searchTermTable == nil then
showEntireGrid()
return
end
local filteredButtons = filterGear(currSearchTerms)
showPartialGrid(filteredButtons)
end
function nukeBackpack()
while #buttons > 0 do
table.remove(buttons)
end
buttons = {}
while #backpackItems > 0 do
table.remove(backpackItems)
end
backpackItems = {}
local scrollingFrameChildren = grid.ScrollingFrame:GetChildren()
for i = 1, #scrollingFrameChildren do
scrollingFrameChildren[i]:remove()
end
end
function getGearContextMenu()
local gearContextMenu = Instance.new("Frame")
gearContextMenu.Active = true
gearContextMenu.Name = "UnequipContextMenu"
gearContextMenu.Size = UDim2.new(0,115,0,70)
gearContextMenu.Position = UDim2.new(0,-16,0,-16)
gearContextMenu.BackgroundTransparency = 1
gearContextMenu.Visible = false
local gearContextMenuButton = Instance.new("TextButton")
gearContextMenuButton.Name = "UnequipContextMenuButton"
gearContextMenuButton.Text = ""
gearContextMenuButton.Style = Enum.ButtonStyle.RobloxButtonDefault
gearContextMenuButton.ZIndex = 8
gearContextMenuButton.Size = UDim2.new(1, 0, 1, -20)
gearContextMenuButton.Visible = true
gearContextMenuButton.Parent = gearContextMenu
local elementHeight = 12
local contextMenuElements = {}
local contextMenuElementsName = {"Remove Hotkey"}
for i = 1, #contextMenuElementsName do
local element = {}
element.Type = "Button"
element.Text = contextMenuElementsName[i]
element.Action = i
element.DoIt = UnequipGearMenuClick
table.insert(contextMenuElements,element)
end
for i, contextElement in ipairs(contextMenuElements) do
local element = contextElement
if element.Type == "Button" then
local button = Instance.new("TextButton")
button.Name = "UnequipContextButton" .. i
button.BackgroundColor3 = Color3.new(0,0,0)
button.BorderSizePixel = 0
button.TextXAlignment = Enum.TextXAlignment.Left
button.Text = " " .. contextElement.Text
button.Font = Enum.Font.Arial
button.FontSize = Enum.FontSize.Size14
button.Size = UDim2.new(1, 8, 0, elementHeight)
button.Position = UDim2.new(0,0,0,elementHeight * i)
button.TextColor3 = Color3.new(1,1,1)
button.ZIndex = 9
button.Parent = gearContextMenuButton
if not IsTouchDevice() then
button.MouseButton1Click:connect(function()
if button.Active and not gearContextMenu.Parent.Active then
local success, result = pcall(function() element.DoIt(element, gearContextMenu) end)
browsingMenu = false
gearContextMenu.Visible = false
clearHighlight(button)
clearPreview()
end
end)
button.MouseEnter:connect(function()
if button.Active and gearContextMenu.Parent.Active then
highlight(button)
end
end)
button.MouseLeave:connect(function()
if button.Active and gearContextMenu.Parent.Active then
clearHighlight(button)
end
end)
end
contextElement.Button = button
contextElement.Element = button
elseif element.Type == "Label" then
local frame = Instance.new("Frame")
frame.Name = "ContextLabel" .. i
frame.BackgroundTransparency = 1
frame.Size = UDim2.new(1, 8, 0, elementHeight)
local label = Instance.new("TextLabel")
label.Name = "Text1"
label.BackgroundTransparency = 1
label.BackgroundColor3 = Color3.new(1,1,1)
label.BorderSizePixel = 0
label.TextXAlignment = Enum.TextXAlignment.Left
label.Font = Enum.Font.ArialBold
label.FontSize = Enum.FontSize.Size14
label.Position = UDim2.new(0.0, 0, 0, 0)
label.Size = UDim2.new(0.5, 0, 1, 0)
label.TextColor3 = Color3.new(1,1,1)
label.ZIndex = 9
label.Parent = frame
element.Label1 = label
if element.GetText2 then
label = Instance.new("TextLabel")
label.Name = "Text2"
label.BackgroundTransparency = 1
label.BackgroundColor3 = Color3.new(1,1,1)
label.BorderSizePixel = 0
label.TextXAlignment = Enum.TextXAlignment.Right
label.Font = Enum.Font.Arial
label.FontSize = Enum.FontSize.Size14
label.Position = UDim2.new(0.5, 0, 0, 0)
label.Size = UDim2.new(0.5, 0, 1, 0)
label.TextColor3 = Color3.new(1,1,1)
label.ZIndex = 9
label.Parent = frame
element.Label2 = label
end
frame.Parent = gearContextMenuButton
element.Label = frame
element.Element = frame
end
end
gearContextMenu.ZIndex = 4
gearContextMenu.MouseLeave:connect(function()
browsingMenu = false
gearContextMenu.Visible = false
clearPreview()
end)
robloxLock(gearContextMenu)
return gearContextMenu
end
function coreGuiChanged(coreGuiType,enabled)
if coreGuiType == Enum.CoreGuiType.Backpack or coreGuiType == Enum.CoreGuiType.All then
if not enabled then
backpack.Gear.Visible = false
end
end
end
local backpackChildren = player.Backpack:GetChildren()
for i = 1, #backpackChildren do
addToGrid(backpackChildren[i])
end
------------------------- Start Lifelong Connections -----------------------
resizeEvent.Event:connect(function(absSize)
if debounce then return end
debounce = true
wait()
resize()
resizeGrid()
debounce = false
end)
currentLoadout.ChildAdded:connect(function(child) loadoutCheck(child, false) end)
currentLoadout.ChildRemoved:connect(function(child) loadoutCheck(child, true) end)
currentLoadout.DescendantAdded:connect(function(descendant)
if not backpack.Visible and ( descendant:IsA("ImageButton") or descendant:IsA("TextButton") ) then
centerGear(currentLoadout:GetChildren())
end
end)
currentLoadout.DescendantRemoving:connect(function(descendant)
if not backpack.Visible and ( descendant:IsA("ImageButton") or descendant:IsA("TextButton") ) then
wait()
centerGear(currentLoadout:GetChildren())
end
end)
grid.MouseEnter:connect(function() clearPreview() end)
grid.MouseLeave:connect(function() clearPreview() end)
player.CharacterRemoving:connect(function()
removeCharacterConnections()
nukeBackpack()
end)
player.CharacterAdded:connect(function() setupCharacterConnections() end)
player.ChildAdded:connect(function(child)
if child:IsA("Backpack") then
playerBackpack = child
if backpackAddCon then backpackAddCon:disconnect() end
backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
end
end)
swapSlot.Changed:connect(function()
if not swapSlot.Value then
updateGridActive()
end
end)
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name,"Slot") then
loadoutChildren[i].ChildRemoved:connect(function()
updateGridActive()
end)
loadoutChildren[i].ChildAdded:connect(function()
updateGridActive()
end)
end
end
------------------------- End Lifelong Connections -----------------------
pcall(function()
coreGuiChanged(Enum.CoreGuiType.Backpack, Game.StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.Backpack))
Game.StarterGui.CoreGuiChangedSignal:connect(coreGuiChanged)
end)
resize()
resizeGrid()
-- make sure any items in the loadout are accounted for in inventory
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
loadoutCheck(loadoutChildren[i], false)
end
if not backpack.Visible then centerGear(currentLoadout:GetChildren()) end
-- make sure that inventory is listening to gear reparenting
if characterChildAddedCon == nil and game.Players.LocalPlayer["Character"] then
setupCharacterConnections()
end
if not backpackAddCon then
backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
end
backpackOpenEvent.Event:connect(backpackOpenHandler)
backpackCloseEvent.Event:connect(backpackCloseHandler)
tabClickedEvent.Event:connect(tabClickHandler)
searchRequestedEvent.Event:connect(showSearchGear)
recalculateScrollLoadout()

View File

@@ -0,0 +1,445 @@
-- This script manages context switches in the backpack (Gear to Wardrobe, etc.) and player state changes. Also manages global functions across different tabs (currently only search)
-- if game.CoreGui.Version < 7 then return end -- peace out if we aren't using the right client
-- basic functions
local function waitForChild(instance, name)
while not instance:FindFirstChild(name) do
instance.ChildAdded:wait()
end
return instance:FindFirstChild(name)
end
local function waitForProperty(instance, property)
while not instance[property] do
instance.Changed:wait()
end
end
-- don't do anything if we are in an empty game
waitForChild(game,"Players")
if #game.Players:GetChildren() < 1 then
game.Players.ChildAdded:wait()
end
-- make sure everything is loaded in before we do anything
-- get our local player
waitForProperty(game.Players,"LocalPlayer")
local player = game.Players.LocalPlayer
------------------------ Locals ------------------------------
local backpack = script.Parent
waitForChild(backpack,"Gear")
local screen = script.Parent.Parent
assert(screen:IsA("ScreenGui"))
waitForChild(backpack, "Tabs")
waitForChild(backpack.Tabs, "CloseButton")
local closeButton = backpack.Tabs.CloseButton
waitForChild(backpack.Tabs, "InventoryButton")
local inventoryButton = backpack.Tabs.InventoryButton
--[[
if game.CoreGui.Version >= 8 then
waitForChild(backpack.Tabs, "WardrobeButton")
local wardrobeButton = backpack.Tabs.WardrobeButton
end]]--
waitForChild(backpack.Parent,"ControlFrame")
local backpackButton = waitForChild(backpack.Parent.ControlFrame,"BackpackButton")
local currentTab = "gear"
local searchFrame = waitForChild(backpack,"SearchFrame")
waitForChild(backpack.SearchFrame,"SearchBoxFrame")
local searchBox = waitForChild(backpack.SearchFrame.SearchBoxFrame,"SearchBox")
local searchButton = waitForChild(backpack.SearchFrame,"SearchButton")
local resetButton = waitForChild(backpack.SearchFrame,"ResetButton")
local robloxGui = waitForChild(Game.CoreGui, 'RobloxGui')
local currentLoadout = waitForChild(robloxGui, 'CurrentLoadout')
local loadoutBackground = waitForChild(currentLoadout, 'Background')
local canToggle = true
local readyForNextEvent = true
local backpackIsOpen = false
local active = true
local disabledByDeveloper = false
local humanoidDiedCon = nil
local backpackButtonPos
local guiTweenSpeed = 0.25 -- how quickly we open/close the backpack
local searchDefaultText = "Search..."
local tilde = "~"
local backquote = "`"
local backpackSize = UDim2.new(0, 600, 0, 400)
if robloxGui.AbsoluteSize.Y <= 320 then
backpackSize = UDim2.new(0, 200, 0, 140)
end
------------------------ End Locals ---------------------------
---------------------------------------- Public Event Setup ----------------------------------------
function createPublicEvent(eventName)
assert(eventName, "eventName is nil")
assert(tostring(eventName),"eventName is not a string")
local newEvent = Instance.new("BindableEvent")
newEvent.Name = tostring(eventName)
newEvent.Parent = script
return newEvent
end
function createPublicFunction(funcName, invokeFunc)
assert(funcName, "funcName is nil")
assert(tostring(funcName), "funcName is not a string")
assert(invokeFunc, "invokeFunc is nil")
assert(type(invokeFunc) == "function", "invokeFunc should be of type 'function'")
local newFunction = Instance.new("BindableFunction")
newFunction.Name = tostring(funcName)
newFunction.OnInvoke = invokeFunc
newFunction.Parent = script
return newFunction
end
-- Events
local resizeEvent = createPublicEvent("ResizeEvent")
local backpackOpenEvent = createPublicEvent("BackpackOpenEvent")
local backpackCloseEvent = createPublicEvent("BackpackCloseEvent")
local tabClickedEvent = createPublicEvent("TabClickedEvent")
local searchRequestedEvent = createPublicEvent("SearchRequestedEvent")
---------------------------------------- End Public Event Setup ----------------------------------------
--------------------------- Internal Functions ----------------------------------------
function deactivateBackpack()
backpack.Visible = false
active = false
end
function activateBackpack()
initHumanoidDiedConnections()
active = true
backpack.Visible = backpackIsOpen
if backpackIsOpen then
toggleBackpack()
end
end
function initHumanoidDiedConnections()
if humanoidDiedCon then
humanoidDiedCon:disconnect()
end
waitForProperty(game.Players.LocalPlayer,"Character")
waitForChild(game.Players.LocalPlayer.Character,"Humanoid")
humanoidDiedCon = game.Players.LocalPlayer.Character.Humanoid.Died:connect(deactivateBackpack)
end
local hideBackpack = function()
backpackIsOpen = false
readyForNextEvent = false
backpackButton.Selected = false
resetSearch()
backpackCloseEvent:Fire(currentTab)
backpack.Tabs.Visible = false
searchFrame.Visible = false
backpack:TweenSizeAndPosition(UDim2.new(0, backpackSize.X.Offset,0, 0), UDim2.new(0.5, -backpackSize.X.Offset/2, 1, -85), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed, true,
function()
game.GuiService:RemoveCenterDialog(backpack)
backpack.Visible = false
backpackButton.Selected = false
end)
delay(guiTweenSpeed,function()
game.GuiService:RemoveCenterDialog(backpack)
backpack.Visible = false
backpackButton.Selected = false
readyForNextEvent = true
canToggle = true
end)
end
function showBackpack()
game.GuiService:AddCenterDialog(backpack, Enum.CenterDialogType.PlayerInitiatedDialog,
function()
backpack.Visible = true
backpackButton.Selected = true
end,
function()
backpack.Visible = false
backpackButton.Selected = false
end)
backpack.Visible = true
backpackButton.Selected = true
backpack:TweenSizeAndPosition(backpackSize, UDim2.new(0.5, -backpackSize.X.Offset/2, 1, -backpackSize.Y.Offset - 88), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed, true)
delay(guiTweenSpeed,function()
backpack.Tabs.Visible = false
searchFrame.Visible = true
backpackOpenEvent:Fire(currentTab)
canToggle = true
readyForNextEvent = true
backpackButton.Image = 'ayaasset://textures/2013/BackpackManager/BackpackButton.png'
backpackButton.Position = UDim2.new(0.5, -60, 1, -backpackSize.Y.Offset - 103)
end)
end
function toggleBackpack()
if not game.Players.LocalPlayer then return end
if not game.Players.LocalPlayer["Character"] then return end
if not canToggle then return end
if not readyForNextEvent then return end
readyForNextEvent = false
canToggle = false
backpackIsOpen = not backpackIsOpen
if backpackIsOpen then
loadoutBackground.Image = 'ayaasset://textures/2013/BackpackManager/LoadoutBackground.png'
loadoutBackground.Position = UDim2.new(-0.03, 0, -0.17, 0)
loadoutBackground.Size = UDim2.new(1.05, 0, 1.25, 0)
loadoutBackground.ZIndex = 2.0
loadoutBackground.Visible = true
showBackpack()
else
backpackButton.Position = UDim2.new(0.5, -60, 1, -44)
loadoutBackground.Visible = false
backpackButton.Selected = false
backpackButton.Image = "ayaasset://textures/2013/BackpackBuilder/BackpackButton.png"
loadoutBackground.Image = 'ayaasset://textures/2015/BackpackBuilder/CLBackground.png'
loadoutBackground.Position = UDim2.new(-0.1, 0, -0.1, 0)
loadoutBackground.Size = UDim2.new(1.2, 0, 1.2, 0)
hideBackpack()
local clChildren = currentLoadout:GetChildren()
for i = 1, #clChildren do
if clChildren[i] and clChildren[i]:IsA('Frame') then
local frame = clChildren[i]
if #frame:GetChildren() > 0 then
backpackButton.Position = UDim2.new(0.5, -60, 1, -108)
backpackButton.Visible = true
loadoutBackground.Visible = true
if frame:GetChildren()[1]:IsA('ImageButton') then
local imgButton = frame:GetChildren()[1]
imgButton.Active = true
imgButton.Draggable = false
end
end
end
end
end
end
function closeBackpack()
if backpackIsOpen then
toggleBackpack()
end
end
function setSelected(tab)
assert(tab)
assert(tab:IsA("TextButton"))
tab.BackgroundColor3 = Color3.new(1,1,1)
tab.TextColor3 = Color3.new(0,0,0)
tab.Selected = true
tab.ZIndex = 3
end
function setUnselected(tab)
assert(tab)
assert(tab:IsA("TextButton"))
tab.BackgroundColor3 = Color3.new(0,0,0)
tab.TextColor3 = Color3.new(1,1,1)
tab.Selected = false
tab.ZIndex = 1
end
function updateTabGui(selectedTab)
assert(selectedTab)
if selectedTab == "gear" then
setSelected(inventoryButton)
setUnselected(wardrobeButton)
elseif selectedTab == "wardrobe" then
setSelected(wardrobeButton)
setUnselected(inventoryButton)
end
end
function mouseLeaveTab(button)
assert(button)
assert(button:IsA("TextButton"))
if button.Selected then return end
button.BackgroundColor3 = Color3.new(0,0,0)
end
function mouseOverTab(button)
assert(button)
assert(button:IsA("TextButton"))
if button.Selected then return end
button.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
end
function newTabClicked(tabName)
assert(tabName)
tabName = string.lower(tabName)
currentTab = tabName
updateTabGui(tabName)
tabClickedEvent:Fire(tabName)
resetSearch()
end
function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
function splitByWhitespace(text)
if type(text) ~= "string" then return nil end
local terms = {}
for token in string.gmatch(text, "[^%s]+") do
if string.len(token) > 0 then
table.insert(terms,token)
end
end
return terms
end
function resetSearchBoxGui()
resetButton.Visible = false
searchBox.Text = searchDefaultText
end
function doSearch()
local searchText = searchBox.Text
if searchText == "" then
resetSearch()
return
end
searchText = trim(searchText)
resetButton.Visible = true
termTable = splitByWhitespace(searchText)
searchRequestedEvent:Fire(searchText) -- todo: replace this with termtable when table passing is possible
end
function resetSearch()
resetSearchBoxGui()
searchRequestedEvent:Fire()
end
local backpackReady = function()
readyForNextEvent = true
end
function coreGuiChanged(coreGuiType,enabled)
if coreGuiType == Enum.CoreGuiType.Backpack or coreGuiType == Enum.CoreGuiType.All then
active = enabled
disabledByDeveloper = not enabled
if disabledByDeveloper then
pcall(function()
game:GetService("GuiService"):RemoveKey(tilde)
game:GetService("GuiService"):RemoveKey(backquote)
end)
else
game:GetService("GuiService"):AddKey(tilde)
game:GetService("GuiService"):AddKey(backquote)
end
resetSearch()
searchFrame.Visible = enabled and backpackIsOpen
currentLoadout.Visible = enabled
backpack.Visible = enabled
backpackButton.Visible = enabled
end
end
--------------------------- End Internal Functions -------------------------------------
------------------------------ Public Functions Setup -------------------------------------
createPublicFunction("CloseBackpack", hideBackpack)
createPublicFunction("BackpackReady", backpackReady)
------------------------------ End Public Functions Setup ---------------------------------
------------------------ Connections/Script Main -------------------------------------------
pcall(function()
coreGuiChanged(Enum.CoreGuiType.Backpack, Game.StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.Backpack))
Game.StarterGui.CoreGuiChangedSignal:connect(coreGuiChanged)
end)
inventoryButton.MouseButton1Click:connect(function() newTabClicked("gear") end)
inventoryButton.MouseEnter:connect(function() mouseOverTab(inventoryButton) end)
inventoryButton.MouseLeave:connect(function() mouseLeaveTab(inventoryButton) end)
--[[
if game.CoreGui.Version >= 8 then
wardrobeButton.MouseButton1Click:connect(function() newTabClicked("wardrobe") end)
wardrobeButton.MouseEnter:connect(function() mouseOverTab(wardrobeButton) end)
wardrobeButton.MouseLeave:connect(function() mouseLeaveTab(wardrobeButton) end)
end]]--
closeButton.MouseButton1Click:connect(closeBackpack)
screen.Changed:connect(function(prop)
if prop == "AbsoluteSize" then
resizeEvent:Fire(screen.AbsoluteSize)
end
end)
-- GuiService key setup
game:GetService("GuiService"):AddKey(tilde)
game:GetService("GuiService"):AddKey(backquote)
game:GetService("GuiService").KeyPressed:connect(function(key)
if not active or disabledByDeveloper then return end
if key == tilde or key == backquote then
toggleBackpack()
end
end)
backpackButton.MouseButton1Click:connect(function()
if not active or disabledByDeveloper then return end
toggleBackpack()
end)
if game.Players.LocalPlayer["Character"] then
activateBackpack()
end
game.Players.LocalPlayer.CharacterAdded:connect(activateBackpack)
-- search functions
searchBox.FocusLost:connect(function(enterPressed)
if enterPressed or searchBox.Text ~= "" then
doSearch()
elseif searchBox.Text == "" then
resetSearch()
end
end)
searchButton.MouseButton1Click:connect(doSearch)
resetButton.MouseButton1Click:connect(resetSearch)
if searchFrame and robloxGui.AbsoluteSize.Y <= 320 then
searchFrame.RobloxLocked = false
searchFrame:Destroy()
end

View File

@@ -0,0 +1,962 @@
-- A couple of necessary functions
local function waitForChild(instance, name)
while not instance:FindFirstChild(name) do
instance.ChildAdded:wait()
end
end
local function waitForProperty(instance, property)
while not instance[property] do
instance.Changed:wait()
end
end
waitForChild(game,"Players")
waitForProperty(game.Players,"LocalPlayer")
local player = game.Players.LocalPlayer
local RbxGui,msg = LoadLibrary("RbxGui")
if not RbxGui then print("could not find RbxGui!") return end
--- Begin Locals
waitForChild(game,"Players")
-- don't do anything if we are in an empty game
if #game.Players:GetChildren() < 1 then
game.Players.ChildAdded:wait()
end
local tilde = "~"
local backquote = "`"
game:GetService("GuiService"):AddKey(tilde) -- register our keys
game:GetService("GuiService"):AddKey(backquote)
local player = game.Players.LocalPlayer
local backpack = script.Parent
local screen = script.Parent.Parent
local closeButton = backpack.Tabs.CloseButton
local openCloseDebounce = false
local backpackItems = {}
local buttons = {}
local debounce = false
local guiTweenSpeed = 1
local backpackOldStateVisible = false
local browsingMenu = false
local mouseEnterCons = {}
local mouseClickCons = {}
local characterChildAddedCon = nil
local characterChildRemovedCon = nil
local backpackAddCon = nil
local humanoidDiedCon = nil
local backpackButtonClickCon = nil
local guiServiceKeyPressCon = nil
waitForChild(player,"Backpack")
local playerBackpack = player.Backpack
waitForChild(backpack,"Gear")
waitForChild(backpack.Gear,"GearPreview")
local gearPreview = backpack.Gear.GearPreview
waitForChild(backpack.Gear,"GearGridScrollingArea")
local scroller = backpack.Gear.GearGridScrollingArea
waitForChild(backpack.Parent,"CurrentLoadout")
local currentLoadout = backpack.Parent.CurrentLoadout
waitForChild(backpack.Parent,"ControlFrame")
waitForChild(backpack.Parent.ControlFrame,"BackpackButton")
local backpackButton = backpack.Parent.ControlFrame.BackpackButton
waitForChild(backpack.Gear,"GearGrid")
waitForChild(backpack.Gear.GearGrid,"GearButton")
local gearButton = backpack.Gear.GearGrid.GearButton
local grid = backpack.Gear.GearGrid
waitForChild(backpack.Gear.GearGrid,"SearchFrame")
waitForChild(backpack.Gear.GearGrid.SearchFrame,"SearchBoxFrame")
waitForChild(backpack.Gear.GearGrid.SearchFrame.SearchBoxFrame,"SearchBox")
local searchBox = backpack.Gear.GearGrid.SearchFrame.SearchBoxFrame.SearchBox
waitForChild(backpack.Gear.GearGrid.SearchFrame,"SearchButton")
local searchButton = backpack.Gear.GearGrid.SearchFrame.SearchButton
waitForChild(backpack.Gear.GearGrid,"ResetFrame")
local resetFrame = backpack.Gear.GearGrid.ResetFrame
waitForChild(backpack.Gear.GearGrid.ResetFrame,"ResetButtonBorder")
local resetButton = backpack.Gear.GearGrid.ResetFrame.ResetButtonBorder
waitForChild(script.Parent,"SwapSlot")
local swapSlot = script.Parent.SwapSlot
-- creating scroll bar early as to make sure items get placed correctly
local scrollFrame, scrollUp, scrollDown, recalculateScroll = RbxGui.CreateScrollingFrame(nil, "grid", Vector2.new(4, 4))
scrollFrame.Position = UDim2.new(0,0,0,30)
scrollFrame.Size = UDim2.new(1,0,1,-30)
scrollFrame.Parent = backpack.Gear.GearGrid
local scrollBar = Instance.new("Frame")
scrollBar.Name = "ScrollBar"
scrollBar.BackgroundTransparency = 0.9
scrollBar.BackgroundColor3 = Color3.new(1,1,1)
scrollBar.BorderSizePixel = 0
scrollBar.Size = UDim2.new(0, 17, 1, -36)
scrollBar.Position = UDim2.new(0,0,0,18)
scrollBar.Parent = scroller
scrollDown.Position = UDim2.new(0,0,1,-17)
scrollUp.Parent = scroller
scrollDown.Parent = scroller
local scrollFrameLoadout, scrollUpLoadout, scrollDownLoadout, recalculateScrollLoadout = RbxGui.CreateScrollingFrame()
scrollFrameLoadout.Position = UDim2.new(0,0,0,0)
scrollFrameLoadout.Size = UDim2.new(1,0,1,0)
scrollFrameLoadout.Parent = backpack.Gear.GearLoadouts.LoadoutsList
local LoadoutButton = Instance.new("TextButton")
LoadoutButton.RobloxLocked = true
LoadoutButton.Name = "LoadoutButton"
LoadoutButton.Font = Enum.Font.ArialBold
LoadoutButton.FontSize = Enum.FontSize.Size14
LoadoutButton.Position = UDim2.new(0,0,0,0)
LoadoutButton.Size = UDim2.new(1,0,0,32)
LoadoutButton.Style = Enum.ButtonStyle.RobloxButton
LoadoutButton.Text = "Loadout #1"
LoadoutButton.TextColor3 = Color3.new(1,1,1)
LoadoutButton.Parent = scrollFrameLoadout
local LoadoutButtonTwo = LoadoutButton:clone()
LoadoutButtonTwo.Text = "Loadout #2"
LoadoutButtonTwo.Parent = scrollFrameLoadout
local LoadoutButtonThree = LoadoutButton:clone()
LoadoutButtonThree.Text = "Loadout #3"
LoadoutButtonThree.Parent = scrollFrameLoadout
local LoadoutButtonFour = LoadoutButton:clone()
LoadoutButtonFour.Text = "Loadout #4"
LoadoutButtonFour.Parent = scrollFrameLoadout
local scrollBarLoadout = Instance.new("Frame")
scrollBarLoadout.Name = "ScrollBarLoadout"
scrollBarLoadout.BackgroundTransparency = 0.9
scrollBarLoadout.BackgroundColor3 = Color3.new(1,1,1)
scrollBarLoadout.BorderSizePixel = 0
scrollBarLoadout.Size = UDim2.new(0, 17, 1, -36)
scrollBarLoadout.Position = UDim2.new(0,0,0,18)
scrollBarLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
scrollDownLoadout.Position = UDim2.new(0,0,1,-17)
scrollUpLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
scrollDownLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
-- Begin Functions
function removeFromMap(map,object)
for i = 1, #map do
if map[i] == object then
table.remove(map,i)
break
end
end
end
function robloxLock(instance)
instance.RobloxLocked = true
children = instance:GetChildren()
if children then
for i, child in ipairs(children) do
robloxLock(child)
end
end
end
function resize()
local size = 0
if gearPreview.AbsoluteSize.Y > gearPreview.AbsoluteSize.X then
size = gearPreview.AbsoluteSize.X * 0.75
else
size = gearPreview.AbsoluteSize.Y * 0.75
end
gearPreview.GearImage.Size = UDim2.new(0,size,0,size)
gearPreview.GearImage.Position = UDim2.new(0,gearPreview.AbsoluteSize.X/2 - size/2,0.75,-size)
resizeGrid()
end
function addToGrid(child)
if not child:IsA("Tool") then
if not child:IsA("HopperBin") then
return
end
end
if child:FindFirstChild("RobloxBuildTool") then return end
for i,v in pairs(backpackItems) do -- check to see if we already have this gear registered
if v == child then return end
end
table.insert(backpackItems,child)
local changeCon = child.Changed:connect(function(prop)
if prop == "Name" then
if buttons[child] then
if buttons[child].Image == "" then
buttons[child].GearText.Text = child.Name
end
end
end
end)
local ancestryCon = nil
ancestryCon = child.AncestryChanged:connect(function(theChild,theParent)
local thisObject = nil
for k,v in pairs(backpackItems) do
if v == child then
thisObject = v
break
end
end
waitForProperty(player,"Character")
waitForChild(player,"Backpack")
if (child.Parent ~= player.Backpack and child.Parent ~= player.Character) then
if ancestryCon then ancestryCon:disconnect() end
if changeCon then changeCon:disconnect() end
for k,v in pairs(backpackItems) do
if v == thisObject then
if mouseEnterCons[buttons[v]] then mouseEnterCons[buttons[v]]:disconnect() end
if mouseClickCons[buttons[v]] then mouseClickCons[buttons[v]]:disconnect() end
buttons[v].Parent = nil
buttons[v] = nil
break
end
end
removeFromMap(backpackItems,thisObject)
resizeGrid()
else
resizeGrid()
end
updateGridActive()
end)
resizeGrid()
end
function buttonClick(button)
if button:FindFirstChild("UnequipContextMenu") and not button.Active then
button.UnequipContextMenu.Visible = true
browsingMenu = true
end
end
function previewGear(button)
if not browsingMenu then
gearPreview.GearImage.Image = button.Image
gearPreview.GearStats.GearName.Text = button.GearReference.Value.Name
end
end
function findEmptySlot()
local smallestNum = nil
local loadout = currentLoadout:GetChildren()
for i = 1, #loadout do
if loadout[i]:IsA("Frame") and #loadout[i]:GetChildren() <= 0 then
local frameNum = tonumber(string.sub(loadout[i].Name,5))
if frameNum == 0 then frameNum = 10 end
if not smallestNum or (smallestNum > frameNum) then
smallestNum = frameNum
end
end
end
if smallestNum == 10 then smallestNum = 0 end
return smallestNum
end
function checkForSwap(button,x,y)
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name,"Slot") then
if x >= loadoutChildren[i].AbsolutePosition.x and x <= (loadoutChildren[i].AbsolutePosition.x + loadoutChildren[i].AbsoluteSize.x) then
if y >= loadoutChildren[i].AbsolutePosition.y and y <= (loadoutChildren[i].AbsolutePosition.y + loadoutChildren[i].AbsoluteSize.y) then
local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
swapGearSlot(slot,button)
return true
end
end
end
end
return false
end
function resizeGrid()
for k,v in pairs(backpackItems) do
if not v:FindFirstChild("RobloxBuildTool") then
if not buttons[v] then
local buttonClone = gearButton:clone()
buttonClone.Parent = grid.ScrollingFrame
buttonClone.Visible = true
buttonClone.Image = v.TextureId
if buttonClone.Image == "" then
buttonClone.GearText.Text = v.Name
end
buttonClone.GearReference.Value = v
buttonClone.Draggable = true
buttons[v] = buttonClone
local unequipMenu = getGearContextMenu()
unequipMenu.Visible = false
unequipMenu.Parent = buttonClone
local beginPos = nil
buttonClone.DragBegin:connect(function(value)
buttonClone.ZIndex = 9
beginPos = value
end)
buttonClone.DragStopped:connect(function(x,y)
buttonClone.ZIndex = 1
if beginPos ~= buttonClone.Position then
if not checkForSwap(buttonClone,x,y) then
buttonClone:TweenPosition(beginPos,Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true)
buttonClone.Draggable = false
delay(0.5,function()
buttonClone.Draggable = true
end)
else
buttonClone.Position = beginPos
end
end
end)
local clickTime = tick()
mouseEnterCons[buttonClone] = buttonClone.MouseEnter:connect(function() previewGear(buttonClone) end)
mouseClickCons[buttonClone] = buttonClone.MouseButton1Click:connect(function()
local newClickTime = tick()
if buttonClone.Active and (newClickTime - clickTime) < 0.5 then
local slot = findEmptySlot()
if slot then
buttonClone.ZIndex = 1
swapGearSlot(slot,buttonClone)
end
else
buttonClick(buttonClone)
end
clickTime = newClickTime
end)
end
end
end
recalculateScroll()
end
function showPartialGrid(subset)
resetFrame.Visible = true
for k,v in pairs(buttons) do
v.Parent = nil
end
for k,v in pairs(subset) do
v.Parent = grid.ScrollingFrame
end
recalculateScroll()
end
function showEntireGrid()
resetFrame.Visible = false
for k,v in pairs(buttons) do
v.Parent = grid.ScrollingFrame
end
recalculateScroll()
end
function inLoadout(gear)
local children = currentLoadout:GetChildren()
for i = 1, #children do
if children[i]:IsA("Frame") then
local button = children[i]:GetChildren()
if #button > 0 then
if button[1].GearReference.Value and button[1].GearReference.Value == gear then
return true
end
end
end
end
return false
end
function updateGridActive()
for k,v in pairs(backpackItems) do
if buttons[v] then
local gear = nil
local gearRef = buttons[v]:FindFirstChild("GearReference")
if gearRef then gear = gearRef.Value end
if not gear then
buttons[v].Active = false
elseif inLoadout(gear) then
buttons[v].Active = false
else
buttons[v].Active = true
end
end
end
end
function centerGear(loadoutChildren)
local gearButtons = {}
local lastSlotAdd = nil
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") and #loadoutChildren[i]:GetChildren() > 0 then
if loadoutChildren[i].Name == "Slot0" then
lastSlotAdd = loadoutChildren[i]
else
table.insert(gearButtons, loadoutChildren[i])
end
end
end
if lastSlotAdd then table.insert(gearButtons,lastSlotAdd) end
local startPos = ( 1 - (#gearButtons * 0.1) ) / 2
for i = 1, #gearButtons do
gearButtons[i]:TweenPosition(UDim2.new(startPos + ((i - 1) * 0.1),0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
end
end
function spreadOutGear(loadoutChildren)
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") then
local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
if slot == 0 then slot = 10 end
loadoutChildren[i]:TweenPosition(UDim2.new((slot - 1)/10,0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
end
end
end
function openCloseBackpack(close)
if openCloseDebounce then return end
openCloseDebounce = true
local visible = not backpack.Visible
if visible and not close then
updateGridActive()
local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(backpack, Enum.CenterDialogType.PlayerInitiatedDialog,
function()
backpack.Visible = true
loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") then
loadoutChildren[i].BackgroundTransparency = 0.5
end
end
spreadOutGear(loadoutChildren)
end,
function()
backpack.Visible = false
end)
end)
backpackButton.Selected = true
backpack:TweenSizeAndPosition(UDim2.new(0.55, 0, 0.6, 0),UDim2.new(0.225, 0, 0.2, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed/2, true)
delay(guiTweenSpeed/2 + 0.01,
function()
local children = backpack:GetChildren()
for i = 1, #children do
if children[i]:IsA("Frame") then
children[i].Visible = true
end
end
resizeGrid()
resize()
openCloseDebounce = false
end)
else
backpackButton.Selected = false
local children = backpack:GetChildren()
for i = 1, #children do
if children[i]:IsA("Frame") then
children[i].Visible = false
end
end
loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") then
loadoutChildren[i].BackgroundTransparency = 1
end
end
centerGear(loadoutChildren)
backpack:TweenSizeAndPosition(UDim2.new(0,0,0,0),UDim2.new(0.5,0,0.5,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed/2, true)
delay(guiTweenSpeed/2 + 0.01,
function()
backpack.Visible = visible
resizeGrid()
resize()
pcall(function() game.GuiService:RemoveCenterDialog(backpack) end)
openCloseDebounce = false
end)
end
end
function loadoutCheck(child, selectState)
if not child:IsA("ImageButton") then return end
for k,v in pairs(backpackItems) do
if buttons[v] then
if child:FindFirstChild("GearReference") and buttons[v]:FindFirstChild("GearReference") then
if buttons[v].GearReference.Value == child.GearReference.Value then
buttons[v].Active = selectState
break
end
end
end
end
end
function clearPreview()
gearPreview.GearImage.Image = ""
gearPreview.GearStats.GearName.Text = ""
end
function removeAllEquippedGear(physGear)
local stuff = player.Character:GetChildren()
for i = 1, #stuff do
if ( stuff[i]:IsA("Tool") or stuff[i]:IsA("HopperBin") ) and stuff[i] ~= physGear then
stuff[i].Parent = playerBackpack
end
end
end
function equipGear(physGear)
removeAllEquippedGear(physGear)
physGear.Parent = player.Character
updateGridActive()
end
function unequipGear(physGear)
physGear.Parent = playerBackpack
updateGridActive()
end
function highlight(button)
button.TextColor3 = Color3.new(0,0,0)
button.BackgroundColor3 = Color3.new(0.8,0.8,0.8)
end
function clearHighlight(button)
button.TextColor3 = Color3.new(1,1,1)
button.BackgroundColor3 = Color3.new(0,0,0)
end
function swapGearSlot(slot,gearButton)
if not swapSlot.Value then -- signal loadout to swap a gear out
swapSlot.Slot.Value = slot
swapSlot.GearButton.Value = gearButton
swapSlot.Value = true
updateGridActive()
end
end
local UnequipGearMenuClick = function(element, menu)
if type(element.Action) ~= "number" then return end
local num = element.Action
if num == 1 then -- remove from loadout
unequipGear(menu.Parent.GearReference.Value)
local inventoryButton = menu.Parent
local gearToUnequip = inventoryButton.GearReference.Value
local loadoutChildren = currentLoadout:GetChildren()
local slot = -1
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") then
local button = loadoutChildren[i]:GetChildren()
if button[1] and button[1].GearReference.Value == gearToUnequip then
slot = button[1].SlotNumber.Text
break
end
end
end
swapGearSlot(slot,nil)
end
end
-- these next two functions are used to stop any use of backpack while the player is dead (can cause issues)
function activateBackpack()
backpack.Visible = backpackOldStateVisible
loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") then
loadoutChildren[i].BackgroundTransparency = 1
end
end
backpackButtonClickCon = backpackButton.MouseButton1Click:connect(function() openCloseBackpack() end)
guiServiceKeyPressCon = game:GetService("GuiService").KeyPressed:connect(function(key)
if key == tilde or key == backquote then
openCloseBackpack()
end
end)
end
function deactivateBackpack()
if backpackButtonClickCon then backpackButtonClickCon:disconnect() end
if guiServiceKeyPressCon then guiServiceKeyPressCon:disconnect() end
backpackOldStateVisible = backpack.Visible
backpack.Visible = false
openCloseBackpack(true)
end
function setupCharacterConnections()
if backpackAddCon then backpackAddCon:disconnect() end
backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
-- make sure we get all the children
local backpackChildren = game.Players.LocalPlayer.Backpack:GetChildren()
for i = 1, #backpackChildren do
addToGrid(backpackChildren[i])
end
if characterChildAddedCon then characterChildAddedCon:disconnect() end
characterChildAddedCon =
game.Players.LocalPlayer.Character.ChildAdded:connect(function(child)
addToGrid(child)
updateGridActive()
end)
if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
characterChildRemovedCon =
game.Players.LocalPlayer.Character.ChildRemoved:connect(function(child)
updateGridActive()
end)
if humanoidDiedCon then humanoidDiedCon:disconnect() end
local localPlayer = game.Players.LocalPlayer
waitForProperty(localPlayer,"Character")
waitForChild(localPlayer.Character,"Humanoid")
humanoidDiedCon = game.Players.LocalPlayer.Character.Humanoid.Died:connect(function() deactivateBackpack() end)
activateBackpack()
wait()
centerGear(currentLoadout:GetChildren())
end
function removeCharacterConnections()
if characterChildAddedCon then characterChildAddedCon:disconnect() end
if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
if backpackAddCon then backpackAddCon:disconnect() end
end
function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
function splitByWhiteSpace(text)
if type(text) ~= "string" then return nil end
local terms = {}
for token in string.gmatch(text, "[^%s]+") do
if string.len(token) > 2 then
table.insert(terms,token)
end
end
return terms
end
function filterGear(searchTerm)
string.lower(searchTerm)
searchTerm = trim(searchTerm)
if string.len(searchTerm) < 2 then return nil end
local terms = splitByWhiteSpace(searchTerm)
local filteredGear = {}
for k,v in pairs(backpackItems) do
if buttons[v] then
local gearString = string.lower(buttons[v].GearReference.Value.Name)
gearString = trim(gearString)
for i = 1, #terms do
if string.match(gearString,terms[i]) then
table.insert(filteredGear,buttons[v])
break
end
end
end
end
return filteredGear
end
function showSearchGear()
local searchText = searchBox.Text
searchBox.Text = "Search..."
local filteredButtons = filterGear(searchText)
if filteredButtons and #filteredButtons > 0 then
showPartialGrid(filteredButtons)
else
showEntireGrid()
end
end
function nukeBackpack()
while #buttons > 0 do
table.remove(buttons)
end
buttons = {}
while #backpackItems > 0 do
table.remove(backpackItems)
end
backpackItems = {}
local scrollingFrameChildren = grid.ScrollingFrame:GetChildren()
for i = 1, #scrollingFrameChildren do
scrollingFrameChildren[i]:remove()
end
end
function getGearContextMenu()
local gearContextMenu = Instance.new("Frame")
gearContextMenu.Active = true
gearContextMenu.Name = "UnequipContextMenu"
gearContextMenu.Size = UDim2.new(0,115,0,70)
gearContextMenu.Position = UDim2.new(0,-16,0,-16)
gearContextMenu.BackgroundTransparency = 1
gearContextMenu.Visible = false
local gearContextMenuButton = Instance.new("TextButton")
gearContextMenuButton.Name = "UnequipContextMenuButton"
gearContextMenuButton.Text = ""
gearContextMenuButton.Style = Enum.ButtonStyle.RobloxButtonDefault
gearContextMenuButton.ZIndex = 8
gearContextMenuButton.Size = UDim2.new(1, 0, 1, -20)
gearContextMenuButton.Visible = true
gearContextMenuButton.Parent = gearContextMenu
local elementHeight = 12
local contextMenuElements = {}
local contextMenuElementsName = {"Remove Hotkey"}
for i = 1, #contextMenuElementsName do
local element = {}
element.Type = "Button"
element.Text = contextMenuElementsName[i]
element.Action = i
element.DoIt = UnequipGearMenuClick
table.insert(contextMenuElements,element)
end
for i, contextElement in ipairs(contextMenuElements) do
local element = contextElement
if element.Type == "Button" then
local button = Instance.new("TextButton")
button.Name = "UnequipContextButton" .. i
button.BackgroundColor3 = Color3.new(0,0,0)
button.BorderSizePixel = 0
button.TextXAlignment = Enum.TextXAlignment.Left
button.Text = " " .. contextElement.Text
button.Font = Enum.Font.Arial
button.FontSize = Enum.FontSize.Size14
button.Size = UDim2.new(1, 8, 0, elementHeight)
button.Position = UDim2.new(0,0,0,elementHeight * i)
button.TextColor3 = Color3.new(1,1,1)
button.ZIndex = 9
button.Parent = gearContextMenuButton
button.MouseButton1Click:connect(function()
if button.Active and not gearContextMenu.Parent.Active then
local success, result = pcall(function() element.DoIt(element, gearContextMenu) end)
browsingMenu = false
gearContextMenu.Visible = false
clearHighlight(button)
clearPreview()
end
end)
button.MouseEnter:connect(function()
if button.Active and gearContextMenu.Parent.Active then
highlight(button)
end
end)
button.MouseLeave:connect(function()
if button.Active and gearContextMenu.Parent.Active then
clearHighlight(button)
end
end)
contextElement.Button = button
contextElement.Element = button
elseif element.Type == "Label" then
local frame = Instance.new("Frame")
frame.Name = "ContextLabel" .. i
frame.BackgroundTransparency = 1
frame.Size = UDim2.new(1, 8, 0, elementHeight)
local label = Instance.new("TextLabel")
label.Name = "Text1"
label.BackgroundTransparency = 1
label.BackgroundColor3 = Color3.new(1,1,1)
label.BorderSizePixel = 0
label.TextXAlignment = Enum.TextXAlignment.Left
label.Font = Enum.Font.ArialBold
label.FontSize = Enum.FontSize.Size14
label.Position = UDim2.new(0.0, 0, 0, 0)
label.Size = UDim2.new(0.5, 0, 1, 0)
label.TextColor3 = Color3.new(1,1,1)
label.ZIndex = 9
label.Parent = frame
element.Label1 = label
if element.GetText2 then
label = Instance.new("TextLabel")
label.Name = "Text2"
label.BackgroundTransparency = 1
label.BackgroundColor3 = Color3.new(1,1,1)
label.BorderSizePixel = 0
label.TextXAlignment = Enum.TextXAlignment.Right
label.Font = Enum.Font.Arial
label.FontSize = Enum.FontSize.Size14
label.Position = UDim2.new(0.5, 0, 0, 0)
label.Size = UDim2.new(0.5, 0, 1, 0)
label.TextColor3 = Color3.new(1,1,1)
label.ZIndex = 9
label.Parent = frame
element.Label2 = label
end
frame.Parent = gearContextMenuButton
element.Label = frame
element.Element = frame
end
end
gearContextMenu.ZIndex = 4
gearContextMenu.MouseLeave:connect(function()
browsingMenu = false
gearContextMenu.Visible = false
clearPreview()
end)
robloxLock(gearContextMenu)
return gearContextMenu
end
local backpackChildren = player.Backpack:GetChildren()
for i = 1, #backpackChildren do
addToGrid(backpackChildren[i])
end
------------------------- Start Lifelong Connections -----------------------
screen.Changed:connect(function(prop)
if prop == "AbsoluteSize" then
if debounce then return end
debounce = true
wait()
resize()
resizeGrid()
debounce = false
end
end)
currentLoadout.ChildAdded:connect(function(child) loadoutCheck(child, false) end)
currentLoadout.ChildRemoved:connect(function(child) loadoutCheck(child, true) end)
currentLoadout.DescendantAdded:connect(function(descendant)
if not backpack.Visible and ( descendant:IsA("ImageButton") or descendant:IsA("TextButton") ) then
centerGear(currentLoadout:GetChildren())
end
end)
currentLoadout.DescendantRemoving:connect(function(descendant)
if not backpack.Visible and ( descendant:IsA("ImageButton") or descendant:IsA("TextButton") ) then
wait()
centerGear(currentLoadout:GetChildren())
end
end)
grid.MouseEnter:connect(function() clearPreview() end)
grid.MouseLeave:connect(function() clearPreview() end)
player.CharacterRemoving:connect(function()
removeCharacterConnections()
nukeBackpack()
end)
player.CharacterAdded:connect(function() setupCharacterConnections() end)
player.ChildAdded:connect(function(child)
if child:IsA("Backpack") then
playerBackpack = child
if backpackAddCon then backpackAddCon:disconnect() end
backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
end
end)
swapSlot.Changed:connect(function()
if not swapSlot.Value then
updateGridActive()
end
end)
searchBox.FocusLost:connect(function(enterPressed)
if enterPressed then
showSearchGear()
end
end)
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name,"Slot") then
loadoutChildren[i].ChildRemoved:connect(function()
updateGridActive()
end)
loadoutChildren[i].ChildAdded:connect(function()
updateGridActive()
end)
end
end
closeButton.Modal = true
closeButton.MouseButton1Click:connect(function() openCloseBackpack() end)
searchButton.MouseButton1Click:connect(function() showSearchGear() end)
resetButton.MouseButton1Click:connect(function() showEntireGrid() end)
------------------------- End Lifelong Connections -----------------------
resize()
resizeGrid()
-- make sure any items in the loadout are accounted for in inventory
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
loadoutCheck(loadoutChildren[i], false)
end
if not backpack.Visible then centerGear(currentLoadout:GetChildren()) end
-- make sure that inventory is listening to gear reparenting
if characterChildAddedCon == nil and game.Players.LocalPlayer["Character"] then
setupCharacterConnections()
end
if not backpackAddCon then
backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
end
recalculateScrollLoadout()

View File

@@ -0,0 +1,659 @@
--[[
// FileName: BubbleChat.lua
// Written by: jeditkacheff
// Description: Code for rendering bubble chat
]]
--[[ SERVICES ]]
local RunService = game:GetService('RunService')
local CoreGuiService = game:GetService('CoreGui')
local PlayersService = game:GetService('Players')
local ChatService = game:GetService("Chat")
local TextService = game:GetService("TextService")
local GameOptions = settings()["Game Options"]
--[[ END OF SERVICES ]]
while PlayersService.LocalPlayer == nil do PlayersService.ChildAdded:wait() end
local GuiRoot = CoreGuiService:WaitForChild('RobloxGui')
-- local playerDropDownModule = require(GuiRoot.Modules:WaitForChild("PlayerDropDown"))
-- local blockingUtility = playerDropDownModule:CreateBlockingUtility()
--[[ SCRIPT VARIABLES ]]
local CHAT_BUBBLE_FONT = Enum.Font.Arial
local CHAT_BUBBLE_FONT_SIZE = Enum.FontSize.Size24 -- if you change CHAT_BUBBLE_FONT_SIZE_INT please change this to match
local CHAT_BUBBLE_FONT_SIZE_INT = 24 -- if you change CHAT_BUBBLE_FONT_SIZE please change this to match
local CHAT_BUBBLE_LINE_HEIGHT = CHAT_BUBBLE_FONT_SIZE_INT + 23
local CHAT_BUBBLE_TAIL_HEIGHT = 14
local CHAT_BUBBLE_WIDTH_PADDING = 27
local CHAT_BUBBLE_FADE_SPEED = 1.5
local BILLBOARD_MAX_WIDTH = 400
local BILLBOARD_MAX_HEIGHT = 250 --This limits the number of bubble chats that you see above characters
local ELIPSES = "..."
local CchMaxChatMessageLength = 128 -- max chat message length, including null terminator and elipses.
local CchMaxChatMessageLengthExclusive = CchMaxChatMessageLength - string.len(ELIPSES) - 1
local NEAR_BUBBLE_DISTANCE = 80 -- 65 --previously 45
local MAX_BUBBLE_DISTANCE = 80 --100 --previously 80
--[[ END OF SCRIPT VARIABLES ]]
-- [[ SCRIPT ENUMS ]]
local ChatType = { PLAYER_CHAT = "pChat",
PLAYER_TEAM_CHAT = "pChatTeam",
PLAYER_WHISPER_CHAT = "pChatWhisper",
GAME_MESSAGE= "gMessage",
PLAYER_GAME_CHAT = "pGame",
BOT_CHAT = "bChat" }
local BubbleColor = { WHITE = "dub",
BLUE = "blu",
GREEN = "gre",
RED = "red" }
--[[ END OF SCRIPT ENUMS ]]
--[[ FUNCTIONS ]]
local function lerpLength(msg, min, max)
return min + (max-min) * math.min(string.len(msg)/75.0, 1.0)
end
local function createFifo()
local this = {}
this.data = {}
local emptyEvent = Instance.new("BindableEvent")
this.Emptied = emptyEvent.Event
function this:Size()
return #this.data
end
function this:Empty()
return this:Size() <= 0
end
function this:PopFront()
table.remove(this.data, 1)
if this:Empty() then emptyEvent:Fire() end
end
function this:Front()
return this.data[1]
end
function this:Get(index)
return this.data[index]
end
function this:PushBack(value)
table.insert(this.data, value)
end
function this:GetData()
return this.data
end
return this
end
local function createCharacterChats()
local this = {}
this.Fifo = createFifo()
this.BillboardGui = nil
return this
end
local function createMap()
local this = {}
this.data = {}
local count = 0
function this:Size()
return count
end
function this:Erase(key)
if this.data[key] then count = count - 1 end
this.data[key] = nil
end
function this:Set(key, value)
this.data[key] = value
if value then count = count + 1 end
end
function this:Get(key)
if not this.data[key] then
this.data[key] = createCharacterChats()
local emptiedCon = nil
emptiedCon = this.data[key].Fifo.Emptied:connect(function()
emptiedCon:disconnect()
this:Erase(key)
end)
end
return this.data[key]
end
function this:GetData()
return this.data
end
return this
end
local function createChatLine(chatType, message, bubbleColor, isLocalPlayer)
local this = {}
function this:ComputeBubbleLifetime(msg, isSelf)
if isSelf then
return lerpLength(msg,8,15)
else
return lerpLength(msg,12,20)
end
end
function this:IsPlayerChat()
if not this.ChatType then return false end
if this.ChatType == ChatType.PLAYER_CHAT or
this.ChatType == ChatType.PLAYER_WHISPER_CHAT or
this.ChatType == ChatType.PLAYER_TEAM_CHAT then
return true
end
return false
end
this.ChatType = chatType
this.Origin = nil
this.RenderBubble = nil
this.Message = message
this.BubbleDieDelay = this:ComputeBubbleLifetime(message, isLocalPlayer)
this.BubbleColor = bubbleColor
this.IsLocalPlayer = isLocalPlayer
return this
end
local function createPlayerChatLine(chatType, player, message, isLocalPlayer)
local this = createChatLine(chatType, message, BubbleColor.WHITE, isLocalPlayer)
if player then
this.User = player.Name
this.Origin = player.Character
end
return this
end
local function createGameChatLine(origin, message, isLocalPlayer, bubbleColor)
local this = createChatLine(origin and ChatType.PLAYER_GAME_CHAT or ChatType.BOT_CHAT, message, bubbleColor, isLocalPlayer)
this.Origin = origin
return this
end
function createChatBubbleMain(filePrefix, sliceRect)
local chatBubbleMain = Instance.new("ImageLabel")
chatBubbleMain.Name = "ChatBubble"
chatBubbleMain.ScaleType = Enum.ScaleType.Slice
chatBubbleMain.SliceCenter = sliceRect
chatBubbleMain.Image = "ayaasset://textures/" .. tostring(filePrefix) .. ".png"
chatBubbleMain.BackgroundTransparency = 1
chatBubbleMain.BorderSizePixel = 0
chatBubbleMain.Size = UDim2.new(1.0, 0, 1.0, 0)
chatBubbleMain.Position = UDim2.new(0,0,0,0)
return chatBubbleMain
end
function createChatBubbleTail(position, size)
local chatBubbleTail = Instance.new("ImageLabel")
chatBubbleTail.Name = "ChatBubbleTail"
chatBubbleTail.Image = "ayaasset://textures/classic/ui/dialog_tail.png"
chatBubbleTail.BackgroundTransparency = 1
chatBubbleTail.BorderSizePixel = 0
chatBubbleTail.Position = position
chatBubbleTail.Size = size
return chatBubbleTail
end
function createChatBubbleWithTail(filePrefix, position, size, sliceRect)
local chatBubbleMain = createChatBubbleMain(filePrefix, sliceRect)
local chatBubbleTail = createChatBubbleTail(position, size)
chatBubbleTail.Parent = chatBubbleMain
return chatBubbleMain
end
function createScaledChatBubbleWithTail(filePrefix, frameScaleSize, position, sliceRect)
local chatBubbleMain = createChatBubbleMain(filePrefix, sliceRect)
local frame = Instance.new("Frame")
frame.Name = "ChatBubbleTailFrame"
frame.BackgroundTransparency = 1
frame.SizeConstraint = Enum.SizeConstraint.RelativeXX
frame.Position = UDim2.new(0.5, 0, 1, 0)
frame.Size = UDim2.new(frameScaleSize, 0, frameScaleSize, 0)
frame.Parent = chatBubbleMain
local chatBubbleTail = createChatBubbleTail(position, UDim2.new(1,0,0.5,-20))
chatBubbleTail.Parent = frame
return chatBubbleMain
end
function createChatImposter(filePrefix, dotDotDot, yOffset)
local result = Instance.new("ImageLabel")
result.Name = "DialogPlaceholder"
result.Image = "ayaasset://textures/" .. tostring(filePrefix) .. ".png"
result.BackgroundTransparency = 1
result.BorderSizePixel = 0
result.Position = UDim2.new(0, 0, -1.25, 0)
result.Size = UDim2.new(1, 0, 1, 0)
local image = Instance.new("ImageLabel")
image.Name = "DotDotDot"
image.Image = "ayaasset://textures/" .. tostring(dotDotDot) .. ".png"
image.BackgroundTransparency = 1
image.BorderSizePixel = 0
image.Position = UDim2.new(0.001, 0, yOffset, 0)
image.Size = UDim2.new(1, 0, 0.7, 0)
image.Parent = result
return result
end
local function createChatOutput()
local this = {}
this.ChatBubble = {}
this.ChatBubbleWithTail = {}
this.ScalingChatBubbleWithTail = {}
this.CharacterSortedMsg = createMap()
-- init chat bubble tables
local function initChatBubbleType(chatBubbleType, fileName, imposterFileName, isInset, sliceRect)
this.ChatBubble[chatBubbleType] = createChatBubbleMain(fileName, sliceRect)
this.ChatBubbleWithTail[chatBubbleType] = createChatBubbleWithTail(fileName, UDim2.new(0.5, -CHAT_BUBBLE_TAIL_HEIGHT + 5, 0.995, -6.5), UDim2.new(0, 20, 0, 20), sliceRect)
this.ScalingChatBubbleWithTail[chatBubbleType] = createScaledChatBubbleWithTail(fileName, 0.01, UDim2.new(-0.4, 0, 0, isInset and -1 or 0), sliceRect)
end
initChatBubbleType(BubbleColor.WHITE, "classic/ui/dialog_white", "classic/ui/chatBubble_white_notify_bkg", false, Rect.new(23,23,23,23))
initChatBubbleType(BubbleColor.BLUE, "ui/dialog_blue", "ui/chatBubble_blue_notify_bkg", true, Rect.new(7,7,33,33))
initChatBubbleType(BubbleColor.RED, "ui/dialog_red", "ui/chatBubble_red_notify_bkg", true, Rect.new(7,7,33,33))
initChatBubbleType(BubbleColor.GREEN, "ui/dialog_green", "ui/chatBubble_green_notify_bkg", true, Rect.new(7,7,33,33))
function this:SanitizeChatLine(msg)
if string.len(msg) > CchMaxChatMessageLengthExclusive then
return string.sub(msg, 1, CchMaxChatMessageLengthExclusive + string.len(ELIPSES))
else
return msg
end
end
local function createBillboardInstance(adornee)
local billboardGui = Instance.new("BillboardGui")
billboardGui.Adornee = adornee
billboardGui.RobloxLocked = true
billboardGui.Size = UDim2.new(0,BILLBOARD_MAX_WIDTH,0,BILLBOARD_MAX_HEIGHT)
billboardGui.StudsOffset = Vector3.new(0, 1.5, 2)
billboardGui.Parent = CoreGuiService
local billboardFrame = Instance.new("Frame")
billboardFrame.Name = "BillboardFrame"
billboardFrame.Size = UDim2.new(1,0,1,0)
billboardFrame.Position = UDim2.new(0,0,-0.5,0)
billboardFrame.BackgroundTransparency = 1
billboardFrame.Parent = billboardGui
local billboardChildRemovedCon = nil
billboardChildRemovedCon = billboardFrame.ChildRemoved:connect(function()
if #billboardFrame:GetChildren() <= 1 then
billboardChildRemovedCon:disconnect()
billboardGui:Destroy()
end
end)
this:CreateSmallTalkBubble(BubbleColor.WHITE).Parent = billboardFrame
return billboardGui
end
function this:CreateBillboardGuiHelper(instance, onlyCharacter)
if not this.CharacterSortedMsg:Get(instance)["BillboardGui"] then
if not onlyCharacter then
if instance:IsA("Part") then
-- Create a new billboardGui object attached to this player
local billboardGui = createBillboardInstance(instance)
this.CharacterSortedMsg:Get(instance)["BillboardGui"] = billboardGui
return
end
end
if instance:IsA("Model") then
local head = instance:FindFirstChild("Head")
if head and head:IsA("Part") then
-- Create a new billboardGui object attached to this player
local billboardGui = createBillboardInstance(head)
this.CharacterSortedMsg:Get(instance)["BillboardGui"] = billboardGui
end
end
end
end
local function distanceToBubbleOrigin(origin)
if not origin then return 100000 end
return (origin.Position - game.Workspace.CurrentCamera.CoordinateFrame.p).magnitude
end
local function isPartOfLocalPlayer(adornee)
if adornee and PlayersService.LocalPlayer.Character then
return adornee:IsDescendantOf(PlayersService.LocalPlayer.Character)
end
end
function this:SetBillboardLODNear(billboardGui)
local isLocalPlayer = isPartOfLocalPlayer(billboardGui.Adornee)
billboardGui.Size = UDim2.new(0, BILLBOARD_MAX_WIDTH, 0, BILLBOARD_MAX_HEIGHT)
billboardGui.StudsOffset = Vector3.new(0, isLocalPlayer and 1.5 or 2.5, isLocalPlayer and 2 or 0)
billboardGui.Enabled = true
local billChildren = billboardGui.BillboardFrame:GetChildren()
for i = 1, #billChildren do
billChildren[i].Visible = true
end
billboardGui.BillboardFrame.SmallTalkBubble.Visible = false
end
function this:SetBillboardLODDistant(billboardGui)
local isLocalPlayer = isPartOfLocalPlayer(billboardGui.Adornee)
billboardGui.Size = UDim2.new(4,0,3,0)
billboardGui.StudsOffset = Vector3.new(0, 3, isLocalPlayer and 2 or 0)
billboardGui.Enabled = true
local billChildren = billboardGui.BillboardFrame:GetChildren()
for i = 1, #billChildren do
billChildren[i].Visible = false
end
billboardGui.BillboardFrame.SmallTalkBubble.Visible = true
end
function this:SetBillboardLODVeryFar(billboardGui)
billboardGui.Enabled = false
end
function this:SetBillboardGuiLOD(billboardGui, origin)
if not origin then return end
if origin:IsA("Model") then
local head = origin:FindFirstChild("Head")
if not head then origin = origin.PrimaryPart
else origin = head end
end
local bubbleDistance = distanceToBubbleOrigin(origin)
if bubbleDistance < NEAR_BUBBLE_DISTANCE then
this:SetBillboardLODNear(billboardGui)
elseif bubbleDistance >= NEAR_BUBBLE_DISTANCE and bubbleDistance < MAX_BUBBLE_DISTANCE then
this:SetBillboardLODDistant(billboardGui)
else
this:SetBillboardLODVeryFar(billboardGui)
end
end
function this:CameraCFrameChanged()
for index, value in pairs(this.CharacterSortedMsg:GetData()) do
local playerBillboardGui = value["BillboardGui"]
if playerBillboardGui then this:SetBillboardGuiLOD(playerBillboardGui, index) end
end
end
function this:CreateBubbleText(message)
local bubbleText = Instance.new("TextLabel")
bubbleText.Name = "BubbleText"
bubbleText.BackgroundTransparency = 1
bubbleText.Position = UDim2.new(0,CHAT_BUBBLE_WIDTH_PADDING/2,0,0)
bubbleText.Size = UDim2.new(1,-CHAT_BUBBLE_WIDTH_PADDING,1,0)
bubbleText.Font = CHAT_BUBBLE_FONT
bubbleText.TextWrapped = true
bubbleText.FontSize = CHAT_BUBBLE_FONT_SIZE
bubbleText.Text = message
bubbleText.Visible = false
return bubbleText
end
function this:CreateSmallTalkBubble(chatBubbleType)
local smallTalkBubble = this.ScalingChatBubbleWithTail[chatBubbleType]:Clone()
smallTalkBubble.Name = "SmallTalkBubble"
smallTalkBubble.Position = UDim2.new(0,0,1,-40)
smallTalkBubble.Visible = false
local text = this:CreateBubbleText("...")
text.TextScaled = true
text.TextWrapped = false
text.Visible = true
text.Parent = smallTalkBubble
return smallTalkBubble
end
function this:UpdateChatLinesForOrigin(origin, currentBubbleYPos)
local bubbleQueue = this.CharacterSortedMsg:Get(origin).Fifo
local bubbleQueueSize = bubbleQueue:Size()
local bubbleQueueData = bubbleQueue:GetData()
if #bubbleQueueData <= 1 then return end
for index = (#bubbleQueueData - 1), 1, -1 do
local value = bubbleQueueData[index]
local bubble = value.RenderBubble
if not bubble then return end
local bubblePos = bubbleQueueSize - index + 1
if bubblePos > 1 then
local tail = bubble:FindFirstChild("ChatBubbleTail")
if tail then tail:Destroy() end
local bubbleText = bubble:FindFirstChild("BubbleText")
if bubbleText then bubbleText.TextTransparency = 0.5 end
end
local udimValue = UDim2.new( bubble.Position.X.Scale, bubble.Position.X.Offset,
1, currentBubbleYPos - bubble.Size.Y.Offset )
bubble:TweenPosition(udimValue, Enum.EasingDirection.Out, Enum.EasingStyle.Bounce, 0.00000001, true)
currentBubbleYPos = currentBubbleYPos - bubble.Size.Y.Offset
end
end
function this:DestroyBubble(bubbleQueue, bubbleToDestroy)
if not bubbleQueue then return end
if bubbleQueue:Empty() then return end
local bubble = bubbleQueue:Front().RenderBubble
if not bubble then
bubbleQueue:PopFront()
return
end
spawn(function()
while bubbleQueue:Front().RenderBubble ~= bubbleToDestroy do
wait()
end
bubble = bubbleQueue:Front().RenderBubble
local timeBetween = 0
local bubbleText = bubble:FindFirstChild("BubbleText")
local bubbleTail = bubble:FindFirstChild("ChatBubbleTail")
--[[
while bubble and bubble.ImageTransparency < 1 do
timeBetween = wait()
if bubble then
local fadeAmount = timeBetween * CHAT_BUBBLE_FADE_SPEED
bubble.ImageTransparency = bubble.ImageTransparency + fadeAmount
if bubbleText then bubbleText.TextTransparency = bubbleText.TextTransparency + fadeAmount end
if bubbleTail then bubbleTail.ImageTransparency = bubbleTail.ImageTransparency + fadeAmount end
end
end]]
if bubble then
bubble:Destroy()
bubbleQueue:PopFront()
end
end)
end
function this:CreateChatLineRender(instance, line, onlyCharacter, fifo)
if not this.CharacterSortedMsg:Get(instance)["BillboardGui"] then
this:CreateBillboardGuiHelper(instance, onlyCharacter)
end
local billboardGui = this.CharacterSortedMsg:Get(instance)["BillboardGui"]
local chatBubbleRender = this.ChatBubbleWithTail[line.BubbleColor]:Clone()
chatBubbleRender.Visible = false
local bubbleText = this:CreateBubbleText(line.Message)
bubbleText.Parent = chatBubbleRender
chatBubbleRender.Parent = billboardGui.BillboardFrame
line.RenderBubble = chatBubbleRender
local currentTextBounds = TextService:GetTextSize(bubbleText.Text, CHAT_BUBBLE_FONT_SIZE_INT, CHAT_BUBBLE_FONT,
Vector2.new(BILLBOARD_MAX_WIDTH, BILLBOARD_MAX_HEIGHT))
local bubbleWidthScale = math.max((currentTextBounds.x + CHAT_BUBBLE_WIDTH_PADDING)/BILLBOARD_MAX_WIDTH, 0.1)
local numOflines = (currentTextBounds.y/CHAT_BUBBLE_FONT_SIZE_INT)
-- prep chat bubble for tween
chatBubbleRender.Size = UDim2.new(0,0,0,0)
chatBubbleRender.Position = UDim2.new(0.5,0,1,0)
local newChatBubbleOffsetSizeY = numOflines * CHAT_BUBBLE_LINE_HEIGHT
chatBubbleRender:TweenSizeAndPosition(UDim2.new(bubbleWidthScale, 0, 0, newChatBubbleOffsetSizeY),
UDim2.new( (1-bubbleWidthScale)/2, 0, 1, -newChatBubbleOffsetSizeY),
Enum.EasingDirection.Out, Enum.EasingStyle.Elastic, 0.1, true,
function() bubbleText.Visible = true end)
-- todo: remove when over max bubbles
this:SetBillboardGuiLOD(billboardGui, line.Origin)
this:UpdateChatLinesForOrigin(line.Origin, -newChatBubbleOffsetSizeY)
delay(line.BubbleDieDelay, function()
this:DestroyBubble(fifo, chatBubbleRender)
end)
end
local testLabel = Instance.new('TextLabel')
function isLabelTextAllowed(message)
--There exists an internal filter that filters out some profanity. It does this silently if you try to set text of an object.
--Here we check if the message is going to be filtered by applying it and comparing it.
testLabel.Text = message
return (testLabel.Text == message)
end
function this:OnPlayerChatMessage(chatType, sourcePlayer, message, targetPlayer)
if not this:BubbleChatEnabled() then return end
-- eliminate display of commands
if string.sub(message, 1, 1) == '/' then return end
local localPlayer = PlayersService.LocalPlayer
local fromOthers = localPlayer ~= nil and sourcePlayer ~= localPlayer
-- annihilate chats made by blocked or muted players
-- if blockingUtility:IsPlayerBlockedByUserId(sourcePlayer.userId) or blockingUtility:IsPlayerMutedByUserId(sourcePlayer.userId) then return end
-- remove messages that are filtered from the default gui text filter
if not isLabelTextAllowed(message) then return end
local luaChatType = ChatType.PLAYER_CHAT
if chatType == Enum.PlayerChatType.Team then
luaChatType = ChatType.PLAYER_TEAM_CHAT
elseif chatType == Enum.PlayerChatType.All then
luaChatType = ChatType.PLAYER_GAME_CHAT
elseif chatType == Enum.PlayerChatType.Whisper then
luaChatType = ChatType.PLAYER_WHISPER_CHAT
end
local safeMessage = this:SanitizeChatLine(message)
local line = createPlayerChatLine(chatType, sourcePlayer, safeMessage, not fromOthers)
local fifo = this.CharacterSortedMsg:Get(line.Origin).Fifo
fifo:PushBack(line)
if sourcePlayer then
--Game chat (badges) won't show up here
this:CreateChatLineRender(sourcePlayer.Character, line, true, fifo)
end
end
function this:OnGameChatMessage(origin, message, color)
if not this:BubbleChatEnabled() then return end
local localPlayer = PlayersService.LocalPlayer
local fromOthers = localPlayer ~= nil and (localPlayer.Character ~= origin)
local bubbleColor = BubbleColor.WHITE
if color == Enum.ChatColor.Blue then bubbleColor = BubbleColor.BLUE
elseif color == Enum.ChatColor.Green then bubbleColor = BubbleColor.GREEN
elseif color == Enum.ChatColor.Red then bubbleColor = BubbleColor.RED end
local safeMessage = this:SanitizeChatLine(message)
local line = createGameChatLine(origin, safeMessage, not fromOthers, bubbleColor)
this.CharacterSortedMsg:Get(line.Origin).Fifo:PushBack(line)
this:CreateChatLineRender(origin, line, false, this.CharacterSortedMsg:Get(line.Origin).Fifo)
end
function this:BubbleChatEnabled()
return PlayersService.BubbleChat
end
function this:CameraChanged(prop)
if prop == "CoordinateFrame" then
this:CameraCFrameChanged()
end
end
-- setup to datamodel connections
PlayersService.PlayerChatted:connect(function(chatType, player, message, targetPlayer) this:OnPlayerChatMessage(chatType, player, message, targetPlayer) end)
ChatService.Chatted:connect(function(origin, message, color) this:OnGameChatMessage(origin, message, color) end)
local cameraChangedCon = nil
if game.Workspace.CurrentCamera then
cameraChangedCon = game.Workspace.CurrentCamera.Changed:connect(function(prop) this:CameraChanged(prop) end)
end
game.Workspace.Changed:connect(function(prop)
if prop == "CurrentCamera" then
if cameraChangedCon then cameraChangedCon:disconnect() end
if game.Workspace.CurrentCamera then
cameraChangedCon = game.Workspace.CurrentCamera.Changed:connect(function(prop) this:CameraChanged(prop) end)
end
end
end)
end
local isClient = false
local success = pcall(function() isClient = game:GetService("RunService"):IsClient()end)
-- init only if we have a simulation going
if isClient or not success then
createChatOutput()
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,263 @@
-- ContextActionTouch.lua
-- this script controls ui and firing of lua functions that are bound in ContextActionService for touch inputs
-- Essentially a user can bind a lua function to a key code, input type (mousebutton1 etc.) and this
-- Variables
local contextActionService = Game:GetService("ContextActionService")
local isTouchDevice = Game:GetService("UserInputService").TouchEnabled
local functionTable = {}
local buttonVector = {}
local buttonScreenGui = nil
local buttonFrame = nil
local ContextDownImage = "ayaasset://textures/2015/ContextActionTouch/ContextDownImage.png"
local ContextUpImage = "ayaasset://textures/2015/ContextActionTouch/ContextUpImage.png"
local oldTouches = {}
local buttonPositionTable = {
[1] = UDim2.new(0,123,0,70),
[2] = UDim2.new(0,30,0,60),
[3] = UDim2.new(0,180,0,160),
[4] = UDim2.new(0,85,0,-25),
[5] = UDim2.new(0,185,0,-25),
[6] = UDim2.new(0,185,0,260),
[7] = UDim2.new(0,216,0,65)
}
local maxButtons = #buttonPositionTable
-- Preload images
Game:GetService("ContentProvider"):Preload(ContextDownImage)
Game:GetService("ContentProvider"):Preload(ContextUpImage)
while not Game.Players do
wait()
end
while not Game.Players.LocalPlayer do
wait()
end
function createContextActionGui()
if not buttonScreenGui and isTouchDevice then
buttonScreenGui = Instance.new("ScreenGui")
buttonScreenGui.Name = "ContextActionGui"
buttonFrame = Instance.new("Frame")
buttonFrame.BackgroundTransparency = 1
buttonFrame.Size = UDim2.new(0.3,0,0.5,0)
buttonFrame.Position = UDim2.new(0.7,0,0.5,0)
buttonFrame.Name = "ContextButtonFrame"
buttonFrame.Parent = buttonScreenGui
end
end
-- functions
function setButtonSizeAndPosition(object)
local buttonSize = 55
local xOffset = 10
local yOffset = 95
-- todo: better way to determine mobile sized screens
local onSmallScreen = (game.CoreGui.RobloxGui.AbsoluteSize.X < 600)
if not onSmallScreen then
buttonSize = 85
xOffset = 40
end
object.Size = UDim2.new(0,buttonSize,0,buttonSize)
end
function contextButtonDown(button, inputObject, actionName)
if inputObject.UserInputType == Enum.UserInputType.Touch then
button.Image = ContextDownImage
contextActionService:CallFunction(actionName, Enum.UserInputState.Begin, inputObject)
end
end
function contextButtonMoved(button, inputObject, actionName)
if inputObject.UserInputType == Enum.UserInputType.Touch then
button.Image = ContextDownImage
contextActionService:CallFunction(actionName, Enum.UserInputState.Change, inputObject)
end
end
function contextButtonUp(button, inputObject, actionName)
button.Image = ContextUpImage
if inputObject.UserInputType == Enum.UserInputType.Touch and inputObject.UserInputState == Enum.UserInputState.End then
contextActionService:CallFunction(actionName, Enum.UserInputState.End, inputObject)
end
end
function isSmallScreenDevice()
return Game:GetService("GuiService"):GetScreenResolution().y <= 320
end
function createNewButton(actionName, functionInfoTable)
local contextButton = Instance.new("ImageButton")
contextButton.Name = "ContextActionButton"
contextButton.BackgroundTransparency = 1
contextButton.Size = UDim2.new(0,90,0,90)
contextButton.Active = true
if isSmallScreenDevice() then
contextButton.Size = UDim2.new(0,70,0,70)
end
contextButton.Image = ContextUpImage
contextButton.Parent = buttonFrame
local currentButtonTouch = nil
Game:GetService("UserInputService").InputEnded:connect(function ( inputObject )
oldTouches[inputObject] = nil
end)
contextButton.InputBegan:connect(function(inputObject)
if oldTouches[inputObject] then return end
if inputObject.UserInputState == Enum.UserInputState.Begin and currentButtonTouch == nil then
currentButtonTouch = inputObject
contextButtonDown(contextButton, inputObject, actionName)
end
end)
contextButton.InputChanged:connect(function(inputObject)
if oldTouches[inputObject] then return end
if currentButtonTouch ~= inputObject then return end
contextButtonMoved(contextButton, inputObject, actionName)
end)
contextButton.InputEnded:connect(function(inputObject)
if oldTouches[inputObject] then return end
if currentButtonTouch ~= inputObject then return end
currentButtonTouch = nil
oldTouches[inputObject] = true
contextButtonUp(contextButton, inputObject, actionName)
end)
local actionIcon = Instance.new("ImageLabel")
actionIcon.Name = "ActionIcon"
actionIcon.Position = UDim2.new(0.175, 0, 0.175, 0)
actionIcon.Size = UDim2.new(0.65, 0, 0.65, 0)
actionIcon.BackgroundTransparency = 1
if functionInfoTable["image"] and type(functionInfoTable["image"]) == "string" then
actionIcon.Image = functionInfoTable["image"]
end
actionIcon.Parent = contextButton
local actionTitle = Instance.new("TextLabel")
actionTitle.Name = "ActionTitle"
actionTitle.Size = UDim2.new(1,0,1,0)
actionTitle.BackgroundTransparency = 1
actionTitle.Font = Enum.Font.SourceSansBold
actionTitle.TextColor3 = Color3.new(1,1,1)
actionTitle.TextStrokeTransparency = 0
actionTitle.FontSize = Enum.FontSize.Size18
actionTitle.TextWrapped = true
actionTitle.Text = ""
if functionInfoTable["title"] and type(functionInfoTable["title"]) == "string" then
actionTitle.Text = functionInfoTable["title"]
end
actionTitle.Parent = contextButton
return contextButton
end
function createButton( actionName, functionInfoTable )
local button = createNewButton(actionName, functionInfoTable)
local position = nil
for i = 1,#buttonVector do
if buttonVector[i] == "empty" then
position = i
break
end
end
if not position then
position = #buttonVector + 1
end
if position > maxButtons then
return -- todo: let user know we have too many buttons already?
end
buttonVector[position] = button
functionTable[actionName]["button"] = button
button.Position = buttonPositionTable[position]
button.Parent = buttonFrame
if buttonScreenGui and buttonScreenGui.Parent == nil then
buttonScreenGui.Parent = Game.Players.LocalPlayer.PlayerGui
end
end
function removeAction(actionName)
if not functionTable[actionName] then return end
local actionButton = functionTable[actionName]["button"]
if actionButton then
actionButton.Parent = nil
for i = 1,#buttonVector do
if buttonVector[i] == actionButton then
buttonVector[i] = "empty"
break
end
end
actionButton:Destroy()
end
functionTable[actionName] = nil
end
function addAction(actionName,createTouchButton,functionInfoTable)
if functionTable[actionName] then
removeAction(actionName)
end
functionTable[actionName] = {functionInfoTable}
if createTouchButton and isTouchDevice then
createContextActionGui()
createButton(actionName, functionInfoTable)
end
end
-- Connections
contextActionService.BoundActionChanged:connect( function(actionName, changeName, changeTable)
if functionTable[actionName] and changeTable then
local button = functionTable[actionName]["button"]
if button then
if changeName == "image" then
button.ActionIcon.Image = changeTable[changeName]
elseif changeName == "title" then
button.ActionTitle.Text = changeTable[changeName]
elseif changeName == "description" then
-- todo: add description to menu
elseif changeName == "position" then
button.Position = changeTable[changeName]
end
end
end
end)
contextActionService.BoundActionAdded:connect( function(actionName, createTouchButton, functionInfoTable)
addAction(actionName, createTouchButton, functionInfoTable)
end)
contextActionService.BoundActionRemoved:connect( function(actionName, functionInfoTable)
removeAction(actionName)
end)
contextActionService.GetActionButtonEvent:connect( function(actionName)
if functionTable[actionName] then
contextActionService:FireActionButtonFoundSignal(actionName, functionTable[actionName]["button"])
end
end)
-- make sure any bound data before we setup connections is handled
local boundActions = contextActionService:GetAllBoundActionInfo()
for actionName, actionData in pairs(boundActions) do
addAction(actionName,actionData["createTouchButton"],actionData)
end

View File

@@ -0,0 +1,609 @@
--[[
This script controls the gui the player sees in regards to his or her health.
Can be turned with Game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Health,false)
--]]
---------------------------------------------------------------------
-- Initialize/Variables
while not game do
wait(1/60)
end
while not game:GetService("Players") do
wait(1/60)
end
local GameSettings = UserSettings().GameSettings
local currentHumanoid = nil
local LegacyHealthGui = nil
local lastHealth = 100
local lastHealth2 = 100
local maxWidth = 0.96
local HealthGui = nil
local lastHealth = 100
local HealthPercentageForOverlay = 5
local maxBarTweenTime = 0.3
local greenColor = Color3.new(0.2, 1, 0.2)
local redColor = Color3.new(1, 0.2, 0.2)
local yellowColor = Color3.new(1, 1, 0.2)
local guiEnabled = false
local healthChangedConnection = nil
local humanoidDiedConnection = nil
local characterAddedConnection = nil
local greenBarImage = "ayaasset://textures/ui/Health-BKG-Center.png"
local greenBarImageLeft = "ayaasset://textures/ui/Health-BKG-Left-Cap.png"
local greenBarImageRight = "ayaasset://textures/ui/Health-BKG-Right-Cap.png"
local hurtOverlayImage = "ayaasset://textures/2015/HealthScript/hurtOverlayImage.png"
game:GetService("ContentProvider"):Preload(greenBarImage)
game:GetService("ContentProvider"):Preload(hurtOverlayImage)
while not game:GetService("Players").LocalPlayer do
wait(1/60)
end
---------------------------------------------------------------------
-- Functions
local capHeight = 15
local capWidth = 7
function CreateGui()
if HealthGui and #HealthGui:GetChildren() > 0 then
HealthGui.Parent = game:GetService("CoreGui").RobloxGui
return
end
local hurtOverlay = Instance.new("ImageLabel")
hurtOverlay.Name = "HurtOverlay"
hurtOverlay.BackgroundTransparency = 1
hurtOverlay.Image = hurtOverlayImage
hurtOverlay.Position = UDim2.new(-10,0,-10,0)
hurtOverlay.Size = UDim2.new(20,0,20,0)
hurtOverlay.Visible = false
hurtOverlay.Parent = HealthGui
local healthFrame = Instance.new("Frame")
healthFrame.Name = "HealthFrame"
healthFrame.BackgroundTransparency = 1
healthFrame.BackgroundColor3 = Color3.new(1,1,1)
healthFrame.BorderColor3 = Color3.new(0,0,0)
healthFrame.BorderSizePixel = 0
healthFrame.Position = UDim2.new(0.5,-85,1,-20)
healthFrame.Size = UDim2.new(0,170,0,capHeight)
healthFrame.Parent = HealthGui
local healthBarBackCenter = Instance.new("ImageLabel")
healthBarBackCenter.Name = "healthBarBackCenter"
healthBarBackCenter.BackgroundTransparency = 1
healthBarBackCenter.Image = greenBarImage
healthBarBackCenter.Size = UDim2.new(1,-capWidth*2,1,0)
healthBarBackCenter.Position = UDim2.new(0,capWidth,0,0)
healthBarBackCenter.Parent = healthFrame
healthBarBackCenter.ImageColor3 = Color3.new(1,1,1)
local healthBarBackLeft = Instance.new("ImageLabel")
healthBarBackLeft.Name = "healthBarBackLeft"
healthBarBackLeft.BackgroundTransparency = 1
healthBarBackLeft.Image = greenBarImageLeft
healthBarBackLeft.Size = UDim2.new(0,capWidth,1,0)
healthBarBackLeft.Position = UDim2.new(0,0,0,0)
healthBarBackLeft.Parent = healthFrame
healthBarBackLeft.ImageColor3 = Color3.new(1,1,1)
local healthBarBackRight = Instance.new("ImageLabel")
healthBarBackRight.Name = "healthBarBackRight"
healthBarBackRight.BackgroundTransparency = 1
healthBarBackRight.Image = greenBarImageRight
healthBarBackRight.Size = UDim2.new(0,capWidth,1,0)
healthBarBackRight.Position = UDim2.new(1,-capWidth,0,0)
healthBarBackRight.Parent = healthFrame
healthBarBackRight.ImageColor3 = Color3.new(1,1,1)
local healthBar = Instance.new("Frame")
healthBar.Name = "HealthBar"
healthBar.BackgroundTransparency = 1
healthBar.BackgroundColor3 = Color3.new(1,1,1)
healthBar.BorderColor3 = Color3.new(0,0,0)
healthBar.BorderSizePixel = 0
healthBar.ClipsDescendants = true
healthBar.Position = UDim2.new(0, 0, 0, 0)
healthBar.Size = UDim2.new(1,0,1,0)
healthBar.Parent = healthFrame
local healthBarCenter = Instance.new("ImageLabel")
healthBarCenter.Name = "healthBarCenter"
healthBarCenter.BackgroundTransparency = 1
healthBarCenter.Image = greenBarImage
healthBarCenter.Size = UDim2.new(1,-capWidth*2,1,0)
healthBarCenter.Position = UDim2.new(0,capWidth,0,0)
healthBarCenter.Parent = healthBar
healthBarCenter.ImageColor3 = greenColor
local healthBarLeft = Instance.new("ImageLabel")
healthBarLeft.Name = "healthBarLeft"
healthBarLeft.BackgroundTransparency = 1
healthBarLeft.Image = greenBarImageLeft
healthBarLeft.Size = UDim2.new(0,capWidth,1,0)
healthBarLeft.Position = UDim2.new(0,0,0,0)
healthBarLeft.Parent = healthBar
healthBarLeft.ImageColor3 = greenColor
local healthBarRight = Instance.new("ImageLabel")
healthBarRight.Name = "healthBarRight"
healthBarRight.BackgroundTransparency = 1
healthBarRight.Image = greenBarImageRight
healthBarRight.Size = UDim2.new(0,capWidth,1,0)
healthBarRight.Position = UDim2.new(1,-capWidth,0,0)
healthBarRight.Parent = healthBar
healthBarRight.ImageColor3 = greenColor
HealthGui.Parent = game:GetService("CoreGui").RobloxGui
end
function UpdateGui(health)
if not HealthGui then return end
local healthFrame = HealthGui:FindFirstChild("HealthFrame")
if not healthFrame then return end
local healthBar = healthFrame:FindFirstChild("HealthBar")
if not healthBar then return end
-- If more than 1/4 health, bar = green. Else, bar = red.
local percentHealth = (health/currentHumanoid.MaxHealth)
if percentHealth ~= percentHealth then
percentHealth = 1
healthBar.healthBarCenter.ImageColor3 = yellowColor
healthBar.healthBarRight.ImageColor3 = yellowColor
healthBar.healthBarLeft.ImageColor3 = yellowColor
elseif percentHealth > 0.25 then
healthBar.healthBarCenter.ImageColor3 = greenColor
healthBar.healthBarRight.ImageColor3 = greenColor
healthBar.healthBarLeft.ImageColor3 = greenColor
else
healthBar.healthBarCenter.ImageColor3 = redColor
healthBar.healthBarRight.ImageColor3 = redColor
healthBar.healthBarLeft.ImageColor3 = redColor
end
local width = (health / currentHumanoid.MaxHealth)
width = math.max(math.min(width,1),0) -- make sure width is between 0 and 1
if width ~= width then width = 1 end
local healthDelta = lastHealth - health
lastHealth = health
local percentOfTotalHealth = math.abs(healthDelta/currentHumanoid.MaxHealth)
percentOfTotalHealth = math.max(math.min(percentOfTotalHealth,1),0) -- make sure percentOfTotalHealth is between 0 and 1
if percentOfTotalHealth ~= percentOfTotalHealth then percentOfTotalHealth = 1 end
local newHealthSize = UDim2.new(width,0,1,0)
healthBar.Size = newHealthSize
local sizeX = healthBar.AbsoluteSize.X
if sizeX < capWidth then
healthBar.healthBarCenter.Visible = false
healthBar.healthBarRight.Visible = false
elseif sizeX < (2*capWidth + 1) then
healthBar.healthBarCenter.Visible = true
healthBar.healthBarCenter.Size = UDim2.new(0,sizeX - capWidth,1,0)
healthBar.healthBarRight.Visible = false
else
healthBar.healthBarCenter.Visible = true
healthBar.healthBarCenter.Size = UDim2.new(1,-capWidth*2,1,0)
healthBar.healthBarRight.Visible = true
end
local thresholdForHurtOverlay = currentHumanoid.MaxHealth * (HealthPercentageForOverlay/100)
if healthDelta >= thresholdForHurtOverlay and guiEnabled then
AnimateHurtOverlay()
end
end
function AnimateHurtOverlay()
if not HealthGui then return end
local overlay = HealthGui:FindFirstChild("HurtOverlay")
if not overlay then return end
local newSize = UDim2.new(20, 0, 20, 0)
local newPos = UDim2.new(-10, 0, -10, 0)
if overlay:IsDescendantOf(game) then
-- stop any tweens on overlay
overlay:TweenSizeAndPosition(newSize,newPos,Enum.EasingDirection.Out,Enum.EasingStyle.Linear,0,true,function()
-- show the gui
overlay.Size = UDim2.new(1,0,1,0)
overlay.Position = UDim2.new(0,0,0,0)
overlay.Visible = true
-- now tween the hide
if overlay:IsDescendantOf(game) then
overlay:TweenSizeAndPosition(newSize,newPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,10,false,function()
overlay.Visible = false
end)
else
overlay.Size = newSize
overlay.Position = newPos
end
end)
else
overlay.Size = newSize
overlay.Position = newPos
end
end
function humanoidDied()
UpdateGui(0)
end
function disconnectPlayerConnections()
if characterAddedConnection then characterAddedConnection:disconnect() end
if humanoidDiedConnection then humanoidDiedConnection:disconnect() end
if healthChangedConnection then healthChangedConnection:disconnect() end
end
function newPlayerCharacter()
disconnectPlayerConnections()
local version = GameSettings.VirtualVersion
if version == Enum.VirtualVersion['2016'] or version == Enum.VirtualVersion['2015'] or version == Enum.VirtualVersion['2014'] then
startGui()
else
startGuiLegacy()
end
end
function startGui()
characterAddedConnection = game:GetService("Players").LocalPlayer.CharacterAdded:connect(newPlayerCharacter)
local character = game:GetService("Players").LocalPlayer.Character
if not character then
return
end
currentHumanoid = character:WaitForChild("Humanoid")
if not currentHumanoid then
return
end
if not game:GetService("StarterGui"):GetCoreGuiEnabled(Enum.CoreGuiType.Health) then
return
end
healthChangedConnection = currentHumanoid.HealthChanged:connect(UpdateGui)
humanoidDiedConnection = currentHumanoid.Died:connect(humanoidDied)
UpdateGui(currentHumanoid.Health)
CreateGui()
end
function CreateGuiLegacy()
if LegacyHealthGui then LegacyHealthGui:Destroy() end
local tray = Instance.new("Frame")
tray.Name = "HealthGui"
tray.BackgroundColor3 = Color3.fromRGB(107, 50, 124)
tray.BackgroundTransparency = 1
tray.BorderColor3 = Color3.fromRGB(27, 42, 53)
tray.BorderSizePixel = 1
tray.Position = UDim2.new(0.5, -44, 1, -26)
tray.Size = UDim2.new(0, 170, 0, 18)
tray.SizeConstraint = Enum.SizeConstraint.RelativeYY
tray.Visible = true
tray.archivable = true
tray.ZIndex = 1
local bkg = Instance.new("ImageLabel")
bkg.Name = "bkg"
bkg.Active = false
bkg.BackgroundTransparency = 1
bkg.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
bkg.BorderColor3 = Color3.fromRGB(27, 42, 53)
bkg.BorderSizePixel = 1
bkg.Position = UDim2.new(0, 0, 0, 0)
bkg.Image = "ayaasset://textures/ui/healthBarBkg.png"
bkg.Size = UDim2.new(1, 0, 1, 0)
bkg.SizeConstraint = Enum.SizeConstraint.RelativeXY
bkg.Visible = true
bkg.archivable = true
bkg.ZIndex = 1
bkg.Parent = tray
local bar2 = Instance.new("Frame")
bar2.Name = "bar2"
bar2.Active = false
bar2.BackgroundTransparency = 1
bar2.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
bar2.BorderColor3 = Color3.fromRGB(27, 42, 53)
bar2.BorderSizePixel = 0
bar2.Position = UDim2.new(0.0189999994, 0, 0.100000001, 0)
bar2.Size = UDim2.new(0.192000002, 0, 0.829999983, 0)
bar2.SizeConstraint = Enum.SizeConstraint.RelativeXY
bar2.Visible = true
bar2.archivable = true
bar2.ZIndex = 1
bar2.Parent = tray
local bar = Instance.new("ImageLabel")
bar.Name = "bar"
bar.Active = false
bar.BackgroundTransparency = 1
bar.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
bar.BorderColor3 = Color3.fromRGB(27, 42, 53)
bar.BorderSizePixel = 1
bar.Position = UDim2.new(0.0189999994, 0, 0.100000001, 0)
bar.Image = "ayaasset://textures/ui/healthBarGreen.png"
bar.Size = UDim2.new(0.959999979, 0, 0.829999983, 0)
bar.SizeConstraint = Enum.SizeConstraint.RelativeXY
bar.Visible = true
bar.archivable = true
bar.ZIndex = 1
bar.Parent = tray
local label = Instance.new("ImageLabel")
label.Name = "label"
label.Active = false
label.BackgroundTransparency = 1
label.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
label.BorderColor3 = Color3.fromRGB(27, 42, 53)
label.BorderSizePixel = 0
label.Position = UDim2.new(0.680000007, 0, 0.300000012, 0)
label.Size = UDim2.new(0.25, 0, 0.349999994, 0)
label.SizeConstraint = Enum.SizeConstraint.RelativeXY
label.Visible = true
label.archivable = true
label.ZIndex = 1
label.Parent = tray
label.Image = "ayaasset://textures/ui/healthLabel.png"
local barRed = Instance.new("ImageLabel")
barRed.Name = "barRed"
barRed.Active = false
barRed.BackgroundTransparency = 1
barRed.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
barRed.BorderColor3 = Color3.fromRGB(27, 42, 53)
barRed.BorderSizePixel = 1
barRed.Position = UDim2.new(0.0189999994, 0, 0.100000001, 0)
barRed.Image = "ayaasset://textures/ui/healthBarRed.png"
barRed.Size = UDim2.new(0, 0, 0, 0)
barRed.SizeConstraint = Enum.SizeConstraint.RelativeXY
barRed.Visible = true
barRed.archivable = true
barRed.ZIndex = 1
barRed.Parent = tray
local hurtOverlay = Instance.new("ImageLabel")
hurtOverlay.Name = "HurtOverlay"
hurtOverlay.BackgroundTransparency = 1
hurtOverlay.Image = "ayaasset://textures/ui/legacyHurtOverlay.png"
hurtOverlay.Position = UDim2.new(10, 0, 0, 0)
hurtOverlay.Size = UDim2.new(1, 0, 1.15, 30)
hurtOverlay.Visible = false
hurtOverlay.Parent = tray
LegacyHealthGui = tray
LegacyHealthGui.Parent = game:GetService("CoreGui").RobloxGui
end
function UpdateGUILegacy(health)
local tray = LegacyHealthGui
local width = (health / currentHumanoid.MaxHealth) * maxWidth
local height = 0.83
local lastX = tray.bar.Position.X.Scale
local x = 0.019 + (maxWidth - width)
local y = 0.1
tray.bar.Position = UDim2.new(x,0,y, 0)
tray.bar.Size = UDim2.new(width, 0, height, 0)
-- If more than 1/4 health, bar = green. Else, bar = red.
if( (health / currentHumanoid.MaxHealth) > 0.25 ) then
tray.barRed.Size = UDim2.new(0, 0, 0, 0)
else
tray.barRed.Position = tray.bar.Position
tray.barRed.Size = tray.bar.Size
tray.bar.Size = UDim2.new(0, 0, 0, 0)
end
if ( (lastHealth - health) > (currentHumanoid.MaxHealth / 10) ) then
lastHealth = health
if currentHumanoid.Health ~= currentHumanoid.MaxHealth then
delay(0,function()
AnimateHurtOverlay()
end)
delay(0,function()
AnimateBarsLegacy(x, y, lastX, height)
end)
end
else
lastHealth = health
end
end
function AnimateHurtOverlay()
-- Start:
-- overlay.Position = UDim2.new(0, 0, 0, -22)
-- overlay.Size = UDim2.new(1, 0, 1.15, 30)
-- Finish:
-- overlay.Position = UDim2.new(-2, 0, -2, -22)
-- overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
overlay = LegacyHealthGui.HurtOverlay
overlay.Position = UDim2.new(-2, 0, -2, -22)
overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
-- Animate In, fast
local i_total = 2
local wiggle_total = 0
local wiggle_i = 0.02
for i=1,i_total do
overlay.Position = UDim2.new( (-2 + (2 * (i/i_total)) + wiggle_total/2), 0, (-2 + (2 * (i/i_total)) + wiggle_total/2), -22 )
overlay.Size = UDim2.new( (4.5 - (3.5 * (i/i_total)) + wiggle_total), 0, (4.65 - (3.5 * (i/i_total)) + wiggle_total), 30 )
wait(0.01)
end
i_total = 30
wait(0.03)
-- Animate Out, slow
for i=1,i_total do
if( math.abs(wiggle_total) > (wiggle_i * 3) ) then
wiggle_i = -wiggle_i
end
wiggle_total = wiggle_total + wiggle_i
overlay.Position = UDim2.new( (0 - (2 * (i/i_total)) + wiggle_total/2), 0, (0 - (2 * (i/i_total)) + wiggle_total/2), -22 )
overlay.Size = UDim2.new( (1 + (3.5 * (i/i_total)) + wiggle_total), 0, (1.15 + (3.5 * (i/i_total)) + wiggle_total), 30 )
wait(0.01)
end
-- Hide after we're done
overlay.Position = UDim2.new(10, 0, 0, 0)
end
function AnimateBarsLegacy(x, y, lastX, height)
local tray = LegacyHealthGui
local width = math.abs(x - lastX)
if( x > lastX ) then
x = lastX
end
tray.bar2.Position = UDim2.new(x,0, y, 0)
tray.bar2.Size = UDim2.new(width, 0, height, 0)
tray.bar2.BackgroundTransparency = 0
local GBchannels = 1
local j = 0.2
local i_total = 30
for i=1,i_total do
-- Increment Values
if (GBchannels < 0.2) then
j = -j
end
GBchannels = GBchannels + j
if (i > (i_total - 10)) then
tray.bar2.BackgroundTransparency = tray.bar2.BackgroundTransparency + 0.1
end
tray.bar2.BackgroundColor3 = Color3.new(1, GBchannels, GBchannels)
wait(0.02)
end
end
function HealthChangedLegacy(health)
UpdateGUILegacy(health)
if ( (lastHealth2 - health) > (currentHumanoid.MaxHealth / 10) ) then
lastHealth2 = health
else
lastHealth2 = health
end
end
function startGuiLegacy()
characterAddedConnection = game:GetService("Players").LocalPlayer.CharacterAdded:connect(newPlayerCharacter)
local character = game:GetService("Players").LocalPlayer.Character
if not character then
return
end
currentHumanoid = character:WaitForChild("Humanoid")
if not currentHumanoid then
return
end
if not game:GetService("StarterGui"):GetCoreGuiEnabled(Enum.CoreGuiType.Health) then
return
end
healthChangedConnection = currentHumanoid.HealthChanged:connect(HealthChangedLegacy)
humanoidDiedConnection = currentHumanoid.Died:connect(function() HealthChangedLegacy(0) end)
CreateGuiLegacy()
end
---------------------------------------------------------------------
-- Start Script
HealthGui = Instance.new("Frame")
HealthGui.Name = "HealthGui"
HealthGui.BackgroundTransparency = 1
HealthGui.Size = UDim2.new(1,0,1,0)
game:GetService("StarterGui").CoreGuiChangedSignal:connect(function(coreGuiType,enabled)
if coreGuiType == Enum.CoreGuiType.Health or coreGuiType == Enum.CoreGuiType.All then
if guiEnabled and not enabled then
if HealthGui then
HealthGui.Parent = nil
end
if LegacyHealthGui then
LegacyHealthGui:Destroy()
end
disconnectPlayerConnections()
elseif not guiEnabled and enabled then
startGui()
end
guiEnabled = enabled
end
end)
if game:GetService("StarterGui"):GetCoreGuiEnabled(Enum.CoreGuiType.Health) and GameSettings.VirtualVersion ~= Enum.VirtualVersion['2016'] then
guiEnabled = true
startGuiLegacy()
end
GameSettings.Changed:connect(function(prop)
if prop ~= 'VirtualVersion' then return end
local enabled = GameSettings.VirtualVersion ~= Enum.VirtualVersion['2016']
if guiEnabled and not enabled then
if HealthGui then
HealthGui.Parent = nil
end
if LegacyHealthGui then
LegacyHealthGui:Destroy()
end
disconnectPlayerConnections()
elseif not guiEnabled and enabled then
startGuiLegacy()
end
guiEnabled = enabled
local version = GameSettings.VirtualVersion
if guiEnabled and HealthGui and version ~= Enum.VirtualVersion['2016'] and version ~= Enum.VirtualVersion['2015'] and version ~= Enum.VirtualVersion['2014'] then
if HealthGui then
HealthGui.Parent = nil
end
disconnectPlayerConnections()
startGuiLegacy()
elseif guiEnabled and LegacyHealthGui and (version == Enum.VirtualVersion['2016'] or version == Enum.VirtualVersion['2015'] or version == Enum.VirtualVersion['2014']) then
if LegacyHealthGui then
LegacyHealthGui:Destroy()
end
disconnectPlayerConnections()
startGuiLegacy()
end
end)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,560 @@
function waitForProperty(instance, name)
while not instance[name] do
instance.Changed:wait()
end
end
function waitForChild(instance, name)
while not instance:FindFirstChild(name) do
instance.ChildAdded:wait()
end
end
local mainFrame
local choices = {}
local lastChoice
local choiceMap = {}
local currentConversationDialog
local currentConversationPartner
local currentAbortDialogScript
local tooFarAwayMessage = "You are too far away to chat!"
local tooFarAwaySize = 300
local characterWanderedOffMessage = "Chat ended because you walked away"
local characterWanderedOffSize = 350
local conversationTimedOut = "Chat ended because you didn't reply"
local conversationTimedOutSize = 350
local player
local screenGui
local chatNotificationGui
local messageDialog
local timeoutScript
local reenableDialogScript
local dialogMap = {}
local dialogConnections = {}
local gui = nil
waitForChild(game,"CoreGui")
waitForChild(game.CoreGui,"RobloxGui")
if game.CoreGui.RobloxGui:FindFirstChild("ControlFrame") then
gui = game.CoreGui.RobloxGui.ControlFrame
else
gui = game.CoreGui.RobloxGui
end
function currentTone()
if currentConversationDialog then
return currentConversationDialog.Tone
else
return Enum.DialogTone.Neutral
end
end
function createChatNotificationGui()
chatNotificationGui = Instance.new("BillboardGui")
chatNotificationGui.Name = "ChatNotificationGui"
chatNotificationGui.ExtentsOffset = Vector3.new(0,1,0)
chatNotificationGui.Size = UDim2.new(4, 0, 5.42857122, 0)
chatNotificationGui.SizeOffset = Vector2.new(0,0)
chatNotificationGui.StudsOffset = Vector3.new(0.4, 4.3, 0)
chatNotificationGui.Enabled = true
chatNotificationGui.RobloxLocked = true
chatNotificationGui.Active = true
local image = Instance.new("ImageLabel")
image.Name = "Image"
image.Active = false
image.BackgroundTransparency = 1
image.Position = UDim2.new(0,0,0,0)
image.Size = UDim2.new(1.0,0,1.0,0)
image.Image = ""
image.RobloxLocked = true
image.Parent = chatNotificationGui
local button = Instance.new("ImageButton")
button.Name = "Button"
button.AutoButtonColor = false
button.Position = UDim2.new(0.0879999995, 0, 0.0529999994, 0)
button.Size = UDim2.new(0.829999983, 0, 0.460000008, 0)
button.Image = ""
button.BackgroundTransparency = 1
button.RobloxLocked = true
button.Parent = image
end
function getChatColor(tone)
if tone == Enum.DialogTone.Neutral then
return Enum.ChatColor.Blue
elseif tone == Enum.DialogTone.Friendly then
return Enum.ChatColor.Green
elseif tone == Enum.DialogTone.Enemy then
return Enum.ChatColor.Red
end
end
function styleChoices(tone)
for i, obj in pairs(choices) do
resetColor(obj, tone)
end
resetColor(lastChoice, tone)
end
function styleMainFrame(tone)
if tone == Enum.DialogTone.Neutral then
mainFrame.Style = Enum.FrameStyle.ChatBlue
mainFrame.Tail.Image = "ayaasset://textures/chatBubble_botBlue_tailRight.png"
elseif tone == Enum.DialogTone.Friendly then
mainFrame.Style = Enum.FrameStyle.ChatGreen
mainFrame.Tail.Image = "ayaasset://textures/chatBubble_botGreen_tailRight.png"
elseif tone == Enum.DialogTone.Enemy then
mainFrame.Style = Enum.FrameStyle.ChatRed
mainFrame.Tail.Image = "ayaasset://textures/chatBubble_botRed_tailRight.png"
end
styleChoices(tone)
end
function setChatNotificationTone(gui, purpose, tone)
if tone == Enum.DialogTone.Neutral then
gui.Image.Image = "ayaasset://textures/chatBubble_botBlue_notify_bkg.png"
elseif tone == Enum.DialogTone.Friendly then
gui.Image.Image = "ayaasset://textures/chatBubble_botGreen_notify_bkg.png"
elseif tone == Enum.DialogTone.Enemy then
gui.Image.Image = "ayaasset://textures/chatBubble_botRed_notify_bkg.png"
end
if purpose == Enum.DialogPurpose.Quest then
gui.Image.Button.Image = "ayaasset://textures/chatBubble_bot_notify_bang.png"
elseif purpose == Enum.DialogPurpose.Help then
gui.Image.Button.Image = "ayaasset://textures/chatBubble_bot_notify_question.png"
elseif purpose == Enum.DialogPurpose.Shop then
gui.Image.Button.Image = "ayaasset://textures/chatBubble_bot_notify_money.png"
end
end
function createMessageDialog()
messageDialog = Instance.new("Frame");
messageDialog.Name = "DialogScriptMessage"
messageDialog.Style = Enum.FrameStyle.RobloxRound
messageDialog.Visible = false
local text = Instance.new("TextLabel")
text.Name = "Text"
text.Position = UDim2.new(0,0,0,-1)
text.Size = UDim2.new(1,0,1,0)
text.FontSize = Enum.FontSize.Size14
text.BackgroundTransparency = 1
text.TextColor3 = Color3.new(1,1,1)
text.RobloxLocked = true
text.Parent = messageDialog
end
function showMessage(msg, size)
messageDialog.Text.Text = msg
messageDialog.Size = UDim2.new(0,size,0,40)
messageDialog.Position = UDim2.new(0.5, -size/2, 0.5, -40)
messageDialog.Visible = true
wait(2)
messageDialog.Visible = false
end
function variableDelay(str)
local length = math.min(string.len(str), 100)
wait(0.75 + ((length/75) * 1.5))
end
function resetColor(frame, tone)
if tone == Enum.DialogTone.Neutral then
frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
frame.Number.TextColor3 = Color3.new(45/255, 142/255, 245/255)
elseif tone == Enum.DialogTone.Friendly then
frame.BackgroundColor3 = Color3.new(0/255, 77/255, 0/255)
frame.Number.TextColor3 = Color3.new(0/255, 190/255, 0/255)
elseif tone == Enum.DialogTone.Enemy then
frame.BackgroundColor3 = Color3.new(140/255, 0/255, 0/255)
frame.Number.TextColor3 = Color3.new(255/255,88/255, 79/255)
end
end
function highlightColor(frame, tone)
if tone == Enum.DialogTone.Neutral then
frame.BackgroundColor3 = Color3.new(2/255, 108/255, 255/255)
frame.Number.TextColor3 = Color3.new(1, 1, 1)
elseif tone == Enum.DialogTone.Friendly then
frame.BackgroundColor3 = Color3.new(0/255, 128/255, 0/255)
frame.Number.TextColor3 = Color3.new(1, 1, 1)
elseif tone == Enum.DialogTone.Enemy then
frame.BackgroundColor3 = Color3.new(204/255, 0/255, 0/255)
frame.Number.TextColor3 = Color3.new(1, 1, 1)
end
end
function wanderDialog()
print("Wander")
mainFrame.Visible = false
endDialog()
showMessage(characterWanderedOffMessage, characterWanderedOffSize)
end
function timeoutDialog()
print("Timeout")
mainFrame.Visible = false
endDialog()
showMessage(conversationTimedOut, conversationTimedOutSize)
end
function normalEndDialog()
print("Done")
endDialog()
end
function endDialog()
if currentAbortDialogScript then
currentAbortDialogScript:Remove()
currentAbortDialogScript = nil
end
local dialog = currentConversationDialog
currentConversationDialog = nil
if dialog and dialog.InUse then
local reenableScript = reenableDialogScript:Clone()
reenableScript.archivable = false
reenableScript.Disabled = false
reenableScript.Parent = dialog
end
for dialog, gui in pairs(dialogMap) do
if dialog and gui then
gui.Enabled = not dialog.InUse
end
end
currentConversationPartner = nil
end
function sanitizeMessage(msg)
if string.len(msg) == 0 then
return "..."
else
return msg
end
end
function selectChoice(choice)
renewKillswitch(currentConversationDialog)
--First hide the Gui
mainFrame.Visible = false
if choice == lastChoice then
game.Chat:Chat(game.Players.LocalPlayer.Character, "Goodbye!", getChatColor(currentTone()))
normalEndDialog()
else
local dialogChoice = choiceMap[choice]
game.Chat:Chat(game.Players.LocalPlayer.Character, sanitizeMessage(dialogChoice.UserDialog), getChatColor(currentTone()))
wait(1)
currentConversationDialog:SignalDialogChoiceSelected(player, dialogChoice)
game.Chat:Chat(currentConversationPartner, sanitizeMessage(dialogChoice.ResponseDialog), getChatColor(currentTone()))
variableDelay(dialogChoice.ResponseDialog)
presentDialogChoices(currentConversationPartner, dialogChoice:GetChildren())
end
end
function newChoice(numberText)
local frame = Instance.new("TextButton")
frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
frame.AutoButtonColor = false
frame.BorderSizePixel = 0
frame.Text = ""
frame.MouseEnter:connect(function() highlightColor(frame, currentTone()) end)
frame.MouseLeave:connect(function() resetColor(frame, currentTone()) end)
frame.MouseButton1Click:connect(function() selectChoice(frame) end)
frame.RobloxLocked = true
local number = Instance.new("TextLabel")
number.Name = "Number"
number.TextColor3 = Color3.new(127/255, 212/255, 255/255)
number.Text = numberText
number.FontSize = Enum.FontSize.Size14
number.BackgroundTransparency = 1
number.Position = UDim2.new(0,4,0,2)
number.Size = UDim2.new(0,20,0,24)
number.TextXAlignment = Enum.TextXAlignment.Left
number.TextYAlignment = Enum.TextYAlignment.Top
number.RobloxLocked = true
number.Parent = frame
local prompt = Instance.new("TextLabel")
prompt.Name = "UserPrompt"
prompt.BackgroundTransparency = 1
prompt.TextColor3 = Color3.new(1,1,1)
prompt.FontSize = Enum.FontSize.Size14
prompt.Position = UDim2.new(0,28, 0, 2)
prompt.Size = UDim2.new(1,-32, 1, -4)
prompt.TextXAlignment = Enum.TextXAlignment.Left
prompt.TextYAlignment = Enum.TextYAlignment.Top
prompt.TextWrap = true
prompt.RobloxLocked = true
prompt.Parent = frame
return frame
end
function initialize(parent)
choices[1] = newChoice("1)")
choices[2] = newChoice("2)")
choices[3] = newChoice("3)")
choices[4] = newChoice("4)")
lastChoice = newChoice("5)")
lastChoice.UserPrompt.Text = "Goodbye!"
lastChoice.Size = UDim2.new(1,0,0,28)
mainFrame = Instance.new("Frame")
mainFrame.Name = "UserDialogArea"
mainFrame.Size = UDim2.new(0, 350, 0, 200)
mainFrame.Style = Enum.FrameStyle.ChatBlue
mainFrame.Visible = false
imageLabel = Instance.new("ImageLabel")
imageLabel.Name = "Tail"
imageLabel.Size = UDim2.new(0,62,0,53)
imageLabel.Position = UDim2.new(1,8,0.25)
imageLabel.Image = "ayaasset://textures/chatBubble_botBlue_tailRight.png"
imageLabel.BackgroundTransparency = 1
imageLabel.RobloxLocked = true
imageLabel.Parent = mainFrame
for n, obj in pairs(choices) do
obj.RobloxLocked = true
obj.Parent = mainFrame
end
lastChoice.RobloxLocked = true
lastChoice.Parent = mainFrame
mainFrame.RobloxLocked = true
mainFrame.Parent = parent
end
function presentDialogChoices(talkingPart, dialogChoices)
if not currentConversationDialog then
return
end
currentConversationPartner = talkingPart
sortedDialogChoices = {}
for n, obj in pairs(dialogChoices) do
if obj:IsA("DialogChoice") then
table.insert(sortedDialogChoices, obj)
end
end
table.sort(sortedDialogChoices, function(a,b) return a.Name < b.Name end)
if #sortedDialogChoices == 0 then
normalEndDialog()
return
end
local pos = 1
local yPosition = 0
choiceMap = {}
for n, obj in pairs(choices) do
obj.Visible = false
end
for n, obj in pairs(sortedDialogChoices) do
if pos <= #choices then
--3 lines is the maximum, set it to that temporarily
choices[pos].Size = UDim2.new(1, 0, 0, 24*3)
choices[pos].UserPrompt.Text = obj.UserDialog
local height = math.ceil(choices[pos].UserPrompt.TextBounds.Y/24)*24
choices[pos].Position = UDim2.new(0, 0, 0, yPosition)
choices[pos].Size = UDim2.new(1, 0, 0, height)
choices[pos].Visible = true
choiceMap[choices[pos]] = obj
yPosition = yPosition + height
pos = pos + 1
end
end
lastChoice.Position = UDim2.new(0,0,0,yPosition)
lastChoice.Number.Text = pos .. ")"
mainFrame.Size = UDim2.new(0, 350, 0, yPosition+24+32)
mainFrame.Position = UDim2.new(0,20,0.0, -mainFrame.Size.Y.Offset-20)
styleMainFrame(currentTone())
mainFrame.Visible = true
end
function doDialog(dialog)
while not Instance.Lock(dialog, player) do
wait()
end
if dialog.InUse then
Instance.Unlock(dialog)
return
else
dialog.InUse = true
Instance.Unlock(dialog)
end
currentConversationDialog = dialog
game.Chat:Chat(dialog.Parent, dialog.InitialPrompt, getChatColor(dialog.Tone))
variableDelay(dialog.InitialPrompt)
presentDialogChoices(dialog.Parent, dialog:GetChildren())
end
function renewKillswitch(dialog)
if currentAbortDialogScript then
currentAbortDialogScript:Remove()
currentAbortDialogScript = nil
end
currentAbortDialogScript = timeoutScript:Clone()
currentAbortDialogScript.archivable = false
currentAbortDialogScript.Disabled = false
currentAbortDialogScript.Parent = dialog
end
function checkForLeaveArea()
while currentConversationDialog do
if currentConversationDialog.Parent and (player:DistanceFromCharacter(currentConversationDialog.Parent.Position) >= currentConversationDialog.ConversationDistance) then
wanderDialog()
end
wait(1)
end
end
function startDialog(dialog)
if dialog.Parent and dialog.Parent:IsA("BasePart") then
if player:DistanceFromCharacter(dialog.Parent.Position) >= dialog.ConversationDistance then
showMessage(tooFarAwayMessage, tooFarAwaySize)
return
end
for dialog, gui in pairs(dialogMap) do
if dialog and gui then
gui.Enabled = false
end
end
renewKillswitch(dialog)
delay(1, checkForLeaveArea)
doDialog(dialog)
end
end
function removeDialog(dialog)
if dialogMap[dialog] then
dialogMap[dialog]:Remove()
dialogMap[dialog] = nil
end
if dialogConnections[dialog] then
dialogConnections[dialog]:disconnect()
dialogConnections[dialog] = nil
end
end
function addDialog(dialog)
if dialog.Parent then
if dialog.Parent:IsA("BasePart") then
local chatGui = chatNotificationGui:clone()
chatGui.Enabled = not dialog.InUse
chatGui.Adornee = dialog.Parent
chatGui.RobloxLocked = true
chatGui.Parent = game.CoreGui
chatGui.Image.Button.MouseButton1Click:connect(function() startDialog(dialog) end)
setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
dialogMap[dialog] = chatGui
dialogConnections[dialog] = dialog.Changed:connect(function(prop)
if prop == "Parent" and dialog.Parent then
--This handles the reparenting case, seperate from removal case
removeDialog(dialog)
addDialog(dialog)
elseif prop == "InUse" then
chatGui.Enabled = not currentConversationDialog and not dialog.InUse
if dialog == currentConversationDialog then
timeoutDialog()
end
elseif prop == "Tone" or prop == "Purpose" then
setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
end
end)
else -- still need to listen to parent changes even if current parent is not a BasePart
dialogConnections[dialog] = dialog.Changed:connect(function(prop)
if prop == "Parent" and dialog.Parent then
--This handles the reparenting case, seperate from removal case
removeDialog(dialog)
addDialog(dialog)
end
end)
end
end
end
function fetchScripts()
local model = game:GetService("InsertService"):LoadPrivateAsset("ayaasset://avatar/scripts/dialogTimeout.rbxmx")
if type(model) == "string" then -- load failed, lets try again
wait(0.1)
model = game:GetService("InsertService"):LoadPrivateAsset("ayaasset://avatar/scripts/dialogTimeout.rbxmx")
end
if type(model) == "string" then -- not going to work, lets bail
return
end
waitForChild(model,"TimeoutScript")
timeoutScript = model.TimeoutScript
waitForChild(model,"ReenableDialogScript")
reenableDialogScript = model.ReenableDialogScript
end
function onLoad()
waitForProperty(game.Players, "LocalPlayer")
player = game.Players.LocalPlayer
waitForProperty(player, "Character")
--print("Fetching Scripts")
fetchScripts()
--print("Creating Guis")
createChatNotificationGui()
--print("Creating MessageDialog")
createMessageDialog()
messageDialog.RobloxLocked = true
messageDialog.Parent = gui
--print("Waiting for BottomLeftControl")
waitForChild(gui, "BottomLeftControl")
--print("Initializing Frame")
local frame = Instance.new("Frame")
frame.Name = "DialogFrame"
frame.Position = UDim2.new(0,0,0,0)
frame.Size = UDim2.new(0,0,0,0)
frame.BackgroundTransparency = 1
frame.RobloxLocked = true
frame.Parent = gui.BottomLeftControl
initialize(frame)
--print("Adding Dialogs")
game.CollectionService.ItemAdded:connect(function(obj) if obj:IsA("Dialog") then addDialog(obj) end end)
game.CollectionService.ItemRemoved:connect(function(obj) if obj:IsA("Dialog") then removeDialog(obj) end end)
for i, obj in pairs(game.CollectionService:GetCollection("Dialog")) do
if obj:IsA("Dialog") then
addDialog(obj)
end
end
end
onLoad()

View File

@@ -0,0 +1,306 @@
function waitForProperty(instance, property)
while not instance[property] do
instance.Changed:wait()
end
end
function waitForChild(instance, name)
while not instance:FindFirstChild(name) do
instance.ChildAdded:wait()
end
end
waitForProperty(game.Players,"LocalPlayer")
waitForChild(script.Parent,"Popup")
waitForChild(script.Parent.Popup,"AcceptButton")
script.Parent.Popup.AcceptButton.Modal = true
local localPlayer = game.Players.LocalPlayer
local teleportUI = nil
local acceptedTeleport = Instance.new("IntValue")
local friendRequestBlacklist = {}
local teleportEnabled = true
local makePopupInvisible = function()
if script.Parent.Popup then script.Parent.Popup.Visible = false end
end
function makeFriend(fromPlayer,toPlayer)
local popup = script.Parent:FindFirstChild("Popup")
if popup == nil then return end -- there is no popup!
if popup.Visible then return end -- currently popping something, abort!
if friendRequestBlacklist[fromPlayer] then return end -- previously cancelled friend request, we don't want it!
popup.PopupText.Text = "Accept Friend Request from " .. tostring(fromPlayer.Name) .. "?"
popup.PopupImage.Image = "http://www.roblox.com/thumbs/avatar.ashx?userId="..tostring(fromPlayer.userId).."&x=352&y=352"
showTwoButtons()
popup.Visible = true
popup.AcceptButton.Text = "Accept"
popup.DeclineButton.Text = "Decline"
popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
local yesCon, noCon
yesCon = popup.AcceptButton.MouseButton1Click:connect(function()
popup.Visible = false
toPlayer:RequestFriendship(fromPlayer)
if yesCon then yesCon:disconnect() end
if noCon then noCon:disconnect() end
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end)
noCon = popup.DeclineButton.MouseButton1Click:connect(function()
popup.Visible = false
toPlayer:RevokeFriendship(fromPlayer)
friendRequestBlacklist[fromPlayer] = true
print("pop up blacklist")
if yesCon then yesCon:disconnect() end
if noCon then noCon:disconnect() end
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end)
end
game.Players.FriendRequestEvent:connect(function(fromPlayer,toPlayer,event)
-- if this doesn't involve me, then do nothing
if fromPlayer ~= localPlayer and toPlayer ~= localPlayer then return end
if fromPlayer == localPlayer then
if event == Enum.FriendRequestEvent.Accept then
game:GetService("GuiService"):SendNotification("You are Friends",
"With " .. toPlayer.Name .. "!",
"http://www.roblox.com/thumbs/avatar.ashx?userId="..tostring(toPlayer.userId).."&x=48&y=48",
5,
function()
end)
end
elseif toPlayer == localPlayer then
if event == Enum.FriendRequestEvent.Issue then
if friendRequestBlacklist[fromPlayer] then return end -- previously cancelled friend request, we don't want it!
game:GetService("GuiService"):SendNotification("Friend Request",
"From " .. fromPlayer.Name,
"http://www.roblox.com/thumbs/avatar.ashx?userId="..tostring(fromPlayer.userId).."&x=48&y=48",
8,
function()
makeFriend(fromPlayer,toPlayer)
end)
elseif event == Enum.FriendRequestEvent.Accept then
game:GetService("GuiService"):SendNotification("You are Friends",
"With " .. fromPlayer.Name .. "!",
"http://www.roblox.com/thumbs/avatar.ashx?userId="..tostring(fromPlayer.userId).."&x=48&y=48",
5,
function()
end)
end
end
end)
function showOneButton()
local popup = script.Parent:FindFirstChild("Popup")
if popup then
popup.OKButton.Visible = true
popup.DeclineButton.Visible = false
popup.AcceptButton.Visible = false
end
end
function showTwoButtons()
local popup = script.Parent:FindFirstChild("Popup")
if popup then
popup.OKButton.Visible = false
popup.DeclineButton.Visible = true
popup.AcceptButton.Visible = true
end
end
function onTeleport(teleportState, placeId, spawnName)
if game:GetService("TeleportService").CustomizedTeleportUI == false then
if teleportState == Enum.TeleportState.Started then
showTeleportUI("Teleport started...", 0)
elseif teleportState == Enum.TeleportState.WaitingForServer then
showTeleportUI("Requesting server...", 0)
elseif teleportState == Enum.TeleportState.InProgress then
showTeleportUI("Teleporting...", 0)
elseif teleportState == Enum.TeleportState.Failed then
showTeleportUI("Teleport failed. Insufficient privileges or target place does not exist.", 3)
end
end
end
function showTeleportUI(message, timer)
if teleportUI ~= nil then
teleportUI:Remove()
end
waitForChild(localPlayer, "PlayerGui")
teleportUI = Instance.new("Message", localPlayer.PlayerGui)
teleportUI.Text = message
if timer > 0 then
wait(timer)
teleportUI:Remove()
end
end
if teleportEnabled then
localPlayer.OnTeleport:connect(onTeleport)
game:GetService("TeleportService").ErrorCallback = function(message)
local popup = script.Parent:FindFirstChild("Popup")
showOneButton()
popup.PopupText.Text = message
local clickCon
clickCon = popup.OKButton.MouseButton1Click:connect(function()
game:GetService("TeleportService"):TeleportCancel()
if clickCon then clickCon:disconnect() end
game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild("Popup"))
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end)
game.GuiService:AddCenterDialog(script.Parent:FindFirstChild("Popup"), Enum.CenterDialogType.QuitDialog,
--ShowFunction
function()
showOneButton()
script.Parent:FindFirstChild("Popup").Visible = true
popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
end,
--HideFunction
function()
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end)
end
game:GetService("TeleportService").ConfirmationCallback = function(message, placeId, spawnName)
local popup = script.Parent:FindFirstChild("Popup")
popup.PopupText.Text = message
popup.PopupImage.Image = ""
local yesCon, noCon
local function killCons()
if yesCon then yesCon:disconnect() end
if noCon then noCon:disconnect() end
game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild("Popup"))
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end
yesCon = popup.AcceptButton.MouseButton1Click:connect(function()
killCons()
local success, err = pcall(function() game:GetService("TeleportService"):TeleportImpl(placeId,spawnName) end)
if not success then
showOneButton()
popup.PopupText.Text = err
local clickCon
clickCon = popup.OKButton.MouseButton1Click:connect(function()
if clickCon then clickCon:disconnect() end
game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild("Popup"))
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end)
game.GuiService:AddCenterDialog(script.Parent:FindFirstChild("Popup"), Enum.CenterDialogType.QuitDialog,
--ShowFunction
function()
showOneButton()
script.Parent:FindFirstChild("Popup").Visible = true
popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
end,
--HideFunction
function()
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end)
end
end)
noCon = popup.DeclineButton.MouseButton1Click:connect(function()
killCons()
local success = pcall(function() game:GetService("TeleportService"):TeleportCancel() end)
end)
local centerDialogSuccess = pcall(function() game.GuiService:AddCenterDialog(script.Parent:FindFirstChild("Popup"), Enum.CenterDialogType.QuitDialog,
--ShowFunction
function()
showTwoButtons()
popup.AcceptButton.Text = "Leave"
popup.DeclineButton.Text = "Stay"
script.Parent:FindFirstChild("Popup").Visible = true
popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
end,
--HideFunction
function()
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end)
end)
if centerDialogSuccess == false then
script.Parent:FindFirstChild("Popup").Visible = true
popup.AcceptButton.Text = "Leave"
popup.DeclineButton.Text = "Stay"
popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
end
return true
end
end
game:GetService("MarketplaceService").ClientLuaDialogRequested:connect(function(message, accept, decline)
local popup = script.Parent:FindFirstChild("Popup")
popup.PopupText.Text = message
popup.PopupImage.Image = ""
local yesCon, noCon
local function killCons()
if yesCon then yesCon:disconnect() end
if noCon then noCon:disconnect() end
game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild("Popup"))
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end
yesCon = popup.AcceptButton.MouseButton1Click:connect(function()
killCons()
game:GetService("MarketplaceService"):SignalServerLuaDialogClosed(true);
end)
noCon = popup.DeclineButton.MouseButton1Click:connect(function()
killCons()
game:GetService("MarketplaceService"):SignalServerLuaDialogClosed(false);
end)
local centerDialogSuccess = pcall(function() game.GuiService:AddCenterDialog(script.Parent:FindFirstChild("Popup"), Enum.CenterDialogType.QuitDialog,
function()
showTwoButtons()
popup.AcceptButton.Text = accept
popup.DeclineButton.Text = decline
script.Parent:FindFirstChild("Popup").Visible = true
popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
end,
function()
popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
end)
end)
if centerDialogSuccess == false then
script.Parent:FindFirstChild("Popup").Visible = true
popup.AcceptButton.Text = accept
popup.DeclineButton.Text = decline
popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
end
return true
end)
Game:GetService("PointsService").PointsAwarded:connect( function(userId, pointsAwarded, userBalanceInGame, userTotalBalance)
if userId == Game.Players.LocalPlayer.userId then
game:GetService("GuiService"):SendNotification("Points Awarded!",
"You received " ..tostring(pointsAwarded) .. " points!",
"ayaasset://textures/PlayerPoint.png",
5,
function()
end)
end
end)

View File

@@ -0,0 +1,349 @@
-- a couple neccessary functions
local function waitForChild(instance, name)
while not instance:FindFirstChild(name) do
instance.ChildAdded:wait()
end
end
local function waitForProperty(instance, prop)
while not instance[prop] do
instance.Changed:wait()
end
end
function securityCheck()
local allowedUserIds = {--[[game.CreatorId,]]7210880}
local canUsePanel = false
local localUserId = game.Players.LocalPlayer.userId
for i = 1, #allowedUserIds do
if localUserId == allowedUserIds[i] then
canUsePanel = true
break
end
end
if not canUsePanel then
script:remove()
end
end
function createGui()
local adminStatsFrame = Instance.new("Frame")
adminStatsFrame.RobloxLocked = true
adminStatsFrame.Name = "AdminStatsFrame"
adminStatsFrame.Active = true
adminStatsFrame.Draggable = true
adminStatsFrame.Position = UDim2.new(0.2,20,0,0)
adminStatsFrame.Size = UDim2.new(0.6,-40,1,0)
adminStatsFrame.Style = Enum.FrameStyle.RobloxRound
adminStatsFrame.Parent = script.Parent
-- AdminStatsFrame Children
local adminStatsTextLabel = Instance.new("TextLabel")
adminStatsTextLabel.RobloxLocked = true
adminStatsTextLabel.Name = "AdminStatsTextLabel"
adminStatsTextLabel.BackgroundTransparency = 1
adminStatsTextLabel.Font = Enum.Font.ArialBold
adminStatsTextLabel.FontSize = Enum.FontSize.Size24
adminStatsTextLabel.Size = UDim2.new(1,0,0,24)
adminStatsTextLabel.Text = "Place Console"
adminStatsTextLabel.TextColor3 = Color3.new(1,1,1)
adminStatsTextLabel.TextYAlignment = Enum.TextYAlignment.Center
adminStatsTextLabel.Parent = adminStatsFrame
local errorPanel = Instance.new("Frame")
errorPanel.RobloxLocked = true
errorPanel.Name = "ErrorPanel"
errorPanel.Position = UDim2.new(0,0,0.5,0)
errorPanel.Size = UDim2.new(1,0,0.5,0)
errorPanel.Style = Enum.FrameStyle.RobloxRound
errorPanel.Parent = adminStatsFrame
-- ErrorPanel Children
local textPanel = Instance.new("Frame")
textPanel.RobloxLocked = true
textPanel.Name = "TextPanel"
textPanel.Position = UDim2.new(0,0,0,18)
textPanel.Size = UDim2.new(1,0,1,-18)
textPanel.BackgroundTransparency = 1
textPanel.Parent = errorPanel
local errorPanelTextLabel = Instance.new("TextLabel")
errorPanelTextLabel.RobloxLocked = true
errorPanelTextLabel.Name = "ErrorPanelTextLabel"
errorPanelTextLabel.Font = Enum.Font.ArialBold
errorPanelTextLabel.FontSize = Enum.FontSize.Size18
errorPanelTextLabel.Size = UDim2.new(1,0,0,18)
errorPanelTextLabel.BackgroundTransparency = 1
errorPanelTextLabel.TextColor3 = Color3.new(1,1,1)
errorPanelTextLabel.Text = "Lua Errors"
errorPanelTextLabel.Parent = errorPanel
local sampleError = Instance.new("TextLabel")
sampleError.RobloxLocked = true
sampleError.Name = "SampleError"
sampleError.Font = Enum.Font.Arial
sampleError.FontSize = Enum.FontSize.Size12
sampleError.Size = UDim2.new(1,0,0,12)
sampleError.BackgroundTransparency = 0.5
sampleError.TextColor3 = Color3.new(1,1,1)
sampleError.Text = "Thu May 19 12:37:09 2011 - Players.Player.Backpack.StamperTool.GuiScript:1199: attempt to index field '?' (a nil value)"
sampleError.TextWrap = true
sampleError.TextXAlignment = Enum.TextXAlignment.Left
sampleError.TextYAlignment = Enum.TextYAlignment.Top
sampleError.Visible = false
sampleError.Parent = errorPanel
local playerStatsFrame = Instance.new("Frame")
playerStatsFrame.RobloxLocked = true
playerStatsFrame.Name = "PlayerStatsFrame"
playerStatsFrame.BackgroundTransparency = 1
playerStatsFrame.Position = UDim2.new(0,0,0,24)
playerStatsFrame.Size = UDim2.new(0,200,0,100)
playerStatsFrame.Style = Enum.FrameStyle.RobloxRound
playerStatsFrame.Parent = adminStatsFrame
local playerStatsTextInfo = Instance.new("TextLabel")
playerStatsTextInfo.Name = "PlayerStatsTextInfo"
playerStatsTextInfo.BackgroundTransparency = 1
playerStatsTextInfo.Font = Enum.Font.ArialBold
playerStatsTextInfo.FontSize = Enum.FontSize.Size14
playerStatsTextInfo.Size = UDim2.new(1,0,1,0)
playerStatsTextInfo.Text = ""
playerStatsTextInfo.TextColor3 = Color3.new(1,1,1)
playerStatsTextInfo.TextYAlignment = Enum.TextYAlignment.Top
local smallFrame = Instance.new("Frame")
smallFrame.BackgroundTransparency = 1
smallFrame.Size = UDim2.new(1,0,0,14)
-- PlayerStatsFrame Children
local avgPlayerTimeFrame = smallFrame:clone()
avgPlayerTimeFrame.RobloxLocked = true
avgPlayerTimeFrame.Name = "AvgPlayerTimeFrame"
avgPlayerTimeFrame.Position = UDim2.new(0,0,0,46)
local newTextInfo = playerStatsTextInfo:clone()
newTextInfo.RobloxLocked = true
newTextInfo.Text = "Avg. Play Time: 0"
newTextInfo.Parent = avgPlayerTimeFrame
avgPlayerTimeFrame.Parent = playerStatsFrame
local joinFrame = smallFrame:clone()
joinFrame.RobloxLocked = true
joinFrame.Name = "JoinFrame"
joinFrame.Position = UDim2.new(0,0,0,18)
local newTextInfo = playerStatsTextInfo:clone()
newTextInfo.RobloxLocked = true
newTextInfo.Text = "# of Joins: 0"
newTextInfo.Parent = joinFrame
joinFrame.Parent = playerStatsFrame
local leaveFrame = smallFrame:clone()
leaveFrame.RobloxLocked = true
leaveFrame.Name = "LeaveFrame"
leaveFrame.Position = UDim2.new(0,0,0,32)
local newTextInfo = playerStatsTextInfo:clone()
newTextInfo.RobloxLocked = true
newTextInfo.Text = "# of Leaves: 0"
newTextInfo.Parent = leaveFrame
leaveFrame.Parent = playerStatsFrame
local uniqueVisitorsFrame = smallFrame:clone()
uniqueVisitorsFrame.RobloxLocked = true
uniqueVisitorsFrame.Name = "UniqueVisitorsFrame"
uniqueVisitorsFrame.Position = UDim2.new(0,0,0,60)
local newTextInfo = playerStatsTextInfo:clone()
newTextInfo.RobloxLocked = true
newTextInfo.Text = "# of Unique Visits: 0"
newTextInfo.Parent = uniqueVisitorsFrame
uniqueVisitorsFrame.Parent = playerStatsFrame
local textHeader = playerStatsTextInfo:clone()
textHeader.Name = "PlayerStatsTextLabel"
textHeader.RobloxLocked = true
textHeader.FontSize = Enum.FontSize.Size18
textHeader.Size = UDim2.new(1,0,0,18)
textHeader.Text = "Player Stats"
textHeader.TextYAlignment = Enum.TextYAlignment.Center
textHeader.Parent = playerStatsFrame
-- Script Stats Frame
local scriptStatsFrame = playerStatsFrame:clone()
scriptStatsFrame.RobloxLocked = true
scriptStatsFrame.Name = "ScriptStatsFrame"
scriptStatsFrame.Position = UDim2.new(0,0,0,126)
scriptStatsFrame.PlayerStatsTextLabel.Name = "ScriptStatsTextLabel"
scriptStatsFrame.ScriptStatsTextLabel.Text = "Lua Stats"
scriptStatsFrame.JoinFrame.Name = "ScriptErrorsFrame"
scriptStatsFrame.ScriptErrorsFrame.PlayerStatsTextInfo.Name = "ScriptErrorsTextInfo"
scriptStatsFrame.ScriptErrorsFrame.ScriptErrorsTextInfo.Text = "# of Lua Errors: 0"
scriptStatsFrame.LeaveFrame.Name = "ScriptWarningFrame"
scriptStatsFrame.ScriptWarningFrame.PlayerStatsTextInfo.Name = "ScriptWarningTextInfo"
scriptStatsFrame.ScriptWarningFrame.ScriptWarningTextInfo.Text = "# of Lua Warnings: 0"
scriptStatsFrame.AvgPlayerTimeFrame.Name = "ScriptsRunningFrame"
scriptStatsFrame.ScriptsRunningFrame.PlayerStatsTextInfo.Name = "ScriptsRunningInfo"
scriptStatsFrame.ScriptsRunningFrame.ScriptsRunningInfo.Text = "# Scripts Running: 0"
scriptStatsFrame.UniqueVisitorsFrame:remove()
scriptStatsFrame.Parent = adminStatsFrame
-- UptimeFrame
local upTimeFrame = Instance.new("Frame")
upTimeFrame.RobloxLocked = true
upTimeFrame.Name = "UptimeFrame"
upTimeFrame.BackgroundTransparency = 1
upTimeFrame.Position = UDim2.new(1,-200,0,24)
upTimeFrame.Size = UDim2.new(0,200,0,100)
upTimeFrame.Style = Enum.FrameStyle.RobloxRound
upTimeFrame.Parent = adminStatsFrame
-- UptimeFrame Children
local secondsUpTimeTextInfo = Instance.new("TextLabel")
secondsUpTimeTextInfo.RobloxLocked = true
secondsUpTimeTextInfo.Name = "SecondsUptimeTextInfo"
secondsUpTimeTextInfo.Font = Enum.Font.ArialBold
secondsUpTimeTextInfo.FontSize = Enum.FontSize.Size14
secondsUpTimeTextInfo.Position = UDim2.new(0,0,0.5,18)
secondsUpTimeTextInfo.Size = UDim2.new(1,0,0.5,-18)
secondsUpTimeTextInfo.Text = "0 Total Seconds"
secondsUpTimeTextInfo.BackgroundTransparency = 1
secondsUpTimeTextInfo.TextColor3 = Color3.new(1,1,1)
secondsUpTimeTextInfo.TextYAlignment = Enum.TextYAlignment.Top
secondsUpTimeTextInfo.Parent = upTimeFrame
local uptimeTextInfo = secondsUpTimeTextInfo:clone()
uptimeTextInfo.RobloxLocked = true
uptimeTextInfo.Name = "UptimeTextInfo"
uptimeTextInfo.Position = UDim2.new(0,0,0,18)
uptimeTextInfo.Size = UDim2.new(1,0,0.5,0)
uptimeTextInfo.TextWrap = true
uptimeTextInfo.Text = "0 Days, 0 Hours, 0 Minutes, 0 Seconds"
uptimeTextInfo.Parent = upTimeFrame
local upTimeTextLabel = uptimeTextInfo:clone()
upTimeTextLabel.RobloxLocked = true
upTimeTextLabel.Name = "UptimeTextLabel"
upTimeTextLabel.FontSize = Enum.FontSize.Size18
upTimeTextLabel.Size = UDim2.new(1,0,0,18)
upTimeTextLabel.Position = UDim2.new(0,0,0,0)
upTimeTextLabel.Text = "Instance Uptime"
upTimeTextLabel.TextYAlignment = Enum.TextYAlignment.Center
upTimeTextLabel.Parent = upTimeFrame
end
-- functions
function initLocals()
-- Top Gui Layer
adminGui = script.Parent
adminFrame = adminGui.AdminStatsFrame
-- Second Gui Layer
upTimeFrame = adminFrame.UptimeFrame
errorFrame = adminFrame.ErrorPanel
playerStatsFrame = adminFrame.PlayerStatsFrame
scriptStatsFrame = adminFrame.ScriptStatsFrame
-- UptimeFrame Children
upTimeFormattedText = upTimeFrame.UptimeTextInfo
upTimeSecondsText = upTimeFrame.SecondsUptimeTextInfo
-- PlayerStatsFrame Children
avgPlayTimeText = playerStatsFrame.AvgPlayerTimeFrame.PlayerStatsTextInfo
joinText = playerStatsFrame.JoinFrame.PlayerStatsTextInfo
leaveText = playerStatsFrame.LeaveFrame.PlayerStatsTextInfo
uniqueVisitorText = playerStatsFrame.UniqueVisitorsFrame.PlayerStatsTextInfo
uniqueUserIds = {}
playTimes = {}
avgPlayTime = 0
placeVisits = 0
placeLeaves = 0
end
function updateUptime()
local currentTime = game.Workspace.DistributedGameTime
upTimeSecondsText.Text = tostring(math.floor(currentTime)) .. " Total Seconds"
local days = math.floor(currentTime/86400)
currentTime = currentTime - (days * 86400)
local hours = math.floor(currentTime/3600)
currentTime = currentTime - (hours * 3600)
local minutes = math.floor(currentTime/60)
currentTime = currentTime - (minutes * 60)
currentTime = math.floor(currentTime)
upTimeFormattedText.Text = tostring(days) .. " Days, " .. tostring(hours) .. " Hours, " .. tostring(minutes) .. " Minutes, " .. tostring(currentTime) .. (" Seconds")
end
function playerJoined(addedPlayer)
placeVisits = placeVisits + 1
joinText.Text = "# of Joins: " .. tostring(placeVisits)
if uniqueUserIds[addedPlayer] == nil then
uniqueUserIds[addedPlayer] = addedPlayer.userId
uniqueVisitorText.Text = "#of Unique Visits: " .. tostring(#uniqueUserIds)
end
playTimes[addedPlayer] = game.Workspace.DistributedGameTime
end
function recalculateAvgPlayTime(removedPlayer)
if playTimes[removedPlayer] then
local playerPlayTime = game.Workspace.DistributedGameTime - playTimes[removedPlayer]
avgPlayTime = ( ((placesLeaves - 1)/placeLeaves) * avgPlayTime ) + ( (1/placeLeaves) * playerPlayTime )
avgPlayTimeText.Text = "Avg. Play Time: " .. tostring(math.floor(avgPlayTime))
end
end
function playerLeft(removedPlayer)
placeLeaves = placeLeaves + 1
leaveText.Text = "# of Leaves: " .. tostring(placeLeaves)
recalculateAvgPlayTime(removedPlayer)
end
function uptimeLoop()
while true do
updateUptime()
wait(1)
end
end
function playerAddedFunction(player)
if player == game.Players.LocalPlayer then
securityCheck()
createGui()
initLocals()
adminFrame.Visible = true
uptimeLoop()
end
playerJoined(addedPlayer)
end
-- Script Start
-- Check to see if we already have players
local playersChildren = game.Players:GetChildren()
for i = 1, #playersChildren do
if playersChildren[i]:IsA("Player") then
playerAddedFunction(playersChildren[i])
end
end
-- Listen for players now
game.Players.PlayerAdded:connect(function(addedPlayer) playerAddedFunction(addedPlayer) end)
game.Players.PlayerRemoving:connect(function(removedPlayer) playerLeft(removedPlayer) end)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
--build our gui
local popupFrame = Instance.new("Frame")
popupFrame.Position = UDim2.new(0.5,-165,0.5,-175)
popupFrame.Size = UDim2.new(0,330,0,350)
popupFrame.Style = Enum.FrameStyle.RobloxRound
popupFrame.ZIndex = 4
popupFrame.Name = "Popup"
popupFrame.Visible = false
popupFrame.Parent = script.Parent
local darken = popupFrame:clone()
darken.Size = UDim2.new(1,16,1,16)
darken.Position = UDim2.new(0,-8,0,-8)
darken.Name = "Darken"
darken.ZIndex = 1
darken.Parent = popupFrame
local acceptButton = Instance.new("TextButton")
acceptButton.Position = UDim2.new(0,20,0,270)
acceptButton.Size = UDim2.new(0,100,0,50)
acceptButton.Font = Enum.Font.ArialBold
acceptButton.FontSize = Enum.FontSize.Size24
acceptButton.Style = Enum.ButtonStyle.RobloxButton
acceptButton.TextColor3 = Color3.new(248/255,248/255,248/255)
acceptButton.Text = "Yes"
acceptButton.ZIndex = 5
acceptButton.Name = "AcceptButton"
acceptButton.Parent = popupFrame
local declineButton = acceptButton:clone()
declineButton.Position = UDim2.new(1,-120,0,270)
declineButton.Text = "No"
declineButton.Name = "DeclineButton"
declineButton.Parent = popupFrame
local okButton = acceptButton:clone()
okButton.Name = "OKButton"
okButton.Text = "OK"
okButton.Position = UDim2.new(0.5,-50,0,270)
okButton.Visible = false
okButton.Parent = popupFrame
local popupImage = Instance.new("ImageLabel")
popupImage.BackgroundTransparency = 1
popupImage.Position = UDim2.new(0.5,-140,0,0)
popupImage.Size = UDim2.new(0,280,0,280)
popupImage.ZIndex = 3
popupImage.Name = "PopupImage"
popupImage.Parent = popupFrame
local backing = Instance.new("ImageLabel")
backing.BackgroundTransparency = 1
backing.Size = UDim2.new(1,0,1,0)
backing.Image = "ayaasset://textures/2012/PopupScript/Backing.png"
backing.Name = "Backing"
backing.ZIndex = 2
backing.Parent = popupImage
local popupText = Instance.new("TextLabel")
popupText.Name = "PopupText"
popupText.Size = UDim2.new(1,0,0.8,0)
popupText.Font = Enum.Font.ArialBold
popupText.FontSize = Enum.FontSize.Size36
popupText.BackgroundTransparency = 1
popupText.Text = "Hello I'm a popup"
popupText.TextColor3 = Color3.new(248/255,248/255,248/255)
popupText.TextWrap = true
popupText.ZIndex = 5
popupText.Parent = popupFrame
script:remove()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
local controlFrame = script.Parent:FindFirstChild("ControlFrame")
if not controlFrame then return end
local topLeftControl = controlFrame:FindFirstChild("TopLeftControl")
local bottomLeftControl = controlFrame:FindFirstChild("BottomLeftControl")
local bottomRightControl = controlFrame:FindFirstChild("BottomRightControl")
local frameTip = Instance.new("TextLabel")
frameTip.Name = "ToolTip"
frameTip.Text = ""
frameTip.Font = Enum.Font.ArialBold
frameTip.FontSize = Enum.FontSize.Size12
frameTip.TextColor3 = Color3.new(1,1,1)
frameTip.BorderSizePixel = 0
frameTip.ZIndex = 10
frameTip.Size = UDim2.new(2,0,1,0)
frameTip.Position = UDim2.new(1,0,0,0)
frameTip.BackgroundColor3 = Color3.new(0,0,0)
frameTip.BackgroundTransparency = 1
frameTip.TextTransparency = 1
frameTip.TextWrap = true
local inside = Instance.new("BoolValue")
inside.Name = "inside"
inside.Value = false
inside.Parent = frameTip
function setUpListeners(frameToListen)
local fadeSpeed = 0.1
frameToListen.Parent.MouseEnter:connect(function()
if frameToListen:FindFirstChild("inside") then
frameToListen.inside.Value = true
wait(1.2)
if frameToListen.inside.Value then
while frameToListen.inside.Value and frameToListen.BackgroundTransparency > 0 do
frameToListen.BackgroundTransparency = frameToListen.BackgroundTransparency - fadeSpeed
frameToListen.TextTransparency = frameToListen.TextTransparency - fadeSpeed
wait()
end
end
end
end)
function killTip(killFrame)
killFrame.inside.Value = false
killFrame.BackgroundTransparency = 1
killFrame.TextTransparency = 1
end
frameToListen.Parent.MouseLeave:connect(function() killTip(frameToListen) end)
frameToListen.Parent.MouseButton1Click:connect(function() killTip(frameToListen) end)
end
function createSettingsButtonTip(parent)
if parent == nil then
parent = bottomLeftControl:FindFirstChild("SettingsButton")
end
local toolTip = frameTip:clone()
toolTip.RobloxLocked = true
toolTip.Text = "Settings/Leave Game"
toolTip.Position = UDim2.new(0,0,0,-18)
toolTip.Size = UDim2.new(0,120,0,20)
toolTip.Parent = parent
setUpListeners(toolTip)
end
wait(5) -- make sure we are loaded in, won't need tool tips for first 5 seconds anyway
---------------- set up Bottom Left Tool Tips -------------------------
local bottomLeftChildren = bottomLeftControl:GetChildren()
local hasSettingsTip = false
for i = 1, #bottomLeftChildren do
if bottomLeftChildren[i].Name == "Exit" then
local exitTip = frameTip:clone()
exitTip.RobloxLocked = true
exitTip.Text = "Leave Place"
exitTip.Position = UDim2.new(0,0,-1,0)
exitTip.Size = UDim2.new(1,0,1,0)
exitTip.Parent = bottomLeftChildren[i]
setUpListeners(exitTip)
elseif bottomLeftChildren[i].Name == "SettingsButton" then
hasSettingsTip = true
createSettingsButtonTip(bottomLeftChildren[i])
end
end
---------------- set up Bottom Right Tool Tips -------------------------
local bottomRightChildren = bottomRightControl:GetChildren()
for i = 1, #bottomRightChildren do
if bottomRightChildren[i].Name:find("Camera") ~= nil then
local cameraTip = frameTip:clone()
cameraTip.RobloxLocked = true
cameraTip.Text = "Camera View"
if bottomRightChildren[i].Name:find("Zoom") then
cameraTip.Position = UDim2.new(-1,0,-1.5)
else
cameraTip.Position = UDim2.new(0,0,-1.5,0)
end
cameraTip.Size = UDim2.new(2,0,1.25,0)
cameraTip.Parent = bottomRightChildren[i]
setUpListeners(cameraTip)
end
end

View File

@@ -0,0 +1,563 @@
-- This is responsible for all touch controls we show (as of this writing, only on iOS)
-- this includes character move thumbsticks, and buttons for jump, use of items, camera, etc.
-- obligatory stuff to make sure we don't access nil data
while not Game do
wait()
end
while not Game:FindFirstChild("Players") do
wait()
end
while not Game.Players.LocalPlayer do
wait()
end
while not Game:FindFirstChild("CoreGui") do
wait()
end
while not Game.CoreGui:FindFirstChild("RobloxGui") do
wait()
end
local userInputService = Game:GetService("UserInputService")
local success = pcall(function() userInputService:IsLuaTouchControls() end)
if not success then
script:Destroy()
end
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- Variables
local screenResolution = Game:GetService("GuiService"):GetScreenResolution()
function isSmallScreenDevice()
return screenResolution.y <= 320
end
local localPlayer = Game.Players.LocalPlayer
local thumbstickInactiveAlpha = 0.3
local thumbstickSize = 120
if isSmallScreenDevice() then
thumbstickSize = 70
end
local touchControlsSheet = "ayaasset://textures/ui/TouchControlsSheet.png"
local ThumbstickDeadZone = 5
local ThumbstickMaxPercentGive = 0.92
local thumbstickTouches = {}
local jumpButtonSize = 90
if isSmallScreenDevice() then
jumpButtonSize = 70
end
local oldJumpTouches = {}
local currentJumpTouch = nil
local CameraRotateSensitivity = 0.007
local CameraRotateDeadZone = CameraRotateSensitivity * 16
local CameraZoomSensitivity = 0.03
local PinchZoomDelay = 0.2
local cameraTouch = nil
-- make sure all of our images are good to go
Game:GetService("ContentProvider"):Preload(touchControlsSheet)
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- Functions
function DistanceBetweenTwoPoints(point1, point2)
local dx = point2.x - point1.x
local dy = point2.y - point1.y
return math.sqrt( (dx*dx) + (dy*dy) )
end
function transformFromCenterToTopLeft(pointToTranslate, guiObject)
return UDim2.new(0,pointToTranslate.x - guiObject.AbsoluteSize.x/2,0,pointToTranslate.y - guiObject.AbsoluteSize.y/2)
end
function rotatePointAboutLocation(pointToRotate, pointToRotateAbout, radians)
local sinAnglePercent = math.sin(radians)
local cosAnglePercent = math.cos(radians)
local transformedPoint = pointToRotate
-- translate point back to origin:
transformedPoint = Vector2.new(transformedPoint.x - pointToRotateAbout.x, transformedPoint.y - pointToRotateAbout.y)
-- rotate point
local xNew = transformedPoint.x * cosAnglePercent - transformedPoint.y * sinAnglePercent
local yNew = transformedPoint.x * sinAnglePercent + transformedPoint.y * cosAnglePercent
-- translate point back:
transformedPoint = Vector2.new(xNew + pointToRotateAbout.x, yNew + pointToRotateAbout.y)
return transformedPoint
end
function dotProduct(v1,v2)
return ((v1.x*v2.x) + (v1.y*v2.y))
end
function stationaryThumbstickTouchMove(thumbstickFrame, thumbstickOuter, touchLocation)
local thumbstickOuterCenterPosition = Vector2.new(thumbstickOuter.Position.X.Offset + thumbstickOuter.AbsoluteSize.x/2, thumbstickOuter.Position.Y.Offset + thumbstickOuter.AbsoluteSize.y/2)
local centerDiff = DistanceBetweenTwoPoints(touchLocation, thumbstickOuterCenterPosition)
-- thumbstick is moving outside our region, need to cap its distance
if centerDiff > (thumbstickSize/2) then
local thumbVector = Vector2.new(touchLocation.x - thumbstickOuterCenterPosition.x,touchLocation.y - thumbstickOuterCenterPosition.y);
local normal = thumbVector.unit
if normal.x == math.nan or normal.x == math.inf then
normal = Vector2.new(0,normal.y)
end
if normal.y == math.nan or normal.y == math.inf then
normal = Vector2.new(normal.x,0)
end
local newThumbstickInnerPosition = thumbstickOuterCenterPosition + (normal * (thumbstickSize/2))
thumbstickFrame.Position = transformFromCenterToTopLeft(newThumbstickInnerPosition, thumbstickFrame)
else
thumbstickFrame.Position = transformFromCenterToTopLeft(touchLocation,thumbstickFrame)
end
return Vector2.new(thumbstickFrame.Position.X.Offset - thumbstickOuter.Position.X.Offset,thumbstickFrame.Position.Y.Offset - thumbstickOuter.Position.Y.Offset)
end
function followThumbstickTouchMove(thumbstickFrame, thumbstickOuter, touchLocation)
local thumbstickOuterCenter = Vector2.new(thumbstickOuter.Position.X.Offset + thumbstickOuter.AbsoluteSize.x/2, thumbstickOuter.Position.Y.Offset + thumbstickOuter.AbsoluteSize.y/2)
-- thumbstick is moving outside our region, need to position outer thumbstick texture carefully (to make look and feel like actual joystick controller)
if DistanceBetweenTwoPoints(touchLocation, thumbstickOuterCenter) > thumbstickSize/2 then
local thumbstickInnerCenter = Vector2.new(thumbstickFrame.Position.X.Offset + thumbstickFrame.AbsoluteSize.x/2, thumbstickFrame.Position.Y.Offset + thumbstickFrame.AbsoluteSize.y/2)
local movementVectorUnit = Vector2.new(touchLocation.x - thumbstickInnerCenter.x, touchLocation.y - thumbstickInnerCenter.y).unit
local outerToInnerVectorCurrent = Vector2.new(thumbstickInnerCenter.x - thumbstickOuterCenter.x, thumbstickInnerCenter.y - thumbstickOuterCenter.y)
local outerToInnerVectorCurrentUnit = outerToInnerVectorCurrent.unit
local movementVector = Vector2.new(touchLocation.x - thumbstickInnerCenter.x, touchLocation.y - thumbstickInnerCenter.y)
-- First, find the angle between the new thumbstick movement vector,
-- and the vector between thumbstick inner and thumbstick outer.
-- We will use this to pivot thumbstick outer around thumbstick inner, gives a nice joystick feel
local crossOuterToInnerWithMovement = (outerToInnerVectorCurrentUnit.x * movementVectorUnit.y) - (outerToInnerVectorCurrentUnit.y * movementVectorUnit.x)
local angle = math.atan2(crossOuterToInnerWithMovement, dotProduct(outerToInnerVectorCurrentUnit, movementVectorUnit))
local anglePercent = angle * math.min( (movementVector.magnitude)/(outerToInnerVectorCurrent.magnitude), 1.0);
-- If angle is significant, rotate about the inner thumbsticks current center
if math.abs(anglePercent) > 0.00001 then
local outerThumbCenter = rotatePointAboutLocation(thumbstickOuterCenter, thumbstickInnerCenter, anglePercent)
thumbstickOuter.Position = transformFromCenterToTopLeft(Vector2.new(outerThumbCenter.x,outerThumbCenter.y), thumbstickOuter)
end
-- now just translate outer thumbstick to make sure it stays nears inner thumbstick
thumbstickOuter.Position = UDim2.new(0,thumbstickOuter.Position.X.Offset+movementVector.x,0,thumbstickOuter.Position.Y.Offset+movementVector.y)
end
thumbstickFrame.Position = transformFromCenterToTopLeft(touchLocation,thumbstickFrame)
-- a bit of error checking to make sure thumbsticks stay close to eachother
thumbstickFramePosition = Vector2.new(thumbstickFrame.Position.X.Offset,thumbstickFrame.Position.Y.Offset)
thumbstickOuterPosition = Vector2.new(thumbstickOuter.Position.X.Offset,thumbstickOuter.Position.Y.Offset)
if DistanceBetweenTwoPoints(thumbstickFramePosition, thumbstickOuterPosition) > thumbstickSize/2 then
local vectorWithLength = (thumbstickOuterPosition - thumbstickFramePosition).unit * thumbstickSize/2
thumbstickOuter.Position = UDim2.new(0,thumbstickFramePosition.x + vectorWithLength.x,0,thumbstickFramePosition.y + vectorWithLength.y)
end
return Vector2.new(thumbstickFrame.Position.X.Offset - thumbstickOuter.Position.X.Offset,thumbstickFrame.Position.Y.Offset - thumbstickOuter.Position.Y.Offset)
end
function movementOutsideDeadZone(movementVector)
return ( (math.abs(movementVector.x) > ThumbstickDeadZone) or (math.abs(movementVector.y) > ThumbstickDeadZone) )
end
function constructThumbstick(defaultThumbstickPos, updateFunction, stationaryThumbstick)
local thumbstickFrame = Instance.new("Frame")
thumbstickFrame.Name = "ThumbstickFrame"
thumbstickFrame.Active = true
thumbstickFrame.Size = UDim2.new(0,thumbstickSize,0,thumbstickSize)
thumbstickFrame.Position = defaultThumbstickPos
thumbstickFrame.BackgroundTransparency = 1
local outerThumbstick = Instance.new("ImageLabel")
outerThumbstick.Name = "OuterThumbstick"
outerThumbstick.Image = touchControlsSheet
outerThumbstick.ImageRectOffset = Vector2.new(0,0)
outerThumbstick.ImageRectSize = Vector2.new(220,220)
outerThumbstick.BackgroundTransparency = 1
outerThumbstick.Size = UDim2.new(0,thumbstickSize,0,thumbstickSize)
outerThumbstick.Position = defaultThumbstickPos
outerThumbstick.Parent = Game.CoreGui.RobloxGui
local innerThumbstick = Instance.new("ImageLabel")
innerThumbstick.Name = "InnerThumbstick"
innerThumbstick.Image = touchControlsSheet
innerThumbstick.ImageRectOffset = Vector2.new(220,0)
innerThumbstick.ImageRectSize = Vector2.new(111,111)
innerThumbstick.BackgroundTransparency = 1
innerThumbstick.Size = UDim2.new(0,thumbstickSize/2,0,thumbstickSize/2)
innerThumbstick.Position = UDim2.new(0, thumbstickFrame.Size.X.Offset/2 - thumbstickSize/4, 0, thumbstickFrame.Size.Y.Offset/2 - thumbstickSize/4)
innerThumbstick.Parent = thumbstickFrame
innerThumbstick.ZIndex = 2
local thumbstickTouch = nil
local userInputServiceTouchMovedCon = nil
local userInputSeviceTouchEndedCon = nil
local startInputTracking = function(inputObject)
if thumbstickTouch then return end
if inputObject == cameraTouch then return end
if inputObject == currentJumpTouch then return end
if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
thumbstickTouch = inputObject
table.insert(thumbstickTouches,thumbstickTouch)
thumbstickFrame.Position = transformFromCenterToTopLeft(thumbstickTouch.Position,thumbstickFrame)
outerThumbstick.Position = thumbstickFrame.Position
userInputServiceTouchMovedCon = userInputService.TouchMoved:connect(function(movedInput)
if movedInput == thumbstickTouch then
local movementVector = nil
if stationaryThumbstick then
movementVector = stationaryThumbstickTouchMove(thumbstickFrame,outerThumbstick,Vector2.new(movedInput.Position.x,movedInput.Position.y))
else
movementVector = followThumbstickTouchMove(thumbstickFrame,outerThumbstick,Vector2.new(movedInput.Position.x,movedInput.Position.y))
end
if updateFunction then
updateFunction(movementVector,outerThumbstick.Size.X.Offset/2)
end
end
end)
userInputSeviceTouchEndedCon = userInputService.TouchEnded:connect(function(endedInput)
if endedInput == thumbstickTouch then
if updateFunction then
updateFunction(Vector2.new(0,0),1)
end
userInputSeviceTouchEndedCon:disconnect()
userInputServiceTouchMovedCon:disconnect()
thumbstickFrame.Position = defaultThumbstickPos
outerThumbstick.Position = defaultThumbstickPos
for i, object in pairs(thumbstickTouches) do
if object == thumbstickTouch then
table.remove(thumbstickTouches,i)
break
end
end
thumbstickTouch = nil
end
end)
end
userInputService.Changed:connect(function(prop)
if prop == "ModalEnabled" then
thumbstickFrame.Visible = not userInputService.ModalEnabled
outerThumbstick.Visible = not userInputService.ModalEnabled
end
end)
thumbstickFrame.InputBegan:connect(startInputTracking)
return thumbstickFrame
end
function setupCharacterMovement( parentFrame )
local lastMovementVector, lastMaxMovement = nil
local moveCharacterFunc = localPlayer.MoveCharacter
local moveCharacterFunction = function ( movementVector, maxMovement )
if localPlayer then
if movementOutsideDeadZone(movementVector) then
lastMovementVector = movementVector
lastMaxMovement = maxMovement
-- sometimes rounding error will not allow us to go max speed at some
-- thumbstick angles, fix this with a bit of fudging near 100% throttle
if movementVector.magnitude/maxMovement > ThumbstickMaxPercentGive then
maxMovement = movementVector.magnitude - 1
end
moveCharacterFunc(localPlayer, movementVector, maxMovement)
else
lastMovementVector = Vector2.new(0,0)
lastMaxMovement = 1
moveCharacterFunc(localPlayer, lastMovementVector, lastMaxMovement)
end
end
end
local thumbstickPos = UDim2.new(0,thumbstickSize/2,1,-thumbstickSize*1.75)
if isSmallScreenDevice() then
thumbstickPos = UDim2.new(0,(thumbstickSize/2) - 10,1,-thumbstickSize - 20)
end
local characterThumbstick = constructThumbstick(thumbstickPos, moveCharacterFunction, false)
characterThumbstick.Name = "CharacterThumbstick"
characterThumbstick.Parent = parentFrame
local refreshCharacterMovement = function()
if localPlayer and moveCharacterFunc and lastMovementVector and lastMaxMovement then
moveCharacterFunc(localPlayer, lastMovementVector, lastMaxMovement)
end
end
return refreshCharacterMovement
end
function setupJumpButton( parentFrame )
local jumpButton = Instance.new("ImageButton")
jumpButton.Name = "JumpButton"
jumpButton.BackgroundTransparency = 1
jumpButton.Image = touchControlsSheet
jumpButton.ImageRectOffset = Vector2.new(176,222)
jumpButton.ImageRectSize = Vector2.new(174,174)
jumpButton.Size = UDim2.new(0,jumpButtonSize,0,jumpButtonSize)
if isSmallScreenDevice() then
jumpButton.Position = UDim2.new(1, -(jumpButtonSize*2.25), 1, -jumpButtonSize - 20)
else
jumpButton.Position = UDim2.new(1, -(jumpButtonSize*2.75), 1, -jumpButtonSize - 120)
end
local playerJumpFunc = localPlayer.JumpCharacter
local doJumpLoop = function ()
while currentJumpTouch do
if localPlayer then
playerJumpFunc(localPlayer)
end
wait(1/60)
end
end
jumpButton.InputBegan:connect(function(inputObject)
if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
if currentJumpTouch then return end
if inputObject == cameraTouch then return end
for i, touch in pairs(oldJumpTouches) do
if touch == inputObject then
return
end
end
currentJumpTouch = inputObject
jumpButton.ImageRectOffset = Vector2.new(0,222)
jumpButton.ImageRectSize = Vector2.new(174,174)
doJumpLoop()
end)
jumpButton.InputEnded:connect(function (inputObject)
if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
jumpButton.ImageRectOffset = Vector2.new(176,222)
jumpButton.ImageRectSize = Vector2.new(174,174)
if inputObject == currentJumpTouch then
table.insert(oldJumpTouches,currentJumpTouch)
currentJumpTouch = nil
end
end)
userInputService.InputEnded:connect(function ( globalInputObject )
for i, touch in pairs(oldJumpTouches) do
if touch == globalInputObject then
table.remove(oldJumpTouches,i)
break
end
end
end)
userInputService.Changed:connect(function(prop)
if prop == "ModalEnabled" then
jumpButton.Visible = not userInputService.ModalEnabled
end
end)
jumpButton.Parent = parentFrame
end
function isTouchUsedByJumpButton( touch )
if touch == currentJumpTouch then return true end
for i, touchToCompare in pairs(oldJumpTouches) do
if touch == touchToCompare then
return true
end
end
return false
end
function isTouchUsedByThumbstick(touch)
for i, touchToCompare in pairs(thumbstickTouches) do
if touch == touchToCompare then
return true
end
end
return false
end
function setupCameraControl(parentFrame, refreshCharacterMoveFunc)
local lastPos = nil
local hasRotatedCamera = false
local rotateCameraFunc = userInputService.RotateCamera
local pinchTime = -1
local shouldPinch = false
local lastPinchScale = nil
local zoomCameraFunc = userInputService.ZoomCamera
local pinchTouches = {}
local pinchFrame = nil
local resetCameraRotateState = function()
cameraTouch = nil
hasRotatedCamera = false
lastPos = nil
end
local resetPinchState = function ()
pinchTouches = {}
lastPinchScale = nil
shouldPinch = false
pinchFrame:Destroy()
pinchFrame = nil
end
local startPinch = function(firstTouch, secondTouch)
-- track pinching in new frame
if pinchFrame then pinchFrame:Destroy() end -- make sure we didn't track in any mud
pinchFrame = Instance.new("Frame")
pinchFrame.Name = "PinchFrame"
pinchFrame.BackgroundTransparency = 1
pinchFrame.Parent = parentFrame
pinchFrame.Size = UDim2.new(1,0,1,0)
pinchFrame.InputChanged:connect(function(inputObject)
if not shouldPinch then
resetPinchState()
return
end
resetCameraRotateState()
if lastPinchScale == nil then -- first pinch move, just set up scale
if inputObject == firstTouch then
lastPinchScale = (inputObject.Position - secondTouch.Position).magnitude
firstTouch = inputObject
elseif inputObject == secondTouch then
lastPinchScale = (inputObject.Position - firstTouch.Position).magnitude
secondTouch = inputObject
end
else -- we are now actually pinching, do comparison to last pinch size
local newPinchDistance = 0
if inputObject == firstTouch then
newPinchDistance = (inputObject.Position - secondTouch.Position).magnitude
firstTouch = inputObject
elseif inputObject == secondTouch then
newPinchDistance = (inputObject.Position - firstTouch.Position).magnitude
secondTouch = inputObject
end
if newPinchDistance ~= 0 then
local pinchDiff = newPinchDistance - lastPinchScale
if pinchDiff ~= 0 then
zoomCameraFunc(userInputService, (pinchDiff * CameraZoomSensitivity))
end
lastPinchScale = newPinchDistance
end
end
end)
pinchFrame.InputEnded:connect(function(inputObject) -- pinch is over, destroy all
if inputObject == firstTouch or inputObject == secondTouch then
resetPinchState()
end
end)
end
local pinchGestureReceivedTouch = function(inputObject)
if #pinchTouches < 1 then
table.insert(pinchTouches,inputObject)
pinchTime = tick()
shouldPinch = false
elseif #pinchTouches == 1 then
shouldPinch = ( (tick() - pinchTime) <= PinchZoomDelay )
if shouldPinch then
table.insert(pinchTouches,inputObject)
startPinch(pinchTouches[1], pinchTouches[2])
else -- shouldn't ever get here, but just in case
pinchTouches = {}
end
end
end
parentFrame.InputBegan:connect(function (inputObject)
if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
if isTouchUsedByJumpButton(inputObject) then return end
local usedByThumbstick = isTouchUsedByThumbstick(inputObject)
if not usedByThumbstick then
pinchGestureReceivedTouch(inputObject)
end
if cameraTouch == nil and not usedByThumbstick then
cameraTouch = inputObject
lastPos = Vector2.new(cameraTouch.Position.x,cameraTouch.Position.y)
lastTick = tick()
end
end)
userInputService.InputChanged:connect(function (inputObject)
if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
if cameraTouch ~= inputObject then return end
local newPos = Vector2.new(cameraTouch.Position.x,cameraTouch.Position.y)
local touchDiff = (lastPos - newPos) * CameraRotateSensitivity
-- first time rotating outside deadzone, just setup for next changed event
if not hasRotatedCamera and (touchDiff.magnitude > CameraRotateDeadZone) then
hasRotatedCamera = true
lastPos = newPos
end
-- fire everytime after we have rotated out of deadzone
if hasRotatedCamera and (lastPos ~= newPos) then
rotateCameraFunc(userInputService, touchDiff)
refreshCharacterMoveFunc()
lastPos = newPos
end
end)
userInputService.InputEnded:connect(function (inputObject)
if cameraTouch == inputObject or cameraTouch == nil then
resetCameraRotateState()
end
for i, touch in pairs(pinchTouches) do
if touch == inputObject then
table.remove(pinchTouches,i)
end
end
end)
end
function setupTouchControls()
local touchControlFrame = Instance.new("Frame")
touchControlFrame.Name = "TouchControlFrame"
touchControlFrame.Size = UDim2.new(1,0,1,0)
touchControlFrame.BackgroundTransparency = 1
touchControlFrame.Parent = Game.CoreGui.RobloxGui
local refreshCharacterMoveFunc = setupCharacterMovement(touchControlFrame)
setupJumpButton(touchControlFrame)
setupCameraControl(touchControlFrame, refreshCharacterMoveFunc)
userInputService.ProcessedEvent:connect(function(inputObject, processed)
if not processed then return end
-- kill camera pan if the touch is used by some user controls
if inputObject == cameraTouch and inputObject.UserInputState == Enum.UserInputState.Begin then
cameraTouch = nil
end
end)
end
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- Start of Script
if userInputService:IsLuaTouchControls() then
setupTouchControls()
else
script:Destroy()
end