add gs
This commit is contained in:
@@ -0,0 +1,516 @@
|
||||
-------------- CONSTANTS --------------
|
||||
local STICK_ROTATION_MULTIPLIER = 3
|
||||
local THUMBSTICK_DEADZONE = 0.2
|
||||
|
||||
-------------- SERVICES --------------
|
||||
local ContextActionService = game:GetService("ContextActionService")
|
||||
local ReplicatedStorage = game:GetService('ReplicatedStorage')
|
||||
local CoreGui = game:GetService('CoreGui')
|
||||
|
||||
------------ MODULES -------------------
|
||||
local GuiRoot = CoreGui:FindFirstChild('RobloxGui')
|
||||
local Modules = GuiRoot:FindFirstChild('Modules')
|
||||
|
||||
local AppState = require(Modules.LuaApp.Legacy.AvatarEditor.AppState)
|
||||
local SetConsoleMenuLevel = require(Modules.LuaApp.Actions.SetConsoleMenuLevel)
|
||||
local ResetCategory = require(Modules.LuaApp.Actions.ResetCategory)
|
||||
local ToggleAvatarType = require(Modules.LuaApp.Actions.ToggleAvatarType)
|
||||
local ToggleAvatarEditorFullView = require(Modules.LuaApp.Actions.ToggleAvatarEditorFullView)
|
||||
|
||||
local CreateCharacterManager = require(Modules.LuaApp.Legacy.AvatarEditor.CharacterManager)
|
||||
local CreatePageManager = require(Modules.LuaApp.Legacy.AvatarEditor.PageManagerConsole)
|
||||
local CreateCategoryMenu = require(Modules.LuaApp.Legacy.AvatarEditor.CategoryMenuConsole)
|
||||
local CreateTabList = require(Modules.LuaApp.Legacy.AvatarEditor.TabListConsole)
|
||||
local ConsoleButtonIndicators = require(Modules.LuaApp.Legacy.AvatarEditor.ConsoleButtonIndicators)
|
||||
local LayoutInfo = require(Modules.LuaApp.Legacy.AvatarEditor.LayoutInfoConsole)
|
||||
local Flags = require(Modules.LuaApp.Legacy.AvatarEditor.Flags)
|
||||
local XboxAppState = require(Modules.Shell.AppState)
|
||||
|
||||
----------- UTILITIES --------------
|
||||
local Utilities = require(Modules.LuaApp.Legacy.AvatarEditor.Utilities)
|
||||
local TableUtilities = require(Modules.LuaApp.TableUtilities)
|
||||
|
||||
------------ SHELL MODULES -------------------
|
||||
local ShellModules = script.Parent
|
||||
local CameraManager = require(ShellModules:FindFirstChild('CameraManager'))
|
||||
local EventHub = require(ShellModules:FindFirstChild('EventHub'))
|
||||
local LoadingWidget = require(ShellModules:FindFirstChild('LoadingWidget'))
|
||||
|
||||
-------------- FFLAGS --------------
|
||||
local SoundManager = require(ShellModules:FindFirstChild('SoundManager'))
|
||||
|
||||
------------ VARIABLES -------------------
|
||||
local characterTemplates = {
|
||||
CharacterR6 = ReplicatedStorage:WaitForChild('CharacterR6');
|
||||
CharacterR15 = ReplicatedStorage:WaitForChild('CharacterR15');
|
||||
CharacterR15New = ReplicatedStorage:WaitForChild('CharacterR15New');
|
||||
}
|
||||
|
||||
|
||||
local cameraTweenerObject = {
|
||||
tweenCamera = function(newCFrame, newFOV)
|
||||
CameraManager:UpdateAvatarEditorCamera(newCFrame, newFOV)
|
||||
end
|
||||
}
|
||||
|
||||
----------- CLASS DECLARATION --------------
|
||||
|
||||
local function createAvatarEditorView()
|
||||
AppState:Init()
|
||||
local this = {}
|
||||
local storeChangedCn = nil
|
||||
local scrollingFrameCn = nil
|
||||
local avatarEditorLoader = nil
|
||||
local savedSelectedGuiObject = nil
|
||||
local selectedGuiObjectEnterFullView = nil
|
||||
local toggleButtonDebounce = true
|
||||
local toggleViewDebounce = true
|
||||
local showCount = 0
|
||||
local inShow = false
|
||||
local inFocus = false
|
||||
local lastCharacterSaveTime = nil
|
||||
|
||||
local characterUpdated = false
|
||||
local characterEquipped = false
|
||||
local savingAvatarMutex = false
|
||||
local rotationInfo = {
|
||||
rotation = 0;
|
||||
lastRotation = 0;
|
||||
delta = 0;
|
||||
}
|
||||
|
||||
local Container = Utilities.create'ScrollingFrame'
|
||||
{
|
||||
Name = 'AvatarEditorContainer';
|
||||
Size = UDim2.new(1, 0, 1, 0);
|
||||
CanvasSize = UDim2.new(1, 0, 1, 0);
|
||||
BackgroundTransparency = 1;
|
||||
ScrollingEnabled = false;
|
||||
Selectable = false;
|
||||
Visible = true;
|
||||
BorderSizePixel = 0;
|
||||
ScrollBarThickness = 0;
|
||||
}
|
||||
|
||||
local BackgroundOverlay = Utilities.create'ImageLabel'
|
||||
{
|
||||
Name = 'BackgroundOverlay';
|
||||
Size = UDim2.new(1, 0, 1, 0);
|
||||
BackgroundTransparency = 1;
|
||||
Visible = true;
|
||||
Image = 'rbxasset://textures/ui/Shell/AvatarEditor/graphic/gr-background overlay merge.png';
|
||||
ZIndex = LayoutInfo.BackgroundLayer;
|
||||
Parent = Container;
|
||||
}
|
||||
|
||||
local frame = Utilities.create'Frame'
|
||||
{
|
||||
Position = UDim2.new(0, 0, 0, 270);
|
||||
Size = UDim2.new(1, 0, 1, 0);
|
||||
Name = "PageFrame";
|
||||
BackgroundTransparency = 1;
|
||||
ClipsDescendants = true;
|
||||
Visible = true;
|
||||
Selectable = false;
|
||||
ZIndex = LayoutInfo.BasicLayer;
|
||||
Parent = Container;
|
||||
}
|
||||
local scrollingFrame = Utilities.create'ScrollingFrame'
|
||||
{
|
||||
AnchorPoint = Vector2.new(1, 0);
|
||||
Position = UDim2.new(1, -99, 0, 0);
|
||||
Size = UDim2.new(0, 491, 1, -270);
|
||||
Name = "ScrollingFrame";
|
||||
BackgroundTransparency = 1;
|
||||
ClipsDescendants = true;
|
||||
Visible = true;
|
||||
ScrollingEnabled = false;
|
||||
ScrollBarThickness = 0;
|
||||
Selectable = false;
|
||||
ZIndex = LayoutInfo.BasicLayer;
|
||||
Parent = frame;
|
||||
}
|
||||
|
||||
ConsoleButtonIndicators.init(Container)
|
||||
local warningFrame = Utilities.create'Frame'
|
||||
{
|
||||
AnchorPoint = Vector2.new(0.5, 0);
|
||||
Position = UDim2.new(0.5, 0, 0, 0);
|
||||
Size = UDim2.new(0, LayoutInfo.WarningMaxLength, 1, 0);
|
||||
Name = "WarningWidget";
|
||||
BackgroundTransparency = 1;
|
||||
Visible = true;
|
||||
Selectable = false;
|
||||
ZIndex = LayoutInfo.IndicatorLayer;
|
||||
Parent = Container;
|
||||
}
|
||||
|
||||
local CameraController = require(Modules.LuaApp.Legacy.AvatarEditor.CameraController)(
|
||||
cameraTweenerObject, LayoutInfo.CameraCenterScreenPosition)
|
||||
|
||||
|
||||
local characterManager = CreateCharacterManager(
|
||||
{
|
||||
get = Utilities.httpGet;
|
||||
post = Utilities.httpPost;
|
||||
},
|
||||
characterTemplates,
|
||||
1
|
||||
)
|
||||
|
||||
local WarningWidget = require(Modules.LuaApp.Legacy.AvatarEditor.WarningWidget)(warningFrame, characterManager, true)
|
||||
|
||||
local PageManager = CreatePageManager(
|
||||
XboxAppState.store:getState().RobloxUser.rbxuid,
|
||||
scrollingFrame,
|
||||
characterManager
|
||||
)
|
||||
characterManager:setUpdateCameraCallback(CameraController.updateCamera)
|
||||
|
||||
local CategoryMenu = CreateCategoryMenu(Container)
|
||||
local TabList = CreateTabList(Container, PageManager)
|
||||
|
||||
local function initStickRotation()
|
||||
local gamepadInput = Vector2.new(0, 0)
|
||||
ContextActionService:UnbindCoreAction("StickRotation")
|
||||
ContextActionService:BindCoreAction("StickRotation", function(actionName, inputState, inputObject)
|
||||
if inputState == Enum.UserInputState.Change then
|
||||
gamepadInput = inputObject.Position or gamepadInput
|
||||
gamepadInput = Vector2.new(gamepadInput.X, gamepadInput.Y)
|
||||
if math.abs(gamepadInput.X) > THUMBSTICK_DEADZONE then
|
||||
rotationInfo.delta = STICK_ROTATION_MULTIPLIER * gamepadInput.X
|
||||
else
|
||||
rotationInfo.delta = 0
|
||||
end
|
||||
end
|
||||
end,
|
||||
false, Enum.KeyCode.Thumbstick2)
|
||||
end
|
||||
|
||||
local function initKeyControls()
|
||||
toggleButtonDebounce = true
|
||||
toggleViewDebounce = true
|
||||
ContextActionService:UnbindCoreAction("KeyControls")
|
||||
ContextActionService:BindCoreAction("KeyControls", function(actionName, inputState, inputObject)
|
||||
if inputState == Enum.UserInputState.Begin then
|
||||
if inputObject.KeyCode == Enum.KeyCode.ButtonSelect and not AppState.Store:getState().FullView then
|
||||
if toggleButtonDebounce then
|
||||
toggleButtonDebounce = false
|
||||
SoundManager:Play('ButtonPress')
|
||||
AppState.Store:dispatch(ToggleAvatarType())
|
||||
toggleButtonDebounce = true
|
||||
end
|
||||
end
|
||||
|
||||
if inputObject.KeyCode == Enum.KeyCode.ButtonR3 then
|
||||
if toggleViewDebounce then
|
||||
toggleViewDebounce = false
|
||||
SoundManager:Play('ScreenChange')
|
||||
AppState.Store:dispatch(ToggleAvatarEditorFullView())
|
||||
toggleViewDebounce = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
false, Enum.KeyCode.ButtonR3, Enum.KeyCode.ButtonSelect)
|
||||
end
|
||||
|
||||
local function initMenuActions()
|
||||
ContextActionService:UnbindCoreAction("AvatarEditorMenu")
|
||||
|
||||
ContextActionService:BindCoreAction("AvatarEditorMenu", function(actionName, inputState, inputObject)
|
||||
if inputState == Enum.UserInputState.End then
|
||||
if inputObject.KeyCode == Enum.KeyCode.ButtonB then
|
||||
if AppState.Store:getState().ConsoleMenuLevel > LayoutInfo.ConsoleMenuLevel.CategoryMenu then
|
||||
local currentMenuLevel = AppState.Store:getState().ConsoleMenuLevel
|
||||
SoundManager:Play('PopUp')
|
||||
AppState.Store:dispatch(SetConsoleMenuLevel(currentMenuLevel - 1))
|
||||
else
|
||||
-- Back to avatar page in AppShell
|
||||
AppState.Store:dispatch(ResetCategory())
|
||||
AppState.Store:dispatch(SetConsoleMenuLevel(LayoutInfo.ConsoleMenuLevel.None))
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
end
|
||||
elseif inputState == Enum.UserInputState.Begin then
|
||||
if inputObject.KeyCode == Enum.KeyCode.ButtonL2 then
|
||||
if AppState.Store:getState().ConsoleMenuLevel == LayoutInfo.ConsoleMenuLevel.CategoryMenu then
|
||||
CategoryMenu:SelectPreviousPage()
|
||||
elseif AppState.Store:getState().ConsoleMenuLevel == LayoutInfo.ConsoleMenuLevel.TabList then
|
||||
TabList:SelectPreviousPage()
|
||||
elseif AppState.Store:getState().ConsoleMenuLevel == LayoutInfo.ConsoleMenuLevel.AssetsPage then
|
||||
PageManager:SelectPreviousPage()
|
||||
end
|
||||
elseif inputObject.KeyCode == Enum.KeyCode.ButtonR2 then
|
||||
if AppState.Store:getState().ConsoleMenuLevel == LayoutInfo.ConsoleMenuLevel.CategoryMenu then
|
||||
CategoryMenu:SelectNextPage()
|
||||
elseif AppState.Store:getState().ConsoleMenuLevel == LayoutInfo.ConsoleMenuLevel.TabList then
|
||||
TabList:SelectNextPage()
|
||||
elseif AppState.Store:getState().ConsoleMenuLevel == LayoutInfo.ConsoleMenuLevel.AssetsPage then
|
||||
PageManager:SelectNextPage()
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
false, Enum.KeyCode.ButtonB, Enum.KeyCode.ButtonL2, Enum.KeyCode.ButtonR2)
|
||||
end
|
||||
|
||||
local function updateFullViewCoreAction(fullView)
|
||||
ContextActionService:UnbindCoreAction("FullView")
|
||||
if fullView == true then
|
||||
ContextActionService:BindCoreAction("FullView",
|
||||
function(actionName, inputState, inputObject)
|
||||
if inputState == Enum.UserInputState.End then
|
||||
if inputObject.KeyCode == Enum.KeyCode.ButtonB then
|
||||
SoundManager:Play('ScreenChange')
|
||||
AppState.Store:dispatch(ToggleAvatarEditorFullView())
|
||||
end
|
||||
return Enum.ContextActionResult.Sink
|
||||
end
|
||||
end,
|
||||
false, Enum.KeyCode.ButtonB, Enum.KeyCode.ButtonA, Enum.KeyCode.ButtonL2, Enum.KeyCode.ButtonR2)
|
||||
|
||||
BackgroundOverlay.Visible = false
|
||||
elseif fullView == false then
|
||||
BackgroundOverlay.Visible = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function FocusAll()
|
||||
initStickRotation()
|
||||
initKeyControls()
|
||||
initMenuActions()
|
||||
CameraController:Focus()
|
||||
|
||||
CategoryMenu:Focus()
|
||||
TabList:Focus()
|
||||
PageManager:Focus()
|
||||
WarningWidget:Focus()
|
||||
|
||||
if not savedSelectedGuiObject and not AppState.Store:getState().FullView then
|
||||
AppState.Store:dispatch(SetConsoleMenuLevel(LayoutInfo.ConsoleMenuLevel.CategoryMenu))
|
||||
elseif savedSelectedGuiObject then
|
||||
Utilities.setSelectedCoreObject(savedSelectedGuiObject)
|
||||
end
|
||||
updateFullViewCoreAction(AppState.Store:getState().FullView)
|
||||
|
||||
storeChangedCn = AppState.Store.changed:connect(function(newState, oldState)
|
||||
if newState.FullView ~= oldState.FullView then
|
||||
updateFullViewCoreAction(newState.FullView)
|
||||
if newState.FullView == true then
|
||||
local selectedCoreObject = Utilities.getSelectedCoreObject()
|
||||
if selectedCoreObject then
|
||||
selectedGuiObjectEnterFullView = selectedCoreObject
|
||||
end
|
||||
Utilities.setSelectedCoreObject(nil)
|
||||
else
|
||||
if selectedGuiObjectEnterFullView then
|
||||
Utilities.setSelectedCoreObject(selectedGuiObjectEnterFullView)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not characterEquipped or not characterUpdated then
|
||||
local didUpdate = false
|
||||
local didEquip = false
|
||||
|
||||
if newState.Character.AvatarType ~= oldState.Character.AvatarType then
|
||||
didUpdate = true
|
||||
end
|
||||
|
||||
if newState.Character.Assets ~= oldState.Character.Assets then
|
||||
for assetType, assetList in pairs(oldState.Character.Assets) do
|
||||
if not newState.Character.Assets[assetType] and assetList then
|
||||
if next(assetList) ~= nil then
|
||||
didUpdate = true
|
||||
didEquip = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not didUpdate or not didEquip then
|
||||
for assetType, _ in pairs(newState.Character.Assets) do
|
||||
if newState.Character.Assets[assetType] ~= oldState.Character.Assets[assetType] then
|
||||
local addTheseAssets = TableUtilities.ListDifference(
|
||||
newState.Character.Assets[assetType] or {},
|
||||
oldState.Character.Assets[assetType] or {})
|
||||
local removeTheseAssets =
|
||||
TableUtilities.ListDifference(oldState.Character.Assets[assetType] or {},
|
||||
newState.Character.Assets[assetType] or {})
|
||||
|
||||
if next(addTheseAssets) ~= nil or next(removeTheseAssets) ~= nil then
|
||||
didUpdate = true
|
||||
didEquip = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if newState.Character.BodyColors ~= oldState.Character.BodyColors then
|
||||
local differentBodyColors =
|
||||
TableUtilities.TableDifference(newState.Character.BodyColors, oldState.Character.BodyColors)
|
||||
if next(differentBodyColors) ~= nil then
|
||||
didUpdate = true
|
||||
end
|
||||
end
|
||||
|
||||
if newState.Character.Scales ~= oldState.Character.Scales then
|
||||
local differentScales =
|
||||
TableUtilities.TableDifference(newState.Character.Scales, oldState.Character.Scales)
|
||||
if next(differentScales) ~= nil then
|
||||
didUpdate = true
|
||||
end
|
||||
end
|
||||
|
||||
if not characterEquipped then
|
||||
characterEquipped = didEquip
|
||||
end
|
||||
|
||||
if not characterUpdated then
|
||||
characterUpdated = didUpdate
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
scrollingFrameCn = scrollingFrame.Changed:connect(
|
||||
function(prop)
|
||||
if prop == 'CanvasPosition' then
|
||||
PageManager:updateListContent(scrollingFrame.CanvasPosition.Y)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function RemoveFocusAll()
|
||||
CameraController:RemoveFocus()
|
||||
PageManager:RemoveFocus()
|
||||
CategoryMenu:RemoveFocus()
|
||||
TabList:RemoveFocus()
|
||||
WarningWidget:RemoveFocus()
|
||||
Utilities.disconnectEvent(storeChangedCn)
|
||||
Utilities.disconnectEvent(scrollingFrameCn)
|
||||
ContextActionService:UnbindCoreAction("FullView")
|
||||
ContextActionService:UnbindCoreAction("AvatarEditorMenu")
|
||||
ContextActionService:UnbindCoreAction("StickRotation")
|
||||
ContextActionService:UnbindCoreAction("KeyControls")
|
||||
end
|
||||
|
||||
function this:Show(parent)
|
||||
local startCount = showCount
|
||||
inShow = true
|
||||
characterUpdated = false
|
||||
characterEquipped = false
|
||||
local prevAvatarEditorLoader = avatarEditorLoader
|
||||
|
||||
Utilities.fastSpawn(function()
|
||||
if startCount == showCount then
|
||||
avatarEditorLoader = LoadingWidget(
|
||||
{Parent = parent},
|
||||
{function()
|
||||
if prevAvatarEditorLoader then
|
||||
prevAvatarEditorLoader:AwaitFinished()
|
||||
prevAvatarEditorLoader:Cleanup()
|
||||
end
|
||||
if startCount == showCount then
|
||||
characterManager.initFromServer()
|
||||
characterManager.show()
|
||||
end
|
||||
end}
|
||||
)
|
||||
avatarEditorLoader:AwaitFinished()
|
||||
if startCount == showCount then
|
||||
avatarEditorLoader:Cleanup()
|
||||
avatarEditorLoader = nil
|
||||
end
|
||||
end
|
||||
|
||||
if startCount == showCount then
|
||||
Container.Parent = parent
|
||||
if inFocus then
|
||||
FocusAll()
|
||||
end
|
||||
|
||||
while startCount == showCount do
|
||||
local deltaT = Utilities.renderWait()
|
||||
if startCount == showCount then
|
||||
rotationInfo.rotation = rotationInfo.rotation + deltaT * rotationInfo.delta
|
||||
characterManager.setRotation(rotationInfo.rotation)
|
||||
if not lastCharacterSaveTime or tick() - lastCharacterSaveTime > 5 then
|
||||
characterManager.saveToServer(false)
|
||||
lastCharacterSaveTime = tick()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function this:Hide()
|
||||
inShow = false
|
||||
showCount = showCount + 1
|
||||
characterManager.hide()
|
||||
savedSelectedGuiObject = nil
|
||||
selectedGuiObjectEnterFullView = nil
|
||||
Container.Parent = nil
|
||||
|
||||
if not avatarEditorLoader then
|
||||
RemoveFocusAll()
|
||||
CategoryMenu:Hide()
|
||||
WarningWidget:Hide()
|
||||
local savedCharacterUpdated = characterUpdated
|
||||
local savedCharacterEquipped = characterEquipped
|
||||
spawn(function()
|
||||
while savingAvatarMutex do
|
||||
wait()
|
||||
end
|
||||
savingAvatarMutex = true
|
||||
characterManager.saveToServer(true)
|
||||
savingAvatarMutex = false
|
||||
|
||||
if savedCharacterUpdated then
|
||||
Utilities.fastSpawn(function()
|
||||
EventHub:dispatchEvent(EventHub.Notifications["CharacterUpdated"])
|
||||
end)
|
||||
end
|
||||
|
||||
if savedCharacterEquipped then
|
||||
Utilities.fastSpawn(function()
|
||||
EventHub:dispatchEvent(EventHub.Notifications["CharacterEquipped"], AppState.Store:getState().Character.Assets, savedCharacterUpdated)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
--Rebind actions, make them in the right order
|
||||
function this:Focus()
|
||||
inFocus = true
|
||||
if inShow and not avatarEditorLoader then
|
||||
FocusAll()
|
||||
end
|
||||
end
|
||||
|
||||
function this:RemoveFocus()
|
||||
inFocus = false
|
||||
if inShow and not avatarEditorLoader then
|
||||
savedSelectedGuiObject = Utilities.getSelectedCoreObject()
|
||||
RemoveFocusAll()
|
||||
end
|
||||
end
|
||||
|
||||
function this:Destruct()
|
||||
this:RemoveFocus()
|
||||
this:Hide()
|
||||
Container:Destroy()
|
||||
characterManager.destroy()
|
||||
AppState:Destruct()
|
||||
end
|
||||
|
||||
return this
|
||||
end
|
||||
|
||||
return createAvatarEditorView
|
||||
Reference in New Issue
Block a user