# Digging Terrain Feature Help

I am making a game where digging terrain is a large feature but I need to only be allowed to do it in a certain area to a certain depth. I wish to try using ‘plots’ of land also and that would mean having the shovel check if it is in the owner’s area possibly through a part collision as the whole map is terrain. But i havent yet reached the point of making the shovel damage the terrain yet.

Here is the script I am using, the output says that
“Torso is not a valid member of Model” on line: 167

``````wait(1)
enabled = true
Tool = script.Parent
down = false -- Mouse isn't down

--sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously was
--returns true if made a wedge, false if the cell remains a block
function MakeWedge(x, y, z, defaultmaterial)
local c = game.Workspace.Terrain
--gather info about all the cells around x, y, z
surroundings = {} --surroundings is a 3 x 3 x 3 array of the material of the cells adjacent to x, y, z
for i = x - 1, x + 1 do
surroundings[i] = {}
for j = y - 1, y + 1 do
surroundings[i][j] = {}
for k = z - 1, z + 1 do
local material, wedge, rotation = c:GetCell(i, j, k)
surroundings[i][j][k] = material.Value
end
end
end
--make some useful arrays and counters
local sides = {} --sides is an array of the material of the 4 adjacent sides
sides[0] = surroundings[x - 1][y][z]
sides[1] = surroundings[x][y][z + 1]
sides[2] = surroundings[x + 1][y][z]
sides[3] = surroundings[x][y][z - 1]
for n = 0, 3 do
if sides[n] > 0 then
end
end
local sidesAbove = {} --sides is an array of the material of the 4 adjacent sides 1 height above
sidesAbove[0] = surroundings[x - 1][y + 1][z]
sidesAbove[1] = surroundings[x][y + 1][z + 1]
sidesAbove[2] = surroundings[x + 1][y + 1][z]
sidesAbove[3] = surroundings[x][y + 1][z - 1]
for n = 0, 3 do
if sidesAbove[n] > 0 then
end
end
local corners = {} --corners is an array of the material of the 4 adjacent corners
corners[0] = surroundings[x - 1][y][z - 1]
corners[1] = surroundings[x - 1][y][z + 1]
corners[2] = surroundings[x + 1][y][z + 1]
corners[3] = surroundings[x + 1][y][z - 1]
for n = 0, 3 do
if corners[n] > 0 then
end
end
local cornersAbove = {} --corners is an array of the material of the 4 adjacent corners 1 height above
cornersAbove[0] = surroundings[x - 1][y + 1][z - 1]
cornersAbove[1] = surroundings[x - 1][y + 1][z + 1]
cornersAbove[2] = surroundings[x + 1][y + 1][z + 1]
cornersAbove[3] = surroundings[x + 1][y + 1][z - 1]
for n = 0, 3 do
if cornersAbove[n] > 0 then
end
end
--determine what type of wedge to make
local material = nil
local wedge = nil
local rotation = nil
if defaultmaterial then
material = defaultmaterial
else
material, wedge, rotation = c:GetCell(x, y, z) --start with the existing material, wedge, and rotation
end
wedge = 0 --default wedge is a block
rotation = 0 --default rotation is 0
--type 1: 45 degree ramp //must not have a block on top and must have a block under, and be surrounded by 1 side; or 3 sides and the 2 corners between them
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
for n = 0, 3 do
if sides[n] > 0 then
wedge = 1
rotation = (n + 1) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and corners[(n + 2) % 4] > 0 and sides[(n + 2) % 4] > 0 then
wedge = 1
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
end
--type 2: 45 degree corner //must not have a block on top and must have a block under, and be surrounded by 2 sides and the 1 corner between them; or 3 sides and 1 corner between 2 of them (facing towards that corner)
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and (adjacentSides == 2 or (adjacentSides == 3 and (corners[(n + 3) % 4] > 0 or (sides[(n + 2) % 4] > 0 and corners[(n + 2) % 4] > 0) or (sides[(n + 3) % 4] > 0 and corners[n] > 0)))) then
wedge = 2
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 3: 45 degree inverse corner //surrounded by three sides or 4 sides and 3 corners, with nothing above or else a block on top surrounded on 2 sides and the corner between them
if adjacentSides == 3 and surroundings[x][y + 1][z] > 0 then
for n = 0, 3 do
if (corners[n] == 0 or cornersAbove[n] == 0) and (sides[(n - 1) % 4] == 0 or sides[n] == 0) and (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
for n = 0, 3 do
if corners[n] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and cornersAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0)) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 4: half a cube, as if it were cut diagonally from front to back //surrounded by 2 sides
for n = 0, 3 do
if sides[n] == 0 and sides[(n + 1) % 4] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] == 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] > 0)) then
wedge = 4
rotation = n
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
c:SetCell(x, y, z, material, wedge, rotation)
return false
end

