null
nil
-
[RBX1]
2.2000001147389412
0
0
0
1
0
0
0
1
0
0
0
1
Workspace
[null]
-
[null]
0
0
13.4481544
13.4481544
1
0
-0
-0
0.707106769
0.707106769
0
-0.707106769
0.707106769
70
0
-0.693981171
-0.693981171
1
0
0
0
1
0
0
0
1
Camera
-
true
-0.5
0.5
0
0
-0.5
0.5
4
0
194
-2
126
-2
1
0
0
0
1
0
0
0
1
true
0.300000012
0.5
-0.5
0.5
0
0
-0.5
0.5
0
0
true
256
Terrain
0
-0.5
0.5
0
0
0
0
0
-0.5
0.5
3
0
0
0
0
0
2044
252
2044
-
0
0
0
1
0
0
0
1
0
0
0
1
NoEventParent
[null]
-
0
0
0
1
0
0
0
1
0
0
0
1
ChildAddedEventParent
[null]
-
0
0
0
1
0
0
0
1
0
0
0
1
ChildAddedEventSelfParent
[null]
-
0
0
0
1
0
0
0
1
0
0
0
1
DescendantAddedEventParent
[null]
-
0
0
0
1
0
0
0
1
0
0
0
1
DescendantAddedEventSelfParent
[null]
-
0
0
0
1
0
0
0
1
0
0
0
1
DescendantRemovingEventParent
[null]
-
0
0
0
1
0
0
0
1
0
0
0
1
ChildRemovedEventParent
[null]
-
0
0
0
1
0
0
0
1
0
0
0
1
NoEventChild
[null]
-
0
0
0
1
0
0
0
1
0
0
0
1
AncestryChangedEventChild
[null]
-
StarterPack
-
true
true
0
0
0
1
0
0
0
1
0
0
0
1
Clone Tool
http://www.watrbx.wtf/asset/?id=73241863
Clone
-
false
-0.5
0.5
0
0
-0.5
0.5
4
0
194
0
0.600000024
0
1
0
0
0
1
0
0
0
1
true
0.5
0.300000012
-0.5
0.5
0
0
-0.5
0.5
0
0
false
256
Handle
0
-0.5
0.5
0
0
0
0
0
-0.5
0.5
3
0
1
0
0
0
1
1
4
1.20000005
2
-
false
CloneScript
-- basic functions
function waitForChild(instance, name)
while not instance:findFirstChild(name) do
instance.ChildAdded:wait()
end
end
function waitForProperty(instance, name)
while not instance[name] do
instance.Changed:wait()
end
end
function getPlayer()
waitForProperty(game.Players,"LocalPlayer")
return game.Players.LocalPlayer
end
-- locals
local RbxStamper = LoadLibrary("RbxStamper")
if not RbxStamper then
print("Error: RbxStamper Library Load Fail! Returning")
return nil
end
local Tool = script.Parent
local stampControl = nil
local stampingCon = nil
local eyeDropperConnection = nil
local eyeDropperMoveConnection = nil
local keyCon = nil
local eyedropperOffGridTolerance = 0.01
local selectionBox = nil
local currentSelection = nil
local Mouse = nil
local currentSelectionColors = {}
local terrainSelectionBox = Instance.new("Part")
terrainSelectionBox.Parent = nil
terrainSelectionBox.formFactor = "Custom"
terrainSelectionBox.Size = Vector3.new(4, 4, 4)
terrainSelectionBox.Archivable = false
terrainSelectionBox.CFrame = CFrame.new()
local selectionBox = Instance.new("SelectionBox")
selectionBox.Name = "CloneSelection"
selectionBox.Color = BrickColor.Green()
selectionBox.Adornee = nil
selectionBox.Archivable = false
waitForChild(script.Parent,"CloneHintGui")
waitForChild(script.Parent.CloneHintGui,"CloneHint")
local hintGui = script.Parent.CloneHintGui
local shortcutHint = script.Parent.CloneHintGui.CloneHint
waitForProperty(game,"PlaceId")
local isRestricted = (game.PlaceId == 41324860 or game.PlaceId == 129686177)
local showBaseplateScript = nil
local hideBaseplateScript = nil
if isRestricted then
waitForChild(getPlayer(), "PlayerGui")
waitForChild(getPlayer().PlayerGui, "Waypoint")
waitForChild(getPlayer().PlayerGui, "showBaseplateWaypoint")
waitForChild(getPlayer().PlayerGui, "hideBaseplateWaypoint")
showBaseplateScript = getPlayer().PlayerGui.showBaseplateWaypoint
hideBaseplateScript = getPlayer().PlayerGui.hideBaseplateWaypoint
end
local modelToStampIn, stampRegion = nil
-- functions
function findModel(part)
if isRestricted then
while part ~= nil do
if part.className == "Model" and part.Name ~= modelToStampIn.Name and part.Name ~= "GarbageParts" then
return part
elseif part.Name == modelToStampIn.Name or part.Name == "GarbageParts" then
return nil
end
part = part.Parent
end
return nil
else
while part ~= game.Workspace do
if part:FindFirstChild("RobloxModel") then
return part
end
part = part.Parent
end
return nil
end
end
function getClosestColorToTerrainMaterial(terrainValue)
if terrainValue == 1 then
return BrickColor.new("Bright green")
elseif terrainValue == 2 then
return BrickColor.new("Bright yellow")
elseif terrainValue == 3 then
return BrickColor.new("Bright red")
elseif terrainValue == 4 then
return BrickColor.new("Sand red")
elseif terrainValue == 5 then
return BrickColor.new("Black")
elseif terrainValue == 6 then
return BrickColor.new("Dark stone grey")
elseif terrainValue == 7 then
return BrickColor.new("Sand blue")
elseif terrainValue == 8 then
return BrickColor.new("Deep orange")
elseif terrainValue == 9 then
return BrickColor.new("Dark orange")
elseif terrainValue == 10 then
return BrickColor.new("Reddish brown")
elseif terrainValue == 11 then
return BrickColor.new("Light orange")
elseif terrainValue == 12 then
return BrickColor.new("Light stone grey")
elseif terrainValue == 13 then
return BrickColor.new("Sand green")
elseif terrainValue == 14 then
return BrickColor.new("Medium stone grey")
elseif terrainValue == 15 then
return BrickColor.new("Really red")
elseif terrainValue == 16 then
return BrickColor.new("Really blue")
elseif terrainValue == 17 then
return BrickColor.new("Bright blue")
else
return BrickColor.new("Bright green")
end
end
function setTerrainSelection(point)
if selectionBox then
local cell = game.Workspace.Terrain:WorldToCellPreferSolid(point)
local cellCenter = game.Workspace.Terrain:CellCenterToWorld(cell.X, cell.Y, cell.Z)
terrainSelectionBox.CFrame = CFrame.new(cellCenter)
selectionBox.Adornee = terrainSelectionBox
currentSelection = game.Workspace.Terrain
end
end
function setSelection(partOrModel)
if partOrModel ~= currentSelection then
clearSelection()
currentSelection = partOrModel
selectionBox.Adornee = currentSelection
end
end
function clearSelection()
if currentSelection ~= nil then
for part, color in pairs(currentSelectionColors) do
part.BrickColor = color
end
selectionBox.Adornee = nil
end
currentSelectionColors = {}
if currentSelection then currentSelection = nil end
if selectionBox then selectionBox.Adornee = nil end
end
function canEyeDropperObject(part)
local stamperTag = part.Parent:FindFirstChild("RobloxStamper")
if stamperTag == nil then stamperTag = part:FindFirstChild("RobloxStamper") end
if isRestricted then
if not inRegion(part) then return false end
end
return part and not (part.Locked) and part:IsA("BasePart") and (part.Position - Tool.Parent.Head.Position).Magnitude < 60 and stamperTag ~= nil
end
function inRegion(partOrModel)
if not stampRegion then return true end
if not partOrModel then return true end
return RbxStamper.CanEditRegion(partOrModel, stampRegion)
end
function isOnGrid(partOrModel)
-- first check to see if off-grid, and if so, prevent eyedropperage
local modelExtentsInWorldCoords
if partOrModel:IsA("Model") then
modelExtentsInWorldCoords = partOrModel:GetModelCFrame():vectorToWorldSpace(partOrModel:GetModelSize())
else
modelExtentsInWorldCoords = partOrModel.CFrame:vectorToWorldSpace(partOrModel.Size)
end
-- we now simply check to see if the above property fits in a 4x4x4 gridspace
offX = math.fmod(math.abs(modelExtentsInWorldCoords.X), 4)
offY = math.fmod(math.abs(modelExtentsInWorldCoords.Y), 4)
offZ = math.fmod(math.abs(modelExtentsInWorldCoords.Z), 4)
local numberOfAxesOffGrid = 0
if math.min(offX, 4 - offX) > eyedropperOffGridTolerance then numberOfAxesOffGrid = numberOfAxesOffGrid + 1 end
if math.min(offY, 4 - offY) > eyedropperOffGridTolerance then numberOfAxesOffGrid = numberOfAxesOffGrid + 1 end
if math.min(offZ, 4 - offZ) > eyedropperOffGridTolerance then numberOfAxesOffGrid = numberOfAxesOffGrid + 1 end
if numberOfAxesOffGrid > 1 then return false -- we allow one axis to be not fit to grid, since any rotation must necessarily affect >= 2 axes (some of the models are like 4x4x6 :( ).
else return true end
end
function setupFakeTerrainPart(cellMat, cellType, cellOrient, isWater, waterForce,waterDirection)
local newTerrainPiece = nil
if (cellType == 1 or cellType == 4) then
newTerrainPiece = Instance.new("WedgePart")
newTerrainPiece.formFactor = "Custom"
elseif (cellType == 2) then
newTerrainPiece = Instance.new("CornerWedgePart")
else
newTerrainPiece = Instance.new("Part")
newTerrainPiece.formFactor = "Custom"
end
newTerrainPiece.Name = "MegaClusterCube"
newTerrainPiece.Size = Vector3.new(4, 4, 4)
newTerrainPiece.BottomSurface = "Smooth"
newTerrainPiece.TopSurface = "Smooth"
-- can add decals or textures here if feeling particularly adventurous... for now, can make a table of look-up colors
newTerrainPiece.BrickColor = getClosestColorToTerrainMaterial(cellMat)
local sideways = 0
local flipped = math.pi
if cellType == 4 then sideways = -math.pi/2 end
if cellType == 2 or cellType == 3 then flipped = 0 end
newTerrainPiece.CFrame = CFrame.Angles(0, math.pi/2 * cellOrient + flipped, sideways)
if cellType == 3 then
local inverseCornerWedgeMesh = Instance.new("SpecialMesh")
inverseCornerWedgeMesh.MeshType = "FileMesh"
inverseCornerWedgeMesh.MeshId = "http://www.watrbx.wtf/asset/?id=66832495"
inverseCornerWedgeMesh.Scale = Vector3.new(2, 2, 2)
inverseCornerWedgeMesh.Parent = newTerrainPiece
end
local materialTag = Instance.new("Vector3Value")
materialTag.Value = Vector3.new(cellMat, cellType, cellOrient)
materialTag.Name = "ClusterMaterial"
materialTag.Parent = newTerrainPiece
if isWater then
local waterForceTag = Instance.new("StringValue",newTerrainPiece)
waterForceTag.Name = "WaterForceTag"
waterForceTag.Value = string.sub(tostring(waterForce),17)
local waterForceDirectionTag = Instance.new("StringValue",newTerrainPiece)
waterForceDirectionTag.Name = "WaterForceDirectionTag"
waterForceDirectionTag.Value = string.sub(tostring(waterDirection),21)
end
return newTerrainPiece
end
function hint(phrase, timeLength)
waitForChild(game.Players.LocalPlayer.PlayerGui,"topHint")
waitForChild(game.Players.LocalPlayer.PlayerGui.topHint, "Add")
waitForChild(game.Players.LocalPlayer.PlayerGui.topHint.Add, "Label")
waitForChild(game.Players.LocalPlayer.PlayerGui.topHint.Add, "Time")
game.Players.LocalPlayer.PlayerGui.topHint.Add.Label.Value = tostring(phrase)
game.Players.LocalPlayer.PlayerGui.topHint.Add.Time.Value = tonumber(timeLength)
game.Players.LocalPlayer.PlayerGui.topHint.Add.Disabled = false
end
function showBaseplateWaypoint()
if modelToStampIn and showBaseplateScript then
local target = showBaseplateScript:FindFirstChild("target")
if target then
delay(0,function()
target.Value = modelToStampIn.Parent:FindFirstChild("RegionBounds")
showBaseplateScript.Disabled = false
showBaseplateScript.Disabled = true
wait(8)
hideBaseplateScript.Disabled = false
hideBaseplateScript.Disabled = true
end)
end
end
end
function stampAttemptFailed()
hint("You can only stamp in your baseplate", 5)
showBaseplateWaypoint()
end
function hasPoints()
waitForChild(game.Players.LocalPlayer, "MaxPoints")
local maxPoints = game.Players.LocalPlayer.MaxPoints
waitForChild(game.Players.LocalPlayer, "PointsUsed")
local pointsUsed = game.Players.LocalPlayer.PointsUsed
return ( (pointsUsed.Value/maxPoints.Value) < 1 )
end
function setupStamper(stampModel)
if stampControl then stampControl.Destroy() end
if stampingCon then
stampingCon:disconnect()
stampingCon = nil
end
if isRestricted then
if not hasPoints() then
hint("Too many parts stamped, delete some to stamp more", 5)
return
else
stampControl = RbxStamper.SetupStamperDragger(stampModel, Mouse, modelToStampIn, stampRegion, stampAttemptFailed)
end
else
stampControl = RbxStamper.SetupStamperDragger(stampModel, Mouse)
end
if stampControl then
stampingCon = stampControl.Stamped.Changed:connect(function()
if stampControl and stampControl.Stamped.Value then
if isRestricted and not hasPoints() then
hint("Too many parts stamped, delete some to stamp more", 5)
if stampCon then stampCon:disconnect() end
stampControl.Destroy()
else
stampControl.ReloadModel()
end
end
end)
shortcutHint.Visible = true
end
end
function onEyeDropperMouseButton1Down()
clearSelection()
if Mouse then
Mouse.Icon = "http://www.watrbx.wtf/asset/?id=66887745"
end
-- deny any attempt to clone something that wasn't stamped using the Stamper tool
if not Mouse or not Mouse.Target then
startEyeDropperOperation()
return
end
local cloneInstance = nil
local isTerrainEyedroppering = false
if Mouse.Target == game.Workspace.Terrain and not isRestricted then -- want to eyedropper a terrain piece; do a little extra footwork
-- make the fake part here
local hitCell = game.Workspace.Terrain:WorldToCellPreferSolid(Mouse.Hit.p)
local cellMat, cellType, cellOrient = game.Workspace.Terrain:GetCell(hitCell.x, hitCell.y, hitCell.z)
local hasAnyWater, waterForce, waterDirection = game.Workspace.Terrain:GetWaterCell(hitCell.x, hitCell.y, hitCell.z)
cloneInstance = setupFakeTerrainPart(cellMat.Value, cellType.Value, cellOrient.Value, hasAnyWater, waterForce, waterDirection)
isTerrainEyedroppering = true
end
local stamperTag = Mouse.Target.Parent:FindFirstChild("RobloxStamper")
if stamperTag == nil then stamperTag = Mouse.Target:FindFirstChild("RobloxStamper") end
if stamperTag == nil and not isTerrainEyedroppering then
startEyeDropperOperation()
return
end
local eyeDropperInstance = nil
-- find out if the target part is part of a Roblox Set Model
local robloxModelTag = Mouse.Target.Parent:FindFirstChild("RobloxModel")
if robloxModelTag ~= nil then
eyeDropperInstance = Mouse.Target.Parent
else
eyeDropperInstance = Mouse.Target
end
-- do not allow certain objects to be captured with eye-dropper
-- for now, locked parts
if eyeDropperInstance:IsA("Part") and eyeDropperInstance.Locked and not isTerrainEyedroppering then
startEyeDropperOperation()
else
if not isTerrainEyedroppering then
cloneInstance = eyeDropperInstance:clone()
-- once more, we make sure it's on grid before eyedroppering
if not isOnGrid(cloneInstance) then
if cloneInstance:IsA("Model") then cloneInstance:ResetOrientationToIdentity()
else cloneInstance.CFrame = CFrame.new(cloneInstance.CFrame.p) end
end
cloneInstance:BreakJoints()
end
if eyeDropperConnection then
eyeDropperConnection:disconnect()
eyeDropperConnection = nil
end
if eyeDropperMoveConnection then
eyeDropperMoveConnection:disconnect()
eyeDropperMoveConnection = nil
end
setupStamper(cloneInstance)
end
end
function onEyeDropperMouseMove()
if not Mouse or not Mouse.Target then
clearSelection()
return
end
local part = Mouse.Target
if part:IsA("Terrain") and Mouse.Hit and not isRestricted then
selectionBox.Color = BrickColor.Green()
setTerrainSelection(Mouse.Hit.p)
elseif canEyeDropperObject(part) then
local model = findModel(part)
if model then
selectionBox.Color = BrickColor.Green()
setSelection(model)
else
selectionBox.Color = BrickColor.Green()
setSelection(part)
end
else
clearSelection()
end
end
function keyHandler(key)
key = key:lower()
if key == 'q' then
startEyeDropperOperation()
end
end
function startEyeDropperOperation()
if stampControl then stampControl.Destroy() end
if Mouse then
Mouse.Icon = "http://www.watrbx.wtf/asset/?id=67163166"
shortcutHint.Visible = false
if not eyeDropperMoveConnection then
eyeDropperConnection = Mouse.Button1Up:connect(onEyeDropperMouseButton1Down)
end
if not eyeDropperMoveConnection then
eyeDropperMoveConnection = Mouse.Move:connect(onEyeDropperMouseMove)
end
end
end
function onEquipped(mouse)
Mouse = mouse
if game:FindFirstChild("Players") then
if game.Players["LocalPlayer"] then
selectionBox.Parent = game.Players.LocalPlayer.PlayerGui
hintGui.Parent = game.Players.LocalPlayer.PlayerGui
end
end
keyCon = Mouse.KeyDown:connect(keyHandler)
startEyeDropperOperation()
end
function onUnequipped()
if stampControl then
stampControl.Destroy()
end
Mouse = nil
selectionBox.Parent = nil
if eyeDropperMoveConnection then
eyeDropperMoveConnection:disconnect()
eyeDropperMoveConnection = nil
end
if eyeDropperConnection then
eyeDropperConnection:disconnect()
eyeDropperConnection = nil
end
if keyCon then
keyCon:disconnect()
keyCon = nil
end
if hintGui then
hintGui.Parent = nil
end
end
------------------------------------------------------------------------------------------------
if isRestricted then -- setup our variables
waitForChild(game,"Workspace")
waitForChild(game.Workspace, "BuildingAreas")
waitForChild(game.Workspace.BuildingAreas, "Area1")
waitForChild(game.Workspace.BuildingAreas, "Area9") -- all areas loaded
while not modelToStampIn do -- check for build area until we find one
local buildAreas = game.Workspace.BuildingAreas:GetChildren()
for i = 1, #buildAreas do
if buildAreas[i]:IsA("Model") then
waitForChild(buildAreas[i],"Player")
if buildAreas[i].Player.Value == game.Players.LocalPlayer.Name then
waitForChild(buildAreas[i],"PlayerArea")
modelToStampIn = buildAreas[i].PlayerArea
break
end
end
end
if not modelToStampIn then
wait(0.5)
end
end
local lowPos = modelToStampIn.Parent:FindFirstChild("LowPos")
local highPos = modelToStampIn.Parent:FindFirstChild("HighPos")
if not lowPos or highPos then
wait(0.5)
lowPos = modelToStampIn.Parent:FindFirstChild("LowPos")
highPos = modelToStampIn.Parent:FindFirstChild("HighPos")
end
while lowPos.Value == Vector3.new(0,0,0) or highPos.Value == Vector3.new(0,0,0) do
wait(0.5)
end -- tool doesn't work until these are defined
stampRegion = Region3.new(lowPos.Value, highPos.Value) -- this is where we can stamp
end
Tool.Equipped:connect(onEquipped)
Tool.Unequipped:connect(onUnequipped)
-
CloneHintGui
-
false
4278190080
0.5
4279970357
1
false
false
2
5
CloneHint
0.5
-85
0
0
0
170
0
30
0
Press Q to Eyedropper
4294967295
false
4278190080
0
0
false
2
1
false
1
-
StarterGui
true
-
0
10
1
Soundscape
1
-
CollectionService
-
PhysicsService
-
BadgeService
-
Geometry
-
RenderHooksService
-
SocialService
-
GamePassService
-
1000
Debris
-
Instance
-
Instance
-
CookiesService
-
Teleport Service
-
true
Players
-
Instance
-
Instance
-
Selection
-
4286611584
1
4278190080
4278190080
4290822336
100000
0
41.7332993
Lighting
4289967032
14:00:00
-
ChangeHistoryService
-
true
true
true
true
TestService
60
-
false
Script
function onChildAdded(child)
print "onChildAdded"
RBX_WARN_THROW(child.Parent = game.Workspace.NoEventParent)
end
function onChildAddedSelf(child)
print "onChildAddedSelf"
child.Parent = game.Workspace.ChildAddedEventSelfParent
end
function onChildRemoved(child)
print "onChildRemoved"
RBX_WARN_THROW(child.Parent = game.Workspace.NoEventParent)
end
function onDescendantAdded(descendant)
print "onDescendantAdded"
RBX_WARN_THROW(descendant.Parent = game.Workspace.NoEventParent)
end
function onDescendantAddedSelf(descendant)
print "onDescendantAddedSelf"
descendant.Parent = game.Workspace.DescendantAddedEventSelfParent
end
function onDescendantRemoving(descendant)
print "onDescendantRemoving"
RBX_WARN_THROW(descendant.Parent = game.Workspace.NoEventParent)
end
function onAncestryChanged(child, parent)
print "onAncestryChanged"
RBX_WARN_THROW(child.Parent = game.Workspace.NoEventParent) -- this will not always throw
end
connection1 = game.Workspace.ChildAddedEventParent.ChildAdded:connect(onChildAdded)
connection2 = game.Workspace.ChildAddedEventSelfParent.ChildAdded:connect(onChildAddedSelf)
connection3 = game.Workspace.ChildRemovedEventParent.ChildRemoved:connect(onChildRemoved)
connection4 = game.Workspace.DescendantAddedEventParent.DescendantAdded:connect(onDescendantAdded)
connection5 = game.Workspace.DescendantAddedEventSelfParent.DescendantAdded:connect(onDescendantAddedSelf)
connection6 = game.Workspace.DescendantRemovingEventParent.DescendantRemoving:connect(onDescendantRemoving)
connection7 = game.Workspace.AncestryChangedEventChild.AncestryChanged:connect(onAncestryChanged)
-- sanity check on the initial values
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
print "Test assigning a parent with no interuptions"
game.Workspace.NoEventChild.Parent = game.Workspace.NoEventParent
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 1)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventParent.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
game.Workspace.NoEventParent.NoEventChild.Parent = game.Workspace
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
print "test changing the parent when adding a child"
game.Workspace.NoEventChild.Parent = game.Workspace.ChildAddedEventParent
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 1)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
game.Workspace.ChildAddedEventParent.NoEventChild.Parent = game.Workspace
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
print "test changing the parent to the current new parent when adding a child"
game.Workspace.NoEventChild.Parent = game.Workspace.ChildAddedEventSelfParent
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 1)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
game.Workspace.ChildAddedEventSelfParent.NoEventChild.Parent = game.Workspace
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
--
-- skip this for now because an exception in the code is thrown during this case
print "test changing the parent when removing a child"
game.Workspace.NoEventChild.Parent = game.Workspace.ChildRemovedEventParent
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 1)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
-- this will throw an exception
-- this is the desired behaviour
game.Workspace.ChildRemovedEventParent.NoEventChild.Parent = game.Workspace
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
print "test changing the parent when adding a descendant"
game.Workspace.NoEventChild.Parent = game.Workspace.DescendantAddedEventParent
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 1)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
game.Workspace.DescendantAddedEventParent.NoEventChild.Parent = game.Workspace
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
--
-- skip this test for now because it puts us in an infinite loop
print "test changing the parent to the current new parent when adding a descendant"
game.Workspace.NoEventChild.Parent = game.Workspace.DescendantAddedEventSelfParent
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 1)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
game.Workspace.DescendantAddedEventSelfParent.NoEventChild.Parent = game.Workspace
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
print "test changing the parent when removing a descendant"
game.Workspace.NoEventChild.Parent = game.Workspace.DescendantRemovingEventParent
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 1)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
game.Workspace.DescendantRemovingEventParent.NoEventChild.Parent = game.Workspace
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
print "test changing the parent when changing the ancestry"
game.Workspace.AncestryChangedEventChild.Parent = game.Workspace.NoEventParent
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 1)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventParent.AncestryChangedEventChild:GetChildren() == 0)
game.Workspace.NoEventParent.AncestryChangedEventChild.Parent = game.Workspace
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)
-- cleanup
print "cleanup"
connection1:disconnect()
connection2:disconnect()
connection3:disconnect()
connection4:disconnect()
connection5:disconnect()
connection6:disconnect()
connection7:disconnect()
--game.Workspace.NoEventParent.AncestryChangedEventChild.Parent = game.Workspace
RBX_CHECK( #game.Workspace.NoEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.ChildRemovedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantAddedEventSelfParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.DescendantRemovingEventParent:GetChildren() == 0)
RBX_CHECK( #game.Workspace.NoEventChild:GetChildren() == 0)
RBX_CHECK( #game.Workspace.AncestryChangedEventChild:GetChildren() == 0)