Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local IncludeTextureForGrid = true
- local GridTexture = "rbxassetid://13786085"
- local IncludeGrid = true
- local GridSize = 2
- local Lerp = true
- local LerpSpeed = 0.1
- local RotIncrement = 90
- local FloorHeight = 1
- local MaxHeight = 60
- local DetectCollision = true
- local IgnoreItems = false
- local BuildModePlacing = true
- local IncludeFloors = true
- local CollisionColor = Color3.fromRGB(255, 55, 55) -- The Color of the model when colliding
- local NoCollisionColor = Color3.fromRGB(55, 255, 55) -- The Color of the model when not colliding
- local RaiseButton = Enum.KeyCode.U
- local LowerButton = Enum.KeyCode.L
- local RotateButton = Enum.KeyCode.R
- local CancelButton = Enum.KeyCode.X
- local placement = {}
- local runService = game:GetService("RunService")
- local userInputService = game:GetService("UserInputService")
- local player = game.Players.LocalPlayer
- local character = player.Character or player.CharacterAdded:Wait()
- local mouse = player:GetMouse()
- wait(0.1) -- DO NOT REMOVE
- local humanoid = character:FindFirstChild("Humanoid")
- local posX
- local posY
- local posZ
- local startingY
- local rot = 0
- local gridScale = math.abs(tonumber(GridSize))
- local model
- local plot
- local ignorable
- local collisionPoints
- local collisionPoint
- local isPlacing = nil
- local canPlace = nil
- local isColliding = nil
- local canStart = true
- local isStacking = nil
- local lctn
- local function SwitchVarsFalse()
- isPlacing = false
- canPlace = false
- isColliding = false
- canStart = true
- if IgnoreItems then
- mouse.TargetFilter = nil
- end
- end
- local function SwitchVarsTrue()
- isPlacing = true
- canPlace = true
- isColliding = false
- if BuildModePlacing then
- canStart = true
- else
- canStart = false
- end
- end
- local function CalcMousePos()
- if IncludeGrid then
- posX = math.floor(mouse.Hit.X / gridScale + 0.5) * gridScale
- posZ = math.floor(mouse.Hit.Z / gridScale + 0.5) * gridScale
- else
- posX = mouse.Hit.X
- posZ = mouse.Hit.Z
- end
- if IncludeFloors then
- if isStacking then
- posY = math.floor(mouse.Hit.Y) + 2
- else
- if posY > MaxHeight then
- posY = MaxHeight
- elseif posY < startingY then
- posY = startingY
- end
- end
- end
- end
- local function Rotate()
- if Lerp then
- CalcMousePos()
- rot = rot + RotIncrement
- model:SetPrimaryPartCFrame(model.PrimaryPart.CFrame:Lerp(CFrame.new(posX, posY, posZ) * CFrame.Angles(0, math.rad(rot), 0), LerpSpeed))
- else
- CalcMousePos()
- rot = rot + RotIncrement
- model:SetPrimaryPartCFrame(CFrame.new(posX, posY, posZ) * CFrame.Angles(0, math.rad(rot), 0))
- end
- end
- local function CollisionDetection(mdl)
- if mdl and model then
- isColliding = false
- collisionPoint = mdl.PrimaryPart.Touched:Connect(function() end)
- collisionPoints = mdl.PrimaryPart:GetTouchingParts()
- for i = 1, #collisionPoints do
- if not collisionPoints[i]:IsDescendantOf(mdl) and not collisionPoints[i]:IsDescendantOf(character) then
- isColliding = true
- break
- end
- end
- collisionPoint:Disconnect()
- return isColliding
- end
- end
- local function HideGrid(plt)
- if IncludeTextureForGrid then
- for i, v in pairs(plt:GetChildren()) do
- if v then
- v:Destroy()
- end
- end
- end
- end
- local function ShowGrid(plt)
- HideGrid(plt)
- if IncludeTextureForGrid then
- local GridTex = Instance.new("Texture")
- GridTex.Texture = GridTexture
- GridTex.Face = Enum.NormalId.Top
- GridTex.Transparency = 1
- GridTex.Parent = plt
- GridTex.Transparency = 0
- end
- end
- local function OnDeath()
- if isPlacing then
- SwitchVarsFalse()
- HideGrid(plot)
- if model then
- model:Destroy()
- model = nil
- end
- end
- end
- local function ChangeColor(mdl)
- if isColliding and mdl and isPlacing then
- mdl.PrimaryPart.Color = CollisionColor
- else
- mdl.PrimaryPart.Color = NoCollisionColor
- end
- end
- local function Inputs(input, gpe)
- if input.KeyCode == RotateButton and isPlacing then
- Rotate()
- elseif input.KeyCode == CancelButton and model and isPlacing then
- SwitchVarsFalse()
- model:Destroy()
- HideGrid(plot)
- elseif input.KeyCode == RaiseButton and model and isPlacing and posY < MaxHeight then
- posY = model.PrimaryPart.CFrame.Y + FloorHeight
- elseif input.KeyCode == LowerButton and model and isPlacing and posY > startingY then
- posY = model.PrimaryPart.CFrame.Y - FloorHeight
- elseif input.KeyCode == Enum.KeyCode.ButtonB then
- if isPlacing then
- SwitchVarsFalse()
- model:Destroy()
- HideGrid(plot)
- end
- end
- end
- local function MoveModelToCalculatedPos()
- if isPlacing and model then
- if IgnoreItems then
- mouse.TargetFilter = ignorable
- else
- mouse.TargetFilter = model
- end
- if Lerp then
- CalcMousePos()
- if DetectCollision then
- CollisionDetection(model)
- ChangeColor(model)
- else
- isColliding = false
- end
- model:SetPrimaryPartCFrame(model.PrimaryPart.CFrame:Lerp(CFrame.new(posX, posY, posZ) * CFrame.Angles(0, math.rad(rot), 0), LerpSpeed))
- else
- CalcMousePos()
- if DetectCollision then
- CollisionDetection(model)
- ChangeColor(model)
- end
- model:SetPrimaryPartCFrame(CFrame.new(posX, posY, posZ) * CFrame.Angles(0, math.rad(rot), 0))
- end
- end
- end
- local function SetUpModel(modl)
- for i, mdl in pairs(model:GetDescendants()) do
- if mdl then
- if mdl:IsA("BasePart") or mdl:IsA("UnionOperation") then
- mdl.CanCollide = false
- mdl.Anchored = true
- end
- end
- end
- model.PrimaryPart.Transparency = 0.8
- if not DetectCollision then
- model.PrimaryPart.Color = NoCollisionColor
- end
- posY = model.PrimaryPart.CFrame.Y
- startingY = model.PrimaryPart.CFrame.Y
- model.Parent = ignorable
- end
- local function SwitchModel(mdl, location)
- if model then
- model:Destroy()
- model = location:FindFirstChild(mdl):Clone()
- SetUpModel(model)
- model:SetPrimaryPartCFrame(CFrame.new(posX, posY, posZ))
- else
- model = location:FindFirstChild(mdl):Clone()
- SetUpModel(model)
- model:SetPrimaryPartCFrame(CFrame.new(posX, posY, posZ))
- end
- end
- function placement:PlaceModel(location, RE)
- if isPlacing and canPlace and not isColliding and model and not BuildModePlacing then
- wait(0.2)
- CollisionDetection(model)
- CalcMousePos()
- RE:FireServer(model.Name, posX, posY, posZ, rot, location)
- SwitchVarsFalse()
- HideGrid(plot)
- model:Destroy()
- elseif not isColliding and canPlace and isPlacing then
- CalcMousePos()
- RE:FireServer(model.Name, posX, posY, posZ, rot, location)
- SwitchModel(model.Name, lctn)
- SwitchVarsTrue()
- wait(0.1)
- end
- end
- function placement:StartPlacement(location, mdlNm, plt, mdls, isSt)
- if canStart and not isPlacing and not BuildModePlacing then
- plot = plt
- ignorable = mdls
- ShowGrid(plot)
- SwitchVarsTrue()
- lctn = location
- model = location:FindFirstChild(mdlNm):Clone()
- SetUpModel(model)
- if isSt then
- IgnoreItems = false
- isStacking = true
- else
- isStacking = false
- end
- elseif BuildModePlacing then
- lctn = location
- plot = plt
- ignorable = mdls
- SwitchModel(mdlNm, location)
- SwitchVarsTrue()
- ShowGrid(plot)
- if isSt then
- IgnoreItems = false
- isStacking = true
- else
- isStacking = false
- end
- end
- end
- userInputService.InputBegan:Connect(Inputs)
- runService:BindToRenderStep("Input", Enum.RenderPriority.Input.Value, MoveModelToCalculatedPos)
- humanoid.Died:Connect(OnDeath)
- return placement
Advertisement
Add Comment
Please, Sign In to add comment