|
|
|
|
| local Players = game:GetService("Players")
|
| local UserInputService = game:GetService("UserInputService")
|
| local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
| local RunService = game:GetService("RunService")
|
|
|
| local BuildingConfig = require(ReplicatedStorage:WaitForChild("Shared"):WaitForChild("BuildingConfig"))
|
| local PlaceBlueprintEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("PlaceBlueprintEvent")
|
|
|
| local player = Players.LocalPlayer
|
| local mouse = player:GetMouse()
|
| local character = player.Character or player.CharacterAdded:Wait()
|
|
|
| local buildModeActive = false
|
| local currentStructureIndex = 1
|
| local currentStructure = BuildingConfig.StructureOrder[1]
|
| local currentRotation = 0
|
| local previewModel = nil
|
|
|
| local function snapToGrid(position, gridSize)
|
| return Vector3.new(
|
| math.floor((position.X + gridSize/2) / gridSize) * gridSize,
|
| position.Y,
|
| math.floor((position.Z + gridSize/2) / gridSize) * gridSize
|
| )
|
| end
|
|
|
| local function getStructureSize()
|
| local config = BuildingConfig.Structures[currentStructure]
|
| if config and config.Size then
|
| return config.Size
|
| end
|
| return Vector3.new(10, 10, 1)
|
| end
|
|
|
| local function cleanupPreview()
|
| if previewModel then
|
| previewModel:Destroy()
|
| previewModel = nil
|
| end
|
| end
|
|
|
| local function createPreview()
|
| cleanupPreview()
|
| local size = getStructureSize()
|
|
|
| previewModel = Instance.new("Part")
|
| previewModel.Size = size
|
| previewModel.Transparency = 0.5
|
| previewModel.BrickColor = BrickColor.new("Neon blue")
|
| previewModel.CanCollide = false
|
| previewModel.Anchored = true
|
| previewModel.Material = Enum.Material.ForceField
|
| previewModel.Parent = workspace.Terrain
|
|
|
|
|
| local billboard = Instance.new("BillboardGui")
|
| billboard.Size = UDim2.new(0, 200, 0, 50)
|
| billboard.StudsOffset = Vector3.new(0, size.Y/2 + 2, 0)
|
| billboard.AlwaysOnTop = true
|
| billboard.Parent = previewModel
|
|
|
| local label = Instance.new("TextLabel")
|
| label.Name = "StructureLabel"
|
| label.Size = UDim2.new(1, 0, 1, 0)
|
| label.BackgroundTransparency = 0.3
|
| label.BackgroundColor3 = Color3.new(0, 0, 0)
|
| label.TextColor3 = Color3.new(1, 1, 1)
|
| label.TextScaled = true
|
| label.Font = Enum.Font.GothamBold
|
|
|
| local config = BuildingConfig.Structures[currentStructure]
|
| label.Text = (config and config.Name or currentStructure) .. " [Q] Cycle [R] Rotate"
|
| label.Parent = billboard
|
| end
|
|
|
| local function toggleBuildMode()
|
| buildModeActive = not buildModeActive
|
| if not buildModeActive then
|
| cleanupPreview()
|
| else
|
| createPreview()
|
| end
|
| end
|
|
|
| local function cycleStructure()
|
| currentStructureIndex = currentStructureIndex + 1
|
| if currentStructureIndex > #BuildingConfig.StructureOrder then
|
| currentStructureIndex = 1
|
| end
|
| currentStructure = BuildingConfig.StructureOrder[currentStructureIndex]
|
| if buildModeActive then
|
| createPreview()
|
| end
|
| end
|
|
|
| local function updatePreview()
|
| if not buildModeActive or not previewModel then return end
|
|
|
| local char = player.Character
|
| if char and char:FindFirstChild("HumanoidRootPart") then
|
| local distance = (char.HumanoidRootPart.Position - mouse.Hit.Position).Magnitude
|
| if distance <= BuildingConfig.MaxPlacementDistance then
|
| local snappedPos = snapToGrid(mouse.Hit.Position, BuildingConfig.GridSnap)
|
| snappedPos = Vector3.new(snappedPos.X, mouse.Hit.Position.Y + (previewModel.Size.Y / 2), snappedPos.Z)
|
|
|
| previewModel.CFrame = CFrame.new(snappedPos) * CFrame.Angles(0, math.rad(currentRotation), 0)
|
| previewModel.BrickColor = BrickColor.new("Neon blue")
|
| else
|
| previewModel.Position = mouse.Hit.Position
|
| previewModel.BrickColor = BrickColor.new("Really red")
|
| end
|
| end
|
| end
|
|
|
| local function onInputBegan(input, gameProcessed)
|
| if gameProcessed then return end
|
|
|
| if input.KeyCode == Enum.KeyCode.B then
|
| toggleBuildMode()
|
| end
|
|
|
| if input.KeyCode == Enum.KeyCode.Q and buildModeActive then
|
| cycleStructure()
|
| end
|
|
|
| if input.KeyCode == Enum.KeyCode.R and buildModeActive then
|
| currentRotation = (currentRotation + 90) % 360
|
| end
|
|
|
| if input.UserInputType == Enum.UserInputType.MouseButton1 and buildModeActive then
|
| if previewModel and previewModel.BrickColor.Name == "Neon blue" then
|
| PlaceBlueprintEvent:FireServer(currentStructure, previewModel.CFrame)
|
| end
|
| end
|
| end
|
|
|
| player.CharacterAdded:Connect(function(char)
|
| character = char
|
| end)
|
|
|
| UserInputService.InputBegan:Connect(onInputBegan)
|
|
|
| RunService.RenderStepped:Connect(function()
|
| if buildModeActive then
|
| updatePreview()
|
| end
|
| end)
|
|
|