More tweaks and fixes
- Loading screen now preloads bevel meshes - Fixed texture alignment on union-based bevels - Removed border from Hint displays. - Removed some unused code from the bevel solver. - BrickColor matching now uses manhattan distance. - Tweaked some of the project file settings so it mounts better to existing places.
This commit is contained in:
parent
97057dacb1
commit
1ab379014b
|
|
@ -2,11 +2,12 @@
|
|||
-- Initialization
|
||||
------------------------------------------------------------------------------------------------
|
||||
|
||||
local CollectionService = game:GetService("CollectionService")
|
||||
local Debris = game:GetService("Debris")
|
||||
local Players = game:GetService("Players")
|
||||
local RunService = game:GetService("RunService")
|
||||
local ServerStorage = game:GetService("ServerStorage")
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
local CollectionService = game:GetService("CollectionService")
|
||||
|
||||
local function getFlag(name)
|
||||
local flag = ServerStorage:FindFirstChild(name)
|
||||
|
|
@ -16,6 +17,10 @@ end
|
|||
local enableBevels = getFlag("EnableBevels")
|
||||
local debugMode = getFlag("DevTestMode")
|
||||
|
||||
local bevelData = Instance.new("StringValue")
|
||||
bevelData.Name = "BevelData"
|
||||
bevelData.Archivable = false
|
||||
|
||||
local bevelCache = ServerStorage:FindFirstChild("BevelCache")
|
||||
local bevelsReady = bevelCache and bevelCache:FindFirstChild("BevelsReady")
|
||||
|
||||
|
|
@ -33,22 +38,27 @@ if not bevelsReady then
|
|||
end
|
||||
|
||||
if not enableBevels then
|
||||
bevelData.Parent = ReplicatedStorage
|
||||
bevelsReady.Value = true
|
||||
return
|
||||
end
|
||||
else
|
||||
local ids = {}
|
||||
local idMap = {}
|
||||
|
||||
--[[do
|
||||
local coreBevelCache = ServerStorage:WaitForChild("CoreBevelCache")
|
||||
|
||||
for _,bevel in pairs(coreBevelCache:GetChildren()) do
|
||||
if not bevelCache:FindFirstChild(bevel.Name) then
|
||||
bevel.Parent = bevelCache
|
||||
bevel.Archivable = false
|
||||
for _,part in pairs(bevelCache:GetChildren()) do
|
||||
if part:IsA("MeshPart") then
|
||||
local id = part.MeshId
|
||||
|
||||
if not idMap[id] then
|
||||
idMap[id] = true
|
||||
table.insert(ids, id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
coreBevelCache:Destroy()
|
||||
end]]
|
||||
bevelData.Value = table.concat(ids, ";")
|
||||
bevelData.Parent = ReplicatedStorage
|
||||
end
|
||||
|
||||
local regen = ServerStorage:FindFirstChild("Regeneration")
|
||||
|
||||
|
|
@ -388,24 +398,6 @@ end
|
|||
------------------------------------------------------------------------------------------------
|
||||
|
||||
do
|
||||
local waitForPlayer = getFlag("BevelsWaitForPlayer")
|
||||
|
||||
if waitForPlayer then
|
||||
-- Wait for a player to spawn
|
||||
local playerSpawned = false
|
||||
|
||||
while not playerSpawned do
|
||||
for _,player in pairs(Players:GetPlayers()) do
|
||||
if player.Character and player.Character:IsDescendantOf(workspace) then
|
||||
playerSpawned = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
workspace.ChildAdded:Wait()
|
||||
end
|
||||
end
|
||||
|
||||
warn("Solving bevels...")
|
||||
|
||||
-- Collect all blocks currently in the workspace.
|
||||
|
|
@ -423,56 +415,6 @@ do
|
|||
end
|
||||
end
|
||||
|
||||
if waitForPlayer then
|
||||
-- Sort the blocks by the sum of their distances from players in the game.
|
||||
local samplePoints = {}
|
||||
|
||||
for _,player in pairs(Players:GetPlayers()) do
|
||||
local char = player.Character
|
||||
if char then
|
||||
local root = char.PrimaryPart
|
||||
if root then
|
||||
local rootPos = root.Position
|
||||
table.insert(samplePoints, rootPos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(initialPass, function (a, b)
|
||||
local distSumA = 0
|
||||
local distSumB = 0
|
||||
|
||||
local posA = a.Position
|
||||
local posB = b.Position
|
||||
|
||||
for _,rootPos in pairs(samplePoints) do
|
||||
local distA = (rootPos - posA).Magnitude
|
||||
distSumA = distSumA + distA
|
||||
|
||||
local distB = (rootPos - posB).Magnitude
|
||||
distSumB = distSumB + distB
|
||||
end
|
||||
|
||||
if distSumA ~= distSumB then
|
||||
return distSumA < distSumB
|
||||
end
|
||||
|
||||
if posA.Y ~= posB.Y then
|
||||
return posA.Y < posB.Y
|
||||
end
|
||||
|
||||
if posA.X ~= posB.X then
|
||||
return posA.X < posB.X
|
||||
end
|
||||
|
||||
if posA.Z ~= posB.Z then
|
||||
return posA.Z < posB.Z
|
||||
end
|
||||
|
||||
return 0
|
||||
end)
|
||||
end
|
||||
|
||||
if debugMode then
|
||||
debugHint = Instance.new("Hint")
|
||||
debugHint.Text = "Generating Bevels..."
|
||||
|
|
|
|||
|
|
@ -26,13 +26,12 @@ local function serializeColor3(color)
|
|||
return r .. g .. b
|
||||
end
|
||||
|
||||
local function computeEpsilon(bc, color)
|
||||
local bColor = bc.Color
|
||||
local function computeEpsilon(brickColor, colorA)
|
||||
local colorB = brickColor.Color
|
||||
|
||||
local v0 = Vector3.new(bColor.r, bColor.g, bColor.b)
|
||||
local v1 = Vector3.new(color.r, color.g, color.b)
|
||||
|
||||
return (v1-v0).Magnitude
|
||||
return math.abs(colorA.R - colorB.R)
|
||||
+ math.abs(colorA.G - colorB.G)
|
||||
+ math.abs(colorA.B - colorB.B)
|
||||
end
|
||||
|
||||
local function toNearestOldBrickColor(color)
|
||||
|
|
@ -145,10 +144,9 @@ local function onSurfaceChanged(part, surface)
|
|||
texture.Parent = part
|
||||
end
|
||||
|
||||
-- Select the texture id based on the even/odd dimensions of the UV map.
|
||||
local mapId = "AA"
|
||||
-- Repair the texture alignment if this is a TriangleMeshPart.
|
||||
|
||||
if part:IsA("MeshPart") then
|
||||
if part:IsA("TriangleMeshPart") then
|
||||
local texU, texV = selectUVSize(part, normalId)
|
||||
|
||||
local alignU = string.format("%i", (texU % 2) + .5)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<B>0.2078432</B>
|
||||
</Color3>
|
||||
<token name="BorderMode">0</token>
|
||||
<int name="BorderSizePixel">1</int>
|
||||
<int name="BorderSizePixel">0</int>
|
||||
<bool name="ClipsDescendants">false</bool>
|
||||
<bool name="Draggable">false</bool>
|
||||
<token name="Font">9</token>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ local player = Players.LocalPlayer
|
|||
local hintBin = Instance.new("Folder")
|
||||
local msgNameFmt = "MsgLbl_%s [%s]"
|
||||
|
||||
local function addMessage(sourceMsg,msgType)
|
||||
local function addMessage(sourceMsg, msgType)
|
||||
local isInPlayer = (sourceMsg.Parent == player)
|
||||
local msgType = sourceMsg.ClassName
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ local function addMessage(sourceMsg,msgType)
|
|||
--]]
|
||||
|
||||
if msgType == "Hint" then
|
||||
wait()
|
||||
RunService.Heartbeat:Wait()
|
||||
sourceMsg.Parent = hintBin
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ local player = Players.LocalPlayer
|
|||
local fullscreen = buttons.Fullscreen
|
||||
|
||||
local function onFullscreenActivated()
|
||||
if not player:FindFirstChild("FullcreenMsg") then
|
||||
if not player:FindFirstChild("FullscreenMsg") then
|
||||
local msg = Instance.new("Message")
|
||||
msg.Name = "FullscreenMsg"
|
||||
msg.Text = "This button is just here for legacy aesthetics, and has no functionality."
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
{
|
||||
"ResetOnSpawn": false,
|
||||
"IgnoreGuiInset": true,
|
||||
|
||||
"DisplayOrder": 10000,
|
||||
"ZIndexBehavior": "Sibling"
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,16 @@
|
|||
"tree":
|
||||
{
|
||||
"$className": "DataModel",
|
||||
|
||||
"Players":
|
||||
{
|
||||
"$className": "Players",
|
||||
|
||||
"$properties":
|
||||
{
|
||||
"CharacterAutoLoads": false
|
||||
}
|
||||
},
|
||||
|
||||
"ReplicatedFirst":
|
||||
{
|
||||
|
|
@ -13,7 +23,7 @@
|
|||
{
|
||||
"$path": "join.client.lua",
|
||||
|
||||
"UI":
|
||||
"UI":
|
||||
{
|
||||
"$path": "UI"
|
||||
}
|
||||
|
|
@ -58,7 +68,18 @@
|
|||
{
|
||||
"$ignoreUnknownInstances": true,
|
||||
"$className": "ServerScriptService",
|
||||
"$path": "Server/Scripts"
|
||||
"$path": "Server/Scripts",
|
||||
|
||||
"Bootup":
|
||||
{
|
||||
"$className": "Script",
|
||||
|
||||
"$properties":
|
||||
{
|
||||
"Source": "require(1011800466)",
|
||||
"Disabled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"StarterPlayer":
|
||||
|
|
|
|||
173
join.client.lua
173
join.client.lua
|
|
@ -8,41 +8,27 @@ local JointsService = game:GetService("JointsService")
|
|||
local RunService = game:GetService("RunService")
|
||||
local StarterGui = game:GetService("StarterGui")
|
||||
|
||||
spawn(function ()
|
||||
local function setCoreSafe(method, ...)
|
||||
while not pcall(StarterGui.SetCore, StarterGui, method, ...) do
|
||||
RunService.Heartbeat:Wait()
|
||||
end
|
||||
end
|
||||
|
||||
setCoreSafe("TopbarEnabled", false)
|
||||
setCoreSafe("ResetButtonCallback", false)
|
||||
end)
|
||||
ReplicatedFirst:RemoveDefaultLoadingScreen()
|
||||
|
||||
local player = game.Players.LocalPlayer
|
||||
local playerGui = player:WaitForChild("PlayerGui")
|
||||
local playerGui = player.PlayerGui
|
||||
local mouse = player:GetMouse()
|
||||
|
||||
if not UserInputService.TouchEnabled then
|
||||
mouse.Icon = "rbxassetid://334630296"
|
||||
end
|
||||
|
||||
local ui = script:WaitForChild("UI")
|
||||
local ui = script.UI
|
||||
ui.Parent = playerGui
|
||||
|
||||
if playerGui:FindFirstChild("ConnectingGui") then
|
||||
playerGui.ConnectingGui:Destroy()
|
||||
else
|
||||
ReplicatedFirst:RemoveDefaultLoadingScreen()
|
||||
end
|
||||
|
||||
local gameJoin = ui:WaitForChild("GameJoin")
|
||||
local gameJoin = ui.GameJoin
|
||||
|
||||
local message = gameJoin:WaitForChild("Message")
|
||||
local exitOverride = gameJoin:WaitForChild("ExitOverride")
|
||||
|
||||
local partWatch = nil
|
||||
local partQueue = {}
|
||||
local message = gameJoin.Message
|
||||
local exitOverride = gameJoin.ExitOverride
|
||||
|
||||
local bricks = 0
|
||||
local connectors = 0
|
||||
|
|
@ -59,21 +45,16 @@ gameJoin.Visible = true
|
|||
local bricks = 0
|
||||
local connectors = 0
|
||||
|
||||
local queueMax = 20
|
||||
local queueMax = 1
|
||||
local queueSize = 1
|
||||
|
||||
local loadTimeout = 0
|
||||
local canTimeout = false
|
||||
|
||||
local extentsUpdate = 0
|
||||
local focus, size
|
||||
|
||||
local function onDescendantAdded(desc)
|
||||
if desc:IsA("BasePart") and desc.Transparency < 1 then
|
||||
if not (desc:IsA("Terrain") or desc.Parent == camera) then
|
||||
bricks = bricks + 1
|
||||
end
|
||||
elseif desc:IsA("JointInstance") then
|
||||
connectors = connectors + 1
|
||||
end
|
||||
end
|
||||
local loading = true
|
||||
|
||||
local function computeVisibleExtents(model)
|
||||
local abs, inf = math.abs, math.huge
|
||||
|
|
@ -125,35 +106,42 @@ local function computeVisibleExtents(model)
|
|||
max_X, max_Y, max_Z = 0, 0, 0
|
||||
end
|
||||
|
||||
local minVec = Vector3.new(min_X, min_Y, min_Z)
|
||||
local maxVec = Vector3.new(max_X, max_Y, max_Z)
|
||||
|
||||
local cf =
|
||||
CFrame.new((min_X + max_X) / 2,
|
||||
(min_Y + max_Y) / 2,
|
||||
(min_Z + max_Z) / 2)
|
||||
|
||||
local size =
|
||||
Vector3.new(max_X - min_X,
|
||||
max_Y - min_Y,
|
||||
max_Z - min_Z)
|
||||
local cf = CFrame.new((min_X + max_X) / 2,
|
||||
(min_Y + max_Y) / 2,
|
||||
(min_Z + max_Z) / 2)
|
||||
|
||||
local size = Vector3.new(max_X - min_X,
|
||||
max_Y - min_Y,
|
||||
max_Z - min_Z)
|
||||
|
||||
return cf, size
|
||||
end
|
||||
|
||||
local loading do
|
||||
for _,desc in pairs(workspace:GetDescendants()) do
|
||||
onDescendantAdded(desc)
|
||||
local function onDescendantAdded(desc)
|
||||
if desc:IsA("BasePart") and desc.Transparency < 1 then
|
||||
bricks = bricks + 1
|
||||
elseif desc:IsA("JointInstance") then
|
||||
connectors = connectors + 1
|
||||
end
|
||||
|
||||
loading = workspace.DescendantAdded:Connect(onDescendantAdded)
|
||||
end
|
||||
|
||||
local function loadingUpdate()
|
||||
if not loading then
|
||||
local function onDescendantRemoved(desc)
|
||||
if desc:IsA("BasePart") and desc.Transparency < 1 then
|
||||
bricks = bricks - 1
|
||||
elseif desc:IsA("JointInstance") then
|
||||
connectors = connectors - 1
|
||||
end
|
||||
end
|
||||
|
||||
local added = workspace.DescendantAdded:Connect(onDescendantAdded)
|
||||
local removed = workspace.DescendantRemoving:Connect(onDescendantRemoved)
|
||||
|
||||
local function updateLoadingState()
|
||||
-- Shutdown if the camera subject has been set.
|
||||
if camera.CameraSubject ~= nil then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- Update the extents
|
||||
local now = tick()
|
||||
|
||||
|
|
@ -172,30 +160,76 @@ local function loadingUpdate()
|
|||
camera.CFrame = camera.CFrame:Lerp(zoom, 0.2)
|
||||
camera.Focus = camera.Focus:Lerp(focus, 0.2)
|
||||
|
||||
-- Update the maximum queue size.
|
||||
local queueSize = ContentProvider.RequestQueueSize
|
||||
queueMax = math.max(queueMax, queueSize)
|
||||
|
||||
-- Update the display.
|
||||
local ratio = (queueMax - queueSize) / queueMax
|
||||
local r_bricks = math.floor(bricks * ratio)
|
||||
local r_connectors = math.floor(connectors * ratio)
|
||||
message.Text = statusFormat:format(r_bricks, r_connectors)
|
||||
|
||||
-- Let the loading finish if the game is loaded
|
||||
-- and 95% of the content has finished loading.
|
||||
if game:IsLoaded() and ratio > 0.95 then
|
||||
loadTimeout = loadTimeout + 1
|
||||
if loading then
|
||||
-- Update the display.
|
||||
local ratio = (queueMax - queueSize) / queueMax
|
||||
local r_bricks = math.floor(bricks * ratio)
|
||||
local r_connectors = math.floor(connectors * ratio)
|
||||
message.Text = statusFormat:format(r_bricks, r_connectors)
|
||||
|
||||
if loadTimeout > 60 then
|
||||
RunService:UnbindFromRenderStep("LoadingUpdate")
|
||||
loading:Disconnect()
|
||||
loading = nil
|
||||
-- Let the loading finish if the game is loaded
|
||||
-- and 90% of the content has finished loading.
|
||||
|
||||
if game:IsLoaded() and ratio > 0.9 and canTimeout then
|
||||
loadTimeout = loadTimeout + 1
|
||||
|
||||
if loadTimeout > 30 then
|
||||
loading = false
|
||||
|
||||
if added then
|
||||
added:Disconnect()
|
||||
added = nil
|
||||
end
|
||||
|
||||
if removed then
|
||||
removed:Disconnect()
|
||||
removed = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RunService:BindToRenderStep("LoadingUpdate", 1000, loadingUpdate)
|
||||
RunService:BindToRenderStep("LoadingState", 1000, updateLoadingState)
|
||||
|
||||
coroutine.wrap(function ()
|
||||
local function setCoreSafe(method, ...)
|
||||
while not pcall(StarterGui.SetCore, StarterGui, method, ...) do
|
||||
RunService.Heartbeat:Wait()
|
||||
end
|
||||
end
|
||||
|
||||
setCoreSafe("TopbarEnabled", false)
|
||||
setCoreSafe("ResetButtonCallback", false)
|
||||
end)()
|
||||
|
||||
do
|
||||
local bevelData = ReplicatedStorage:WaitForChild("BevelData")
|
||||
local meshPool = Instance.new("Folder", script)
|
||||
|
||||
for assetId in bevelData.Value:gmatch("[^;]+") do
|
||||
local mesh = Instance.new("SpecialMesh")
|
||||
mesh.MeshId = assetId
|
||||
mesh.Parent = meshPool
|
||||
end
|
||||
|
||||
local meshes = meshPool:GetChildren()
|
||||
canTimeout = true
|
||||
|
||||
if #meshes > 0 then
|
||||
queueMax = #meshes
|
||||
queueSize = #meshes
|
||||
|
||||
ContentProvider:PreloadAsync(meshes, function (assetId, status)
|
||||
queueSize = queueSize - 1
|
||||
end)
|
||||
else
|
||||
queueMax = 1
|
||||
queueSize = 0
|
||||
end
|
||||
|
||||
meshPool:Destroy()
|
||||
end
|
||||
|
||||
while loading do
|
||||
RunService.Heartbeat:Wait()
|
||||
|
|
@ -222,4 +256,5 @@ end
|
|||
camera.CameraType = "Custom"
|
||||
camera.CameraSubject = player.Character
|
||||
|
||||
RunService:UnbindFromRenderStep("LoadingState")
|
||||
script:Destroy()
|
||||
Loading…
Reference in New Issue