local config = {
x = 40,
z = 40,
y_origin = 16000,
grid = 3,
freq = 2,
amplitude = 1.15,
cave_smoothness = 40,
scale = 130,
maxDensity = 0.7,
}
local max_mult = 9
local layers = {
{Enum.Material.Slate, Color3.new(0.639216, 0.635294, 0.647059)},
{Enum.Material.Slate, Color3.new(0.482353, 0.482353, 0.486275)},
{Enum.Material.Slate, Color3.new(0.34902, 0.356863, 0.321569)},
{Enum.Material.Limestone, Color3.new(0.45098, 0.431373, 0.32549)},
{Enum.Material.Salt, Color3.new(0.45098, 0.337255, 0.301961)},
{Enum.Material.Rock, Color3.new(0.45098, 0.25098, 0.25098)},
{Enum.Material.Rock, Color3.new(0.45098, 0.243137, 0.160784), 1.3},
{Enum.Material.CrackedLava, Color3.new(0.227451, 0.160784, 0.160784), 2.4},
{Enum.Material.CrackedLava, Color3.new(0.835294, 0.45098, 0.239216), 4.5},
}
local deepest = -450
local ore = {
{
cost = 10,
id = "http://www.roblox.com/asset/?id=639996737",
freq = 0.71,
w = 10,
name = "Coal",
y = {-7, -600}
},
{
cost = 20,
id = "http://www.roblox.com/asset/?id=639997022",
freq = 0.74,
w = 8,
name = "Silver",
y = {-13, -800}
},
{
cost = 14,
id = "http://www.roblox.com/asset/?id=639996462",
freq = 0.72,
w = 7,
name = "Copper",
y = {-6, -500}
},
{
cost = 80,
id = "rbxassetid://8241352709",
freq = 0.84,
w = 4,
name = "Judgement",
rare = true,
y = {-200, -600},
sound = "rbxassetid://7007957247"
},
{
cost = 28,
id = "http://www.roblox.com/asset/?id=640017880",
freq = 0.78,
w = 6,
name = "Gold",
y = {-20, -600}
},
{
cost = 50,
id = "http://www.roblox.com/asset/?id=639954603",
freq = 0.85,
w = 5,
name = "Topaz",
y = {-40, -700}
},
{
cost = 220,
id = "http://www.roblox.com/asset/?id=639966173",
freq = 0.98,
w = 5,
name = "Painite",
y = {-120, -700},
},
{
cost = 62,
id = "http://www.roblox.com/asset/?id=634982240",
freq = 0.88,
w = 5,
name = "Opal",
y = {-50, -730}
},
}
local xOffset = 27624
local yOffset = 8434
local zOffset = 43753
local far_cf = CFrame.new(9e9, 9e9, 9e9)
local vec = Vector3.new
local normals = {}
for i = 1, 6 do
normals[i] = Vector3.FromNormalId(Enum.NormalId:GetEnumItems()[i])
end
local storage = Instance.new("Folder", script)
local grid = {}
grid.__index = grid
function grid.new()
return setmetatable({
data = {}
}, grid)
end
function grid:clear()
table.clear(self.data)
end
function grid:list()
local list = {}
for x, yd in self.data do
for y, zd in yd do
for z, d in zd do
list[Vector3.new(x, y, z)] = d
end
end
end
return list
end
function grid:set(position, value)
local x, y, z = position.x, position.y, position.z
if not self.data[x] then
self.data[x] = {}
end
if not self.data[x][y] then
self.data[x][y] = {}
end
self.data[x][y][z] = value
end
function grid:get(position)
local x, y, z = position.x, position.y, position.z
local xdata = self.data[x]
if xdata then
local ydata = xdata[y]
if ydata then
return ydata[z]
end
end
end
local mining = {}
local gen = {}
gen.air_blocks = grid.new()
gen.solid_blocks = grid.new()
gen.cache = {}
gen.count = 0
local seed = os.clock()
local is_gen = false
function gen:add_cache(block)
block.CFrame = far_cf
block:ClearAllChildren()
table.insert(self.cache, block)
end
function gen:set_air(position)
if not position then error("Position is nil.", 2) end
local result = {}
self.air_blocks:set(position, true)
for i = 1, 6 do
local direction = normals[i]
local surrounding_position = position + (direction * config.grid)
local block_exists = self.solid_blocks:get(surrounding_position)
local air_exists = self.air_blocks:get(surrounding_position)
local below_limit = surrounding_position.y <= config.y_origin
if (not block_exists) and (not air_exists) and below_limit then
table.insert(result, surrounding_position)
end
end
return result
end
function check_stats(plr)
local ls = plr:FindFirstChild("leaderstats")
if not ls then
ls = Instance.new("Folder")
ls.Name = "leaderstats"
end
for i, v in {
["Blocks"] = {
"NumberValue",
0
},
["Ore price"] = {
"NumberValue",
0
},
} do
if not ls:FindFirstChild(i) then
local val = Instance.new(v[1])
val.Value = v[2]
val.Name = i
val.Parent = ls
end
end
ls.Parent = plr
return ls
end
function gen:remove(block, player)
if typeof(block) == "table" then
for i = 1, #block do
self:remove(table.unpack(block[i]))
end
return
end
if not block then error("Block is nil.", 2) end
if player then
if not mining[player] then
mining[player] = {
discovered = {},
send_noti = false,
}
print("New miner.")
end
local ore_data = ore[block:GetAttribute("OreData")]
if ore_data and not mining[player].discovered[ore_data.name] then
mining[player].discovered[ore_data.name] = true
if mining[player].send_noti then
end
end
local ls = check_stats(player)
if ore_data then
ls["Ore price"].Value += ore_data.cost * math.round( math.clamp( ( ( ( config.y_origin - block.Position.Y ) / config.grid ) / -deepest) * max_mult, 1, max_mult ) )
end
ls.Blocks.Value += 1
end
local result = self:set_air(block.Position)
self:add_cache(block)
self.solid_blocks:set(block:GetAttribute("Position"), nil)
for i = 1, #result do
self:new_block(result[i], true)
end
end
function gen:sub_radius(origin, radius)
if not origin then error("Origin is nil.", 2) end
if not radius then error("Radius is nil.", 2) end
radius = math.clamp(radius, 1, 5) * config.grid
end
function gen:new_block(position, cave_support)
if typeof(position) == "table" then
for i = 1, #position do
self:new_block(table.unpack(position[i]))
end
return
end
if not position then error("Position is nil.", 2) end
position = vec(math.round(position.X / config.grid) * config.grid, math.round(position.Y / config.grid) * config.grid, math.round(position.Z / config.grid) * config.grid)
local block_exists = self.solid_blocks:get(position)
if block_exists then return end
if cave_support then
if math.noise(position.x / config.cave_smoothness, position.z / config.cave_smoothness, (position.y + seed) / config.cave_smoothness) <= -0.4 then
--[[local xP = math.noise(((position.Y + yOffset + seed) / config.scale) * config.freq , ((position.z + zOffset + seed) / config.scale) * config.freq) * config.amplitude
local yP = math.noise(((position.X + xOffset + seed) / config.scale) * config.freq , ((position.Z + zOffset + seed) / config.scale) * config.freq) * config.amplitude
local zP = math.noise(((position.X + xOffset + seed) / config.scale) * config.freq , ((position.Y + yOffset + seed) / config.scale) * config.freq) * config.amplitude
local density = xP + yP + zP
if density >= config.maxDensity then]]
local result = self:set_air(position)
self.count += 1
if self.count%80 == 0 then
task.wait()
end
for i = 1, #result do
local cave_block_position = result[i]
self:new_block(cave_block_position, true)
end
return
end
end
local cache_block = self.cache[1]
if cache_block and cache_block.Parent == nil then
cache_block = nil
end
local l = layers[math.round( math.clamp( ( ( ( config.y_origin - position.Y ) / config.grid ) / -deepest) * 9, 1, 9 ) )]
local part = Instance.new("Part\0")
part.Material = l[1]
part.Color = l[2]
part.Size = Vector3.one * config.grid
part.Locked = true
part.Anchored = true
if l[3] then
local t
t = part.Touched:Connect(function(h)
local hm = h.Parent:FindFirstChild("Humanoid")
if hm and not hm:GetAttribute("dmg") then
hm:SetAttribute("dmg", true)
hm:TakeDamage(l[3])
task.wait(0.6)
hm:SetAttribute("dmg", false)
end
end)
task.delay(7, function()
t:Disconnect()
end)
end
local block = part
table.remove(self.cache, 1)
block.Position = position
block.Parent = storage
local ore_data
local ore_ind
if is_gen then
--[[local s = Instance.new("Sound\0")
s.SoundId = "rbxassetid://12221967"
s.Volume = 1
s.PlayOnRemove = true
s.Parent = block
s:Destroy()]]
end
for i,v in ore do
if position.Y <= config.y_origin + (v.y[1] * config.grid) and position.Y >= config.y_origin + (v.y[2] * config.grid) then
local n = math.noise(position.x / v.w, position.z / v.w, (position.y + seed + i) / v.w) * 1.15
if n >= v.freq or v.freq == -1 then
for _, face in Enum.NormalId:GetEnumItems() do
local d = Instance.new("Decal\0")
d.Texture = v.id
d.Face = face
d.Parent = block
end
ore_data = v
ore_ind = i
break
end
end
end
block:SetAttribute("OreData", ore_ind)
block:SetAttribute("MinesBlock", true)
block:SetAttribute("Position", position)
block.Destroying:Connect(function()
if ore_data and ore_data.unmineable then
if math.random() >= 0.9 then
return
end
end
self:remove(block)
end)
self.solid_blocks:set(position, {
block,
ore_data
})
local click_detector = Instance.new("ClickDetector\0")
click_detector.Parent = block
click_detector.MouseClick:Connect(function(player)
local sfx = Instance.new("Sound\0")
sfx.PlayOnRemove = true
sfx.SoundId = "rbxassetid://6496157434"
sfx.Volume = 1
sfx.PlaybackSpeed = 1 + (math.random() / 3.5)
sfx.Parent = block
sfx:Destroy()
task.delay(2, game.Destroy, sfx)
self:remove(block, player)
end)
return block
end
function player_handler(player)
player.Chatted:Connect(function(m)
if m:sub(1,5) == "!seed" then
seed = tonumber(m:sub(7))
is_gen = true
storage:ClearAllChildren()
gen.air_blocks:clear()
gen.solid_blocks:clear()
for xv = config.x * config.grid * -0.5, config.x * config.grid * 0.5, config.grid do
for zv = config.z * config.grid * -0.5, config.z * config.grid * 0.5, config.grid do
local b = gen:new_block(vec(xv, config.y_origin, zv), true)
if (zv + xv) % 25 == 0 then
task.wait()
end
end
end
is_gen = false
local msg = Instance.new("Message", script)
msg.Text = "Mines V2 loaded. Say !mines to teleport."
task.delay(3.5, game.Destroy, msg)
end
if m == "!mines" then
local character = player.Character
if character then
character:MoveTo(storage:GetChildren()[1].Position)
end
end
end)
end
local players = game:GetService("Players")
for i,v in players:GetPlayers() do
player_handler(v)
end
players.PlayerAdded:Connect(player_handler)
local request_api = Instance.new("Folder", script)
request_api.Name = "MINES_API"
local new_block = Instance.new("BindableFunction", request_api)
new_block.Name = "new_block"
new_block.OnInvoke = function(...)
return gen:new_block(...)
end
local set_air = Instance.new("BindableFunction", request_api)
set_air.Name = "set_air"
set_air.OnInvoke = function(...)
return gen:set_air(...)
end
local remove = Instance.new("BindableEvent", request_api)
remove.Name = "remove"
remove.Event:Connect(function(...)
gen:remove(...)
end)
local add_cache = Instance.new("BindableEvent", request_api)
add_cache.Name = "add_cache"
add_cache.Event:Connect(function(...)
gen:add_cache(...)
end)
--[[
local API = workspace:FindFirstChild("MINES_API", true)
local gen = setmetatable({}, {
__index = function(self, index)
local endpoint = API:FindFirstChild(index)
local call = endpoint:IsA("BindableEvent") and endpoint.Fire or endpoint.Invoke
return function(self,...)
return call(endpoint, ...)
end
end
})
shared.gen = gen
]]
local x, y, z = config.x, config.y_origin, config.z
local pos = CFrame.new(0, y, 0)
local sp = Instance.new("SpawnLocation")
sp.Anchored = true
sp.Position = pos.Position
sp.Transparency = 1
sp.Parent = script
local part = Instance.new("Part")
part.BottomSurface = Enum.SurfaceType.Smooth
part.CFrame = pos + Vector3.new(1024 + (x * config.grid * 0.5) + 0.5, config.grid, 0)
part.Material = Enum.Material.Slate
part.Size = Vector3.new(2048, config.grid, 2048)
part.Anchored = true
part.TopSurface = Enum.SurfaceType.Smooth
part.Parent = script
local part = Instance.new("Part")
part.BottomSurface = Enum.SurfaceType.Smooth
part.CFrame = pos - Vector3.new(1024 + (x * config.grid * 0.5) - 0.5, -config.grid, 0)
part.Material = Enum.Material.Slate
part.Size = Vector3.new(2048, config.grid, 2048)
part.Anchored = true
part.TopSurface = Enum.SurfaceType.Smooth
part.Parent = script
local part = Instance.new("Part")
part.BottomSurface = Enum.SurfaceType.Smooth
part.CFrame = pos - Vector3.new(-0.5, -config.grid, 512 + (x * config.grid * 0.5) - 0.5)
part.Material = Enum.Material.Slate
part.Size = Vector3.new(x * config.grid, config.grid, 1024)
part.Anchored = true
part.TopSurface = Enum.SurfaceType.Smooth
part.Parent = script
local part = Instance.new("Part")
part.BottomSurface = Enum.SurfaceType.Smooth
part.CFrame = pos + Vector3.new(0.5, config.grid, 512 + (x * config.grid * 0.5) + 0.5)
part.Material = Enum.Material.Slate
part.Size = Vector3.new(x * config.grid, config.grid, 1024)
part.Anchored = true
part.TopSurface = Enum.SurfaceType.Smooth
part.Parent = script