Skip to content

Commit dc3a15f

Browse files
committed
feat: start work on geometry and btools extensions, prepwork for extension searching
1 parent 6d30f45 commit dc3a15f

13 files changed

Lines changed: 264 additions & 42 deletions

File tree

pesde.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name = "team_fireworks/rocket"
2-
version = "0.1.0"
2+
version = "0.0.0"
33
description = "General-purpose Roblox building plugin"
44
authors = ["Team Fireworks"]
55
repository = "https://github.com/team-fireworks/rocket"

src/CommandContext.luau

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,38 @@
11
local ChangeHistoryService = game:GetService("ChangeHistoryService")
2+
local Selection = game:GetService("Selection")
23

34
local Gizmos = require("@src/Gizmos")
45
local Iris = require("@src/Iris")
56
local Trove = require("@pkgs/Trove")
7+
local fzy = require("@vendor/fzy")
68

79
local CommandContext = {}
810
CommandContext.__index = CommandContext
911
CommandContext.iris = Iris
1012
CommandContext.gizmos = Gizmos
13+
CommandContext.fzy = fzy
1114

1215
-- LUAU: command is typed any to avoid circular requires
1316
export type CommandContext = setmetatable<{
1417
command: any,
1518
trove: Trove.Trove,
1619
mouse: PluginMouse,
20+
state: { [any]: any },
1721
}, typeof(CommandContext)>
1822

1923
function CommandContext.new(command: any, plugin: Plugin, trove: Trove.Trove): CommandContext
20-
return setmetatable({ command = command, trove = trove, mouse = plugin:GetMouse() }, CommandContext)
24+
local self = setmetatable({
25+
command = command,
26+
trove = trove,
27+
mouse = plugin:GetMouse(),
28+
state = {},
29+
}, CommandContext)
30+
31+
trove:Add(function()
32+
table.clear(self.state)
33+
end)
34+
35+
return self
2136
end
2237

2338
function CommandContext.recordChanges(self: CommandContext, id: string?, title: string?)
@@ -33,6 +48,27 @@ function CommandContext.recordChanges(self: CommandContext, id: string?, title:
3348
end
3449
end
3550

51+
function CommandContext.cleanup(self: CommandContext)
52+
self.trove:Destroy()
53+
end
54+
55+
function CommandContext:getSelection()
56+
return Selection:Get()
57+
end
58+
59+
function CommandContext:setSelection(instances: { Instance })
60+
Selection:Set(instances)
61+
end
62+
63+
function CommandContext.getState(self: CommandContext, key: any): any
64+
return self.state[key]
65+
end
66+
67+
function CommandContext.setState<T>(self: CommandContext, key: any, value: T): T
68+
self.state[key] = value
69+
return value
70+
end
71+
3672
function CommandContext.__tostring(self: CommandContext)
3773
return `CommandContext({string.format("%q", self.command:formatId())})`
3874
end

src/Extension.luau

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ Extension.allCommands = Charm.computed(function(): { Command.Command }
2121
return result
2222
end)
2323

24+
Extension.extensionTitles = Charm.computed(function(): { string }
25+
local allExtensions = Extension.allExtensions()
26+
local result = table.create(#allExtensions) :: { string }
27+
for ext in allExtensions do
28+
table.insert(result, ext._metadata.title)
29+
end
30+
table.sort(result)
31+
return result
32+
end)
33+
2434
Extension.commandTitles = Charm.computed(function(): { string }
2535
local allCommands = Extension.allCommands()
2636
local result = table.create(#allCommands) :: { string }

src/extensions/btools/tools/MoveTool.luau

Whitespace-only changes.

src/extensions/btools/tools/RotateTool.luau

Whitespace-only changes.

src/extensions/btools/tools/ScaleTool.luau

Whitespace-only changes.

src/extensions/btools/tools/SelectTool.luau

Whitespace-only changes.

src/extensions/geometry/init.luau

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
local Extension = require("@src/Extension")
2+
local assets = require("@src/assets")
3+
4+
local plugin = script:FindFirstAncestorWhichIsA("Plugin") :: Plugin
5+
local ext = Extension.new(plugin, {
6+
id = "rocket-geometry",
7+
title = "Geometry",
8+
description = "TBA",
9+
icon = { Image = assets.extensions.settings.base },
10+
authors = { "Team Fireworks" },
11+
})
12+
13+
return ext
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
local UserInputService = game:GetService("UserInputService")
2+
3+
local Extension = require("@src/Extension")
4+
local ext = require(".")
5+
6+
type TrussMaterial = { name: string, properties: { [string]: any } }
7+
8+
local function createSurfaceProperties(surface: Enum.SurfaceType): { [string]: any }
9+
return {
10+
TopSurface = surface,
11+
BottomSurface = surface,
12+
RightSurface = surface,
13+
LeftSurface = surface,
14+
FrontSurface = surface,
15+
BackSurface = surface,
16+
}
17+
end
18+
19+
local TRUSS_MATERIALS: { TrussMaterial } = {
20+
{ name = "Neon", properties = { Material = Enum.Material.Neon } },
21+
{ name = "Granite", properties = { Material = Enum.Material.Granite } },
22+
{ name = "Glass", properties = { Material = Enum.Material.Glass, Transparency = 0.5 } },
23+
{ name = "Plastic", properties = { Material = Enum.Material.Plastic } },
24+
{ name = "Stud", properties = createSurfaceProperties(Enum.SurfaceType.Studs) },
25+
{ name = "Inlet", properties = createSurfaceProperties(Enum.SurfaceType.Inlet) },
26+
{ name = "Universal", properties = createSurfaceProperties(Enum.SurfaceType.Universal) },
27+
{ name = "Smooth", properties = createSurfaceProperties(Enum.SurfaceType.Smooth) },
28+
{ name = "Glue", properties = createSurfaceProperties(Enum.SurfaceType.Glue) },
29+
}
30+
31+
local TRUSS_MATERIAL_NAMES = {}
32+
local TRUSS_MATERIALS_BY_NAMES = {}
33+
for i, material in TRUSS_MATERIALS do
34+
TRUSS_MATERIAL_NAMES[i] = material.name
35+
TRUSS_MATERIALS_BY_NAMES[material.name] = material
36+
end
37+
38+
local TRUSS_FILLER_TAG = `Rocket Geometry: Truss Filler`
39+
40+
local function fill(truss: TrussPart, material: TrussMaterial)
41+
local filler: BasePart
42+
local fillerName = truss.Name .. "Fill"
43+
44+
local existing = truss:FindFirstChild(fillerName)
45+
if existing and existing:HasTag(TRUSS_FILLER_TAG) and existing:IsA("BasePart") then
46+
filler = existing
47+
end
48+
49+
filler = filler or Instance.new("Part")
50+
51+
filler.Anchored = true
52+
filler.CanCollide = false
53+
filler.CastShadow = truss.CastShadow
54+
filler.CFrame = truss.CFrame
55+
filler.Color = truss.Color
56+
filler.Name = fillerName
57+
filler.Reflectance = truss.Reflectance
58+
filler.Size = truss.Size - Vector3.new(0.5, 0.5, 0.5)
59+
filler.Transparency = truss.Transparency
60+
61+
for property, value in material.properties do
62+
(filler :: any)[property] = value
63+
end
64+
65+
filler.Parent = truss
66+
filler:AddTag(TRUSS_FILLER_TAG)
67+
end
68+
69+
local function fillRecursive(instances: { Instance }, material: TrussMaterial)
70+
for _, child in instances do
71+
if child:IsA("TrussPart") then
72+
fill(child, material)
73+
end
74+
75+
fillRecursive(child:GetChildren(), material)
76+
end
77+
end
78+
79+
for _, material in TRUSS_MATERIALS do
80+
ext:newCommand({
81+
id = `fill-trusses-with-{string.lower(material.name)}`,
82+
title = `Fill Trusses with {material.name}`,
83+
description = `Fills selected TrussParts with {material.name} parts.`,
84+
85+
run = function(ctx: Extension.CommandContext)
86+
ctx:recordChanges()
87+
fillRecursive(ctx:getSelection(), material)
88+
end,
89+
})
90+
end
91+
92+
ext:newCommand({
93+
id = "fill-trusses",
94+
title = "Select and Fill Trusses",
95+
description = "Fills selected TrussParts with the given material",
96+
97+
run = function(ctx: Extension.CommandContext)
98+
ctx:recordChanges()
99+
ctx:setState("firstRun", true)
100+
end,
101+
102+
renderInViewport = function(ctx: Extension.CommandContext)
103+
local Iris = ctx.iris
104+
local window = Iris.Window(
105+
{ "Select material to fill trusses" },
106+
{ position = UserInputService:GetMouseLocation() } :: any
107+
)
108+
109+
if window.closed() then
110+
ctx:cleanup()
111+
Iris.End()
112+
return
113+
end
114+
115+
local search = ""
116+
local inputField = Iris.InputText({ "", "Search materials..." })
117+
local input = inputField.Instance:FindFirstChildWhichIsA("TextBox")
118+
if input then
119+
search = input.Text
120+
if ctx:getState("firstRun") then
121+
ctx:setState("firstRun", false)
122+
input:CaptureFocus()
123+
end
124+
end
125+
126+
local searchResults: { string } = TRUSS_MATERIAL_NAMES
127+
if search ~= "" then
128+
local results = ctx.fzy.filter(search, TRUSS_MATERIAL_NAMES)
129+
searchResults = table.create(#results) :: { string }
130+
for i, result in results do
131+
searchResults[i] = TRUSS_MATERIAL_NAMES[result[1]]
132+
end
133+
end
134+
135+
local selectedMaterial: TrussMaterial?
136+
for _, name in searchResults do
137+
if Iris.Button(name, UDim2.fromScale(1, 0)).clicked() then
138+
selectedMaterial = TRUSS_MATERIALS_BY_NAMES[name]
139+
end
140+
end
141+
142+
if not selectedMaterial then
143+
if inputField.textChanged() then
144+
local first = searchResults[1]
145+
if first then
146+
selectedMaterial = TRUSS_MATERIALS_BY_NAMES[first]
147+
end
148+
end
149+
end
150+
151+
if selectedMaterial then
152+
fillRecursive(ctx:getSelection(), selectedMaterial)
153+
ctx:cleanup()
154+
end
155+
156+
Iris.End()
157+
end,
158+
})
159+
160+
ext:newCommand({
161+
id = "delete-truss-fill",
162+
title = "Delete Truss Fill",
163+
description = "Deletes fills in selected TrussParts that was added by this extension.",
164+
165+
run = function(ctx: Extension.CommandContext)
166+
ctx:recordChanges()
167+
168+
for _, selected in ctx:getSelection() do
169+
if selected:HasTag(TRUSS_FILLER_TAG) then
170+
selected:Destroy()
171+
continue
172+
end
173+
174+
for _, descendant in selected:GetDescendants() do
175+
if descendant:HasTag(TRUSS_FILLER_TAG) then
176+
descendant:Destroy()
177+
end
178+
end
179+
end
180+
end,
181+
})
182+
183+
return nil

src/extensions/lighting/init.luau

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,24 @@
11
-- Inspired by EzLight and Elttob Relight
22
-- Reposition logic partially based on EzLight
33

4-
local ChangeHistoryService = game:GetService("ChangeHistoryService")
54
local Lighting = game:GetService("Lighting")
65
local Selection = game:GetService("Selection")
76
local UserInputService = game:GetService("UserInputService")
87
local Workspace = game:GetService("Workspace")
98

109
local Extension = require("@src/Extension")
11-
-- local Gizmos = require("@src/Gizmos")
1210
local assets = require("@src/assets")
11+
local repositions = require("@self/repositions")
1312
local types = require("@self/types")
1413

1514
local TAU = math.pi * 2
16-
-- local GIZMO_COLOR = Color3.fromHex("#AC7400")
17-
-- local GIZMO_PROPERTIES: Gizmos.PartialProperties = { Color3 = GIZMO_COLOR }
1815

1916
local plugin = script:FindFirstAncestorWhichIsA("Plugin") :: Plugin
20-
2117
local sources = {
2218
{ id = "sun", title = "Sun", longtitudeFactor = 1, icon = assets.extensions.lighting.sun },
2319
{ id = "moon", title = "Moon", longtitudeFactor = -1, icon = assets.extensions.lighting.moon },
2420
}
2521

26-
local repositions: { types.Reposition } = {
27-
require("@self/repositions/CursorReposition"),
28-
require("@self/repositions/FaceReposition"),
29-
require("@self/repositions/LineReposition"),
30-
require("@self/repositions/ReflectionReposition"),
31-
require("@self/repositions/ShadowReposition"),
32-
}
33-
3422
local ext = Extension.new(plugin, {
3523
id = "rocket-lighting",
3624
title = "Lighting",
@@ -70,7 +58,7 @@ for _, source in sources do
7058
local hasInitiallyClicked = false
7159
ext:newCommand({
7260
id = `reposition-{source.id}-by-{reposition.id}`,
73-
title = `Reposition {source.title} by {reposition.title}`,
61+
title = `Reposition the {source.title} by {reposition.title}`,
7462
description = `Reposition the {source.title} by {reposition.describedBy}.`,
7563
icon = { Image = source.icon },
7664

0 commit comments

Comments
 (0)