Super-Nostalgia-Zone/Server/Scripts/Parts.server.lua

282 lines
6.8 KiB
Lua

local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local brickColors = require(ReplicatedStorage:WaitForChild("BrickColors"))
local oldColors = {}
for _,v in ipairs(brickColors) do
oldColors[v] = true
end
local textureCaches = setmetatable({}, { __mode = 'k'})
local weakValueMT = { __mode = 'v'}
local colorCaches = {}
local char = string.char
local floor = math.floor
local clamp = math.clamp
local function serializeColor3(color)
local r = clamp(floor(color.r * 256), 0, 255)
local g = clamp(floor(color.g * 256), 0, 255)
local b = clamp(floor(color.b * 256), 0, 255)
return r .. g .. b
end
local function computeEpsilon(brickColor, colorA)
local colorB = brickColor.Color
return math.abs(colorA.R - colorB.R)
+ math.abs(colorA.G - colorB.G)
+ math.abs(colorA.B - colorB.B)
end
local function toNearestOldBrickColor(color)
local colorKey = serializeColor3(color)
if not colorCaches[colorKey] then
local bestColor, bestEpsilon = nil, math.huge
for bcName in pairs(oldColors) do
local bc = BrickColor.new(bcName)
local epsilon = computeEpsilon(bc, color)
if epsilon < bestEpsilon then
bestEpsilon = epsilon
bestColor = bc
end
end
colorCaches[colorKey] = bestColor
end
return colorCaches[colorKey]
end
local function onBrickColorUpdated(part)
part.BrickColor = toNearestOldBrickColor(part.Color)
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local scale = 1
if ServerStorage:FindFirstChild("StudScale") then
scale = ServerStorage.StudScale.Value
end
local surfaces =
{
TopSurface = "Top";
BottomSurface = "Bottom";
LeftSurface = "Left";
RightSurface = "Right";
FrontSurface = "Front";
BackSurface = "Back";
}
local textures =
{
Studs = 3309082834;
Inlet = 3307955447;
Glue = 3308133326;
Weld = 3308005654;
}
local normalIdToAxis =
{
Left = 'X';
Right = 'X';
Top = 'Y';
Bottom = 'Y';
Front = 'Z';
Back = 'Z';
}
local function selectUVSize(part, normalId)
if typeof(normalId) == "EnumItem" then
normalId = normalId.Name
end
local axis = normalIdToAxis[normalId]
local size = part.Size
if axis == 'X' then
return size.Z, size.Y
elseif axis == 'Z' then
return size.X, size.Y
elseif axis == 'Y' then
return size.X, size.Z
end
end
local function onSurfaceChanged(part, surface)
local surfaceId = part[surface].Name
if surfaceId ~= "SmoothNoOutlines" then
local normalId = surfaces[surface]
local textureId = textures[surfaceId]
local cache = textureCaches[part]
local texture = cache[surface]
if not textureId then
if texture then
texture.Texture = ""
end
return
end
if not (texture and texture:IsA("Texture")) then
texture = Instance.new("Texture")
texture.Archivable = false
cache[surface] = texture
texture.StudsPerTileU = 2;
texture.StudsPerTileV = 4;
texture.Face = normalId
texture.Name = surface
texture.Parent = part
end
-- Repair the texture alignment if this is a TriangleMeshPart.
if part:IsA("TriangleMeshPart") then
local texU, texV = selectUVSize(part, normalId)
local alignU = string.format("%i", (texU % 2) + .5)
local alignV = string.format("%i", (texV % 2) + .5)
if alignU == '1' then
texture.OffsetStudsU = 0.5
end
if alignV == '1' then
texture.OffsetStudsV = 0.5
end
end
texture.Texture = "rbxassetid://" .. textureId
end
end
local function onTransparencyChanged(part)
local textureCache = textureCaches[part]
for _,texture in pairs(textureCache) do
texture.Transparency = 0.25 + (part.Transparency * 0.75)
end
end
local function registerPartSurfaces(part)
local textureCache = setmetatable({}, weakValueMT)
textureCaches[part] = textureCache
for surface in pairs(surfaces) do
onSurfaceChanged(part, surface)
end
onBrickColorUpdated(part)
onTransparencyChanged(part)
part.Material = "SmoothPlastic"
end
local function applyCharacter(humanoid)
local model = humanoid.Parent
if not CollectionService:HasTag(humanoid, "Classified") then
local characterAssets = ServerStorage:WaitForChild("CharacterAssets")
CollectionService:AddTag(humanoid, "Classified")
for _,v in pairs(model:GetDescendants()) do
if v:IsA("SpecialMesh") and v.MeshType == Enum.MeshType.Brick then
v:Destroy()
end
end
for _,child in pairs(characterAssets:GetChildren()) do
if child:IsA("CharacterMesh") then
local copy = child:Clone()
copy.Parent = model
CollectionService:AddTag(copy, "NoCharacterBevels")
end
end
delay(1, function ()
if not model:FindFirstChildWhichIsA("Shirt") then
characterAssets.Shirt:Clone().Parent = model
end
if not model:FindFirstChildWhichIsA("Pants") then
characterAssets.Pants:Clone().Parent = model
end
end)
end
end
local function onDescendantAdded(desc)
if desc:IsA("BasePart") then
local model = desc:FindFirstAncestorWhichIsA("Model")
if model then
local humanoid = model:FindFirstChildWhichIsA("Humanoid")
if humanoid then
applyCharacter(humanoid)
return
end
local fileMesh = desc:FindFirstChildWhichIsA("FileMesh")
if fileMesh then
local meshType = fileMesh.MeshType.Name
if meshType == "Head" or meshType == "FileMesh" then
desc.Material = "SmoothPlastic"
return
end
end
if desc:IsA("VehicleSeat") then
desc.HeadsUpDisplay = false
end
if not CollectionService:HasTag(desc, "NoBevels") then
registerPartSurfaces(desc)
end
end
elseif desc:IsA("Decal") and desc.Texture:lower() == "rbxasset://textures/spawnlocation.png" then
desc.Texture = "rbxassetid://989514407"
elseif desc:IsA("Humanoid") then
applyCharacter(desc)
end
end
local function onItemChanged(object, descriptor)
if textureCaches[object] then
if surfaces[descriptor] then
onSurfaceChanged(object, descriptor)
elseif descriptor == "Transparency" then
onTransparencyChanged(object)
elseif descriptor == "BrickColor" then
onBrickColorUpdated(object)
end
end
end
for _,desc in pairs(workspace:GetDescendants()) do
onDescendantAdded(desc)
end
workspace.DescendantAdded:Connect(onDescendantAdded)
game.ItemChanged:Connect(onItemChanged)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------