climate_api support - add distance fog

Add more appropriate/atmosphere distance fog to the nether, via climate_api mod to avoid conflicting with other mods.
Any game or server with climate_api mod installed will be expecting climate_api to take control of sky values.
This commit is contained in:
Treer 2021-02-02 19:15:51 +11:00
parent 00099f2aa2
commit 3008b167b2
5 changed files with 174 additions and 42 deletions

View File

@ -6,3 +6,4 @@ fire?
loot?
mesecons?
moreblocks?
climate_api?

View File

@ -42,12 +42,18 @@ end
-- Global Nether namespace
nether = {}
nether.mapgen = {} -- Shared Nether mapgen namespace, for mapgen files to expose functions and constants
nether.modname = minetest.get_current_modname()
nether.path = minetest.get_modpath(nether.modname)
nether.get_translator = S
-- nether.useBiomes allows other mods to know whether they can register ores etc. in the Nether.
-- See mapgen.lua for an explanation of why minetest.read_schematic is being checked
nether.useBiomes = minetest.get_mapgen_setting("mg_name") ~= "v6" and minetest.read_schematic ~= nil
nether.fogColor = { -- only used if climate_api is installed
netherCaverns = "#1D0504", -- Distance-fog colour for classic nether
mantle = "#070916", -- Distance-fog colour for the Mantle region
geodes = "#300530" -- Distance-fog colour for secondary region
}
-- Settings
@ -227,7 +233,89 @@ The expedition parties have found no diamonds or gold, and after an experienced
end
})
-- Set appropriate nether distance-fog if climate_api is available
--
-- Delegating to a mod like climate_api means nether won't unexpectedly stomp on the sky of
-- any other mod.
-- Skylayer is another mod which can perform this role, and skylayer support could be added
-- here as well. However skylayer doesn't provide a position-based method of specifying sky
-- colours out-of-the-box, so the nether mod will have to monitor when players enter and
-- leave the nether.
if minetest.get_modpath("climate_api") and minetest.global_exists("climate_api") and climate_api.register_weather ~= nil then
climate_api.register_influence(
"nether_biome",
function(pos)
local result = "surface"
if pos.y <= nether.DEPTH_CEILING and pos.y >= nether.DEPTH_FLOOR then
result = "nether"
if nether.mapgen.getRegion ~= nil then
-- the biomes-based mapgen supports 2 extra regions
local regions = nether.mapgen.RegionEnum
local region = nether.mapgen.getRegion(pos)
if region == regions.Center or region == regions.CenterShell then
result = "mantle"
elseif region == regions.Negative or region == regions.NegativeShell then
result = "geode"
end
end
end
return result
end
)
-- using sky type "plain" unfortunately means we don't get smooth fading transitions when
-- the color of the sky changes, but it seems to be the only way to obtain a sky colour
-- which doesn't brighten during the daytime.
local undergroundSky = {
sky_data = {
base_color = nil,
type = "plain",
textures = nil,
clouds = false,
},
sun_data = {
visible = false,
sunrise_visible = false
},
moon_data = {
visible = false
},
star_data = {
visible = false
}
}
local netherSky, mantleSky, geodeSky = table.copy(undergroundSky), table.copy(undergroundSky), table.copy(undergroundSky)
netherSky.sky_data.base_color = nether.fogColor.netherCaverns
mantleSky.sky_data.base_color = nether.fogColor.mantle
geodeSky.sky_data.base_color = nether.fogColor.geodes
climate_api.register_weather(
"nether:nether",
{ nether_biome = "nether" },
{ ["climate_api:skybox"] = netherSky }
)
climate_api.register_weather(
"nether:mantle",
{ nether_biome = "mantle" },
{ ["climate_api:skybox"] = mantleSky }
)
climate_api.register_weather(
"nether:geode",
{ nether_biome = "geode" },
{ ["climate_api:skybox"] = geodeSky }
)
end
end -- end of "if nether.NETHER_REALM_ENABLED..."
-- Play bubbling lava sounds if player killed by lava

View File

@ -45,7 +45,6 @@ local BASALT_COLUMN_LOWER_LIMIT = CENTER_CAVERN_LIMIT * 0.25 -- This value
-- Shared Nether mapgen namespace
-- For mapgen files to share functions and constants
nether.mapgen = {}
local mapgen = nether.mapgen
mapgen.TCAVE = TCAVE -- const needed in mapgen_mantle.lua
@ -257,6 +256,19 @@ mapgen.np_cave = {
--flags = ""
}
local cavePointPerlin = nil
mapgen.getCavePointPerlin = function()
cavePointPerlin = cavePointPerlin or minetest.get_perlin(mapgen.np_cave)
return cavePointPerlin
end
mapgen.getCavePerlinAt = function(pos)
cavePointPerlin = cavePointPerlin or minetest.get_perlin(mapgen.np_cave)
return cavePointPerlin:get3d(pos)
end
-- Buffers and objects we shouldn't recreate every on_generate
local nobj_cave = nil
@ -658,7 +670,7 @@ end
-- use knowledge of the nether mapgen algorithm to return a suitable ground level for placing a portal.
-- player_name is optional, allowing a player to spawn a remote portal in their own protected areas.
function nether.find_nether_ground_y(target_x, target_z, start_y, player_name)
local nobj_cave_point = minetest.get_perlin(mapgen.np_cave)
local nobj_cave_point = mapgen.getCavePointPerlin()
local air = 0 -- Consecutive air nodes found
local minp_schem, maxp_schem = nether.get_schematic_volume({x = target_x, y = 0, z = target_z}, nil, "nether_portal")

View File

