mirror of
https://github.com/FaceDeer/dfcaverns.git
synced 2025-01-23 16:50:17 +01:00
A simple pit cave mod, based off of code from the volcano pipes in my magma_conduits mod
This commit is contained in:
parent
79fd356477
commit
c71766aaea
@ -5,7 +5,7 @@ Sounds and textures are under various licenses, see the license.txt file in the
|
||||
License for Code
|
||||
----------------
|
||||
|
||||
Copyright (C) 2018 FaceDeer
|
||||
Copyright (C) 2021 FaceDeer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
22
pit_caves/LICENSE.txt
Normal file
22
pit_caves/LICENSE.txt
Normal file
@ -0,0 +1,22 @@
|
||||
License for Code
|
||||
----------------
|
||||
|
||||
Copyright (C) 2021 FaceDeer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
196
pit_caves/init.lua
Normal file
196
pit_caves/init.lua
Normal file
@ -0,0 +1,196 @@
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
local min_depth = tonumber(minetest.settings:get("pit_caves_min_bottom") or -2500)
|
||||
local max_depth = tonumber(minetest.settings:get("pit_caves_max_bottom") or -500)
|
||||
local min_top = tonumber(minetest.settings:get("pit_caves_min_top") or -100)
|
||||
local max_top = tonumber(minetest.settings:get("pit_caves_max_top") or 100)
|
||||
|
||||
assert(min_depth < max_depth, "pit_caves_min_bottom is above pit_caves_max_bottom")
|
||||
assert(min_top < max_top, "pit_caves_min_top is above pit_caves_max_top")
|
||||
assert(max_depth < min_top, "pit_caves_max_bottom is above pit_caves_min_top")
|
||||
|
||||
local pit_radius = 3 -- approximate minimum radius of pit - noise adds a lot to this
|
||||
|
||||
local region_mapblocks = tonumber(minetest.settings:get("pit_caves_mapblock_spacing") or 16)
|
||||
local mapgen_chunksize = tonumber(minetest.get_mapgen_setting("chunksize"))
|
||||
local pit_region_size = region_mapblocks * mapgen_chunksize * 16
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_gravel = c_air
|
||||
if minetest.get_modpath("default") then
|
||||
c_gravel = minetest.get_content_id("default:gravel")
|
||||
end
|
||||
|
||||
local water_level = tonumber(minetest.get_mapgen_setting("water_level"))
|
||||
local mapgen_seed = tonumber(minetest.get_mapgen_setting("seed")) % 2^16
|
||||
|
||||
local scatter_2d = function(min_xz, gridscale, border_width)
|
||||
local bordered_scale = gridscale - 2 * border_width
|
||||
local point = {}
|
||||
point.x = math.floor(math.random() * bordered_scale + min_xz.x + border_width)
|
||||
point.y = 0
|
||||
point.z = math.floor(math.random() * bordered_scale + min_xz.z + border_width)
|
||||
return point
|
||||
end
|
||||
|
||||
-- For some reason, map chunks generate with -32, -32, -32 as the "origin" minp. To make the large-scale grid align with map chunks it needs to be offset like this.
|
||||
local get_corner = function(pos)
|
||||
return {x = math.floor((pos.x+32) / pit_region_size) * pit_region_size - 32, z = math.floor((pos.z+32) / pit_region_size) * pit_region_size - 32}
|
||||
end
|
||||
|
||||
local get_pit = function(pos)
|
||||
local corner_xz = get_corner(pos)
|
||||
local next_seed = math.random(1, 1000000000)
|
||||
math.randomseed(corner_xz.x + corner_xz.z * 2 ^ 8 + mapgen_seed + 1)
|
||||
|
||||
local location = scatter_2d(corner_xz, pit_region_size, 0)
|
||||
local depth = math.floor(math.random() * (max_depth - min_depth) + min_depth)
|
||||
local top = math.floor(math.random() * (max_top - min_top) + min_top)
|
||||
|
||||
math.randomseed(next_seed)
|
||||
return {location = location, depth = depth, top = top}
|
||||
end
|
||||
|
||||
local perlin_params = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
spread = {x=30, y=30, z=30},
|
||||
seed = 45011,
|
||||
octaves = 3,
|
||||
persist = 0.67
|
||||
}
|
||||
local data = {}
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, seed)
|
||||
if minp.y > max_top or maxp.y < min_depth then
|
||||
return
|
||||
end
|
||||
|
||||
local pit = get_pit(minp)
|
||||
|
||||
if pit == nil then
|
||||
return -- no pit in this map region
|
||||
end
|
||||
|
||||
local location_x = pit.location.x
|
||||
local location_z = pit.location.z
|
||||
|
||||
-- early out if the pit is too far away to matter
|
||||
-- The plus 20 is because the noise being added will generally be in the 0-20 range, see the "distance" calculation below
|
||||
if location_x - 20 > maxp.x or
|
||||
location_x + 20 < minp.x or
|
||||
location_z - 20 > maxp.z or
|
||||
location_z + 20 < minp.z
|
||||
then
|
||||
return
|
||||
end
|
||||
|
||||
local top = pit.top
|
||||
local depth = pit.depth
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
||||
vm:get_data(data)
|
||||
|
||||
local nvals_perlin = mapgen_helper.perlin3d("pit_caves:pit", emin, emax, perlin_params)
|
||||
|
||||
for vi, x, y, z in area:iterp_xyz(emin, emax) do
|
||||
|
||||
local distance_perturbation = (nvals_perlin[vi]+1)*10
|
||||
local distance = vector.distance({x=x, y=y, z=z}, {x=location_x, y=y, z=location_z}) - distance_perturbation
|
||||
local taper_min = top - 40
|
||||
|
||||
if y < top and y > depth then
|
||||
|
||||
-- taper the top end
|
||||
if y > top - 40 then
|
||||
distance = distance - ((taper_min - y)/2)
|
||||
end
|
||||
|
||||
if distance < pit_radius then
|
||||
if y < depth + 20 and data[vi] ~= c_air then
|
||||
data[vi] = c_gravel
|
||||
else
|
||||
data[vi] = c_air
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--send data back to voxelmanip
|
||||
vm:set_data(data)
|
||||
--calc lighting
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
--write it to world
|
||||
vm:write_to_map()
|
||||
end)
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
-- Debugging and sightseeing commands
|
||||
|
||||
function round(val, decimal)
|
||||
if (decimal) then
|
||||
return math.floor( (val * 10^decimal) + 0.5) / (10^decimal)
|
||||
else
|
||||
return math.floor(val+0.5)
|
||||
end
|
||||
end
|
||||
|
||||
local send_pit_state = function(pos, name)
|
||||
local pit = get_pit(pos)
|
||||
if pit == nil then
|
||||
return false
|
||||
end
|
||||
local location = {x=math.floor(pit.location.x), y=pit.top, z=math.floor(pit.location.z)}
|
||||
minetest.chat_send_player(name, S("Pit at @1, bottom @2", minetest.pos_to_string(location), pit.depth))
|
||||
return true
|
||||
end
|
||||
|
||||
local send_nearby_states = function(pos, name)
|
||||
local retval = false
|
||||
retval = send_pit_state({x=pos.x-pit_region_size, y=0, z=pos.z+pit_region_size}, name) or retval
|
||||
retval = send_pit_state({x=pos.x, y=0, z=pos.z+pit_region_size}, name) or retval
|
||||
retval = send_pit_state({x=pos.x+pit_region_size, y=0, z=pos.z+pit_region_size}, name) or retval
|
||||
retval = send_pit_state({x=pos.x-pit_region_size, y=0, z=pos.z}, name) or retval
|
||||
retval = send_pit_state(pos, name) or retval
|
||||
retval = send_pit_state({x=pos.x+pit_region_size, y=0, z=pos.z}, name) or retval
|
||||
retval = send_pit_state({x=pos.x-pit_region_size, y=0, z=pos.z-pit_region_size}, name) or retval
|
||||
retval = send_pit_state({x=pos.x, y=0, z=pos.z-pit_region_size}, name) or retval
|
||||
retval = send_pit_state({x=pos.x+pit_region_size, y=0, z=pos.z-pit_region_size}, name) or retval
|
||||
return retval
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("findpit", {
|
||||
params = "pos", -- Short parameter description
|
||||
description = S("find the pits near the player's map region, or in the map region containing pos if provided"),
|
||||
func = function(name, param)
|
||||
if minetest.check_player_privs(name, {server = true}) then
|
||||
local pos = {}
|
||||
pos.x, pos.y, pos.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
|
||||
pos.x = tonumber(pos.x)
|
||||
pos.y = tonumber(pos.y)
|
||||
pos.z = tonumber(pos.z)
|
||||
if pos.x and pos.y and pos.z then
|
||||
if not send_nearby_states(pos, name) then
|
||||
minetest.chat_send_player(name, S("No pits near @1", minetest.pos_to_string(pos)))
|
||||
end
|
||||
return true
|
||||
else
|
||||
local playerobj = minetest.get_player_by_name(name)
|
||||
pos = playerobj:get_pos()
|
||||
if not send_nearby_states(pos, name) then
|
||||
pos.x = math.floor(pos.x)
|
||||
pos.y = math.floor(pos.y)
|
||||
pos.z = math.floor(pos.z)
|
||||
minetest.chat_send_player(name, S("No pits near @1", minetest.pos_to_string(pos)))
|
||||
end
|
||||
return true
|
||||
end
|
||||
else
|
||||
return false, S("You need the server privilege to use this command.")
|
||||
end
|
||||
end,
|
||||
})
|
11
pit_caves/locale/template.txt
Normal file
11
pit_caves/locale/template.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# textdomain: pit_caves
|
||||
|
||||
|
||||
### init.lua ###
|
||||
|
||||
No pits near @1=
|
||||
Pit at @1, bottom @2=
|
||||
You need the server privilege to use this command.=
|
||||
|
||||
find the pits near the player's map region, or in the map region containing pos if provided=
|
||||
|
4
pit_caves/mod.conf
Normal file
4
pit_caves/mod.conf
Normal file
@ -0,0 +1,4 @@
|
||||
name = pit_caves
|
||||
description = Inserts very tall "pit" caves underground
|
||||
depends =
|
||||
optional_depends = mapgen_helper, default
|
5
pit_caves/settingtypes.txt
Normal file
5
pit_caves/settingtypes.txt
Normal file
@ -0,0 +1,5 @@
|
||||
pit_caves_min_bottom (Lower limit of bottoms of pits) int -2500
|
||||
pit_caves_max_bottom (Upper limit of bottoms of pits) int -500
|
||||
pit_caves_min_top (Lower limit of tops of pits) int -100
|
||||
pit_caves_max_top (Upper limit of tops of pits) int 100
|
||||
pit_caves_mapblock_spacing (Average number of map blocks between pits) int 16
|
Loading…
Reference in New Issue
Block a user