mirror of
https://github.com/FaceDeer/dfcaverns.git
synced 2025-07-04 01:10:38 +02:00
Compare commits
6 Commits
bubble-cav
...
v2.4.4
Author | SHA1 | Date | |
---|---|---|---|
de08a9d481 | |||
8edf220213 | |||
2f2577eada | |||
06096ddc8f | |||
b27a9eb8da | |||
a6cd433ecf |
60
API.md
Normal file
60
API.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Chat commands
|
||||
|
||||
There are not many chat commands provided by this modpack since it's primarily a mapgen mod. Only one is available to non-server-admins:
|
||||
|
||||
`mute_df_ambience`: Mutes or unmutes ambient sounds in deep caverns. This muted state is saved per-player, so players that are bothered by ambient sounds can disable them for themselves.
|
||||
|
||||
The following are only available for server admins:
|
||||
|
||||
`find_pit`: Finds the nearest glowing pit in the Underworld layer.
|
||||
|
||||
`mapgen_helper_loc` and `mapgen_helper_tour`: only available if the `mapgen_helper_log_locations` setting has been set to true. mapgen_helper will then record the locations of various types of mapgen feature as they are generated, and these commands will teleport the server admin to them.
|
||||
|
||||
`find_pit_caves`: Lists the locations of nearby vertical shaft caverns, including the top and bottom elevations.
|
||||
|
||||
# APIs
|
||||
|
||||
Not all APIs are listed here, this list focuses on APIs that modders may wish to use in sub-mods that modify DF Caverns' functionality in the existing context of this modpack.
|
||||
|
||||
## bones_loot
|
||||
|
||||
This mod populates the bones in the underworld with loot.
|
||||
|
||||
`bones_loot.register_loot`
|
||||
|
||||
Uses same table format as dungeon_loot from the default minetest_game. eg, {{name = "bucket:bucket_water", chance = 0.45, types = {"sandstone", "desert"}},
|
||||
|
||||
if dungeon_loot is installed it uses dungeon_loot's registration function directly.
|
||||
|
||||
## chasms
|
||||
|
||||
`chasms.register_ignore(node_name)`: Use this to set node types to be left alone by chasm-carving
|
||||
|
||||
`chasms.is_in_chasm(pos)`: returns true if pos is inside a chasm.
|
||||
|
||||
## df_ambience
|
||||
|
||||
`df_ambience.add_set(def)`: adds a sound set to the ambience mod. See soundsets.lua for a bunch of examples of what can go in the `def` table.
|
||||
|
||||
This mod has a lot of similarities to the [https://notabug.org/TenPlus1/ambience](ambience) mod, but after struggling to get that mod to "play nice" with df_caverns' needs it turned out to be easier to just re-implement the specific parts of the mod that were needed here.
|
||||
|
||||
## df_caverns
|
||||
|
||||
`df_caverns.get_biome(pos)`: returns the string name of the df_cavern biome that pos is located in, or nil if it's outside of any of df_caverns' cavern layers. df_caverns uses a homebrew biome system rather than the built-in biome registration system.
|
||||
|
||||
`df_caverns.is_ground_content(node_id)`: used by subterrane's mapgen to avoid removing nodes placed by df_caverns' mapgen. If you're adding new map features inside dfcavern's hollow spaces and they're being chopped in half at mapblock boundaries then you may be able to solve this by overriding this method with one that recognizes the nodes you're adding.
|
||||
|
||||
This was never really expected to be something that someone would need to do, though, so this is a little clunky. If you're having trouble with this please file an issue.
|
||||
|
||||
`df_caverns.populate_puzzle_chest(pos)`: When a "puzzle chest" is generated in the Underworld ruins this method gets called to populate its contents. If you wish to override the contents of the puzzle chest then you can override this method. Place items in the "main" inventory at the pos parameter's location.
|
||||
|
||||
## looped_node_sound
|
||||
|
||||
`looped_node_sound.register(def)`: A simple mod for making nodes emit a looped sound when the player is nearby.
|
||||
|
||||
def = {
|
||||
node_list = {"df_trees:torchspine_1_lit"},
|
||||
sound = "dfcaverns_torchspine_loop",
|
||||
max_gain = 0.5,
|
||||
gain_per_node = 0.05,
|
||||
}
|
@ -28,6 +28,8 @@ Some of the other cave decorations provide dim bioluminescent lighting in some c
|
||||
|
||||
[A more comprehensive guide can be found here.](guide.md)
|
||||
|
||||
[APIs and player commands can be found here.](API.md)
|
||||
|
||||
## Synergies with other mods
|
||||
|
||||
"[dynamic liquid](https://github.com/minetest-mods/dynamic_liquid)" is recommended to provide Dwarf Fortress-like fluid dynamics and to deal with water that might spill into caverns.
|
||||
|
@ -1,144 +0,0 @@
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
local mapgen_test_path = minetest.get_modpath("mapgen_test")
|
||||
--local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local c_air = minetest.get_content_id("air")
|
||||
|
||||
local c_glow
|
||||
if minetest.get_modpath("df_underworld_items") then
|
||||
c_glow = minetest.get_content_id("df_underworld_items:glowstone")
|
||||
end
|
||||
|
||||
local perlin_params = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
spread = {x=1000, y=500, z=1000},
|
||||
seed = 501221,
|
||||
octaves = 3,
|
||||
persist = 0.67
|
||||
}
|
||||
local data = {}
|
||||
local light_data = {}
|
||||
local light = 15 + (15 * 16)
|
||||
|
||||
local max_depth = -5000
|
||||
local min_depth = -6000
|
||||
|
||||
local noise_obj
|
||||
|
||||
local block_size = 80
|
||||
local cube_inside = 1/math.sqrt(3) -- https://www.quora.com/What-is-the-largest-volume-of-a-cube-that-can-be-enclosed-in-a-sphere-of-diameter-2
|
||||
|
||||
local get_bubbles = function(pos)
|
||||
noise_obj = noise_obj or minetest.get_perlin(perlin_params)
|
||||
local bubbles = {}
|
||||
local next_seed = math.random(1000000)
|
||||
for block_x = -1, 1 do
|
||||
for block_y = -1, 1 do
|
||||
for block_z = -1, 1 do
|
||||
local this_pos = vector.add(pos, {x=block_x*block_size, y=block_y*block_size, z=block_z*block_size})
|
||||
math.randomseed(this_pos.x + this_pos.y*8 + this_pos.z*16)
|
||||
this_pos.x = this_pos.x + math.floor(math.random()*block_size - block_size/2)
|
||||
this_pos.y = this_pos.y + math.floor(math.random()*block_size - block_size/2)
|
||||
this_pos.z = this_pos.z + math.floor(math.random()*block_size - block_size/2)
|
||||
local noise_val = math.min(noise_obj:get_3d(this_pos), 1.0)
|
||||
if noise_val > 0 then
|
||||
local radius = noise_val*block_size*math.random()+5
|
||||
local y = this_pos.y
|
||||
if y + radius < max_depth and y - radius > min_depth then -- make sure bubbles remain within the layer
|
||||
if mapgen_test_path then
|
||||
if noise_val < 0.1 then
|
||||
mapgen_test.record_first_location("bubble cave sparse", this_pos, "a bubble cave in a sparsely populated region")
|
||||
elseif noise_val < 0.55 and noise_val > 0.45 then
|
||||
mapgen_test.record_first_location("bubble cave middle", this_pos, "a bubble cave in a middlingly populated region")
|
||||
elseif noise_val > 0.9 then
|
||||
mapgen_test.record_first_location("bubble cave dense", this_pos, "a bubble cave in a densely populated region")
|
||||
end
|
||||
end
|
||||
table.insert(bubbles, {loc=this_pos, radius=radius})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
math.randomseed(next_seed)
|
||||
return bubbles
|
||||
end
|
||||
|
||||
|
||||
if mapgen_test_path then
|
||||
mapgen_test.log_time_settings("bubble_caves")
|
||||
end
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, seed)
|
||||
if minp.y > max_depth or maxp.y < min_depth then
|
||||
return
|
||||
end
|
||||
|
||||
local nearby_bubbles = get_bubbles({x=minp.x+block_size/2, y=minp.y+block_size/2, z=minp.z+block_size/2})
|
||||
if not next(nearby_bubbles) then
|
||||
return
|
||||
end
|
||||
|
||||
if mapgen_test_path then
|
||||
mapgen_test.log_time_start("bubble_caves")
|
||||
end
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
||||
vm:get_data(data)
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:get_light_data(light_data)
|
||||
|
||||
for vi, x, y, z in area:iterp_xyz(emin, emax) do
|
||||
for _, bubble in pairs(nearby_bubbles) do
|
||||
if data[vi] ~= c_air then
|
||||
local loc = bubble.loc
|
||||
local loc_x = loc.x
|
||||
local loc_y = loc.y
|
||||
local loc_z = loc.z
|
||||
local radius = bubble.radius
|
||||
-- check outer bounding box first, faster than true distance
|
||||
if x <= loc_x + radius and x >= loc_x - radius and y <= loc_y + radius and y >= loc_y - radius and z <= loc_z + radius and z >= loc_z - radius then
|
||||
local inner_box = radius * cube_inside
|
||||
if (x <= loc_x + inner_box and x >= loc_x - inner_box and y <= loc_y + inner_box and y >= loc_y - inner_box and z <= loc_z + inner_box and z >= loc_z - inner_box)
|
||||
or vector.distance({x=x, y=y, z=z}, loc) < radius+math.random()/2 then
|
||||
data[vi] = c_air
|
||||
light_data[vi] = light
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if c_glow then
|
||||
for _, bubble in pairs(nearby_bubbles) do
|
||||
local loc = bubble.loc
|
||||
if area:containsp(loc) then
|
||||
local vol = math.floor(bubble.radius / 20)
|
||||
if vol > 0 then
|
||||
for vi in area:iter(loc.x-vol, loc.y-vol, loc.z-vol, loc.x+vol, loc.y+vol, loc.z+vol) do
|
||||
if area:containsi(vi) then
|
||||
data[vi] = c_glow
|
||||
end
|
||||
end
|
||||
else
|
||||
data[area:indexp(loc)] = c_glow
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--send data back to voxelmanip
|
||||
vm:set_data(data)
|
||||
--calc lighting
|
||||
vm:set_light_data(light_data)
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
--write it to world
|
||||
vm:write_to_map()
|
||||
|
||||
if mapgen_test_path then
|
||||
mapgen_test.log_time_stop("bubble_caves")
|
||||
end
|
||||
|
||||
end)
|
@ -1,4 +0,0 @@
|
||||
name = bubble_caves
|
||||
description = Inserts foamy spherical bubble caves in a layer underground
|
||||
depends = mapgen_helper
|
||||
optional_depends = mapgen_test, df_underworld_items
|
@ -60,6 +60,7 @@ local plant_node_achievements =
|
||||
}
|
||||
|
||||
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
|
||||
if placer == nil then return end
|
||||
local player_name = placer:get_player_name()
|
||||
if player_name == nil then return end
|
||||
local player_awards = awards.player(player_name)
|
||||
@ -150,4 +151,4 @@ awards.register_achievement("dfcaverns_plant_all_farmables", {
|
||||
achievement_name="dfcaverns_plant_all_farmables",
|
||||
target=df_achievements.get_child_achievement_count("dfcaverns_plant_all_farmables"),
|
||||
},
|
||||
})
|
||||
})
|
||||
|
@ -47,7 +47,12 @@ df_caverns.register_biome_check(function(pos, heat, humidity)
|
||||
end
|
||||
local biome = get_biome(heat, humidity)
|
||||
if biome == "bloodnether" then
|
||||
if subterrane.get_cavern_value("cavern layer 3", pos) < 0 then
|
||||
local cavern_value = subterrane.get_cavern_value("cavern layer 3", pos)
|
||||
if cavern_value == nil then
|
||||
-- this shouldn't happen, the pos.y check above should prevent it.
|
||||
return nil
|
||||
end
|
||||
if cavern_value < 0 then
|
||||
return "nethercap"
|
||||
end
|
||||
return "bloodthorn"
|
||||
|
@ -1,4 +1,4 @@
|
||||
name = df_caverns
|
||||
description = Adds vast underground caverns in the style of Dwarf Fortress, complete with underground flora in diverse biomes. Also adds stalactite/stalagmite decorations in the smaller tunnels.
|
||||
depends = df_dependencies, subterrane, df_trees, df_mapitems
|
||||
optional_depends = df_farming, ice_sprites, oil, df_underworld_items, magma_conduits, bones_loot, named_waypoints, name_generator, fireflies, chasms, big_webs, mcl_flowers
|
||||
depends = df_dependencies, subterrane, df_trees, df_mapitems,
|
||||
optional_depends = df_farming, ice_sprites, oil, df_underworld_items, magma_conduits, bones_loot, named_waypoints, name_generator, fireflies, chasms, big_webs, mcl_flowers, mine_gas
|
@ -28,6 +28,7 @@ df_caverns.register_biome_check = function(func)
|
||||
table.insert(get_biome_at_pos_list, func)
|
||||
end
|
||||
df_caverns.get_biome = function(pos)
|
||||
pos = vector.round(pos)
|
||||
local heat = minetest.get_heat(pos)
|
||||
local humidity = minetest.get_humidity(pos)
|
||||
for _, val in pairs(get_biome_at_pos_list) do
|
||||
|
@ -17,6 +17,17 @@ if mapgen_helper.log_location_enabled then
|
||||
log_location = mapgen_helper.log_first_location
|
||||
end
|
||||
|
||||
-- Exposed as a global so that other mods can override it.
|
||||
df_caverns.populate_puzzle_chest = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
for i = 1, math.random(1,8) do
|
||||
local item = ItemStack(df_underworld_items.colour_items[math.random(1,#df_underworld_items.colour_items)])
|
||||
--item:set_count(math.random(1,4))
|
||||
inv:add_item("main", item)
|
||||
end
|
||||
end
|
||||
|
||||
local name_pit = function() end
|
||||
local name_ruin = function() end
|
||||
|
||||
@ -81,8 +92,6 @@ if named_waypoints_path then
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local c_slade = df_caverns.node_id.slade
|
||||
local c_slade_block = df_caverns.node_id.slade_block
|
||||
local c_air = df_caverns.node_id.air
|
||||
@ -496,13 +505,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
|
||||
if puzzle_chest then
|
||||
local def = minetest.registered_nodes["df_underworld_items:puzzle_chest_closed"]
|
||||
def.can_dig(puzzle_chest) -- initializes the inventory
|
||||
local meta = minetest.get_meta(puzzle_chest)
|
||||
local inv = meta:get_inventory()
|
||||
for i = 1, math.random(1,8) do
|
||||
local item = ItemStack(df_underworld_items.colour_items[math.random(1,#df_underworld_items.colour_items)])
|
||||
--item:set_count(math.random(1,4))
|
||||
inv:add_item("main", item)
|
||||
end
|
||||
df_caverns.populate_puzzle_chest(puzzle_chest)
|
||||
end
|
||||
end)
|
||||
elseif building.building_type == "medium building" then
|
||||
|
@ -215,8 +215,33 @@ if minetest.get_modpath("mcl_init") then -- Mineclone 2
|
||||
|
||||
mcl_vars.mg_overworld_min = lowest_elevation
|
||||
mcl_vars.mg_bedrock_overworld_min = mcl_vars.mg_overworld_min
|
||||
mcl_vars.mg_bedrock_overworld_max = mcl_vars.mg_overworld_min + 4
|
||||
mcl_vars.mg_lava_overworld_max = mcl_vars.mg_overworld_min + 10
|
||||
mcl_vars.mg_end_max = mcl_vars.mg_overworld_min - 2000
|
||||
mcl_vars.mg_realm_barrier_overworld_end_max = mcl_vars.mg_end_max
|
||||
mcl_vars.mg_realm_barrier_overworld_end_min = mcl_vars.mg_end_max - 11
|
||||
|
||||
-- try to detect any variables that should have been modified but weren't
|
||||
local bad_entries = {}
|
||||
for k, v in pairs(mcl_vars) do
|
||||
-- if a value is in this range, it's probably a new value added by MineClone2 that we should be adjusting, add it to the table
|
||||
if type(v) == "number" and v <= old_overworld_min + 10 and v >= mcl_vars.mg_overworld_min + 100 then
|
||||
bad_entries[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
-- mark variables as ignored that we intentionally don't change, like so:
|
||||
-- bad_entries.mg_value_that_shouldnt_be_adjusted = nil
|
||||
|
||||
for k, v in pairs(bad_entries) do
|
||||
local new_value = v + mcl_vars.mg_overworld_min - old_overworld_min
|
||||
minetest.log("error", "dfcaverns: variable wasn't modified or marked as ignored! guessing new value:")
|
||||
minetest.log("error", "mcl_var." .. tostring(k) .. " = " .. tostring(new_value) .. " -- was " .. tostring(v))
|
||||
minetest.log("error", "if it shouldn't be changed, mark it as ignored in df_dependencies/mapgen.lua like so:")
|
||||
minetest.log("error", "bad_entries." .. tostring(k) .. " = nil")
|
||||
minetest.log("error", "This is a bug, please report it to https://github.com/FaceDeer/dfcaverns/issues/new")
|
||||
mcl_vars[k] = new_value
|
||||
end
|
||||
|
||||
-- shouldn't need to worry about the setting, extend_ores checks if the ores
|
||||
-- have already been registered.
|
||||
|
@ -3,7 +3,7 @@ local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local invulnerable = df_underworld_items.config.invulnerable_slade and not minetest.settings:get_bool("creative_mode")
|
||||
|
||||
local server_diggable_only = function(pos, player)
|
||||
if player then
|
||||
if player and player:is_player() then
|
||||
return minetest.check_player_privs(player, "server")
|
||||
end
|
||||
return false
|
||||
@ -181,4 +181,4 @@ end
|
||||
|
||||
if minetest.get_modpath("mesecons_mvps") and df_underworld_items.config.invulnerable_slade then
|
||||
mesecon.register_mvps_stopper("df_underworld_items:slade")
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user