function updateMouseRadius(mouse) -- Makes sure that while the player is digging he doesn't go move his mouse somewhere else going outside our magnitude
p = game.Players.LocalPlayer
if (mouse.Hit.p - p.Character.Torso.Position).magnitude > 10 then -- YOU RULE BREAKER!!!
onDeselect() -- Acts as if they stopped holding the mouse down
end
end

function onClick(mouse)
h = game.Players.LocalPlayer.Character.Humanoid
if not enabled or down or h == nil then
return
end
p = game.Players.LocalPlayer
if (p == nil) then return end
if (p.Character == nil) then return end
LINE 167 if (mouse.Hit.p - p.Character.Torso.Position).magnitude > 10 then return end
down = true
enabled = false
c = game.Workspace.Terrain
while down do
Tool.Dirt.Smoke.Enabled = true
local l = gui:clone()
l.Parent = p.PlayerGui
script.Parent.guiObject.Value = l
end
guivalue.Value = guivalue.Value + 1
if guivalue.Value >= 100 then
local cellPos = c:WorldToCellPreferSolid(Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
local x = cellPos.x
local y = cellPos.y
local z = cellPos.z
c:SetCell(x, y, z, 0, 0, 0)
for i = x - 1, x + 1 do
for j = y - 1, y + 1 do
for k = z - 1, z + 1 do
MakeWedge(i, j, k)
end
end
end
Tool.Dirt.Smoke.Enabled = false
onDeselect(mouse) -- Kills GUI
enabled = false
mouse.Icon = "rbxasset://textures\\GunWaitCursor.png"
wait(0.5)
mouse.Icon = "rbxasset://textures\\GunCursor.png"
enabled = true
end
wait()
end
end

function onClickOff(mouse)
Tool.Dirt.Smoke.Enabled = false
enabled = true
down = false
if script.Parent.guiObject.Value ~= nil then
script.Parent.guiObject.Value:remove()
end
if Tool.DiggyDiggyHole.Value ~= nil then
Tool.DiggyDiggyHole.Value:Stop()
Tool.DiggyDiggyHole.Value:remove()
end
Tool.GripForward = Vector3.new(0,0,-1)
Tool.GripRight = Vector3.new(0,0,0)
Tool.GripUp = Vector3.new(0, 1, 0)
Tool.Animate.Disabled = true -- The script seems to crash after digging due to the animation becoming nil. Just restart it.
Tool.Animate.Disabled = false
end

function onDeselect(mouse)
Tool.Dirt.Smoke.Enabled = false
enabled = true
down = false
if script.Parent.guiObject.Value ~= nil then
script.Parent.guiObject.Value:remove()
end
if Tool.DiggyDiggyHole.Value ~= nil then
Tool.DiggyDiggyHole.Value:Stop()
Tool.DiggyDiggyHole.Value:remove()
end
Tool.GripForward = Vector3.new(0,0,-1)
Tool.GripRight = Vector3.new(0,0,0)
Tool.GripUp = Vector3.new(0, 1, 0)
Tool.Animate.Disabled = true -- The script seems to crash after digging due to the animation becoming nil. Just restart it.
Tool.Animate.Disabled = false
end

function onSelect(mouse)
mouse.Icon = "rbxasset://textures\\GunCursor.png"
mouse.Button1Down:connect(function () onClick(mouse) end)
mouse.Button1Up:connect(function () onClickOff(mouse) end)
end

script.Parent.Equipped:connect(onSelect)
script.Parent.UnEquipped:connect(onDeselect)
``````

Something possibly to do with this block:

``````function onClick(mouse)
h = game.Players.LocalPlayer.Character.Humanoid
if not enabled or down or h == nil then
return
end
p = game.Players.LocalPlayer
if (p == nil) then return end
if (p.Character == nil) then return end
LINE 167	if (mouse.Hit.p - p.Character.Torso.Position).magnitude > 10 then return end
down = true
enabled = false
c = game.Workspace.Terrain
``````

I dont honestly know how to write one of these so i’m willing to answer unclear questions

its not a valid member if you are using r15 instead just use HumanoidRootPart it is available for both r6 and r15 characters

1 Like

Awesome thanks ill give it a shot!

EDIT: It worked now I just need to implement a small explosion to damage the terrain thanks so much!