From 3744c68cabcab0de2bfb7a3ea6b4b16404b64a8f Mon Sep 17 00:00:00 2001
From: Robert Chiquini
Date: Tue, 11 Apr 2017 06:56:10 -0700
Subject: [PATCH 1/3] Add part index to Selection and BoundingBox modules,
deselect before deleting
This change makes the SelectionModule maintain and use a binary index
for keeping track of selected items, making it significantly faster
to check whether parts are selected or not. BoundingBoxModule is also
updated to maintain and use a binary index for tracking static parts.
Additionally, deletion operations now remove deleting parts from the
selection beforehand to prevent cascades of automatic individual
deselections as parts are deleted. These changes all optimize actions
involving selected parts, and make building dramatically smoother.
Signed-off-by: Robert Chiquini
---
BoundingBoxModule.lua | 212 ++++++++++++++++++++++--------------------
Core.lua | 13 ++-
SelectionModule.lua | 141 ++++++++++++++++------------
TargetingModule.lua | 24 +++--
tools/Lighting.lua | 8 +-
tools/Move.lua | 17 ++--
tools/Paint.lua | 2 +-
tools/Resize.lua | 2 +-
tools/Surface.lua | 10 +-
tools/Texture.lua | 2 +-
10 files changed, 236 insertions(+), 195 deletions(-)
diff --git a/BoundingBoxModule.lua b/BoundingBoxModule.lua
index 4d8f138..966525d 100644
--- a/BoundingBoxModule.lua
+++ b/BoundingBoxModule.lua
@@ -1,8 +1,17 @@
-- Libraries
-Core = require(script.Parent.Core);
-Support = Core.Support;
+local Core = require(script.Parent.Core);
+local Support = Core.Support;
-BoundingBoxModule = {};
+-- Initialize module
+local BoundingBoxModule = {};
+
+-- Initialize internal module state
+local StaticParts = {};
+local StaticPartsIndex = {};
+local StaticPartMonitors = {};
+local RecalculateStaticExtents = true;
+local AggregatingStaticParts = false;
+local StaticPartAggregators = {};
function BoundingBoxModule.StartBoundingBox(HandleAttachmentCallback)
-- Creates and starts a selection bounding box
@@ -116,109 +125,104 @@ function BoundingBoxModule.ClearBoundingBox()
end;
-StaticParts = {};
-StaticPartMonitors = {};
-RecalculateStaticExtents = true;
-AggregatingStaticParts = false;
-StaticPartAggregators = {};
+function AddStaticParts(Parts)
+ -- Adds the static parts to the list for state tracking
-function AddStaticPart(Part)
- -- Adds the static part to the list for state tracking
+ -- Add each given part
+ for _, Part in pairs(Parts) do
- -- Make sure the part isn't already in the list
- if Support.IsInTable(StaticParts, Part) then
- return;
- end;
+ -- Ensure part isn't already indexed, and verify it is static
+ if not StaticPartsIndex[Part] and Part.Anchored then
+
+ -- Add part to static index
+ StaticPartsIndex[Part] = true;
- -- Add the part to the list
- table.insert(StaticParts, Part);
+ -- Start monitoring part for changes
+ StaticPartMonitors[Part] = Part.Changed:connect(function (Property)
- -- Starts monitoring the part
- StaticPartMonitors[Part] = Part.Changed:connect(function (Property)
+ -- Trigger static extent recalculations on position or size changes
+ if Property == 'CFrame' or Property == 'Size' then
+ RecalculateStaticExtents = true;
- if Property == 'CFrame' or Property == 'Size' then
- RecalculateStaticExtents = true;
+ -- Remove part from static index if it becomes mobile
+ elseif Property == 'Anchored' and not Part.Anchored then
+ RemoveStaticParts { Part };
+ end;
+
+ end);
- elseif Property == 'Anchored' and not Part.Anchored then
- RemoveStaticPart(Part);
end;
- end);
+ end;
+
+ -- Update the static parts list
+ StaticParts = Support.Keys(StaticPartsIndex);
- -- Recalculate the extents including this new part
+ -- Recalculate static extents to include added parts
RecalculateStaticExtents = true;
end;
-function RemoveStaticPart(Part)
- -- Removes the part from the static part tracking list
+function RemoveStaticParts(Parts)
+ -- Removes the given parts from the static parts index
- -- Get the part's key in the list
- local PartKey = Support.FindTableOccurrence(StaticParts, Part);
+ -- Remove each given part
+ for _, Part in pairs(Parts) do
- -- Remove it from the list
- if PartKey then
- StaticParts[PartKey] = nil;
- end;
+ -- Remove part from static parts index
+ StaticPartsIndex[Part] = nil;
+
+ -- Clean up the part's change monitors
+ if StaticPartMonitors[Part] then
+ StaticPartMonitors[Part]:disconnect();
+ StaticPartMonitors[Part] = nil;
+ end;
- -- Clear its state monitors
- if StaticPartMonitors[Part] then
- StaticPartMonitors[Part]:disconnect();
- StaticPartMonitors[Part] = nil;
end;
+ -- Update the static parts list
+ StaticParts = Support.Keys(StaticPartsIndex);
+
+ -- Recalculate static extents to exclude removed parts
+ RecalculateStaticExtents = true;
+
end;
function StartAggregatingStaticParts()
-- Begins to look for and identify static parts
- -- Add current static parts
- for _, Part in pairs(Core.Selection.Items) do
- if Part.Anchored then
- AddStaticPart(Part);
- end;
+ -- Add current qualifying parts to static parts index
+ AddStaticParts(Core.Selection.Items);
- -- Watch for parts that become anchored
+ -- Watch for parts that become static
+ for _, Part in pairs(Core.Selection.Items) do
table.insert(StaticPartAggregators, Part.Changed:connect(function (Property)
if Property == 'Anchored' and Part.Anchored then
- AddStaticPart(Part);
+ AddStaticParts { Part };
end;
end));
end;
- -- Add newly selected anchored parts
+ -- Watch newly selected parts
table.insert(StaticPartAggregators, Core.Selection.ItemsAdded:connect(function (Parts)
- -- Go through each selected part
- for _, Part in pairs(Parts) do
+ -- Add qualifying parts to static parts index
+ AddStaticParts(Parts);
- -- Only add anchored, static parts
- if Part.Anchored then
- AddStaticPart(Part);
- end;
-
- -- Watch for parts that become anchored
+ -- Watch for parts that become anchored
+ for _, Part in pairs(Parts) do
table.insert(StaticPartAggregators, Part.Changed:connect(function (Property)
if Property == 'Anchored' and Part.Anchored then
- AddStaticPart(Part);
+ AddStaticParts { Part };
end;
end));
-
end;
end));
- -- Remove deselected parts
+ -- Remove deselected parts from static parts index
table.insert(StaticPartAggregators, Core.Selection.ItemsRemoved:connect(function (Parts)
-
- -- Remove the items
- for _, Part in pairs(Parts) do
- RemoveStaticPart(Part);
- end;
-
- -- Recalculate static extents without the removed parts
- RecalculateStaticExtents = true;
-
+ RemoveStaticParts(Parts);
end));
end;
@@ -240,6 +244,7 @@ function StopAggregatingStaticParts()
-- Clear all static part information
StaticParts = {};
+ StaticPartsIndex = {};
BoundingBoxModule.StaticExtents = nil;
end;
@@ -250,6 +255,7 @@ local table_insert = table.insert;
local CFrame_toWorldSpace = CFrame.new().toWorldSpace;
local math_min = math.min;
local math_max = math.max;
+local unpack = unpack;
function BoundingBoxModule.CalculateExtents(Items, StaticExtents, ExtentsOnly)
-- Returns the size and position of a box covering all items in `Items`
@@ -279,45 +285,45 @@ function BoundingBoxModule.CalculateExtents(Items, StaticExtents, ExtentsOnly)
local Corner;
local XPoints, YPoints, ZPoints = {}, {}, {};
- Corner = CFrame_toWorldSpace(PartCFrame, CFrame_new(SizeX, SizeY, SizeZ));
- table_insert(XPoints, Corner['x']);
- table_insert(YPoints, Corner['y']);
- table_insert(ZPoints, Corner['z']);
-
- Corner = CFrame_toWorldSpace(PartCFrame, CFrame_new(-SizeX, SizeY, SizeZ));
- table_insert(XPoints, Corner['x']);
- table_insert(YPoints, Corner['y']);
- table_insert(ZPoints, Corner['z']);
-
- Corner = CFrame_toWorldSpace(PartCFrame, CFrame_new(SizeX, -SizeY, SizeZ));
- table_insert(XPoints, Corner['x']);
- table_insert(YPoints, Corner['y']);
- table_insert(ZPoints, Corner['z']);
-
- Corner = CFrame_toWorldSpace(PartCFrame, CFrame_new(SizeX, SizeY, -SizeZ));
- table_insert(XPoints, Corner['x']);
- table_insert(YPoints, Corner['y']);
- table_insert(ZPoints, Corner['z']);
-
- Corner = CFrame_toWorldSpace(PartCFrame, CFrame_new(-SizeX, SizeY, -SizeZ));
- table_insert(XPoints, Corner['x']);
- table_insert(YPoints, Corner['y']);
- table_insert(ZPoints, Corner['z']);
-
- Corner = CFrame_toWorldSpace(PartCFrame, CFrame_new(-SizeX, -SizeY, SizeZ));
- table_insert(XPoints, Corner['x']);
- table_insert(YPoints, Corner['y']);
- table_insert(ZPoints, Corner['z']);
-
- Corner = CFrame_toWorldSpace(PartCFrame, CFrame_new(SizeX, -SizeY, -SizeZ));
- table_insert(XPoints, Corner['x']);
- table_insert(YPoints, Corner['y']);
- table_insert(ZPoints, Corner['z']);
-
- Corner = CFrame_toWorldSpace(PartCFrame, CFrame_new(-SizeX, -SizeY, -SizeZ));
- table_insert(XPoints, Corner['x']);
- table_insert(YPoints, Corner['y']);
- table_insert(ZPoints, Corner['z']);
+ Corner = PartCFrame * CFrame_new(SizeX, SizeY, SizeZ);
+ table_insert(XPoints, Corner.x);
+ table_insert(YPoints, Corner.y);
+ table_insert(ZPoints, Corner.z);
+
+ Corner = PartCFrame * CFrame_new(-SizeX, SizeY, SizeZ);
+ table_insert(XPoints, Corner.x);
+ table_insert(YPoints, Corner.y);
+ table_insert(ZPoints, Corner.z);
+
+ Corner = PartCFrame * CFrame_new(SizeX, -SizeY, SizeZ);
+ table_insert(XPoints, Corner.x);
+ table_insert(YPoints, Corner.y);
+ table_insert(ZPoints, Corner.z);
+
+ Corner = PartCFrame * CFrame_new(SizeX, SizeY, -SizeZ);
+ table_insert(XPoints, Corner.x);
+ table_insert(YPoints, Corner.y);
+ table_insert(ZPoints, Corner.z);
+
+ Corner = PartCFrame * CFrame_new(-SizeX, SizeY, -SizeZ);
+ table_insert(XPoints, Corner.x);
+ table_insert(YPoints, Corner.y);
+ table_insert(ZPoints, Corner.z);
+
+ Corner = PartCFrame * CFrame_new(-SizeX, -SizeY, SizeZ);
+ table_insert(XPoints, Corner.x);
+ table_insert(YPoints, Corner.y);
+ table_insert(ZPoints, Corner.z);
+
+ Corner = PartCFrame * CFrame_new(SizeX, -SizeY, -SizeZ);
+ table_insert(XPoints, Corner.x);
+ table_insert(YPoints, Corner.y);
+ table_insert(ZPoints, Corner.z);
+
+ Corner = PartCFrame * CFrame_new(-SizeX, -SizeY, -SizeZ);
+ table_insert(XPoints, Corner.x);
+ table_insert(YPoints, Corner.y);
+ table_insert(ZPoints, Corner.z);
-- Reduce gathered points to min/max extents
MinX = math_min(MinX, unpack(XPoints));
diff --git a/Core.lua b/Core.lua
index 6803be3..4e780af 100644
--- a/Core.lua
+++ b/Core.lua
@@ -331,6 +331,9 @@ function CloneSelection()
Unapply = function (HistoryRecord)
-- Reverts this change
+ -- Deselect the clones
+ Selection.Remove(HistoryRecord.Clones, false);
+
-- Remove the clones
SyncAPI:Invoke('Remove', HistoryRecord.Clones);
@@ -400,6 +403,9 @@ function DeleteSelection()
Apply = function (HistoryRecord)
-- Applies this change
+ -- Deselect the parts
+ Selection.Remove(HistoryRecord.Parts, false);
+
-- Remove the parts
SyncAPI:Invoke('Remove', HistoryRecord.Parts);
@@ -407,8 +413,11 @@ function DeleteSelection()
};
+ -- Deselect parts before deleting
+ Selection.Remove(HistoryRecord.Parts, false);
+
-- Perform the removal
- SyncAPI:Invoke('Remove', Selection.Items);
+ SyncAPI:Invoke('Remove', HistoryRecord.Parts);
-- Register the history record
History.Add(HistoryRecord);
@@ -458,7 +467,7 @@ function PrismSelect()
for _, Part in pairs(Selection.Items) do
local TouchingParts = Part:GetTouchingParts();
for _, TouchingPart in pairs(TouchingParts) do
- if not Selection.Find(TouchingPart) then
+ if not Selection.IsSelected(TouchingPart) then
Parts[TouchingPart] = true;
end;
end;
diff --git a/SelectionModule.lua b/SelectionModule.lua
index ed5596c..6639e64 100644
--- a/SelectionModule.lua
+++ b/SelectionModule.lua
@@ -6,6 +6,7 @@ local Support = require(script.Parent.SupportLibrary);
-- Core selection system
Selection = {};
Selection.Items = {};
+Selection.ItemIndex = {};
Selection.Outlines = {};
Selection.Color = BrickColor.new 'Cyan';
Selection.Multiselecting = false;
@@ -20,51 +21,38 @@ Selection.Changed = RbxUtility.CreateSignal();
-- Item existence listeners
local Listeners = {};
-function Selection.Find(Needle)
- -- Return `Needle`'s index in the selection, or `nil` if not found
+function Selection.IsSelected(Item)
+ -- Returns whether `Item` is selected or not
- -- Go through each selected item
- for Index, Item in pairs(Selection.Items) do
+ -- Check and return item presence in index
+ return Selection.ItemIndex[Item];
- -- Return the index if a match is found
- if Item == Needle then
- return Index;
- end;
-
- end;
-
- -- Return `nil` if no match is found
- return nil;
end;
function Selection.Add(Items, RegisterHistory)
-- Adds the given items to the selection
- local SelectableItems = {};
+ -- Get core API
+ local Core = GetCore();
-- Go through and validate each given item
+ local SelectableItems = {};
for _, Item in pairs(Items) do
-- Make sure each item is valid and not already selected
- if GetCore().IsSelectable(Item) and not Selection.Find(Item) then
-
- -- Queue each part to be added into the selection
+ if Core.IsSelectable(Item) and not Selection.ItemIndex[Item] then
table.insert(SelectableItems, Item);
-
end;
end;
- local OldSelection = Support.CloneTable(Selection.Items);
+ local OldSelection = Selection.Items;
-- Go through the valid new selection items
for _, Item in pairs(SelectableItems) do
-- Add each valid item to the selection
- table.insert(Selection.Items, Item);
-
- -- Add a selection box
- CreateSelectionBox(Item);
+ Selection.ItemIndex[Item] = true;
-- Deselect items that are destroyed
Listeners[Item] = Item.AncestryChanged:connect(function (Object, Parent)
@@ -75,11 +63,17 @@ function Selection.Add(Items, RegisterHistory)
end;
+ -- Update selected item list
+ Selection.Items = Support.Keys(Selection.ItemIndex);
+
-- Create a history record for this selection change, if requested
if RegisterHistory and #SelectableItems > 0 then
TrackSelectionChange(OldSelection);
end;
+ -- Create selection boxes for the selection
+ CreateSelectionBoxes(SelectableItems);
+
-- Fire relevant events
Selection.ItemsAdded:fire(SelectableItems);
Selection.Changed:fire();
@@ -89,28 +83,24 @@ end;
function Selection.Remove(Items, RegisterHistory)
-- Removes the given items from the selection
- local DeselectableItems = {};
-
-- Go through and validate each given item
+ local DeselectableItems = {};
for _, Item in pairs(Items) do
-- Make sure each item is actually selected
- if Selection.Find(Item) then
+ if Selection.IsSelected(Item) then
table.insert(DeselectableItems, Item);
end;
end;
- local OldSelection = Support.CloneTable(Selection.Items);
+ local OldSelection = Selection.Items;
-- Go through the valid deselectable items
for _, Item in pairs(DeselectableItems) do
- -- Clear item's selection box
- RemoveSelectionBox(Item);
-
-- Remove item from selection
- table.remove(Selection.Items, Selection.Find(Item));
+ Selection.ItemIndex[Item] = nil;
-- Stop tracking item's parent
Listeners[Item]:disconnect();
@@ -118,6 +108,12 @@ function Selection.Remove(Items, RegisterHistory)
end;
+ -- Remove selection boxes from deselected items
+ RemoveSelectionBoxes(DeselectableItems);
+
+ -- Update selected item list
+ Selection.Items = Support.Keys(Selection.ItemIndex);
+
-- Create a history record for this selection change, if requested
if RegisterHistory and #DeselectableItems > 0 then
TrackSelectionChange(OldSelection);
@@ -155,7 +151,7 @@ function Selection.SetFocus(Item)
-- Selects `Item` as the focused selection item
-- Make sure the item is selected or is `nil`
- if not Selection.Find(Item) and Item ~= nil then
+ if not Selection.IsSelected(Item) and Item ~= nil then
return;
end;
@@ -189,47 +185,72 @@ function GetCore()
return require(script.Parent.Core);
end;
-function CreateSelectionBox(Item)
- -- Creates a SelectionBox for the given item
+function CreateSelectionBoxes(Items)
+ -- Creates a SelectionBox for each given item
+
+ -- Get the core API
+ local Core = GetCore();
-- Only create selection boxes if in tool mode
- if GetCore().Mode ~= 'Tool' then
+ if Core.Mode ~= 'Tool' then
return;
end;
- -- Avoid duplicate selection boxes
- if Selection.Outlines[Item] then
- return;
- end;
+ -- Track new selection boxes
+ local SelectionBoxes = {};
+
+ -- Create an outline for each part
+ for _, Item in pairs(Items) do
+
+ -- Avoid duplicate selection boxes
+ if not Selection.Outlines[Item] then
+
+ -- Create the selection box
+ local SelectionBox = Instance.new 'SelectionBox';
+ SelectionBox.Name = 'BTSelectionBox';
+ SelectionBox.Color = Selection.Color;
+ SelectionBox.Adornee = Item;
+ SelectionBox.LineThickness = 0.025;
+ SelectionBox.Transparency = 0.5;
- -- Create the selection box
- local SelectionBox = RbxUtility.Create 'SelectionBox' {
- Name = 'BTSelectionBox';
- Color = Selection.Color;
- Adornee = Item;
- LineThickness = 0.025;
- Transparency = 0.5;
- };
+ -- Register the outline
+ Selection.Outlines[Item] = SelectionBox;
+ table.insert(SelectionBoxes, SelectionBox);
- -- Register the selection box
- SelectionBox.Parent = GetCore().UIContainer;
- Selection.Outlines[Item] = SelectionBox;
+ end;
+
+ end;
+
+ -- Parent the selection boxes
+ for _, SelectionBox in pairs(SelectionBoxes) do
+ SelectionBox.Parent = Core.UIContainer;
+ end;
end;
-function RemoveSelectionBox(Item)
+function RemoveSelectionBoxes(Items)
-- Removes the given item's selection box
- -- Get the item's selection box
- local SelectionBox = Selection.Outlines[Item];
-
- -- Remove the selection box if found
- if SelectionBox then
- SelectionBox:Destroy();
+ -- Only proceed if in tool mode
+ if GetCore().Mode ~= 'Tool' then
+ return;
end;
- -- Deregister the selection box
- Selection.Outlines[Item] = nil;
+ -- Remove each item's outline
+ for _, Item in pairs(Items) do
+
+ -- Get the item's selection box
+ local SelectionBox = Selection.Outlines[Item];
+
+ -- Remove the selection box if found
+ if SelectionBox then
+ SelectionBox:Destroy();
+ end;
+
+ -- Deregister the selection box
+ Selection.Outlines[Item] = nil;
+
+ end;
end;
@@ -332,7 +353,7 @@ function TrackSelectionChange(OldSelection)
History.Add({
Before = OldSelection;
- After = Support.CloneTable(Selection.Items);
+ After = Selection.Items;
Unapply = function (HistoryRecord)
-- Reverts this change
diff --git a/TargetingModule.lua b/TargetingModule.lua
index ef0e8ec..f9500e1 100644
--- a/TargetingModule.lua
+++ b/TargetingModule.lua
@@ -10,23 +10,27 @@ TargetingModule.TargetChanged = RbxUtility.CreateSignal();
function TargetingModule.EnableTargeting()
-- Begin targeting parts from the mouse
+ -- Get core API
+ local Core = GetCore();
+
+ -- Get current mouse
Mouse = GetCore().Mouse;
-- Listen for target changes
- GetCore().Connections.Targeting = Mouse.Move:connect(TargetingModule.UpdateTarget);
+ Core.Connections.Targeting = Mouse.Move:connect(TargetingModule.UpdateTarget);
-- Listen for target clicks
- GetCore().Connections.Selecting = Mouse.Button1Up:connect(TargetingModule.SelectTarget);
+ Core.Connections.Selecting = Mouse.Button1Up:connect(TargetingModule.SelectTarget);
-- Listen for 2D selection
- GetCore().Connections.RectSelectionStarted = Mouse.Button1Down:connect(TargetingModule.StartRectangleSelecting);
- GetCore().Connections.RectSelectionFinished = Support.AddUserInputListener('Ended', 'MouseButton1', true, TargetingModule.FinishRectangleSelecting);
+ Core.Connections.RectSelectionStarted = Mouse.Button1Down:connect(TargetingModule.StartRectangleSelecting);
+ Core.Connections.RectSelectionFinished = Support.AddUserInputListener('Ended', 'MouseButton1', true, TargetingModule.FinishRectangleSelecting);
-- Hide target box when tool is unequipped
- GetCore().Connections.HideTargetBoxOnDisable = GetCore().Disabling:connect(TargetingModule.HighlightTarget);
+ Core.Connections.HideTargetBoxOnDisable = Core.Disabling:connect(TargetingModule.HighlightTarget);
-- Cancel any ongoing selection when tool is unequipped
- GetCore().Connections.CancelSelectionOnDisable = GetCore().Disabling:connect(TargetingModule.CancelRectangleSelecting);
+ Core.Connections.CancelSelectionOnDisable = Core.Disabling:connect(TargetingModule.CancelRectangleSelecting);
end;
@@ -73,7 +77,7 @@ function TargetingModule.SelectTarget()
end;
-- Focus on clicked, selected item
- if not Selection.Multiselecting and Selection.Find(Target) then
+ if not Selection.Multiselecting and Selection.IsSelected(Target) then
Selection.SetFocus(Target);
return;
end;
@@ -85,7 +89,7 @@ function TargetingModule.SelectTarget()
end;
-- Unselect clicked, selected item if multiselection is enabled
- if Selection.Multiselecting and Selection.Find(Target) then
+ if Selection.Multiselecting and Selection.IsSelected(Target) then
Selection.Remove({ Target }, true);
return;
end;
@@ -240,9 +244,9 @@ function TargetingModule.FinishRectangleSelecting()
end;
TargetingModule.TargetChanged:connect(function (Target)
-
+
-- Hide target box if no/unselectable target
- if not Target or not GetCore().IsSelectable(Target) or GetCore().Selection.Find(Target) then
+ if not Target or not GetCore().IsSelectable(Target) or GetCore().Selection.IsSelected(Target) then
TargetingModule.HighlightTarget(nil);
-- Show target outline if target is selectable
diff --git a/tools/Lighting.lua b/tools/Lighting.lua
index 393012b..1f6c62a 100644
--- a/tools/Lighting.lua
+++ b/tools/Lighting.lua
@@ -90,7 +90,7 @@ function EnableSurfaceClickSelection(LightType)
-- Add the new click connection
Connections.SurfaceClickSelection = UserInputService.InputEnded:connect(function (Input, GameProcessedEvent)
- if not GameProcessedEvent and Input.UserInputType == Enum.UserInputType.MouseButton1 and Selection.Find(Core.Mouse.Target) then
+ if not GameProcessedEvent and Input.UserInputType == Enum.UserInputType.MouseButton1 and Selection.IsSelected(Core.Mouse.Target) then
SetSurface(LightType, Core.Mouse.TargetSurface);
end;
end);
@@ -155,7 +155,7 @@ function EnableLightSettingsUI(LightSettingsUI)
-- Enable light type-specific features
if LightType == 'SpotLight' or LightType == 'SurfaceLight' then
-
+
-- Create a surface selection dropdown
Surfaces = { 'Top', 'Bottom', 'Front', 'Back', 'Left', 'Right' };
local SurfaceDropdown = Core.Cheer(Options.SideOption.Dropdown).Start(Surfaces, '', function (Surface)
@@ -292,7 +292,7 @@ function CloseLightOptions(Exception)
),
Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true
);
-
+
-- Make sure to not resize the exempt light type UI
if not Exception or Exception and LightType ~= Exception then
@@ -415,7 +415,7 @@ function UpdateUI()
-- Update the surface dropdown input
local Face = Support.IdentifyCommonProperty(Lights, 'Face');
SideDropdown.SetOption(Face and Face.Name or '*');
-
+
end;
-- Update special color input
diff --git a/tools/Move.lua b/tools/Move.lua
index bfc7613..60044de 100644
--- a/tools/Move.lua
+++ b/tools/Move.lua
@@ -183,7 +183,7 @@ function UpdateUI()
local CommonY = Support.IdentifyCommonItem(YVariations);
local CommonZ = Support.IdentifyCommonItem(ZVariations);
- -- Shortcuts to indicators
+ -- Shortcuts to indicators
local XIndicator = MoveTool.UI.Info.Center.X.TextBox;
local YIndicator = MoveTool.UI.Info.Center.Y.TextBox;
local ZIndicator = MoveTool.UI.Info.Center.Z.TextBox;
@@ -244,7 +244,7 @@ local AxisMultipliers = {
function AttachHandles(Part, Autofocus)
-- Creates and attaches handles to `Part`, and optionally automatically attaches to the focused part
-
+
-- Enable autofocus if requested and not already on
if Autofocus and not Connections.AutofocusHandle then
Connections.AutofocusHandle = Selection.FocusChanged:connect(function ()
@@ -638,7 +638,7 @@ function TrackChange()
Parts = Support.CloneTable(Selection.Items);
BeforeCFrame = {};
AfterCFrame = {};
-
+
Unapply = function (Record)
-- Reverts this change
@@ -723,7 +723,7 @@ function EnableDragging()
end;
-- Select the target if it's not selected
- if not Selection.Find(Core.Mouse.Target) then
+ if not Selection.IsSelected(Core.Mouse.Target) then
Selection.Replace({ Core.Mouse.Target }, true);
end;
@@ -1036,13 +1036,14 @@ end;
function TranslatePartsRelativeToPart(BasePart, InitialState, Parts)
-- Moves the given parts to BasePart's current position, with their original offset from it
- for _, Part in pairs(Parts) do
+ -- Get focused part's position for offsetting
+ local RelativeTo = InitialState[BasePart].CFrame:inverse();
- -- Calculate the focused part's position
- local RelativeTo = InitialState[BasePart].CFrame;
+ -- Calculate offset and move each part
+ for _, Part in pairs(Parts) do
-- Calculate how far apart we should be from the focused part
- local Offset = RelativeTo:toObjectSpace(InitialState[Part].CFrame);
+ local Offset = RelativeTo * InitialState[Part].CFrame;
-- Move relative to the focused part by this part's offset from it
Part.CFrame = BasePart.CFrame * Offset;
diff --git a/tools/Paint.lua b/tools/Paint.lua
index a032d56..5778b4c 100644
--- a/tools/Paint.lua
+++ b/tools/Paint.lua
@@ -254,7 +254,7 @@ function EnableClickPainting()
-- Watch out for clicks on selected parts
Connections.ClickPainting = Selection.FocusChanged:connect(function (Part)
- if Selection.Find(Core.Mouse.Target) then
+ if Selection.IsSelected(Core.Mouse.Target) then
-- Paint the selected parts
PaintParts();
diff --git a/tools/Resize.lua b/tools/Resize.lua
index e29bd77..c6ff1c5 100644
--- a/tools/Resize.lua
+++ b/tools/Resize.lua
@@ -756,7 +756,7 @@ function StartSnapping()
-- Only enable corner snapping
SnapTracking.TrackEdgeMidpoints = false;
SnapTracking.TrackFaceCentroids = false;
- SnapTracking.TargetFilter = Selection.Find;
+ SnapTracking.TargetFilter = Selection.IsSelected;
-- Trigger the PointSnapped event when a new point is snapped
SnapTracking.StartTracking(function (NewPoint)
diff --git a/tools/Surface.lua b/tools/Surface.lua
index b946cf0..34752d9 100644
--- a/tools/Surface.lua
+++ b/tools/Surface.lua
@@ -173,7 +173,7 @@ function UpdateUI()
end;
end;
-
+
-- Identify common surface type in selection
local CommonSurfaceType = Support.IdentifyCommonItem(SurfaceTypeVariations);
@@ -215,7 +215,7 @@ function SetSurfaceType(SurfaceType)
Part.BackSurface = SurfaceType;
Part.LeftSurface = SurfaceType;
Part.RightSurface = SurfaceType;
-
+
-- Change specific selected surface
else
Part[SurfaceTool.Surface .. 'Surface'] = SurfaceType;
@@ -233,7 +233,7 @@ function EnableSurfaceSelection()
-- Watch out for clicks on selected parts
Connections.SurfaceSelection = Selection.FocusChanged:connect(function (Part)
- if Selection.Find(Core.Mouse.Target) then
+ if Selection.IsSelected(Core.Mouse.Target) then
-- Set the surface option to the target surface
SetSurface(Core.Mouse.TargetSurface.Name);
@@ -302,7 +302,7 @@ function TrackChange()
Surfaces.Back = Part.BackSurface;
Surfaces.Left = Part.LeftSurface;
Surfaces.Right = Part.RightSurface;
-
+
-- Record specific selected surface
else
Surfaces[SurfaceTool.Surface] = Part[SurfaceTool.Surface .. 'Surface'];
@@ -336,7 +336,7 @@ function RegisterChange()
Surfaces.Back = Part.BackSurface;
Surfaces.Left = Part.LeftSurface;
Surfaces.Right = Part.RightSurface;
-
+
-- Record specific selected surface
else
Surfaces[SurfaceTool.Surface] = Part[SurfaceTool.Surface .. 'Surface'];
diff --git a/tools/Texture.lua b/tools/Texture.lua
index 99d03f9..06227a2 100644
--- a/tools/Texture.lua
+++ b/tools/Texture.lua
@@ -145,7 +145,7 @@ function EnableSurfaceClickSelection()
-- Add the new click connection
Connections.SurfaceClickSelection = UserInputService.InputEnded:connect(function (Input, GameProcessedEvent)
- if not GameProcessedEvent and Input.UserInputType == Enum.UserInputType.MouseButton1 and Selection.Find(Core.Mouse.Target) then
+ if not GameProcessedEvent and Input.UserInputType == Enum.UserInputType.MouseButton1 and Selection.IsSelected(Core.Mouse.Target) then
SetFace(Core.Mouse.TargetSurface);
end;
end);
From 451570ede934ebbdda135426a62bab74f1290108 Mon Sep 17 00:00:00 2001
From: Robert Chiquini
Date: Tue, 11 Apr 2017 07:51:01 -0700
Subject: [PATCH 2/3] Catch handle releases at all times in Move, Resize, &
Rotate tools
This change moves logic for finalizing mouse-involving operations
from outside of temporary connections, in order to prevent issues
where parts are left in a mid-operation state because the tool was
switched or disabled too early.
Signed-off-by: Robert Chiquini
---
tools/Move.lua | 93 +++++++++++++++++++++++-----------------------
tools/Resize.lua | 97 +++++++++++++++++++++++++-----------------------
tools/Rotate.lua | 62 +++++++++++++++----------------
3 files changed, 125 insertions(+), 127 deletions(-)
diff --git a/tools/Move.lua b/tools/Move.lua
index 60044de..a7e2275 100644
--- a/tools/Move.lua
+++ b/tools/Move.lua
@@ -65,6 +65,19 @@ function ClearConnections()
end;
+function ClearConnection(ConnectionKey)
+ -- Clears the given specific connection
+
+ local Connection = Connections[ConnectionKey];
+
+ -- Disconnect the connection if it exists
+ if Connections[ConnectionKey] then
+ Connection:disconnect();
+ Connections[ConnectionKey] = nil;
+ end;
+
+end;
+
function ShowUI()
-- Creates and reveals the UI
@@ -253,8 +266,7 @@ function AttachHandles(Part, Autofocus)
-- Disable autofocus if not requested and on
elseif not Autofocus and Connections.AutofocusHandle then
- Connections.AutofocusHandle:disconnect();
- Connections.AutofocusHandle = nil;
+ ClearConnection 'AutofocusHandle';
end;
-- Just attach and show the handles if they already exist
@@ -277,7 +289,6 @@ function AttachHandles(Part, Autofocus)
-- Prepare for moving parts when the handle is clicked
------------------------------------------------------
- local InitialState = {};
local AreaPermissions;
Handles.MouseButton1Down:connect(function ()
@@ -299,36 +310,6 @@ function AttachHandles(Part, Autofocus)
AreaPermissions = Security.GetPermissions(Security.GetSelectionAreas(Selection.Items), Core.Player);
end;
- ------------------------------------------------------
- -- Finalize changes to parts when the handle is let go
- ------------------------------------------------------
-
- Connections.HandleRelease = UserInputService.InputEnded:connect(function (InputInfo, GameProcessedEvent)
-
- -- Make sure this was button 1 being released, and dragging is ongoing
- if not HandleDragging or (InputInfo.UserInputType ~= Enum.UserInputType.MouseButton1) then
- return;
- end;
-
- -- Disable dragging
- HandleDragging = false;
-
- -- Clear this connection to prevent it from firing again
- Connections.HandleRelease:disconnect();
- Connections.HandleRelease = nil;
-
- -- Make joints, restore original anchor and collision states
- for _, Part in pairs(Selection.Items) do
- Part:MakeJoints();
- Part.CanCollide = InitialState[Part].CanCollide;
- Part.Anchored = InitialState[Part].Anchored;
- end;
-
- -- Register the change
- RegisterChange();
-
- end);
-
end);
------------------------------------------
@@ -363,6 +344,32 @@ function AttachHandles(Part, Autofocus)
end;
+-- Finalize changes to parts when the handle is let go
+Support.AddUserInputListener('Ended', 'MouseButton1', true, function (Input)
+
+ -- Ensure handle dragging is ongoing
+ if not HandleDragging then
+ return;
+ end;
+
+ -- Disable dragging
+ HandleDragging = false;
+
+ -- Clear this connection to prevent it from firing again
+ ClearConnection 'HandleRelease';
+
+ -- Make joints, restore original anchor and collision states
+ for _, Part in pairs(Selection.Items) do
+ Part:MakeJoints();
+ Part.CanCollide = InitialState[Part].CanCollide;
+ Part.Anchored = InitialState[Part].Anchored;
+ end;
+
+ -- Register the change
+ RegisterChange();
+
+end);
+
function HideHandles()
-- Hides the resizing handles
@@ -375,11 +382,8 @@ function HideHandles()
Handles.Visible = false;
Handles.Parent = nil;
- -- Disable handle autofocus if enabled
- if Connections.AutofocusHandle then
- Connections.AutofocusHandle:disconnect();
- Connections.AutofocusHandle = nil;
- end;
+ -- Disable handle autofocus
+ ClearConnection 'AutofocusHandle';
end;
@@ -741,7 +745,7 @@ function EnableDragging()
SetUpDragging(DragStartTarget, SnapTracking.Enabled and SnappedPoint or nil);
-- Disable watching for potential dragging
- Connections.WatchForDrag:disconnect();
+ ClearConnection 'WatchForDrag';
end;
@@ -757,10 +761,7 @@ function EnableDragging()
DragStartTarget = nil;
-- Disconnect dragging-start listeners
- if Connections.WatchForDrag then
- Connections.WatchForDrag:disconnect();
- Connections.WatchForDrag = nil;
- end;
+ ClearConnection 'WatchForDrag';
end);
@@ -1064,13 +1065,11 @@ function FinishDragging()
Dragging = false;
-- Stop the dragging action
- Connections.Drag:disconnect()
- Connections.Drag = nil;
+ ClearConnection 'Drag';
-- Stop, clean up snapping point tracking
SnapTracking.StopTracking();
- Connections.DragSnapping:disconnect();
- Connections.DragSnapping = nil;
+ ClearConnection 'DragSnapping';
-- Restore the original state of each part
for _, Part in pairs(Selection.Items) do
diff --git a/tools/Resize.lua b/tools/Resize.lua
index c6ff1c5..84afbb8 100644
--- a/tools/Resize.lua
+++ b/tools/Resize.lua
@@ -42,6 +42,7 @@ function ResizeTool.Unequip()
HideHandles();
ClearConnections();
SnapTracking.StopTracking();
+ FinishSnapping();
end;
@@ -264,7 +265,6 @@ function ShowHandles()
-- Prepare for resizing parts when the handle is clicked
--------------------------------------------------------
- local InitialState = {};
local AreaPermissions;
Handles.MouseButton1Down:connect(function ()
@@ -286,38 +286,6 @@ function ShowHandles()
AreaPermissions = Security.GetPermissions(Security.GetSelectionAreas(Selection.Items), Core.Player);
end;
- ------------------------------------------------------
- -- Finalize changes to parts when the handle is let go
- ------------------------------------------------------
-
- Connections.HandleRelease = UserInputService.InputEnded:connect(function (InputInfo, GameProcessedEvent)
-
- -- Make sure this was button 1 being released, and handle resizing is ongoing
- if not HandleResizing or (InputInfo.UserInputType ~= Enum.UserInputType.MouseButton1) then
- return;
- end;
-
- -- Disable resizing
- HandleResizing = false;
-
- -- Prevent selection
- Core.Targeting.CancelSelecting();
-
- -- Clear this connection to prevent it from firing again
- ClearConnection 'HandleRelease';
-
- -- Make joints, restore original anchor and collision states
- for _, Part in pairs(Selection.Items) do
- Part:MakeJoints();
- Part.CanCollide = InitialState[Part].CanCollide;
- Part.Anchored = InitialState[Part].Anchored;
- end;
-
- -- Register the change
- RegisterChange();
-
- end);
-
end);
------------------------------------------
@@ -359,6 +327,36 @@ function ShowHandles()
end;
+
+-- Finalize changes to parts when the handle is let go
+Support.AddUserInputListener('Ended', 'MouseButton1', true, function (Input)
+
+ -- Ensure handle resizing is ongoing
+ if not HandleResizing then
+ return;
+ end;
+
+ -- Disable resizing
+ HandleResizing = false;
+
+ -- Prevent selection
+ Core.Targeting.CancelSelecting();
+
+ -- Clear this connection to prevent it from firing again
+ ClearConnection 'HandleRelease';
+
+ -- Make joints, restore original anchor and collision states
+ for _, Part in pairs(Selection.Items) do
+ Part:MakeJoints();
+ Part.CanCollide = InitialState[Part].CanCollide;
+ Part.Anchored = InitialState[Part].Anchored;
+ end;
+
+ -- Register the change
+ RegisterChange();
+
+end);
+
function HideHandles()
-- Hides the resizing handles
@@ -938,32 +936,37 @@ function StartSnapping()
end);
- -- Listen for the end of the snapping
- Connections.SnapDragEnd = Support.AddUserInputListener('Ended', 'MouseButton1', true, function (Input)
+end;
- -- If destination stage was reached, restore the selection's original state
- if SnappingStage == 'Destination' then
- for Part, PartState in pairs(SnappingStartSelectionState) do
- Part:MakeJoints();
- Part.CanCollide = PartState.CanCollide;
- Part.Anchored = PartState.Anchored;
- end;
- end;
+-- Stop snapping whenever mouse is released
+Support.AddUserInputListener('Ended', 'MouseButton1', true, function (Input)
- -- Finish snapping
- FinishSnapping();
+ -- Ensure snapping is ongoing
+ if not SnappingStage then
+ return;
+ end;
- end);
+ -- Finish snapping
+ FinishSnapping();
+
+end);
-end;
function FinishSnapping()
+ -- Cleans up and finalizes the snapping operation
-- Ensure snapping is ongoing
if not SnappingStage then
return;
end;
+ -- Restore the selection's original state
+ for Part, PartState in pairs(SnappingStartSelectionState) do
+ Part:MakeJoints();
+ Part.CanCollide = PartState.CanCollide;
+ Part.Anchored = PartState.Anchored;
+ end;
+
-- Disable any snapping stage
SnappingStage = nil;
diff --git a/tools/Rotate.lua b/tools/Rotate.lua
index f58b0e8..88a575e 100644
--- a/tools/Rotate.lua
+++ b/tools/Rotate.lua
@@ -273,7 +273,6 @@ function AttachHandles(Part, Autofocus)
-- Prepare for rotating parts when the handle is clicked
--------------------------------------------------------
- local InitialState = {};
local AreaPermissions;
Handles.MouseButton1Down:connect(function ()
@@ -305,38 +304,6 @@ function AttachHandles(Part, Autofocus)
PivotPoint = InitialState[Selection.Focus].CFrame;
end;
- ------------------------------------------------------
- -- Finalize changes to parts when the handle is let go
- ------------------------------------------------------
-
- Connections.HandleRelease = UserInputService.InputEnded:connect(function (InputInfo, GameProcessedEvent)
-
- -- Make sure this was button 1 being released, and rotating is ongoing
- if not HandleRotating or (InputInfo.UserInputType ~= Enum.UserInputType.MouseButton1) then
- return;
- end;
-
- -- Prevent selection
- Core.Targeting.CancelSelecting();
-
- -- Disable rotating
- HandleRotating = false;
-
- -- Clear this connection to prevent it from firing again
- ClearConnection 'HandleRelease';
-
- -- Make joints, restore original anchor and collision states
- for _, Part in pairs(Selection.Items) do
- Part:MakeJoints();
- Part.CanCollide = InitialState[Part].CanCollide;
- Part.Anchored = InitialState[Part].Anchored;
- end;
-
- -- Register the change
- RegisterChange();
-
- end);
-
end);
------------------------------------------
@@ -375,6 +342,35 @@ function AttachHandles(Part, Autofocus)
end;
+-- Finalize changes to parts when the handle is let go
+Support.AddUserInputListener('Ended', 'MouseButton1', true, function (Input)
+
+ -- Make sure rotating is ongoing
+ if not HandleRotating then
+ return;
+ end;
+
+ -- Prevent selection
+ Core.Targeting.CancelSelecting();
+
+ -- Disable rotating
+ HandleRotating = false;
+
+ -- Clear this connection to prevent it from firing again
+ ClearConnection 'HandleRelease';
+
+ -- Make joints, restore original anchor and collision states
+ for _, Part in pairs(Selection.Items) do
+ Part:MakeJoints();
+ Part.CanCollide = InitialState[Part].CanCollide;
+ Part.Anchored = InitialState[Part].Anchored;
+ end;
+
+ -- Register the change
+ RegisterChange();
+
+end);
+
function HideHandles()
-- Hides the resizing handles
From 00801b9a78bded2c16d42a2806eb9668f4fe9754 Mon Sep 17 00:00:00 2001
From: Robert Chiquini
Date: Tue, 11 Apr 2017 16:01:24 -0700
Subject: [PATCH 3/3] Update asset builds to 2.1.0
Signed-off-by: Robert Chiquini
---
build/Building Tools by F3X (plugin).rbxmx | 2715 ++++++++++----------
build/Building Tools by F3X.rbxmx | 2635 +++++++++----------
2 files changed, 2716 insertions(+), 2634 deletions(-)
diff --git a/build/Building Tools by F3X (plugin).rbxmx b/build/Building Tools by F3X (plugin).rbxmx
index 1b01426..72786f5 100644
--- a/build/Building Tools by F3X (plugin).rbxmx
+++ b/build/Building Tools by F3X (plugin).rbxmx
@@ -1,11 +1,11 @@
null
nil
- -
+
-
Building Tools by F3X
-
-
+
-
false
-0.5
@@ -76,7 +76,7 @@
0.800000012
-
-
+
-
4294967295
5
@@ -85,7 +85,7 @@
0
- -
+
-
4294967295
2
@@ -94,7 +94,7 @@
0
- -
+
-
4294967295
3
@@ -103,7 +103,7 @@
0
- -
+
-
4294967295
0
@@ -112,7 +112,7 @@
0
- -
+
-
4294967295
1
@@ -121,7 +121,7 @@
0
- -
+
-
4294967295
4
@@ -131,17 +131,17 @@
- -
+
-
Version
- 2.0.4
+ 2.1.0
- -
+
-
SupportLibrary
- {3B9C733D-B278-4AF3-BD73-0B2B8F2F19B6}
+ {D9556558-E69B-4CD7-9D50-507908257A86}
- -
+
-
SecurityModule
- {3DDB9821-CE15-4B40-96CC-A55AA6A0799A}
+ {3401EA9C-1E9D-46EB-9EDB-D8C28B9B075A}
- -
+
-
Region by AxisAngle
- {A7098394-ADCC-42BC-8CF8-721A4E28C48A}
+ {6B95E6D0-B586-444C-B188-EEB7C7A5730E}
- -
+
-
false
@@ -1818,11 +1818,11 @@ end;
-- Expose GetLibraries function
_G.GetLibraries = GetLibraries;]]>
-
-
+
-
F3X/SupportLibrary@1.0.0
- {56910557-0736-4D62-BBD6-096A11CA38C4}
+ {946A4CC1-6686-4565-8C0C-F43458BE8291}
-
-
+
-
Metadata
- {DFA05253-9F57-4AD2-810F-1B8F6F6603D7}
+ {0DFB0D00-B07F-4B3B-A6C9-323C815AA535}
- -
+
-
F3X/Cheer@0.0.1
- {B78F7E1B-6DC5-4724-9A36-69A8C62BF466}
+ {C8D0DAD5-92DD-4750-A047-343030A539F5}
-
-
+
-
SupportLibrary
- {59DE0AAC-A2F9-42E6-90AE-41CE14C10416}
+ {2CDD67FF-2CDB-4C67-BBD4-57C0CBB5A70E}
- -
+
-
Metadata
- {4CA35FAB-5CCC-45F9-BA2E-EA8BF37BF4D7}
+ {2E19CEB9-BF5B-43F9-BA77-1DA1CC3DAFAC}
- -
+
-
F3X/Try@1.0.0
- {C9142536-A61B-499E-9BF4-F36E3D790E33}
+ {38EC51E1-C3FF-48F8-B733-2BD0FFD6C100}
-
-
+
-
SupportLibrary
@@ -5232,11 +5232,11 @@ end;
return SupportLibrary;]]>
- -
+
-
Metadata
- {5B1FFCCF-5CB0-4338-B6A4-DEE602998C87}
+ {F020D70C-F566-46EC-8243-A067D75DC97A}
- -
+
-
SerializationModule
- {A8AC26D7-FAE7-44FF-8012-1BDCE2C60108}
+ {9191D0B1-4975-4981-A4FB-CAE28F816E67}
- -
+
-
SyncAPI
-
-
+
-
SyncModule
- {185C63EE-A1E9-412F-BF5F-417C8DDC25F7}
+ {8618E884-723D-4B16-831F-49569C0FA7AD}
- -
+
-
ServerEndpoint
-
-
+
-
false
ServerEndpointScript
- {D444E596-4AB5-4706-8E5D-2AEEE8624027}
+ {A636FC52-37C6-4282-983D-9055AA44EA23}
- -
+
-
false
@@ -7269,22 +7269,22 @@ end;]]>
- -
+
-
Loaded
false
-
-
+
-
ComponentCount
0
-
-
+
-
false
ComponentCounter
- {FBD76AE5-1813-4620-B28F-0C5012254C16}
+ {FB5BBEC8-7693-47F9-8C70-7743534EAA27}
- -
+
-
false
@@ -7322,11 +7322,11 @@ Indicator.Value = true;]]>
- -
+
-
Assets
- {E4FD0134-1BB0-44E3-90F6-2D2B49C39A0C}
+ {8386F054-27DA-48D3-874D-4DB007D7AC97}
return Assets;]]>
- -
+
-
Core
- {D1D7CD74-FBF6-4C28-B6D2-A6A58313E257}
+ {3F7B7FC9-3744-4313-8368-025A623568D8}
- -
+
-
false
@@ -8068,15 +8077,15 @@ local Core = require(Tool:WaitForChild 'Core');
require(Tool.Tools.CoreToolLoader);]]>
- -
+
-
Tools
-
-
+
-
MoveTool
- {82360781-7673-4323-AB3E-AC34A6F2A311}
+ {2021DF9B-3BD7-43FE-8924-64425F88CD6D}
- -
+
-
ResizeTool
- {19FD1962-6261-4080-AC86-0BFB98FDB40D}
+ {6229027D-CD04-4E61-A4A7-2F9FBC02A02E}
- -
+
-
RotateTool
- {D8D1A850-A8F6-40A8-A073-A861D4185523}
+ {F5DD8618-4AD2-446C-9A05-59461E6E6D8E}
- -
+
-
PaintTool
- {A3455F9B-2BB9-4113-947A-0BFE1C08C2A3}
+ {62FCFCF7-500D-4FD8-83F5-417690A02F2A}
-
-
+
-
Colors
- {995577E2-6193-427F-876D-9CDFEACF3E74}
+ {C77AD9DB-8BD6-48BA-B5AF-263A23F16A92}
- -
+
-
MaterialTool
- {7468CFF9-ED7E-4663-8974-DA3D503D40A9}
+ {2747D86F-B1CA-4529-B354-5A86C124E911}
- -
+
-
SurfaceTool
- {62B9775B-0545-49AF-A5DC-890C45D0FB71}
+ {99123F42-467B-421A-AFFB-3A545AC944A8}
- -
+
-
AnchorTool
- {6AC72367-BF28-4729-89E8-706C53D67D6A}
+ {15498961-470C-4B54-A827-55C5C8ED6B09}
- -
+
-
WeldTool
- {CAB289F8-788B-4958-A998-DC5CB7DA7DF1}
+ {7BA551AA-3379-4CFA-867D-438842125D5B}
- -
+
-
TextureTool
- {A95E3D63-F4EF-4A0A-A3B9-921B60840F50}
+ {5BFFDB99-730E-438C-89C9-52DF3E4BD08F}
- -
+
-
MeshTool
- {E0407536-C797-4A89-AABC-D6D77D03087F}
+ {0A200B0A-52D2-4290-A89F-5E49D32B2C9A}
- -
+
-
NewPartTool
- {43D159F3-8D8C-45DC-BFE0-1F54602DD688}
+ {DDF5E457-D488-469F-A321-6C84AD4A60CA}
- -
+
-
CollisionTool
- {F62F31F5-D5A7-4AEA-B68A-D014718C6AA9}
+ {CC65B47C-CA64-46BD-A588-52F108ED8266}
- -
+
-
LightingTool
- {E4D77A7B-1674-4A3A-9142-40E4BC33CE75}
+ {6E982A66-92A4-4382-9997-1A3672BBAC8F}
- -
+
-
DecorateTool
- {094F5ED3-553F-46F5-8DD6-BF7159FC80B0}
+ {9CB4F583-E59A-42F4-93DE-7CFF182DA317}
- -
+
-
CoreToolLoader
- {D22B21E9-BBED-4E42-8D0E-91E5A911D82A}
+ {CAA38DE4-A8CA-4882-8F5D-812628B6E3E7}
- -
+
-
HistoryModule
- {EA89A3E5-DCA9-4FA4-8BCB-61DB5C7705AC}
+ {907F8522-3B02-4BC3-A5EF-DCF223C6F3BB}
- -
+
-
SelectionModule
- {E45B8E2E-9E24-40CE-A269-8954B76A6A12}
+ {13D9B62D-3AD6-4348-BF0D-B31495403346}
0 then
TrackSelectionChange(OldSelection);
end;
+ -- Create selection boxes for the selection
+ CreateSelectionBoxes(SelectableItems);
+
-- Fire relevant events
Selection.ItemsAdded:fire(SelectableItems);
Selection.Changed:fire();
@@ -16177,28 +16181,24 @@ end;
function Selection.Remove(Items, RegisterHistory)
-- Removes the given items from the selection
- local DeselectableItems = {};
-
-- Go through and validate each given item
+ local DeselectableItems = {};
for _, Item in pairs(Items) do
-- Make sure each item is actually selected
- if Selection.Find(Item) then
+ if Selection.IsSelected(Item) then
table.insert(DeselectableItems, Item);
end;
end;
- local OldSelection = Support.CloneTable(Selection.Items);
+ local OldSelection = Selection.Items;
-- Go through the valid deselectable items
for _, Item in pairs(DeselectableItems) do
- -- Clear item's selection box
- RemoveSelectionBox(Item);
-
-- Remove item from selection
- table.remove(Selection.Items, Selection.Find(Item));
+ Selection.ItemIndex[Item] = nil;
-- Stop tracking item's parent
Listeners[Item]:disconnect();
@@ -16206,6 +16206,12 @@ function Selection.Remove(Items, RegisterHistory)
end;
+ -- Remove selection boxes from deselected items
+ RemoveSelectionBoxes(DeselectableItems);
+
+ -- Update selected item list
+ Selection.Items = Support.Keys(Selection.ItemIndex);
+
-- Create a history record for this selection change, if requested
if RegisterHistory and #DeselectableItems > 0 then
TrackSelectionChange(OldSelection);
@@ -16243,7 +16249,7 @@ function Selection.SetFocus(Item)
-- Selects `Item` as the focused selection item
-- Make sure the item is selected or is `nil`
- if not Selection.Find(Item) and Item ~= nil then
+ if not Selection.IsSelected(Item) and Item ~= nil then
return;
end;
@@ -16277,47 +16283,72 @@ function GetCore()
return require(script.Parent.Core);
end;
-function CreateSelectionBox(Item)
- -- Creates a SelectionBox for the given item
+function CreateSelectionBoxes(Items)
+ -- Creates a SelectionBox for each given item
+
+ -- Get the core API
+ local Core = GetCore();
-- Only create selection boxes if in tool mode
- if GetCore().Mode ~= 'Tool' then
+ if Core.Mode ~= 'Tool' then
return;
end;
- -- Avoid duplicate selection boxes
- if Selection.Outlines[Item] then
- return;
- end;
+ -- Track new selection boxes
+ local SelectionBoxes = {};
- -- Create the selection box
- local SelectionBox = RbxUtility.Create 'SelectionBox' {
- Name = 'BTSelectionBox';
- Color = Selection.Color;
- Adornee = Item;
- LineThickness = 0.025;
- Transparency = 0.5;
- };
+ -- Create an outline for each part
+ for _, Item in pairs(Items) do
+
+ -- Avoid duplicate selection boxes
+ if not Selection.Outlines[Item] then
+
+ -- Create the selection box
+ local SelectionBox = Instance.new 'SelectionBox';
+ SelectionBox.Name = 'BTSelectionBox';
+ SelectionBox.Color = Selection.Color;
+ SelectionBox.Adornee = Item;
+ SelectionBox.LineThickness = 0.025;
+ SelectionBox.Transparency = 0.5;
- -- Register the selection box
- SelectionBox.Parent = GetCore().UIContainer;
- Selection.Outlines[Item] = SelectionBox;
+ -- Register the outline
+ Selection.Outlines[Item] = SelectionBox;
+ table.insert(SelectionBoxes, SelectionBox);
+
+ end;
+
+ end;
+
+ -- Parent the selection boxes
+ for _, SelectionBox in pairs(SelectionBoxes) do
+ SelectionBox.Parent = Core.UIContainer;
+ end;
end;
-function RemoveSelectionBox(Item)
+function RemoveSelectionBoxes(Items)
-- Removes the given item's selection box
- -- Get the item's selection box
- local SelectionBox = Selection.Outlines[Item];
-
- -- Remove the selection box if found
- if SelectionBox then
- SelectionBox:Destroy();
+ -- Only proceed if in tool mode
+ if GetCore().Mode ~= 'Tool' then
+ return;
end;
- -- Deregister the selection box
- Selection.Outlines[Item] = nil;
+ -- Remove each item's outline
+ for _, Item in pairs(Items) do
+
+ -- Get the item's selection box
+ local SelectionBox = Selection.Outlines[Item];
+
+ -- Remove the selection box if found
+ if SelectionBox then
+ SelectionBox:Destroy();
+ end;
+
+ -- Deregister the selection box
+ Selection.Outlines[Item] = nil;
+
+ end;
end;
@@ -16420,7 +16451,7 @@ function TrackSelectionChange(OldSelection)
History.Add({
Before = OldSelection;
- After = Support.CloneTable(Selection.Items);
+ After = Selection.Items;
Unapply = function (HistoryRecord)
-- Reverts this change
@@ -16444,11 +16475,11 @@ end;
return Selection;]]>
- -
+
-
SnappingModule
- {7A7F3F7D-DB6B-4B1C-90D6-E221EEC993B3}
+ {6B31D07F-DDFD-4374-B798-4B7DC3EB11DE}
- -
+
-
FilterMode
false
-
-
+
-
false
FilterModeEnabler
- {DF4E1777-7B85-4886-9BFF-D14BC07A64E7}
+ {337B8939-C72D-4605-95ED-ECB4C0FE6122}
script.Parent.Value = Workspace.FilteringEnabled;
- -
+
-
BoundingBoxModule
- {EAC88C68-8BF4-4F05-A508-12CC700A8666}
+ {8B65974F-30B0-4FC6-AF4D-93385327981D}
- -
+
-
TargetingModule
- {9ED3863D-5CE8-4F57-B2A1-4DA34A4F49D9}
+ {D7DCED7D-68BB-4010-BE05-78F7D1304731}
- -
+
-
Interfaces
-
-
+
-
true
@@ -17389,7 +17430,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -17428,7 +17469,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -17468,7 +17509,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -17519,7 +17560,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -17571,7 +17612,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -17610,7 +17651,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -17661,7 +17702,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -17700,7 +17741,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -17740,7 +17781,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -17795,7 +17836,7 @@ return TargetingModule;]]>
2
- -
+
-
false
@@ -17856,7 +17897,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -17908,7 +17949,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -17947,7 +17988,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -17987,7 +18028,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -18042,7 +18083,7 @@ return TargetingModule;]]>
2
- -
+
-
false
@@ -18103,7 +18144,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -18156,7 +18197,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -18195,7 +18236,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -18235,7 +18276,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -18288,7 +18329,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -18327,7 +18368,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -18366,7 +18407,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -18406,7 +18447,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -18457,7 +18498,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -18509,7 +18550,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -18548,7 +18589,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -18599,7 +18640,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -18638,7 +18679,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -18678,7 +18719,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -18733,7 +18774,7 @@ return TargetingModule;]]>
2
- -
+
-
false
@@ -18794,7 +18835,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -18846,7 +18887,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -18885,7 +18926,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -18925,7 +18966,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -18980,7 +19021,7 @@ return TargetingModule;]]>
2
- -
+
-
false
@@ -19041,7 +19082,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -19094,7 +19135,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -19133,7 +19174,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -19173,7 +19214,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -19226,7 +19267,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -19265,7 +19306,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -19305,7 +19346,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -19344,7 +19385,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -19384,7 +19425,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -19435,7 +19476,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -19487,7 +19528,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -19526,7 +19567,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -19577,7 +19618,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -19642,7 +19683,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -19682,7 +19723,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -19737,7 +19778,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -19792,7 +19833,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -19832,7 +19873,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -19871,7 +19912,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -19910,7 +19951,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -19961,7 +20002,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -20000,7 +20041,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -20061,7 +20102,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -20101,7 +20142,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -20157,7 +20198,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -20196,7 +20237,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -20247,7 +20288,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -20286,7 +20327,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -20347,7 +20388,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -20387,7 +20428,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -20443,7 +20484,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -20482,7 +20523,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -20533,7 +20574,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -20572,7 +20613,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -20633,7 +20674,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -20673,7 +20714,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -20729,7 +20770,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -20768,7 +20809,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
true
@@ -20832,7 +20873,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -20873,7 +20914,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -20924,7 +20965,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -20963,7 +21004,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -21003,7 +21044,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -21058,7 +21099,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -21109,7 +21150,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -21148,7 +21189,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -21199,7 +21240,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -21264,7 +21305,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -21304,7 +21345,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -21359,7 +21400,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -21414,7 +21455,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -21454,7 +21495,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -21493,7 +21534,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -21532,7 +21573,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -21583,7 +21624,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -21622,7 +21663,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -21683,7 +21724,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -21723,7 +21764,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -21779,7 +21820,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -21818,7 +21859,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -21869,7 +21910,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -21908,7 +21949,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -21969,7 +22010,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -22009,7 +22050,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -22065,7 +22106,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -22104,7 +22145,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
true
@@ -22168,7 +22209,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -22209,7 +22250,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -22260,7 +22301,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -22299,7 +22340,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -22339,7 +22380,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -22392,7 +22433,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -22431,7 +22472,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
true
@@ -22495,7 +22536,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -22536,7 +22577,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -22587,7 +22628,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -22626,7 +22667,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -22666,7 +22707,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -22721,7 +22762,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -22760,7 +22801,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -22811,7 +22852,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -22876,7 +22917,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -22916,7 +22957,7 @@ return TargetingModule;]]>
1
- -
+
-
true
@@ -22971,7 +23012,7 @@ return TargetingModule;]]>
2
- -
+
-
true
@@ -23026,7 +23067,7 @@ return TargetingModule;]]>
2
- -
+
-
false
@@ -23066,7 +23107,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -23105,7 +23146,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -23144,7 +23185,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
true
@@ -23208,7 +23249,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -23249,7 +23290,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -23300,7 +23341,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -23339,7 +23380,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -23379,7 +23420,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -23435,7 +23476,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -23474,7 +23515,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -23513,7 +23554,7 @@ return TargetingModule;]]>
false
1
-
-
+
-
false
@@ -23552,7 +23593,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
true
@@ -23616,7 +23657,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -23655,7 +23696,7 @@ return TargetingModule;]]>
false
2
-
-
+
-
false
@@ -23695,7 +23736,7 @@ return TargetingModule;]]>
2
- -
+
-
false
@@ -23748,7 +23789,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -23812,7 +23853,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -23851,7 +23892,7 @@ return TargetingModule;]]>
false
2
-
-
+
-
false
@@ -23891,7 +23932,7 @@ return TargetingModule;]]>
2
- -
+
-
false
@@ -23944,7 +23985,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -24008,7 +24049,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -24047,7 +24088,7 @@ return TargetingModule;]]>
false
3
-
-
+
-
false
@@ -24087,7 +24128,7 @@ return TargetingModule;]]>
3
- -
+
-
false
@@ -24140,7 +24181,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -24179,7 +24220,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -24218,7 +24259,7 @@ return TargetingModule;]]>
false
2
-
-
+
-
false
@@ -24258,7 +24299,7 @@ return TargetingModule;]]>
2
- -
+
-
false
@@ -24311,7 +24352,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -24366,7 +24407,7 @@ return TargetingModule;]]>
2
- -
+
-
true
@@ -24422,7 +24463,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -24476,7 +24517,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -24527,7 +24568,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -24566,7 +24607,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
true
@@ -24621,7 +24662,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -24661,7 +24702,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -24714,7 +24755,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -24753,7 +24794,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
true
@@ -24817,7 +24858,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -24879,7 +24920,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -24943,7 +24984,7 @@ return TargetingModule;]]>
true
2
-
-
+
-
false
@@ -24983,7 +25024,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -25045,7 +25086,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -25084,7 +25125,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -25135,7 +25176,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -25174,7 +25215,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -25215,7 +25256,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -25268,7 +25309,7 @@ return TargetingModule;]]>
true
2
-
-
+
-
false
@@ -25331,7 +25372,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -25370,7 +25411,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -25421,7 +25462,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -25460,7 +25501,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -25501,7 +25542,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -25554,7 +25595,7 @@ return TargetingModule;]]>
true
2
-
-
+
-
false
@@ -25617,7 +25658,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -25656,7 +25697,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -25707,7 +25748,7 @@ return TargetingModule;]]>
1
- -
+
-
false
@@ -25746,7 +25787,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -25787,7 +25828,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -25840,7 +25881,7 @@ return TargetingModule;]]>
true
2
-
-
+
-
false
@@ -25903,7 +25944,7 @@ return TargetingModule;]]>
- -
+
-
false
@@ -25942,7 +25983,7 @@ return TargetingModule;]]>
true
1
-
-
+
-
false
@@ -25983,7 +26024,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -26037,7 +26078,7 @@ return TargetingModule;]]>
true
2
-
-
+
-
false
@@ -26078,7 +26119,7 @@ return TargetingModule;]]>
- -
+
-
true
@@ -26132,7 +26173,7 @@ return TargetingModule;]]>
true
2
-
-
+
-
false
@@ -26173,7 +26214,7 @@ return TargetingModule;]]>
- -
+
-
[Component]
@@ -26301,7 +26342,7 @@ return Component;]]>
- -
+
-
true
@@ -26340,7 +26381,7 @@ return Component;]]>
true
1
-
-
+
-
false
@@ -26379,7 +26420,7 @@ return Component;]]>
true
1
-
-
+
-
false
@@ -26419,7 +26460,7 @@ return Component;]]>
1
- -
+
-
true
@@ -26474,7 +26515,7 @@ return Component;]]>
1
- -
+
-
true
@@ -26529,7 +26570,7 @@ return Component;]]>
1
- -
+
-
false
@@ -26569,7 +26610,7 @@ return Component;]]>
1
- -
+
-
true
@@ -26634,7 +26675,7 @@ return Component;]]>
1
- -
+
-
false
@@ -26685,7 +26726,7 @@ return Component;]]>
1
- -
+
-
false
@@ -26724,7 +26765,7 @@ return Component;]]>
true
1
-
-
+
-
false
@@ -26763,7 +26804,7 @@ return Component;]]>
true
1
-
-
+
-
false
@@ -26814,7 +26855,7 @@ return Component;]]>
1
- -
+
-
true
@@ -26880,7 +26921,7 @@ return Component;]]>
- -
+
-
false
@@ -26919,7 +26960,7 @@ return Component;]]>
true
1
-
-
+
-
false
@@ -26958,7 +26999,7 @@ return Component;]]>
true
1
-
-
+
-
true
@@ -27012,7 +27053,7 @@ return Component;]]>
2
- -
+
-
false
@@ -27073,7 +27114,7 @@ return Component;]]>
1
- -
+
-
false
@@ -27114,7 +27155,7 @@ return Component;]]>
- -
+
-
false
@@ -27166,7 +27207,7 @@ return Component;]]>
- -
+
-
false
@@ -27205,7 +27246,7 @@ return Component;]]>
true
1
-
-
+
-
false
@@ -27244,7 +27285,7 @@ return Component;]]>
true
1
-
-
+
-
true
@@ -27298,7 +27339,7 @@ return Component;]]>
2
- -
+
-
false
@@ -27359,7 +27400,7 @@ return Component;]]>