@ -49,7 +49,6 @@ local np_basalt = {
local nobj_basalt = nil
local nbuf_basalt = {}
local cavePerlin = nil
-- Content ids
@ -414,22 +413,27 @@ mapgen.excavate_tunnel_to_center_of_the_nether = function(data, area, nvals_cave
end
minetest.register_chatcommand("nether_whereami",
{
description = "Describes which region of the nether the player is in",
privs = {debug = true},
func = function(name, param)
-- an enumerated list of the different regions in the nether
mapgen.RegionEnum = {
Overworld = "overworld", -- Outside the Nether / none of the regions in the Nether
Positive = "positive", -- The classic nether caverns are here - where cavePerlin > 0.6
PositiveShell = "positive shell", -- the nether side of the wall/buffer area separating classic nether from the mantle
Center = "center", -- The Mantle caverns are here
CenterShell = "center shell", -- the mantle side of the wall/buffer area separating the positive and negative regions from the center region
Negative = "negative", -- Secondary/spare region - where cavePerlin < -0.6
NegativeShell = "negative shell", -- the spare region side of the wall/buffer area separating the negative region from the mantle
}
local player = minetest.get_player_by_name(name)
if player == nil then return false, "Unknown player position" end
local pos = vector.round(player:get_pos())
-- Returns (region, noise) where region is a value from mapgen.RegionEnum
-- and noise is the unadjusted cave perlin value
mapgen.getRegion = function(pos)
if pos.y > nether.DEPTH_CEILING or pos.y < nether.DEPTH_FLOOR then
return true, "The Overworld"
return mapgen.RegionEnum.Overworld, nil
end
cavePerlin = cavePerlin or minetest.get_perlin(mapgen.np_cave)
local densityNoise = cavePerlin:get_3d(pos)
local caveNoise = mapgen.getCavePerlinAt(pos)
local sea_level, cavern_limit_distance = mapgen.find_nearest_lava_sealevel(pos.y)
local tcave_adj, centerRegionLimit_adj = mapgen.get_mapgenblend_adjustments(pos.y)
local tcave = mapgen.TCAVE + tcave_adj
@ -438,28 +442,55 @@ minetest.register_chatcommand("nether_whereami",
mapgen.CENTER_REGION_LIMIT * (cavern_limit_distance * cavern_limit_distance * cavern_limit_distance) -
centerRegionLimit_adj -- cavern_noise_adj gets added to noise value instead of added to the limit np_noise is compared against, so subtract centerRegionLimit_adj so subtract centerRegionLimit_adj instead of adding
local desc
local region
if caveNoise > tcave then
region = mapgen.RegionEnum.Positive
elseif -caveNoise > tcave then
region = mapgen.RegionEnum.Negative
elseif math_abs(caveNoise) < tmantle then
if densityNoise > tcave then
desc = "Positive nether"
elseif -densityNoise > tcave then
desc = "Negative nether"
elseif math_abs(densityNoise) < tmantle then
desc = "Mantle"
if math_abs(densityNoise) + cavern_noise_adj < mapgen.CENTER_CAVERN_LIMIT then
desc = desc .. " inside cavern"
if math_abs(caveNoise) + cavern_noise_adj < mapgen.CENTER_CAVERN_LIMIT then
region = mapgen.RegionEnum.Center
else
desc = desc .. " but outside cavern"
region = mapgen.RegionEnum.CenterShell
end
elseif densityNoise > 0 then
desc = "Shell between positive nether and center region"
elseif caveNoise > 0 then
region = mapgen.RegionEnum.PositiveShell
else
desc = "Shell between negative nether and center region"
region = mapgen.RegionEnum.NegativeShell
end
local sea_pos = pos.y - sea_level
return region, caveNoise
end
minetest.register_chatcommand("nether_whereami",
{
description = "Describes which region of the nether the player is in",
privs = {debug = true},
func = function(name, param)
local player = minetest.get_player_by_name(name)
if player == nil then return false, "Unknown player position" end
local playerPos = vector.round(player:get_pos())
local region, caveNoise = mapgen.getRegion(playerPos)
local seaLevel, cavernLimitDistance = mapgen.find_nearest_lava_sealevel(playerPos.y)
local tcave_adj, centerRegionLimit_adj = mapgen.get_mapgenblend_adjustments(playerPos.y)
local regionLabels = {
[mapgen.RegionEnum.Overworld] = "The Overworld",
[mapgen.RegionEnum.Positive] = "Positive nether",
[mapgen.RegionEnum.PositiveShell] = "Shell between positive nether and center region",
[mapgen.RegionEnum.Center] = "Center/Mantle, inside cavern",
[mapgen.RegionEnum.CenterShell] = "Center/Mantle, but outside the caverns",
[mapgen.RegionEnum.Negative] = "Negative nether",
[mapgen.RegionEnum.NegativeShell] = "Shell between negative nether and center region"
}
local desc = regionLabels[region]
local sea_pos = playerPos.y - seaLevel
if sea_pos > 0 then
desc = desc .. ", " .. sea_pos .. "m above lava-sea level"
else
@ -470,7 +501,7 @@ minetest.register_chatcommand("nether_whereami",
desc = desc .. ", approaching y boundary of Nether"
end
return true, "[Perlin " .. (math_floor(densityNoise * 1000) / 1000) .. "] " .. desc
return true, "[Perlin " .. (math_floor(caveNoise * 1000) / 1000) .. "] " .. desc
end
}
)

View File

@ -1,4 +1,4 @@
name = nether
description = Adds a deep underground realm with different mapgen that you can reach with obsidian portals.
depends = stairs, default
optional_depends = moreblocks, mesecons, loot, dungeon_loot, doc_basics, fire
optional_depends = moreblocks, mesecons, loot, dungeon_loot, doc_basics, fire, climate_api