Created
May 17, 2023 22:06
-
-
Save MrAsynchronous/4801f8c14c57a510fee791a3e8b2c66c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local EnumsInternal = {} | |
local makeEnum | |
-- Luau can only type enumSpec adaptively if we describe it as an adaptive table first and then reassign it using its adaptive table type. | |
local enumSpec = {} | |
enumSpec = setmetatable({}, { | |
__newindex = function(self, name, spec) | |
makeEnum(name, spec) | |
end | |
}) :: typeof(enumSpec) | |
local Enums = setmetatable({}, { | |
__newindex = function() | |
error('Enums may not be added at runtime.') | |
end, | |
__tostring = function() | |
return '[ Enum Provider ]' | |
end, | |
__index = function(self, key) | |
if key == 'All' then | |
return {unpack(EnumsInternal)} | |
elseif EnumsInternal[key] then | |
return EnumsInternal[key] | |
else | |
error(`"{key}" is not a valid enum.`) | |
end | |
end, | |
__iter = function(self) | |
return next, EnumsInternal | |
end | |
}) :: typeof(enumSpec) | |
export type CustomEnumItem<IndexMap> = { | |
Name: string, | |
Value: number, | |
Enum: CustomEnum<IndexMap> | |
} | |
export type CustomEnum<IndexMap> = { | |
GetEnumItems: (CustomEnum<IndexMap>)->{CustomEnumItem<IndexMap>}, | |
EnumName: string | |
} & IndexMap | |
local enum_meta = { | |
__index = function(self, key) | |
if key == "GetEnumItems" then | |
return function(self): {CustomEnumItem<any>} | |
return table.clone(self._itemsArray) | |
end | |
elseif key == "EnumName" then | |
return self._name | |
elseif self._itemsMap[key] then | |
return self._itemsMap[key] | |
else | |
error(`{key} is not a valid property, function, or EnumItem`) | |
end | |
end, | |
__newindex = function() | |
error("Can't set properties of CustomEnum") | |
end, | |
__metatable = "Enum metatable not available", | |
__tostring = function(self) | |
return `[Custom Enum "{self._name}"]` | |
end, | |
__iter = function(self) | |
return next, self._itemsArray | |
end | |
} | |
local enumItem_meta = { | |
__metatable = "EnumItem metatable not available", | |
__tostring = function(self) | |
return `[Custom Enum Item {self._enum._name}.{self._key} [{self._value}]]` | |
end, | |
__index = function(self, key) | |
if key == "Name" then | |
return self._key | |
elseif key == "Value" then | |
return self._value | |
elseif key == "Enum" then | |
return self._enum | |
else | |
error(`{key} is not a valid member of CustomEnumItem`) | |
end | |
end, | |
__newindex = function(self, key, value) | |
error("Can't set properties of CustomEnumItem") | |
end | |
} | |
function makeEnum<T>(enumName: string, spec: T): T | |
for key, value in spec do | |
assert(typeof(key) == "string", "Enum keys must be strings") | |
assert(typeof(value) == "number", "Enum values must be numbers") | |
assert(value % 1 == 0 and value > 0, "Enum values must be integers greater than 0") | |
for otherKey, otherValue in spec do | |
assert(key == otherKey or value ~= otherValue, `Enum values must be unique. {otherKey} and {key} both share {value}`) | |
end | |
end | |
local itemsArray = {} | |
local itemsMap = {} | |
local enum = setmetatable({ | |
_itemsArray = itemsArray, | |
_itemsMap = itemsMap, | |
_name = enumName, | |
}, enum_meta) | |
for key, value in spec do | |
local item = setmetatable({ | |
_value = value, | |
_key = key, | |
_enum = enum | |
}, enumItem_meta) | |
table.insert(itemsArray, item) | |
itemsMap[key] = item | |
itemsMap[value] = item | |
end | |
EnumsInternal[enumName] = enum | |
return enum :: typeof(spec) | |
end | |
enumSpec.WorldEditorAction = { | |
Cut = 1, | |
Copy = 2, | |
Paste = 3, | |
Delete = 4, | |
Edit = 5 | |
} | |
export type WorldEditorAction = CustomEnumItem<typeof(enumSpec.WorldEditorAction)> | |
enumSpec.WorldContextMenuType = { | |
World = 1, | |
Stamp = 2, | |
Circuit = 3 | |
} | |
export type WorldContextMenuType = CustomEnumItem<typeof(enumSpec.WorldContextMenuType)> | |
enumSpec.WorldEditorTool = { | |
Selector = 1, | |
Dragger = 2, | |
Rotator = 3 | |
} | |
export type WorldEditorTool = CustomEnumItem<typeof(enumSpec.WorldEditorTool)> | |
enumSpec.InventoryCategory = { | |
Stamps = 1, | |
Souvenirs = 2, | |
Worlds = 3, | |
Stickers = 4, | |
} | |
export type InventoryCategory = CustomEnumItem<typeof(enumSpec.InventoryCategory)> | |
enumSpec.ToolboxStampSort = { | |
Relevance = 1, | |
Likes = 2, | |
Favorites = 3 | |
} | |
export type ToolboxStampSort = CustomEnumItem<typeof(enumSpec.ToolboxStampSort)> | |
enumSpec.ToolboxCategory = { | |
Inventory = 1, | |
Library = 2 | |
} | |
export type ToolboxCategory = CustomEnumItem<typeof(enumSpec.ToolboxCategory)> | |
enumSpec.GuiTheme = { | |
Light = 1, | |
Dark = 2 | |
} | |
export type GuiTheme = CustomEnumItem<typeof(enumSpec.GuiTheme)> | |
enumSpec.StampSort = { | |
New = 1, | |
Player = 2, | |
} | |
enumSpec.WorldSort = { | |
New = 1, | |
Player = 2 | |
} | |
export type WorldSort = CustomEnumItem<typeof(enumSpec.WorldSort)> | |
enumSpec.WorldMutation = { | |
PlaceStamp = 1, | |
MoveStamp = 2, | |
DeleteStamp = 3, | |
} | |
export type WorldMutation = CustomEnumItem<typeof(enumSpec.WorldMutation)> | |
enumSpec.StampDialogAction = { | |
New = 1, | |
LoadInventory = 2, | |
LoadMarketplace = 3, | |
LoadMagica = 4, | |
} | |
export type StampDialogAction = CustomEnumItem<typeof(enumSpec.StampDialogAction)> | |
enumSpec.WorldEntryAction = { | |
NewSort = 1, | |
PlayerSort = 2, | |
CreateWorld = 3, | |
} | |
export type WorldEntryAction = CustomEnumItem<typeof(enumSpec.WorldEntryAction)> | |
enumSpec.ServerRunContext = { | |
Hub = 1, | |
WorldPlay = 2, | |
WorldEdit = 3, | |
All = 4 | |
} | |
export type ServerRunContext = CustomEnumItem<typeof(enumSpec.ServerRunContext)> | |
enumSpec.ButtonType = { | |
Text = 1, | |
Image = 2, | |
Viewport = 3 | |
} | |
export type ButtonType = CustomEnumItem<typeof(enumSpec.ButtonType)> | |
enumSpec.InterfaceContext = { | |
None = 1, | |
Standalone = 2, | |
VoxelEditor = 3 | |
} | |
export type InterfaceContext = CustomEnumItem<typeof(enumSpec.InterfaceContext)> | |
enumSpec.VoxelEditorTool = { | |
None = 1, | |
Select = 2, | |
Add = 3, | |
Subtract = 4, | |
MagicWand = 5, | |
Eyedropper = 6, | |
Style = 7, | |
Extrude = 8, | |
Move = 9, | |
Rotate = 10, | |
} | |
export type VoxelEditorTool = CustomEnumItem<typeof(enumSpec.VoxelEditorTool)> | |
enumSpec.TerrainEditorTool = { | |
None = 1, | |
Select = 2, | |
Add = 3, | |
Subtract = 4, | |
Paint = 5, | |
Smooth = 6, | |
Transform = 7, | |
} | |
export type TerrainEditorTool = CustomEnumItem<typeof(enumSpec.TerrainEditorTool)> | |
enumSpec.TerrainEditorTargetingMode = { | |
LockToPlane = 1, | |
Free = 2, | |
} | |
export type TerrainEditorTargetingMode = CustomEnumItem<typeof(enumSpec.TerrainEditorTargetingMode)> | |
enumSpec.TerrainEditorShapeMode = { | |
Box = 1, | |
Sphere = 2, | |
Wedge = 3, | |
} | |
export type TerrainEditorMode = CustomEnumItem<typeof(enumSpec.TerrainEditorShapeMode)> | |
enumSpec.TerrainEditorAction = { | |
Style = 1, | |
Load = 2, | |
Exit = 3 | |
} | |
export type TerrainEditorAction = CustomEnumItem<typeof(enumSpec.TerrainEditorAction)> | |
enumSpec.VoxelEditorAction = { | |
Style = 1, | |
Load = 2, | |
Discard = 3, | |
Save = 4, | |
SaveAs = 5, | |
Delete = 6 | |
} | |
export type VoxelEditorAction = CustomEnumItem<typeof(enumSpec.VoxelEditorAction)> | |
enumSpec.VoxelEditorTargetingMode = { | |
None = 1, | |
Cell = 2, | |
Face = 3, | |
} | |
export type VoxelEditorTargetingMode = CustomEnumItem<typeof(enumSpec.VoxelEditorTargetingMode)> | |
enumSpec.DamageType = { | |
Bludgeoning = 1, | |
Slashing = 2, | |
Piercing = 3, | |
Water = 4, | |
Fire = 5, | |
Earth = 6, | |
Wind = 7, | |
Lightning = 8, | |
Force = 9, | |
Sonic = 10, | |
Light = 11, | |
Shadow = 12, | |
Acid = 13, | |
Poison = 14, | |
Ice = 15, | |
Radioactive = 16, | |
Spirit = 17 | |
} | |
export type DamageType = CustomEnumItem<typeof(enumSpec.DamageType)> | |
enumSpec.VoxelUnionChannel = { | |
Plastic = 1, | |
Translucent = 2, | |
TranslucentNeon = 3, | |
Neon = 4, | |
Metal = 5, | |
Slate = 6 | |
} | |
export type VoxelUnionChannel = CustomEnumItem<typeof(enumSpec.VoxelUnionChannel)> | |
enumSpec.VoxelId = { | |
-- Blue | |
Aqua = 1, | |
BrightBlue = 2, | |
BrightBluishGreen = 3, | |
EarthBlue = 4, | |
LightRoyalBlue = 5, | |
MediumAzur = 6, | |
MediumBlue = 7, | |
SandBlue = 8, | |
-- Green | |
BrightGreen = 9, | |
BrightYellowishGreen = 10, | |
DarkGreen = 11, | |
EarthGreen = 12, | |
OliveGreen = 13, | |
SandGreen = 14, | |
SpringYellowishGreen = 15, | |
-- Yellow | |
BrickYellow = 16, | |
BrightYellow = 17, | |
CoolYellow = 18, | |
Gold = 19, | |
-- Orange | |
BrightOrange = 20, | |
DarkBrown = 21, | |
DarkOrange = 22, | |
FlameYellowOrange = 23, | |
LightNougat = 24, | |
MediumNougat = 25, | |
Nougat = 26, | |
SandBrown = 27, | |
-- Red | |
BrightRed = 28, | |
DarkRed = 29, | |
FlourescentReddishOrange = 30, | |
ReddishBrown = 31, | |
VibrantCoral = 32, | |
-- Purple | |
BrightPurple = 33, | |
BrightReddishViolet = 34, | |
BrightViolet = 35, | |
Lavender = 36, | |
LightPurple = 37, | |
MediumLavendar = 38, | |
MediumLilac = 39, | |
-- Black | |
Black = 40, | |
DarkStoneGrey = 41, | |
MediumStoneGrey = 42, | |
TitaniumMetallic = 43, | |
White = 44, | |
-- Glass | |
Glass = 45, | |
-- Bludgeoning, Slashing, Piercing | |
DarkMetal = 46, | |
LightMetal = 47, | |
MediumMetal = 48, | |
-- Water | |
Foam = 49, | |
Ocean = 50, | |
-- Fire | |
Cinder = 51, | |
Ember = 52, | |
Flame = 53, | |
-- Earth | |
Dirt = 54, | |
Stone = 55, | |
-- Wind | |
Breeze = 56, | |
Gust = 57, | |
Gale = 58, | |
-- Lightning | |
Tesla = 59, | |
Volta = 60, | |
Ampere = 61, | |
Watt = 62, | |
-- Force | |
Nova = 63, | |
Impulse = 64, | |
-- Sonic | |
Subsonic = 65, | |
Supersonic = 66, | |
-- Light | |
Starlight = 67, | |
Divinity = 68, | |
-- Shadow | |
Penumbra = 69, | |
Darkness = 70, | |
-- Acid | |
StrongAcid = 71, | |
WeakAcid = 72, | |
-- Poison | |
Malaise = 73, | |
Plague = 74, | |
-- Ice | |
Frost = 75, | |
Ice = 76, | |
-- Radioactive | |
Wasteland = 77, | |
Uranium = 78, | |
-- Spirit | |
Haunt = 79, | |
Scream = 80 | |
} | |
export type VoxelId = CustomEnumItem<typeof(enumSpec.VoxelId)> | |
return Enums |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment