v1.0
This commit is contained in:
27
.eslintrc
27
.eslintrc
@@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"parserOptions": {
|
|
||||||
"jsx": true,
|
|
||||||
"useJSXTextNode": true,
|
|
||||||
"ecmaVersion": 2018,
|
|
||||||
"sourceType": "module",
|
|
||||||
"project": "./tsconfig.json"
|
|
||||||
},
|
|
||||||
"ignorePatterns": [
|
|
||||||
"/out"
|
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
"@typescript-eslint",
|
|
||||||
"roblox-ts",
|
|
||||||
"prettier"
|
|
||||||
],
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended",
|
|
||||||
"plugin:@typescript-eslint/recommended",
|
|
||||||
"plugin:roblox-ts/recommended-legacy",
|
|
||||||
"plugin:prettier/recommended"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"prettier/prettier": "warn"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
51
eslint.config.mjs
Normal file
51
eslint.config.mjs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { defineConfig, globalIgnores } from "eslint/config";
|
||||||
|
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
||||||
|
import robloxTs from "eslint-plugin-roblox-ts";
|
||||||
|
import prettier from "eslint-plugin-prettier";
|
||||||
|
import tsParser from "@typescript-eslint/parser";
|
||||||
|
import path from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import js from "@eslint/js";
|
||||||
|
import { FlatCompat } from "@eslint/eslintrc";
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
baseDirectory: __dirname,
|
||||||
|
recommendedConfig: js.configs.recommended,
|
||||||
|
allConfig: js.configs.all,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(["out"]),
|
||||||
|
{
|
||||||
|
extends: compat.extends(
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:roblox-ts/recommended-legacy",
|
||||||
|
"plugin:prettier/recommended",
|
||||||
|
),
|
||||||
|
|
||||||
|
plugins: {
|
||||||
|
"@typescript-eslint": typescriptEslint,
|
||||||
|
robloxTs,
|
||||||
|
prettier,
|
||||||
|
},
|
||||||
|
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
ecmaVersion: 2018,
|
||||||
|
sourceType: "module",
|
||||||
|
|
||||||
|
parserOptions: {
|
||||||
|
jsx: true,
|
||||||
|
useJSXTextNode: true,
|
||||||
|
project: "./tsconfig.json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
"prettier/prettier": "warn",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -12,6 +12,8 @@
|
|||||||
"@rbxts/signal": "^1.1.1"
|
"@rbxts/signal": "^1.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
|
"@eslint/js": "^9.35.0",
|
||||||
"@rbxts/compiler-types": "^3.0.0-types.0",
|
"@rbxts/compiler-types": "^3.0.0-types.0",
|
||||||
"@rbxts/types": "^1.0.881",
|
"@rbxts/types": "^1.0.881",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.43.0",
|
"@typescript-eslint/eslint-plugin": "^8.43.0",
|
||||||
|
|||||||
@@ -6,13 +6,17 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rbxtsc",
|
"build": "rbxtsc",
|
||||||
"watch": "rbxtsc -w",
|
"watch": "rbxtsc -w",
|
||||||
"build-to-roblox": "rbxtsc && rojo build --plugin \"next-station.rbxm\""
|
"build-to-roblox": "rbxtsc && rojo build --plugin \"next-station.rbxm\"",
|
||||||
|
"lint": "eslint",
|
||||||
|
"lint-fix": "eslint --fix"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
|
"@eslint/js": "^9.35.0",
|
||||||
"@rbxts/compiler-types": "^3.0.0-types.0",
|
"@rbxts/compiler-types": "^3.0.0-types.0",
|
||||||
"@rbxts/types": "^1.0.881",
|
"@rbxts/types": "^1.0.881",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.43.0",
|
"@typescript-eslint/eslint-plugin": "^8.43.0",
|
||||||
|
|||||||
46
src/Adornment/ArcHandles.ts
Normal file
46
src/Adornment/ArcHandles.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import Signal from "@rbxts/signal";
|
||||||
|
import { createAnchor } from "Utils/Gui";
|
||||||
|
import { snapCFrameRotation } from "Utils/Math";
|
||||||
|
|
||||||
|
export class ArcHandles {
|
||||||
|
currentCframe: CFrame = new CFrame();
|
||||||
|
anchor: Part;
|
||||||
|
valueChanged = new Signal<(newValue: CFrame) => void>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
model: Folder,
|
||||||
|
startPosition: CFrame = CFrame.identity,
|
||||||
|
anchor = createAnchor(model, startPosition.Position),
|
||||||
|
) {
|
||||||
|
this.anchor = anchor;
|
||||||
|
anchor.CFrame = startPosition;
|
||||||
|
|
||||||
|
const handles = new Instance("ArcHandles");
|
||||||
|
handles.Adornee = this.anchor;
|
||||||
|
handles.Parent = model;
|
||||||
|
handles.MouseButton1Down.Connect(() => {
|
||||||
|
this.currentCframe = this.anchor.CFrame;
|
||||||
|
});
|
||||||
|
handles.MouseDrag.Connect((axis, distance) => {
|
||||||
|
// Apply the rotation to the anchor's Cframe
|
||||||
|
let rotation = CFrame.identity;
|
||||||
|
switch (axis) {
|
||||||
|
case Enum.Axis.X:
|
||||||
|
rotation = CFrame.Angles(distance, 0, 0);
|
||||||
|
break;
|
||||||
|
case Enum.Axis.Y:
|
||||||
|
rotation = CFrame.Angles(0, distance, 0);
|
||||||
|
break;
|
||||||
|
case Enum.Axis.Z:
|
||||||
|
rotation = CFrame.Angles(0, 0, distance);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.anchor.CFrame = this.currentCframe.mul(snapCFrameRotation(rotation));
|
||||||
|
});
|
||||||
|
|
||||||
|
handles.MouseButton1Up.Connect(() => {
|
||||||
|
const newCFrame = this.anchor.CFrame;
|
||||||
|
this.valueChanged.Fire(newCFrame);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/Adornment/Exit.ts
Normal file
12
src/Adornment/Exit.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
export function doorAdornment(model: Folder, anchor: Part) {
|
||||||
|
const doorAdornment = new Instance("BoxHandleAdornment");
|
||||||
|
doorAdornment.Adornee = anchor;
|
||||||
|
doorAdornment.Size = new Vector3(5, 7, 1);
|
||||||
|
doorAdornment.AlwaysOnTop = true;
|
||||||
|
doorAdornment.ZIndex = 5;
|
||||||
|
doorAdornment.Color3 = new Color3(1, 0, 0);
|
||||||
|
doorAdornment.Transparency = 0.8;
|
||||||
|
doorAdornment.Parent = model;
|
||||||
|
doorAdornment.CFrame = new CFrame(0, 3.5, 0);
|
||||||
|
return doorAdornment;
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ export class Handles {
|
|||||||
currentVector: Vector3 = new Vector3();
|
currentVector: Vector3 = new Vector3();
|
||||||
anchor: Part;
|
anchor: Part;
|
||||||
valueChanged = new Signal<(newValue: Vector3) => void>();
|
valueChanged = new Signal<(newValue: Vector3) => void>();
|
||||||
|
handles: HandlesBase;
|
||||||
|
|
||||||
constructor(model: Folder, startPosition: Vector3 = Vector3.zero, anchor = createAnchor(model, startPosition)) {
|
constructor(model: Folder, startPosition: Vector3 = Vector3.zero, anchor = createAnchor(model, startPosition)) {
|
||||||
this.anchor = anchor;
|
this.anchor = anchor;
|
||||||
@@ -48,5 +49,7 @@ export class Handles {
|
|||||||
const newpos = this.anchor.Position;
|
const newpos = this.anchor.Position;
|
||||||
this.valueChanged.Fire(newpos);
|
this.valueChanged.Fire(newpos);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.handles = handles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export function createAnchor(model: Folder, position: Vector3) {
|
export function createAnchor(model: Folder, position: Vector3 = Vector3.zero) {
|
||||||
// Create Anchor for Adornments
|
// Create Anchor for Adornments
|
||||||
const anchor = new Instance("Part");
|
const anchor = new Instance("Part");
|
||||||
anchor.Anchored = true;
|
anchor.Anchored = true;
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
export function roundVector(vector: Vector3) {
|
export function roundVector(vector: Vector3) {
|
||||||
return new Vector3(math.round(vector.X * 4) / 4, math.round(vector.Y * 4) / 4, math.round(vector.Z * 4) / 4);
|
return new Vector3(math.round(vector.X * 4) / 4, math.round(vector.Y * 4) / 4, math.round(vector.Z * 4) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function snapCFrameRotation(cf: CFrame) {
|
||||||
|
let [x, y, z] = cf.ToEulerAnglesXYZ();
|
||||||
|
|
||||||
|
x = math.round(math.deg(x) / 10) * 10;
|
||||||
|
y = math.round(math.deg(y) / 10) * 10;
|
||||||
|
z = math.round(math.deg(z) / 10) * 10;
|
||||||
|
|
||||||
|
const snappedRot = CFrame.Angles(math.rad(x), math.rad(y), math.rad(z));
|
||||||
|
return new CFrame(cf.Position).mul(snappedRot);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import { ArcHandles } from "Adornment/ArcHandles";
|
||||||
|
import { doorAdornment } from "Adornment/Exit";
|
||||||
|
import { Handles } from "Adornment/Handles";
|
||||||
import CollapsibleTitledSection from "Lualibs/CollapsibleTitledSection";
|
import CollapsibleTitledSection from "Lualibs/CollapsibleTitledSection";
|
||||||
import CustomTextButton from "Lualibs/CustomTextButton";
|
import CustomTextButton from "Lualibs/CustomTextButton";
|
||||||
import LabeledTextInput from "Lualibs/LabeledTextInput";
|
import LabeledTextInput from "Lualibs/LabeledTextInput";
|
||||||
@@ -22,7 +25,7 @@ export class RoomWidget {
|
|||||||
true, // minimizable?
|
true, // minimizable?
|
||||||
false, // minimized by default?
|
false, // minimized by default?
|
||||||
);
|
);
|
||||||
exitCollapse = new CollapsibleTitledSection(
|
exitsCollapse = new CollapsibleTitledSection(
|
||||||
"ExitCollapse", // name suffix of the gui object
|
"ExitCollapse", // name suffix of the gui object
|
||||||
"Exit", // title text of the collapsible arrow
|
"Exit", // title text of the collapsible arrow
|
||||||
true, // have the content frame auto-update its size?
|
true, // have the content frame auto-update its size?
|
||||||
@@ -72,7 +75,7 @@ export class RoomWidget {
|
|||||||
const typeTextBox = this.roomTypeInput.GetFrame().FindFirstChildWhichIsA("TextBox", true)!;
|
const typeTextBox = this.roomTypeInput.GetFrame().FindFirstChildWhichIsA("TextBox", true)!;
|
||||||
typeTextBox.ClearTextOnFocus = false;
|
typeTextBox.ClearTextOnFocus = false;
|
||||||
this.listFrame.AddChild(this.roomCollapse.GetSectionFrame());
|
this.listFrame.AddChild(this.roomCollapse.GetSectionFrame());
|
||||||
this.listFrame.AddChild(this.exitCollapse.GetSectionFrame());
|
this.listFrame.AddChild(this.exitsCollapse.GetSectionFrame());
|
||||||
|
|
||||||
this.listFrame.AddBottomPadding();
|
this.listFrame.AddBottomPadding();
|
||||||
|
|
||||||
@@ -85,32 +88,101 @@ export class RoomWidget {
|
|||||||
this.roomIdInput.SetValue(tostring(config.RoomId.Value));
|
this.roomIdInput.SetValue(tostring(config.RoomId.Value));
|
||||||
this.roomTypeValue = config.RoomType;
|
this.roomTypeValue = config.RoomType;
|
||||||
this.roomTypeInput.SetValue(config.RoomType.Value);
|
this.roomTypeInput.SetValue(config.RoomType.Value);
|
||||||
|
|
||||||
|
const exits = config
|
||||||
|
.GetChildren()
|
||||||
|
.filter(
|
||||||
|
(value) => !string.match(value.Name, "^Exit_[0-9]+$").isEmpty() && value.IsA("CFrameValue"),
|
||||||
|
) as CFrameValue[];
|
||||||
|
|
||||||
|
this.ReloadExits(exits, config);
|
||||||
}
|
}
|
||||||
SetActive(active: boolean) {
|
SetActive(active: boolean) {
|
||||||
this.noRoomLabel.Visible = !active;
|
this.noRoomLabel.Visible = !active;
|
||||||
}
|
}
|
||||||
ReloadExits(exits: CFrameValue[]) {
|
ReloadExits(exits: CFrameValue[], config: RoomConfig) {
|
||||||
this.exitCollapse.GetContentsFrame().ClearAllChildren();
|
this.exitsCollapse.GetContentsFrame().ClearAllChildren();
|
||||||
|
|
||||||
|
const exitListFrame = new VerticallyScalingListFrame("RoomWidget");
|
||||||
|
|
||||||
for (const exit of exits) {
|
for (const exit of exits) {
|
||||||
const exitCollapse = new CollapsibleTitledSection(
|
const posbutton = new CustomTextButton(
|
||||||
"ExitCollapse_" + exit.Name, // name suffix of the gui object
|
|
||||||
exit.Name, // the text displayed beside the collapsible arrow
|
|
||||||
true, // have the content frame auto-update its size?
|
|
||||||
true, // minimizable?
|
|
||||||
false, // minimized by default?
|
|
||||||
);
|
|
||||||
|
|
||||||
const button = new CustomTextButton(
|
|
||||||
"edit_button", // name of the gui object
|
"edit_button", // name of the gui object
|
||||||
"Edit", // the text displayed on the button
|
`Edit ${exit.Name} position`, // the text displayed on the button
|
||||||
);
|
);
|
||||||
(button.GetButton() as ImageButton).Activated.Connect(() => {
|
const posbuttonobject = posbutton.GetButton() as ImageButton;
|
||||||
|
posbuttonobject.Activated.Connect(() => {
|
||||||
|
this.LoadExitMoveHandles(exit);
|
||||||
});
|
});
|
||||||
|
posbuttonobject.Size = new UDim2(0, 150, 0, 20);
|
||||||
|
|
||||||
// Handle widget
|
const rotbutton = new CustomTextButton(
|
||||||
exitCollapse.GetContentsFrame().Parent = this.exitCollapse.GetSectionFrame();
|
"edit_button", // name of the gui object
|
||||||
|
`Edit ${exit.Name} rotation`, // the text displayed on the button
|
||||||
|
);
|
||||||
|
const rotbuttonobject = rotbutton.GetButton() as ImageButton;
|
||||||
|
rotbuttonobject.Activated.Connect(() => {
|
||||||
|
this.LoadExitRotationHandles(exit);
|
||||||
|
});
|
||||||
|
rotbuttonobject.Size = new UDim2(0, 150, 0, 20);
|
||||||
|
|
||||||
|
exitListFrame.AddChild(posbuttonobject);
|
||||||
|
exitListFrame.AddChild(rotbuttonobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rotbutton = new CustomTextButton(
|
||||||
|
"create_button", // name of the gui object
|
||||||
|
`Create a Exit`, // the text displayed on the button
|
||||||
|
);
|
||||||
|
const createbutobject = rotbutton.GetButton() as ImageButton;
|
||||||
|
createbutobject.Activated.Connect(() => {
|
||||||
|
const exit = new Instance("CFrameValue");
|
||||||
|
exit.Parent = config;
|
||||||
|
exit.Value = new CFrame(config.Origin.Value);
|
||||||
|
exit.Name = `Exit_${exits.size()}`;
|
||||||
|
exits.push(exit);
|
||||||
|
this.ReloadExits(exits, config);
|
||||||
|
});
|
||||||
|
createbutobject.Size = new UDim2(0, 150, 0, 20);
|
||||||
|
exitListFrame.AddChild(createbutobject);
|
||||||
|
|
||||||
|
exitListFrame.AddBottomPadding();
|
||||||
|
exitListFrame.GetFrame().Parent = this.exitsCollapse.GetContentsFrame();
|
||||||
|
}
|
||||||
|
LoadExitMoveHandles(exit: CFrameValue) {
|
||||||
|
this.clearExitHandles();
|
||||||
|
|
||||||
|
const folder = new Instance("Folder");
|
||||||
|
folder.Parent = this.model;
|
||||||
|
folder.Name = "_exit_handle";
|
||||||
|
|
||||||
|
const exithandle = new Handles(folder, exit.Value.Position);
|
||||||
|
exithandle.valueChanged.Connect((value) => {
|
||||||
|
const oldvalue = exit.Value;
|
||||||
|
exit.Value = new CFrame(value).mul(oldvalue.sub(oldvalue.Position));
|
||||||
|
});
|
||||||
|
doorAdornment(folder, exithandle.anchor);
|
||||||
|
}
|
||||||
|
LoadExitRotationHandles(exit: CFrameValue) {
|
||||||
|
this.clearExitHandles();
|
||||||
|
|
||||||
|
const folder = new Instance("Folder");
|
||||||
|
folder.Parent = this.model;
|
||||||
|
folder.Name = "_exit_handle";
|
||||||
|
|
||||||
|
const exithandle = new ArcHandles(folder, exit.Value);
|
||||||
|
exithandle.valueChanged.Connect((value) => {
|
||||||
|
const oldvalue = exit.Value;
|
||||||
|
exit.Value = new CFrame(oldvalue.Position).mul(value.Rotation);
|
||||||
|
});
|
||||||
|
doorAdornment(folder, exithandle.anchor);
|
||||||
|
}
|
||||||
|
clearExitHandles() {
|
||||||
|
const childs = this.model.GetChildren();
|
||||||
|
childs
|
||||||
|
.filter((value) => value.Name === "_exit_handle")
|
||||||
|
.forEach((value) => {
|
||||||
|
value.Destroy();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,209 +0,0 @@
|
|||||||
local RoomWidget = {}
|
|
||||||
|
|
||||||
local ScrollingFrame = require(script.Parent.Parent.Parent.StudioWidgets.VerticalScrollingFrame)
|
|
||||||
local VerticallyScalingListFrame = require(script.Parent.Parent.Parent.StudioWidgets.VerticallyScalingListFrame)
|
|
||||||
local CollapsibleTitledSection = require(script.Parent.Parent.Parent.StudioWidgets.CollapsibleTitledSection)
|
|
||||||
local LabeledTextInput = require(script.Parent.Parent.Parent.StudioWidgets.LabeledTextInput)
|
|
||||||
local CustomTextButton = require(script.Parent.Parent.Parent.StudioWidgets.CustomTextButton)
|
|
||||||
|
|
||||||
local guiModule = require(script.Parent.Parent.Parent.Tools.Gui)
|
|
||||||
local UseLessModule = require(script.Parent.Parent.Parent.Tools.Useless)
|
|
||||||
|
|
||||||
|
|
||||||
function RoomWidget:new(plugin:Plugin,adornmentContainer:Folder,pluginModel:Folder)
|
|
||||||
self = setmetatable({}, {__index = RoomWidget})
|
|
||||||
|
|
||||||
self.adornmentContainer = adornmentContainer
|
|
||||||
self.pluginModel = pluginModel
|
|
||||||
|
|
||||||
-- Create Widget
|
|
||||||
self.info = DockWidgetPluginGuiInfo.new(
|
|
||||||
Enum.InitialDockState.Left,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
200,
|
|
||||||
300,
|
|
||||||
150,
|
|
||||||
150
|
|
||||||
)
|
|
||||||
|
|
||||||
self.widget = plugin:CreateDockWidgetPluginGui(
|
|
||||||
"RoomWidget",
|
|
||||||
self.info
|
|
||||||
)
|
|
||||||
self.widget.Title = "Room Info"
|
|
||||||
|
|
||||||
-- Create Widget Components
|
|
||||||
-- Create No Room Label
|
|
||||||
self.noRoomLabel = Instance.new("TextLabel")
|
|
||||||
self.noRoomLabel.Name = "NoSelect"
|
|
||||||
self.noRoomLabel.Text = "Select a room to use this widget."
|
|
||||||
self.noRoomLabel.Size = UDim2.new(1,0,1,0)
|
|
||||||
guiModule.syncGuiColors({ self.noRoomLabel })
|
|
||||||
|
|
||||||
-- Create Scrolling Frame
|
|
||||||
self.scrollFrame = ScrollingFrame.new("RoomScroll")
|
|
||||||
|
|
||||||
-- Create Vertical Scaling List Frame
|
|
||||||
self.listFrame = VerticallyScalingListFrame.new("RoomWidget")
|
|
||||||
|
|
||||||
-- Create Room Collapse
|
|
||||||
self.roomCollapse = CollapsibleTitledSection.new(
|
|
||||||
"suffix", -- name suffix of the gui object
|
|
||||||
"Room", -- the text displayed beside the collapsible arrow
|
|
||||||
true, -- have the content frame auto-update its size?
|
|
||||||
true, -- minimizable?
|
|
||||||
false -- minimized by default?
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Create Exit Collapse
|
|
||||||
self.exitCollapse = CollapsibleTitledSection.new(
|
|
||||||
"ExitCollapse", -- name suffix of the gui object
|
|
||||||
"Exit", -- title text of the collapsible arrow
|
|
||||||
true, -- have the content frame auto-update its size?
|
|
||||||
true, -- minimizable?
|
|
||||||
false -- minimized by default?
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Create TextInput
|
|
||||||
self.roomIdValue = Instance.new("IntValue")
|
|
||||||
self.roomIdLabel = LabeledTextInput.new(
|
|
||||||
"RoomId", -- name suffix of gui object
|
|
||||||
"Room Id", -- title text of the multi choice
|
|
||||||
"0" -- default value
|
|
||||||
)
|
|
||||||
self.roomIdLabel:SetValueChangedFunction(
|
|
||||||
function (value)
|
|
||||||
self.roomIdValue.Value = value
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
self.typeValue = Instance.new("StringValue")
|
|
||||||
self.typeLabel = LabeledTextInput.new(
|
|
||||||
"RoomType", -- name suffix of gui object
|
|
||||||
"Room Type", -- title text of the multi choice
|
|
||||||
"" -- default value
|
|
||||||
)
|
|
||||||
self.typeLabel:SetMaxGraphemes(255)
|
|
||||||
self.typeLabel:SetValueChangedFunction(
|
|
||||||
function (value)
|
|
||||||
self.typeValue.Value = value
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Setup Widget
|
|
||||||
self.roomIdLabel:GetFrame().Parent = self.roomCollapse:GetContentsFrame()
|
|
||||||
self.typeLabel:GetFrame().Parent = self.roomCollapse:GetContentsFrame()
|
|
||||||
self.listFrame:AddChild(self.roomCollapse:GetSectionFrame())
|
|
||||||
self.listFrame:AddChild(self.exitCollapse:GetSectionFrame())
|
|
||||||
|
|
||||||
self.listFrame:AddBottomPadding()
|
|
||||||
|
|
||||||
self.listFrame:GetFrame().Parent = self.scrollFrame:GetContentsFrame()
|
|
||||||
self.scrollFrame:GetSectionFrame().Parent = self.widget
|
|
||||||
self.noRoomLabel.Parent = self.widget
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
function RoomWidget:UpdateValue(roomIdValue:IntValue,roomTypeValue:StringValue,roomExit:{CFrameValue})
|
|
||||||
self.roomIdValue = roomIdValue
|
|
||||||
self.roomIdLabel:SetValue(roomIdValue.Value)
|
|
||||||
self.typeValue = roomTypeValue
|
|
||||||
self.typeLabel:SetValue(roomTypeValue.Value)
|
|
||||||
end
|
|
||||||
|
|
||||||
function RoomWidget:SetActive(active:boolean)
|
|
||||||
self.noRoomLabel.Visible = not active
|
|
||||||
self.scrollFrame.Visible = active
|
|
||||||
end
|
|
||||||
|
|
||||||
function RoomWidget:_clearAdornment()
|
|
||||||
self.adornmentContainer:ClearAllChildren()
|
|
||||||
self.pluginModel:ClearAllChildren()
|
|
||||||
end
|
|
||||||
|
|
||||||
function RoomWidget:ReloadExit(exits:{CFrameValue})
|
|
||||||
self.exitCollapse:GetContentsFrame():ClearAllChildren()
|
|
||||||
|
|
||||||
for _,exit in exits do
|
|
||||||
local exitCollapse = CollapsibleTitledSection.new(
|
|
||||||
"ExitCollapse_"..exit.Name, -- name suffix of the gui object
|
|
||||||
exit.Name, -- the text displayed beside the collapsible arrow
|
|
||||||
true, -- have the content frame auto-update its size?
|
|
||||||
true, -- minimizable?
|
|
||||||
false -- minimized by default?
|
|
||||||
)
|
|
||||||
|
|
||||||
local button = CustomTextButton.new(
|
|
||||||
"edit_button", -- name of the gui object
|
|
||||||
"Edit" -- the text displayed on the button
|
|
||||||
)
|
|
||||||
button:GetButton().Activated:Connect(
|
|
||||||
function(inputObject: InputObject, clickCount: number)
|
|
||||||
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Handle widget
|
|
||||||
exitCollapse:GetContentsFrame().Parent = self.exitCollapse:GetSectionFrame()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function RoomWidget:LoadExitMoveHandles(exit: CFrameValue)
|
|
||||||
self:_clearAdornment()
|
|
||||||
|
|
||||||
local function createAnchor(position: Vector3)
|
|
||||||
-- Create Anchor for Adornments
|
|
||||||
local anchor = Instance.new("Part")
|
|
||||||
anchor.Anchored = true
|
|
||||||
anchor.CanCollide = false
|
|
||||||
anchor.Transparency = 1
|
|
||||||
anchor.Size = Vector3.new(0.1, 0.1, 0.1)
|
|
||||||
anchor.Position = position
|
|
||||||
anchor.Parent = self.pluginModel
|
|
||||||
anchor.Name = "_GizmoAnchor"
|
|
||||||
return anchor
|
|
||||||
end
|
|
||||||
|
|
||||||
local anchor = createAnchor(exit.Value.Position)
|
|
||||||
local handles = Instance.new("Handles")
|
|
||||||
handles.Adornee = anchor
|
|
||||||
handles.Parent = self.adornmentContainer
|
|
||||||
|
|
||||||
local currentVector = Vector3.new(0, 0, 0)
|
|
||||||
|
|
||||||
handles.MouseButton1Down:Connect(
|
|
||||||
function(face: Enum.NormalId)
|
|
||||||
currentVector = anchor.Position
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
handles.MouseDrag:Connect(
|
|
||||||
function(face: Enum.NormalId, distance: number)
|
|
||||||
-- Apply the changes to the anchor's position
|
|
||||||
if face == Enum.NormalId.Top or face == Enum.NormalId.Right or face == Enum.NormalId.Back then
|
|
||||||
anchor.Position = UseLessModule.roundVector3(currentVector + Vector3.new(
|
|
||||||
UseLessModule.bton(face == Enum.NormalId.Right) * distance,
|
|
||||||
UseLessModule.bton(face == Enum.NormalId.Top) * distance,
|
|
||||||
UseLessModule.bton(face == Enum.NormalId.Back) * distance
|
|
||||||
))
|
|
||||||
else
|
|
||||||
anchor.Position = UseLessModule.roundVector3(currentVector - Vector3.new(
|
|
||||||
UseLessModule.bton(face == Enum.NormalId.Left) * distance,
|
|
||||||
UseLessModule.bton(face == Enum.NormalId.Bottom) * distance,
|
|
||||||
UseLessModule.bton(face == Enum.NormalId.Front) * distance
|
|
||||||
))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
handles.MouseButton1Up:Connect(
|
|
||||||
function(face: Enum.NormalId)
|
|
||||||
local newpos = anchor.Position
|
|
||||||
position.Value = newpos
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
return RoomWidget
|
|
||||||
@@ -27,6 +27,12 @@ const toolbar = plugin.CreateToolbar("Next Station Plugin");
|
|||||||
// Create Buttons
|
// Create Buttons
|
||||||
new WidgetButton(toolbar, roomWidget.widget, "Room Info", "rbxassetid://14978048121");
|
new WidgetButton(toolbar, roomWidget.widget, "Room Info", "rbxassetid://14978048121");
|
||||||
createNewRoomButton(toolbar);
|
createNewRoomButton(toolbar);
|
||||||
|
// const button = toolbar.CreateButton("debugUi", "Debug", "");
|
||||||
|
// button.Click.Connect(() => {
|
||||||
|
// const gui = new Instance("ScreenGui");
|
||||||
|
// roomWidget.widget.GetChildren().forEach((v) => (v.Parent = gui));
|
||||||
|
// gui.Parent = game.GetService("StarterGui");
|
||||||
|
// });
|
||||||
|
|
||||||
// Selection Room Config Controller
|
// Selection Room Config Controller
|
||||||
function clearAdornment() {
|
function clearAdornment() {
|
||||||
|
|||||||
Reference in New Issue
Block a user