forked from aya/aya
Initial commit
This commit is contained in:
@@ -0,0 +1,512 @@
|
||||
-- This script creates almost all gui elements found in the backpack (warning: there are a lot!)
|
||||
-- TODO: automate this process
|
||||
|
||||
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
|
||||
|
||||
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, -240, 1, -85)
|
||||
CurrentLoadout.Size = UDim2.new(0, 480, 0, 48)
|
||||
CurrentLoadout.BackgroundTransparency = 1
|
||||
CurrentLoadout.RobloxLocked = true
|
||||
CurrentLoadout.Parent = gui
|
||||
|
||||
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/ui/backpackButton.png"
|
||||
BackpackButton.Position = UDim2.new(0.5, -195, 1, -30)
|
||||
BackpackButton.Size = UDim2.new(0,107,0,26)
|
||||
waitForChild(gui,"ControlFrame")
|
||||
BackpackButton.Parent = gui.ControlFrame
|
||||
|
||||
for i = 0, 9 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)
|
||||
if i == 0 then
|
||||
slotFrame.Position = UDim2.new(0.9,0,0,0)
|
||||
else
|
||||
slotFrame.Position = UDim2.new((i - 1) * 0.1,0,0,0)
|
||||
end
|
||||
slotFrame.Size = UDim2.new(0.1,0,1,0)
|
||||
slotFrame.Parent = CurrentLoadout
|
||||
end
|
||||
|
||||
local TempSlot = Instance.new("ImageButton")
|
||||
TempSlot.Name = "TempSlot"
|
||||
TempSlot.Active = true
|
||||
TempSlot.Size = UDim2.new(1,0,1,0)
|
||||
TempSlot.Style = Enum.ButtonStyle.RobloxButton
|
||||
TempSlot.Visible = false
|
||||
TempSlot.RobloxLocked = true
|
||||
TempSlot.Parent = CurrentLoadout
|
||||
|
||||
-- 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,-7,0,-7)
|
||||
GearImage.Size = UDim2.new(1,14,1,14)
|
||||
GearImage.ZIndex = 2
|
||||
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,-7,0,-7)
|
||||
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.ZIndex = 4
|
||||
SlotNumber.RobloxLocked = true
|
||||
SlotNumber.Parent = TempSlot
|
||||
|
||||
local SlotNumberDownShadow = SlotNumber:clone()
|
||||
SlotNumberDownShadow.Name = "SlotNumberDownShadow"
|
||||
SlotNumberDownShadow.TextColor3 = Color3.new(0,0,0)
|
||||
SlotNumberDownShadow.ZIndex = 3
|
||||
SlotNumberDownShadow.Position = UDim2.new(0,-6,0,-6)
|
||||
SlotNumberDownShadow.Parent = TempSlot
|
||||
|
||||
local SlotNumberUpShadow = SlotNumberDownShadow:clone()
|
||||
SlotNumberUpShadow.Name = "SlotNumberUpShadow"
|
||||
SlotNumberUpShadow.Position = UDim2.new(0,-8,0,-8)
|
||||
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.ZIndex = 2
|
||||
GearText.Size = UDim2.new(1,16,1,16)
|
||||
GearText.Text = ""
|
||||
GearText.TextColor3 = Color3.new(1,1,1)
|
||||
GearText.TextWrap = true
|
||||
GearText.Parent = TempSlot
|
||||
|
||||
--- 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(0,0,0)
|
||||
Backpack.BackgroundTransparency = 0.08
|
||||
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 = true
|
||||
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
|
||||
|
||||
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.69,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,64,0,64)
|
||||
GearButton.Style = Enum.ButtonStyle.RobloxButton
|
||||
GearButton.Parent = GearGrid
|
||||
|
||||
-- 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(0.7,0,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
|
||||
|
||||
------------------------------- WARDROBE -------------------------------------------------------
|
||||
script:remove()
|
||||
return
|
||||
|
||||
863
client/common/content/scripts/CoreScripts/2012/BackpackGear.lua
Normal file
863
client/common/content/scripts/CoreScripts/2012/BackpackGear.lua
Normal file
@@ -0,0 +1,863 @@
|
||||
-- A couple of necessary functions
|
||||
local function waitForChild(instance, name)
|
||||
assert(instance)
|
||||
assert(name)
|
||||
while not instance:FindFirstChild(name) do
|
||||
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
|
||||
|
||||
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/2012/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")
|
||||
|
||||
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.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)
|
||||
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
|
||||
|
||||
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 -----------------------
|
||||
|
||||
|
||||
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 -----------------------
|
||||
|
||||
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()
|
||||
@@ -0,0 +1,348 @@
|
||||
-- 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)
|
||||
|
||||
-- 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
|
||||
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 canToggle = true
|
||||
local readyForNextEvent = true
|
||||
local backpackIsOpen = false
|
||||
local active = true
|
||||
|
||||
local humanoidDiedCon = nil
|
||||
|
||||
local guiTweenSpeed = 0.25 -- how quickly we open/close the backpack
|
||||
|
||||
local searchDefaultText = "Search..."
|
||||
local tilde = "~"
|
||||
local backquote = "`"
|
||||
|
||||
------------------------ 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
|
||||
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,0,0,0),UDim2.new(0.5,0,0.5,0), 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
|
||||
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(UDim2.new(0.55, 0, 0.76, 0),UDim2.new(0.225, 0, 0.09, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed, true)
|
||||
delay(guiTweenSpeed,function()
|
||||
backpack.Tabs.Visible = true
|
||||
searchFrame.Visible = true
|
||||
backpackOpenEvent:Fire(currentTab)
|
||||
canToggle = true
|
||||
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
|
||||
showBackpack()
|
||||
else
|
||||
backpackButton.Selected = false
|
||||
hideBackpack()
|
||||
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
|
||||
|
||||
--------------------------- End Internal Functions -------------------------------------
|
||||
|
||||
|
||||
------------------------------ Public Functions Setup -------------------------------------
|
||||
createPublicFunction("CloseBackpack", hideBackpack)
|
||||
createPublicFunction("BackpackReady", backpackReady)
|
||||
------------------------------ End Public Functions Setup ---------------------------------
|
||||
|
||||
|
||||
------------------------ Connections/Script Main -------------------------------------------
|
||||
|
||||
inventoryButton.MouseButton1Click:connect(function() newTabClicked("gear") end)
|
||||
inventoryButton.MouseEnter:connect(function() mouseOverTab(inventoryButton) end)
|
||||
inventoryButton.MouseLeave:connect(function() mouseLeaveTab(inventoryButton) 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 then return end
|
||||
if key == tilde or key == backquote then
|
||||
toggleBackpack()
|
||||
end
|
||||
end)
|
||||
backpackButton.MouseButton1Click:connect(function()
|
||||
if not active 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)
|
||||
|
||||
backpackButton.Visible = true
|
||||
659
client/common/content/scripts/CoreScripts/2012/BubbleChat.lua
Normal file
659
client/common/content/scripts/CoreScripts/2012/BubbleChat.lua
Normal 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
|
||||
1319
client/common/content/scripts/CoreScripts/2012/ChatScript.lua
Normal file
1319
client/common/content/scripts/CoreScripts/2012/ChatScript.lua
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
609
client/common/content/scripts/CoreScripts/2012/HealthScript.lua
Normal file
609
client/common/content/scripts/CoreScripts/2012/HealthScript.lua
Normal 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)
|
||||
888
client/common/content/scripts/CoreScripts/2012/LoadoutScript.lua
Normal file
888
client/common/content/scripts/CoreScripts/2012/LoadoutScript.lua
Normal file
@@ -0,0 +1,888 @@
|
||||
|
||||
-- A couple of necessary 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
|
||||
|
||||
local currentLoadout = script.Parent
|
||||
local StaticTabName = "gear"
|
||||
|
||||
local robloxGui = game:GetService("CoreGui"):FindFirstChild("RobloxGui")
|
||||
assert(robloxGui)
|
||||
waitForChild(robloxGui,"CurrentLoadout")
|
||||
waitForChild(robloxGui.CurrentLoadout,"TempSlot")
|
||||
waitForChild(robloxGui.CurrentLoadout.TempSlot,"SlotNumber")
|
||||
|
||||
|
||||
--- Begin Locals
|
||||
|
||||
|
||||
waitForChild(game,"Players")
|
||||
|
||||
waitForProperty(game.Players,"LocalPlayer")
|
||||
|
||||
local player = game.Players.LocalPlayer
|
||||
|
||||
|
||||
-- waitForChild(game, "LocalBackpack")
|
||||
-- game.LocalBackpack:SetOldSchoolBackpack(false)
|
||||
|
||||
|
||||
waitForChild(currentLoadout.Parent,"Backpack")
|
||||
local guiBackpack = currentLoadout.Parent.Backpack
|
||||
|
||||
|
||||
local backpackManager = waitForChild(guiBackpack,"CoreScripts/2012/BackpackManager")
|
||||
|
||||
|
||||
local backpackOpenEvent = waitForChild(backpackManager,"BackpackOpenEvent")
|
||||
local backpackCloseEvent = waitForChild(backpackManager,"BackpackCloseEvent")
|
||||
local tabClickedEvent = waitForChild(backpackManager,"TabClickedEvent")
|
||||
local resizeEvent = waitForChild(backpackManager,"ResizeEvent")
|
||||
|
||||
|
||||
local inGearTab = true
|
||||
|
||||
local maxNumLoadoutItems = 10
|
||||
|
||||
local characterChildAddedCon = nil
|
||||
local backpackChildCon = nil
|
||||
|
||||
local debounce = false
|
||||
|
||||
local enlargeFactor = 1.18
|
||||
local buttonSizeEnlarge = UDim2.new(1 * enlargeFactor,0,1 * enlargeFactor,0)
|
||||
local buttonSizeNormal = UDim2.new(1,0,1,0)
|
||||
local enlargeOverride = true
|
||||
local guiTweenSpeed = 0.5
|
||||
|
||||
local inventory = {}
|
||||
|
||||
for i = 0, 9 do
|
||||
game:GetService("GuiService"):AddKey(tostring(i)) -- register our keys
|
||||
end
|
||||
|
||||
local gearSlots = {}
|
||||
for i = 1, maxNumLoadoutItems do
|
||||
gearSlots[i] = "empty"
|
||||
end
|
||||
--- End Locals
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Begin Functions
|
||||
local function kill(prop,con,gear)
|
||||
if con then con:disconnect() end
|
||||
if prop == true and gear then
|
||||
reorganizeLoadout(gear,false)
|
||||
end
|
||||
end
|
||||
|
||||
function characterInWorkspace()
|
||||
if game.Players["LocalPlayer"] then
|
||||
if game.Players.LocalPlayer["Character"] then
|
||||
if game.Players.LocalPlayer.Character ~= nil then
|
||||
if game.Players.LocalPlayer.Character.Parent ~= nil then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function removeGear(gear)
|
||||
local emptySlot = nil
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] == gear and gear.Parent ~= nil then
|
||||
emptySlot = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if emptySlot then
|
||||
if gearSlots[emptySlot].GearReference.Value then
|
||||
if gearSlots[emptySlot].GearReference.Value.Parent == game.Players.LocalPlayer.Character then -- if we currently have this equipped, unequip it
|
||||
gearSlots[emptySlot].GearReference.Value.Parent = game.Players.LocalPlayer.Backpack
|
||||
end
|
||||
|
||||
if gearSlots[emptySlot].GearReference.Value:IsA("HopperBin") and gearSlots[emptySlot].GearReference.Value.Active then -- this is an active hopperbin
|
||||
gearSlots[emptySlot].GearReference.Value:Disable()
|
||||
gearSlots[emptySlot].GearReference.Value.Active = false
|
||||
end
|
||||
end
|
||||
|
||||
gearSlots[emptySlot] = "empty"
|
||||
|
||||
local centerizeX = gear.Size.X.Scale/2
|
||||
local centerizeY = gear.Size.Y.Scale/2
|
||||
gear:TweenSizeAndPosition(UDim2.new(0,0,0,0),
|
||||
UDim2.new(gear.Position.X.Scale + centerizeX,gear.Position.X.Offset,gear.Position.Y.Scale + centerizeY,gear.Position.Y.Offset),
|
||||
Enum.EasingDirection.Out, Enum.EasingStyle.Quad,guiTweenSpeed/4,true)
|
||||
delay(guiTweenSpeed/2,
|
||||
function()
|
||||
gear:remove()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function insertGear(gear, addToSlot)
|
||||
local pos = nil
|
||||
if not addToSlot then
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] == "empty" then
|
||||
pos = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if pos == 1 and gearSlots[1] ~= "empty" then gear:remove() return end -- we are currently full, can't add in
|
||||
else
|
||||
pos = addToSlot
|
||||
-- push all gear down one slot
|
||||
local start = 1
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] == "empty" then
|
||||
start = i
|
||||
break
|
||||
end
|
||||
end
|
||||
for i = start, pos + 1, -1 do
|
||||
gearSlots[i] = gearSlots[i - 1]
|
||||
if i == 10 then
|
||||
gearSlots[i].SlotNumber.Text = "0"
|
||||
gearSlots[i].SlotNumberDownShadow.Text = "0"
|
||||
gearSlots[i].SlotNumberUpShadow.Text = "0"
|
||||
else
|
||||
gearSlots[i].SlotNumber.Text = i
|
||||
gearSlots[i].SlotNumberDownShadow.Text = i
|
||||
gearSlots[i].SlotNumberUpShadow.Text = i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
gearSlots[pos] = gear
|
||||
if pos ~= maxNumLoadoutItems then
|
||||
if(type(tostring(pos)) == "string") then
|
||||
local posString = tostring(pos)
|
||||
gear.SlotNumber.Text = posString
|
||||
gear.SlotNumberDownShadow.Text = posString
|
||||
gear.SlotNumberUpShadow.Text = posString
|
||||
end
|
||||
else -- tenth gear doesn't follow mathematical pattern :(
|
||||
gear.SlotNumber.Text = "0"
|
||||
gear.SlotNumberDownShadow.Text = "0"
|
||||
gear.SlotNumberUpShadow.Text = "0"
|
||||
end
|
||||
gear.Visible = true
|
||||
|
||||
local con = nil
|
||||
con = gear.Kill.Changed:connect(function(prop) kill(prop,con,gear) end)
|
||||
end
|
||||
|
||||
|
||||
function reorganizeLoadout(gear, inserting, equipped, addToSlot)
|
||||
if inserting then -- add in gear
|
||||
insertGear(gear, addToSlot)
|
||||
else
|
||||
removeGear(gear)
|
||||
end
|
||||
if gear ~= "empty" then gear.ZIndex = 1 end
|
||||
end
|
||||
|
||||
function checkToolAncestry(child,parent)
|
||||
if child:FindFirstChild("RobloxBuildTool") then return end -- don't show roblox build tools
|
||||
if child:IsA("Tool") or child:IsA("HopperBin") then
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] ~= "empty" and gearSlots[i].GearReference.Value == child then
|
||||
if parent == nil then
|
||||
gearSlots[i].Kill.Value = true
|
||||
return false
|
||||
elseif child.Parent == player.Character then
|
||||
gearSlots[i].Selected = true
|
||||
return true
|
||||
elseif child.Parent == player.Backpack then
|
||||
if child:IsA("Tool") or child:IsA("HopperBin") then gearSlots[i].Selected = false end
|
||||
return true
|
||||
else
|
||||
gearSlots[i].Kill.Value = true
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
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
|
||||
if stuff[i]:IsA("Tool") then stuff[i].Parent = player.Backpack end
|
||||
if stuff[i]:IsA("HopperBin") then
|
||||
stuff[i]:Disable()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function hopperBinSwitcher(numKey, physGear)
|
||||
if not physGear then return end
|
||||
|
||||
physGear:ToggleSelect()
|
||||
|
||||
if gearSlots[numKey] == "empty" then return end
|
||||
|
||||
if not physGear.Active then
|
||||
gearSlots[numKey].Selected = false
|
||||
normalizeButton(gearSlots[numKey])
|
||||
else
|
||||
gearSlots[numKey].Selected = true
|
||||
enlargeButton(gearSlots[numKey])
|
||||
end
|
||||
end
|
||||
|
||||
function toolSwitcher(numKey)
|
||||
|
||||
if not gearSlots[numKey] then return end
|
||||
local physGear = gearSlots[numKey].GearReference.Value
|
||||
if physGear == nil then return end
|
||||
|
||||
removeAllEquippedGear(physGear) -- we don't remove this gear, as then we get a double switcheroo
|
||||
|
||||
local key = numKey
|
||||
if numKey == 0 then key = 10 end
|
||||
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] and gearSlots[i] ~= "empty" and i ~= key then
|
||||
normalizeButton(gearSlots[i])
|
||||
gearSlots[i].Selected = false
|
||||
if gearSlots[i].GearReference and gearSlots[i].GearReference.Value and gearSlots[i].GearReference.Value:IsA("HopperBin") and gearSlots[i].GearReference.Value.Active then
|
||||
gearSlots[i].GearReference.Value:ToggleSelect()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if physGear:IsA("HopperBin") then
|
||||
hopperBinSwitcher(numKey,physGear)
|
||||
else
|
||||
if physGear.Parent == player.Character then
|
||||
physGear.Parent = player.Backpack
|
||||
|
||||
if gearSlots[numKey] ~= "empty" then
|
||||
gearSlots[numKey].Selected = false
|
||||
normalizeButton(gearSlots[numKey])
|
||||
end
|
||||
else
|
||||
--player.Character.Humanoid:EquipTool(physGear)
|
||||
|
||||
physGear.Parent = player.Character
|
||||
gearSlots[numKey].Selected = true
|
||||
|
||||
enlargeButton(gearSlots[numKey])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function activateGear(num)
|
||||
local numKey = nil
|
||||
if num == "0" then
|
||||
numKey = 10 -- why do lua indexes have to start at 1? :(
|
||||
else
|
||||
numKey = tonumber(num)
|
||||
end
|
||||
|
||||
if(numKey == nil) then return end
|
||||
|
||||
if gearSlots[numKey] ~= "empty" then
|
||||
toolSwitcher(numKey)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
enlargeButton = function(button)
|
||||
if button.Size.Y.Scale > 1 then return end
|
||||
if not button.Parent then return end
|
||||
if not button.Selected then return end
|
||||
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] == "empty" then break end
|
||||
if gearSlots[i] ~= button then
|
||||
normalizeButton(gearSlots[i])
|
||||
end
|
||||
end
|
||||
|
||||
if not enlargeOverride then
|
||||
return
|
||||
end
|
||||
|
||||
if button:IsA("ImageButton") or button:IsA("TextButton") then
|
||||
button.ZIndex = 2
|
||||
local centerizeX = -(buttonSizeEnlarge.X.Scale - button.Size.X.Scale)/2
|
||||
local centerizeY = -(buttonSizeEnlarge.Y.Scale - button.Size.Y.Scale)/2
|
||||
button:TweenSizeAndPosition(buttonSizeEnlarge,
|
||||
UDim2.new(button.Position.X.Scale + centerizeX,button.Position.X.Offset,button.Position.Y.Scale + centerizeY,button.Position.Y.Offset),
|
||||
Enum.EasingDirection.Out, Enum.EasingStyle.Quad,guiTweenSpeed/5,enlargeOverride)
|
||||
end
|
||||
end
|
||||
|
||||
normalizeAllButtons = function()
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] == "empty" then break end
|
||||
if gearSlots[i] ~= button then
|
||||
normalizeButton(gearSlots[i],0.1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
normalizeButton = function(button, speed)
|
||||
if not button then return end
|
||||
if button.Size.Y.Scale <= 1 then return end
|
||||
if button.Selected then return end
|
||||
if not button.Parent then return end
|
||||
|
||||
local moveSpeed = speed
|
||||
if moveSpeed == nil or type(moveSpeed) ~= "number" then moveSpeed = guiTweenSpeed/5 end
|
||||
|
||||
if button:IsA("ImageButton") or button:IsA("TextButton") then
|
||||
button.ZIndex = 1
|
||||
local inverseEnlarge = 1/enlargeFactor
|
||||
local centerizeX = -(buttonSizeNormal.X.Scale - button.Size.X.Scale)/2
|
||||
local centerizeY = -(buttonSizeNormal.Y.Scale - button.Size.Y.Scale)/2
|
||||
button:TweenSizeAndPosition(buttonSizeNormal,
|
||||
UDim2.new(button.Position.X.Scale + centerizeX,button.Position.X.Offset,button.Position.Y.Scale + centerizeY,button.Position.Y.Offset),
|
||||
Enum.EasingDirection.Out, Enum.EasingStyle.Quad,moveSpeed,enlargeOverride)
|
||||
end
|
||||
end
|
||||
|
||||
local waitForDebounce = function()
|
||||
while debounce do
|
||||
wait()
|
||||
end
|
||||
end
|
||||
|
||||
function pointInRectangle(point,rectTopLeft,rectSize)
|
||||
if point.x > rectTopLeft.x and point.x < (rectTopLeft.x + rectSize.x) then
|
||||
if point.y > rectTopLeft.y and point.y < (rectTopLeft.y + rectSize.y) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function swapGear(gearClone,toFrame)
|
||||
local toFrameChildren = toFrame:GetChildren()
|
||||
if #toFrameChildren == 1 then
|
||||
if toFrameChildren[1]:FindFirstChild("SlotNumber") then
|
||||
|
||||
local toSlot = tonumber(toFrameChildren[1].SlotNumber.Text)
|
||||
local gearCloneSlot = tonumber(gearClone.SlotNumber.Text)
|
||||
if toSlot == 0 then toSlot = 10 end
|
||||
if gearCloneSlot == 0 then gearCloneSlot = 10 end
|
||||
|
||||
gearSlots[toSlot] = gearClone
|
||||
gearSlots[gearCloneSlot] = toFrameChildren[1]
|
||||
|
||||
toFrameChildren[1].SlotNumber.Text = gearClone.SlotNumber.Text
|
||||
toFrameChildren[1].SlotNumberDownShadow.Text = gearClone.SlotNumber.Text
|
||||
toFrameChildren[1].SlotNumberUpShadow.Text = gearClone.SlotNumber.Text
|
||||
|
||||
local subString = string.sub(toFrame.Name,5)
|
||||
gearClone.SlotNumber.Text = subString
|
||||
gearClone.SlotNumberDownShadow.Text = subString
|
||||
gearClone.SlotNumberUpShadow.Text = subString
|
||||
|
||||
gearClone.Position = UDim2.new(gearClone.Position.X.Scale,0,gearClone.Position.Y.Scale,0)
|
||||
toFrameChildren[1].Position = UDim2.new(toFrameChildren[1].Position.X.Scale,0,toFrameChildren[1].Position.Y.Scale,0)
|
||||
|
||||
toFrameChildren[1].Parent = gearClone.Parent
|
||||
gearClone.Parent = toFrame
|
||||
end
|
||||
else
|
||||
local slotNum = tonumber(gearClone.SlotNumber.Text)
|
||||
if slotNum == 0 then slotNum = 10 end
|
||||
gearSlots[slotNum] = "empty" -- reset this gear slot
|
||||
|
||||
local subString = string.sub(toFrame.Name,5)
|
||||
gearClone.SlotNumber.Text = subString
|
||||
gearClone.SlotNumberDownShadow.Text = subString
|
||||
gearClone.SlotNumberUpShadow.Text = subString
|
||||
|
||||
local toSlotNum = tonumber(gearClone.SlotNumber.Text)
|
||||
if toSlotNum == 0 then toSlotNum = 10 end
|
||||
gearSlots[toSlotNum] = gearClone
|
||||
gearClone.Position = UDim2.new(gearClone.Position.X.Scale,0,gearClone.Position.Y.Scale,0)
|
||||
gearClone.Parent = toFrame
|
||||
end
|
||||
end
|
||||
|
||||
function resolveDrag(gearClone,x,y)
|
||||
local mousePoint = Vector2.new(x,y)
|
||||
|
||||
local frame = gearClone.Parent
|
||||
local frames = frame.Parent:GetChildren()
|
||||
|
||||
for i = 1, #frames do
|
||||
if frames[i]:IsA("Frame") then
|
||||
if pointInRectangle(mousePoint, frames[i].AbsolutePosition,frames[i].AbsoluteSize) then
|
||||
swapGear(gearClone,frames[i])
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if x < frame.AbsolutePosition.x or x > ( frame.AbsolutePosition.x + frame.AbsoluteSize.x ) then
|
||||
reorganizeLoadout(gearClone,false)
|
||||
return false
|
||||
elseif y < frame.AbsolutePosition.y or y > ( frame.AbsolutePosition.y + frame.AbsoluteSize.y ) then
|
||||
reorganizeLoadout(gearClone,false)
|
||||
return false
|
||||
else
|
||||
if dragBeginPos then gearClone.Position = dragBeginPos end
|
||||
return -1
|
||||
end
|
||||
end
|
||||
|
||||
function unequipAllItems(dontEquipThis)
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] == "empty" then break end
|
||||
if gearSlots[i].GearReference.Value and gearSlots[i].GearReference.Value ~= dontEquipThis then
|
||||
if gearSlots[i].GearReference.Value:IsA("HopperBin") then
|
||||
gearSlots[i].GearReference.Value:Disable()
|
||||
elseif gearSlots[i].GearReference.Value:IsA("Tool") then
|
||||
gearSlots[i].GearReference.Value.Parent = game.Players.LocalPlayer.Backpack
|
||||
end
|
||||
gearSlots[i].Selected = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function showToolTip(button, tip)
|
||||
if button and button:FindFirstChild("ToolTipLabel") and button.ToolTipLabel:IsA("TextLabel") then
|
||||
button.ToolTipLabel.Text = tostring(tip)
|
||||
local xSize = button.ToolTipLabel.TextBounds.X + 6
|
||||
button.ToolTipLabel.Size = UDim2.new(0,xSize,0,20)
|
||||
button.ToolTipLabel.Position = UDim2.new(0.5,-xSize/2,0,-30)
|
||||
button.ToolTipLabel.Visible = true
|
||||
end
|
||||
end
|
||||
|
||||
function hideToolTip(button, tip)
|
||||
if button and button:FindFirstChild("ToolTipLabel") and button.ToolTipLabel:IsA("TextLabel") then
|
||||
button.ToolTipLabel.Visible = false
|
||||
end
|
||||
end
|
||||
|
||||
local addingPlayerChild = function(child, equipped, addToSlot, inventoryGearButton)
|
||||
waitForDebounce()
|
||||
debounce = true
|
||||
|
||||
if child:FindFirstChild("RobloxBuildTool") then debounce = false return end -- don't show roblox build tools
|
||||
if not child:IsA("Tool") then
|
||||
if not child:IsA("HopperBin") then
|
||||
debounce = false
|
||||
return -- we don't care about anything besides tools (sigh...)
|
||||
end
|
||||
end
|
||||
|
||||
if not addToSlot then
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] ~= "empty" and gearSlots[i].GearReference.Value == child then -- we already have gear, do nothing
|
||||
debounce = false
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local gearClone = currentLoadout.TempSlot:clone()
|
||||
gearClone.Name = child.Name
|
||||
gearClone.GearImage.Image = child.TextureId
|
||||
if gearClone.GearImage.Image == "" then
|
||||
gearClone.GearText.Text = child.Name
|
||||
end
|
||||
gearClone.GearReference.Value = child
|
||||
|
||||
gearClone.MouseEnter:connect(function()
|
||||
if gearClone.GearReference and gearClone.GearReference.Value["ToolTip"] and gearClone.GearReference.Value.ToolTip ~= "" then
|
||||
showToolTip(gearClone, gearClone.GearReference.Value.ToolTip)
|
||||
end
|
||||
end)
|
||||
|
||||
gearClone.MouseLeave:connect(function()
|
||||
if gearClone.GearReference and gearClone.GearReference.Value["ToolTip"] and gearClone.GearReference.Value.ToolTip ~= "" then
|
||||
hideToolTip(gearClone, gearClone.GearReference.Value.ToolTip)
|
||||
end
|
||||
end)
|
||||
|
||||
gearClone.RobloxLocked = true
|
||||
|
||||
local slotToMod = -1
|
||||
|
||||
if not addToSlot then
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] == "empty" then
|
||||
slotToMod = i
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
slotToMod = addToSlot
|
||||
end
|
||||
|
||||
if slotToMod == - 1 then -- No available slot to add in!
|
||||
debounce = false
|
||||
return
|
||||
end
|
||||
|
||||
local slotNum = slotToMod % 10
|
||||
local parent = currentLoadout:FindFirstChild("Slot"..tostring(slotNum))
|
||||
gearClone.Parent = parent
|
||||
|
||||
if inventoryGearButton then
|
||||
local absolutePositionFinal = inventoryGearButton.AbsolutePosition
|
||||
local currentAbsolutePosition = gearClone.AbsolutePosition
|
||||
local diff = absolutePositionFinal - currentAbsolutePosition
|
||||
gearClone.Position = UDim2.new(gearClone.Position.X.Scale,diff.x,gearClone.Position.Y.Scale,diff.y)
|
||||
gearClone.ZIndex = 4
|
||||
end
|
||||
|
||||
if addToSlot then
|
||||
reorganizeLoadout(gearClone, true, equipped, addToSlot)
|
||||
else
|
||||
reorganizeLoadout(gearClone, true)
|
||||
end
|
||||
|
||||
if gearClone.Parent == nil then debounce = false return end -- couldn't fit in (hopper is full!)
|
||||
|
||||
if equipped then
|
||||
gearClone.Selected = true
|
||||
unequipAllItems(child)
|
||||
delay(guiTweenSpeed + 0.01,function() -- if our gear is equipped, we will want to enlarge it when done moving
|
||||
if gearClone:FindFirstChild("GearReference") and ( (gearClone.GearReference.Value:IsA("Tool") and gearClone.GearReference.Value.Parent == player.Character) or
|
||||
(gearClone.GearReference.Value:IsA("HopperBin") and gearClone.GearReference.Value.Active == true) ) then
|
||||
enlargeButton(gearClone)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local dragBeginPos = nil
|
||||
local clickCon, buttonDeleteCon, mouseEnterCon, mouseLeaveCon, dragStop, dragBegin = nil
|
||||
clickCon = gearClone.MouseButton1Click:connect(function()
|
||||
if characterInWorkspace() then
|
||||
if not gearClone.Draggable then
|
||||
activateGear(gearClone.SlotNumber.Text)
|
||||
end
|
||||
end
|
||||
end)
|
||||
mouseEnterCon = gearClone.MouseEnter:connect(function()
|
||||
if guiBackpack.Visible then
|
||||
gearClone.Draggable = true
|
||||
end
|
||||
end)
|
||||
dragBegin = gearClone.DragBegin:connect(function(pos)
|
||||
dragBeginPos = pos
|
||||
gearClone.ZIndex = 7
|
||||
local children = gearClone:GetChildren()
|
||||
for i = 1, #children do
|
||||
if children[i]:IsA("TextLabel") then
|
||||
if string.find(children[i].Name,"Shadow") then
|
||||
children[i].ZIndex = 8
|
||||
else
|
||||
children[i].ZIndex = 9
|
||||
end
|
||||
elseif children[i]:IsA("Frame") or children[i]:IsA("ImageLabel") then
|
||||
children[i].ZIndex = 7
|
||||
end
|
||||
end
|
||||
end)
|
||||
dragStop = gearClone.DragStopped:connect(function(x,y)
|
||||
if gearClone.Selected then
|
||||
gearClone.ZIndex = 2
|
||||
else
|
||||
gearClone.ZIndex = 1
|
||||
end
|
||||
local children = gearClone:GetChildren()
|
||||
for i = 1, #children do
|
||||
if children[i]:IsA("TextLabel") then
|
||||
if string.find(children[i].Name,"Shadow") then
|
||||
children[i].ZIndex = 3
|
||||
else
|
||||
children[i].ZIndex = 4
|
||||
end
|
||||
elseif children[i]:IsA("Frame") or children[i]:IsA("ImageLabel") then
|
||||
children[i].ZIndex = 2
|
||||
end
|
||||
end
|
||||
resolveDrag(gearClone,x,y)
|
||||
end)
|
||||
mouseLeaveCon = gearClone.MouseLeave:connect(function()
|
||||
gearClone.Draggable = false
|
||||
end)
|
||||
buttonDeleteCon = gearClone.AncestryChanged:connect(function()
|
||||
if gearClone.Parent and gearClone.Parent.Parent == currentLoadout then return end
|
||||
if clickCon then clickCon:disconnect() end
|
||||
if buttonDeleteCon then buttonDeleteCon:disconnect() end
|
||||
if mouseEnterCon then mouseEnterCon:disconnect() end
|
||||
if mouseLeaveCon then mouseLeaveCon:disconnect() end
|
||||
if dragStop then dragStop:disconnect() end
|
||||
if dragBegin then dragBegin:disconnect() end
|
||||
end) -- this probably isn't necessary since objects are being deleted (probably), but this might still leak just in case
|
||||
|
||||
local childCon = nil
|
||||
local childChangeCon = nil
|
||||
childCon = child.AncestryChanged:connect(function(newChild,parent)
|
||||
if not checkToolAncestry(newChild,parent) then
|
||||
if childCon then childCon:disconnect() end
|
||||
if childChangeCon then childChangeCon:disconnect() end
|
||||
removeFromInventory(child)
|
||||
elseif parent == game.Players.LocalPlayer.Backpack then
|
||||
normalizeButton(gearClone)
|
||||
end
|
||||
end)
|
||||
|
||||
childChangeCon = child.Changed:connect(function(prop)
|
||||
if prop == "Name" then
|
||||
if gearClone and gearClone.GearImage.Image == "" then
|
||||
gearClone.GearText.Text = child.Name
|
||||
end
|
||||
elseif prop == "Active" then
|
||||
if child and child:IsA("HopperBin") then
|
||||
if not child.Active then
|
||||
gearClone.Selected = false
|
||||
normalizeButton(gearClone)
|
||||
end
|
||||
end
|
||||
elseif prop == "TextureId" then
|
||||
gearClone.GearImage.Image = child.TextureId
|
||||
end
|
||||
end)
|
||||
|
||||
debounce = false
|
||||
|
||||
end
|
||||
|
||||
function addToInventory(child)
|
||||
if not child:IsA("Tool") or not child:IsA("HopperBin") then return end
|
||||
|
||||
local slot = nil
|
||||
for i = 1, #inventory do
|
||||
if inventory[i] and inventory[i] == child then return end
|
||||
if not inventory[i] then slot = i end
|
||||
end
|
||||
if slot then
|
||||
inventory[slot] = child
|
||||
elseif #inventory < 1 then
|
||||
inventory[1] = child
|
||||
else
|
||||
inventory[#inventory + 1] = child
|
||||
end
|
||||
end
|
||||
|
||||
function removeFromInventory(child)
|
||||
for i = 1, #inventory do
|
||||
if inventory[i] == child then
|
||||
table.remove(inventory,i)
|
||||
inventory[i] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local spreadOutGear = function()
|
||||
loadoutChildren = currentLoadout:GetChildren()
|
||||
|
||||
for i = 1, #loadoutChildren do
|
||||
if loadoutChildren[i]:IsA("Frame") then
|
||||
loadoutChildren[i].BackgroundTransparency = 0.5
|
||||
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
|
||||
|
||||
local centerGear = function()
|
||||
loadoutChildren = currentLoadout:GetChildren()
|
||||
local gearButtons = {}
|
||||
local lastSlotAdd = nlii
|
||||
|
||||
for i = 1, #loadoutChildren do
|
||||
if loadoutChildren[i]:IsA("Frame") then
|
||||
if #loadoutChildren[i]:GetChildren() > 0 then
|
||||
if loadoutChildren[i].Name == "Slot0" then
|
||||
lastSlotAdd = loadoutChildren[i]
|
||||
else
|
||||
table.insert(gearButtons, loadoutChildren[i])
|
||||
end
|
||||
end
|
||||
loadoutChildren[i].BackgroundTransparency = 1
|
||||
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 editLoadout()
|
||||
if inGearTab then
|
||||
spreadOutGear()
|
||||
end
|
||||
end
|
||||
|
||||
function readonlyLoadout()
|
||||
if not inGearTab then
|
||||
centerGear()
|
||||
end
|
||||
end
|
||||
|
||||
function setupBackpackListener()
|
||||
if backpackChildCon then backpackChildCon:disconnect() backpackChildCon = nil end
|
||||
backpackChildCon = player.Backpack.ChildAdded:connect(function(child)
|
||||
addingPlayerChild(child)
|
||||
addToInventory(child)
|
||||
end)
|
||||
end
|
||||
|
||||
function playerCharacterChildAdded(child)
|
||||
addingPlayerChild(child,true)
|
||||
addToInventory(child)
|
||||
end
|
||||
|
||||
function activateLoadout()
|
||||
currentLoadout.Visible = true
|
||||
end
|
||||
|
||||
function deactivateLoadout()
|
||||
currentLoadout.Visible = false
|
||||
end
|
||||
|
||||
function tabHandler(inFocus)
|
||||
inGearTab = inFocus
|
||||
if inFocus then
|
||||
editLoadout()
|
||||
else
|
||||
readonlyLoadout()
|
||||
end
|
||||
end
|
||||
-- End Functions
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Begin Script
|
||||
wait() -- let stuff initialize incase this is first heartbeat...
|
||||
|
||||
waitForChild(player,"Backpack")
|
||||
waitForProperty(player,"Character")
|
||||
local backpackChildren = player.Backpack:GetChildren()
|
||||
local size = math.min(10,#backpackChildren)
|
||||
for i = 1, size do
|
||||
addingPlayerChild(backpackChildren[i],false)
|
||||
end
|
||||
setupBackpackListener()
|
||||
|
||||
waitForProperty(player,"Character")
|
||||
for i,v in ipairs(player.Character:GetChildren()) do
|
||||
playerCharacterChildAdded(v)
|
||||
end
|
||||
characterChildAddedCon = player.Character.ChildAdded:connect(function(child) playerCharacterChildAdded(child) end)
|
||||
|
||||
waitForChild(player.Character,"Humanoid")
|
||||
humanoidDiedCon = player.Character.Humanoid.Died:connect(function()
|
||||
if humanoidDiedCon then humanoidDiedCon:disconnect() humanoidDiedCon = nil end
|
||||
deactivateLoadout()
|
||||
if backpackChildCon then backpackChildCon:disconnect() backpackChildCon = nil end
|
||||
end)
|
||||
|
||||
player.CharacterRemoving:connect(function()
|
||||
for i = 1, #gearSlots do
|
||||
if gearSlots[i] ~= "empty" then
|
||||
gearSlots[i].Parent = nil
|
||||
gearSlots[i] = "empty"
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
player.CharacterAdded:connect(function()
|
||||
waitForProperty(game.Players,"LocalPlayer")
|
||||
player = game.Players.LocalPlayer -- make sure we are still looking at the correct character
|
||||
waitForChild(player,"Backpack")
|
||||
|
||||
|
||||
delay(1,function()
|
||||
local backpackChildren = player.Backpack:GetChildren()
|
||||
local size = math.min(10,#backpackChildren)
|
||||
for i = 1, size do
|
||||
addingPlayerChild(backpackChildren[i],false)
|
||||
end
|
||||
setupBackpackListener()
|
||||
end)
|
||||
|
||||
activateLoadout()
|
||||
|
||||
if characterChildAddedCon then
|
||||
characterChildAddedCon:disconnect()
|
||||
characterChildAddedCon = nil
|
||||
end
|
||||
|
||||
characterChildAddedCon =
|
||||
player.Character.ChildAdded:connect(function(child)
|
||||
addingPlayerChild(child,true)
|
||||
end)
|
||||
|
||||
waitForChild(player.Character,"Humanoid")
|
||||
humanoidDiedCon =
|
||||
player.Character.Humanoid.Died:connect(function()
|
||||
deactivateLoadout()
|
||||
|
||||
if humanoidDiedCon then humanoidDiedCon:disconnect() humanoidDiedCon = nil end
|
||||
if backpackChildCon then backpackChildCon:disconnect() backpackChildCon = nil end
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
waitForChild(guiBackpack,"SwapSlot")
|
||||
guiBackpack.SwapSlot.Changed:connect(function()
|
||||
if guiBackpack.SwapSlot.Value then
|
||||
local swapSlot = guiBackpack.SwapSlot
|
||||
local pos = swapSlot.Slot.Value
|
||||
if pos == 0 then pos = 10 end
|
||||
if gearSlots[pos] then
|
||||
reorganizeLoadout(gearSlots[pos],false)
|
||||
end
|
||||
if swapSlot.GearButton.Value then
|
||||
addingPlayerChild(swapSlot.GearButton.Value.GearReference.Value,false,pos)
|
||||
end
|
||||
guiBackpack.SwapSlot.Value = false
|
||||
end
|
||||
end)
|
||||
|
||||
game:GetService("GuiService").KeyPressed:connect(function(key)
|
||||
if characterInWorkspace() then
|
||||
activateGear(key)
|
||||
end
|
||||
end)
|
||||
|
||||
backpackOpenEvent.Event:connect(editLoadout)
|
||||
backpackCloseEvent.Event:connect(centerGear)
|
||||
tabClickedEvent.Event:connect(function ( tabName )
|
||||
tabHandler(tabName == StaticTabName)
|
||||
end)
|
||||
@@ -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()
|
||||
@@ -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 ContentProvider = game:GetService("ContentProvider")
|
||||
local localPlayer = game.Players.LocalPlayer
|
||||
local teleportUI = nil
|
||||
|
||||
local acceptedTeleport = Instance.new("IntValue")
|
||||
local ContentProvider =
|
||||
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 = ContentProvider.BaseUrl .. "thumbnail/headshot?id=" .. tostring(fromPlayer.userId)
|
||||
|
||||
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 .. "!",
|
||||
ContentProvider.BaseUrl .. "thumbnail/headshot?id=" .. tostring(toPlayer.userId),
|
||||
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,
|
||||
ContentProvider.BaseUrl .. "thumbnail/headshot?id=" .. tostring(fromPlayer.userId),
|
||||
8,
|
||||
function()
|
||||
makeFriend(fromPlayer,toPlayer)
|
||||
end)
|
||||
elseif event == Enum.FriendRequestEvent.Accept then
|
||||
game:GetService("GuiService"):SendNotification("You are Friends",
|
||||
"With " .. fromPlayer.Name .. "!",
|
||||
ContentProvider.BaseUrl .. "thumbnail/headshot?id=" .. tostring(fromPlayer.userId),
|
||||
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)
|
||||
@@ -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)
|
||||
2452
client/common/content/scripts/CoreScripts/2012/PlayerListScript.lua
Normal file
2452
client/common/content/scripts/CoreScripts/2012/PlayerListScript.lua
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
||||
--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
|
||||
File diff suppressed because it is too large
Load Diff
109
client/common/content/scripts/CoreScripts/2012/ToolTip.lua
Normal file
109
client/common/content/scripts/CoreScripts/2012/ToolTip.lua
Normal 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
|
||||
563
client/common/content/scripts/CoreScripts/2012/TouchControls.lua
Normal file
563
client/common/content/scripts/CoreScripts/2012/TouchControls.lua
Normal 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
|
||||
Reference in New Issue
Block a user