write something there
This commit is contained in:
commit
b4b6c08f4f
8546 changed files with 309825 additions and 0 deletions
9
mods/asuna/asuna_core/LICENSE
Normal file
9
mods/asuna/asuna_core/LICENSE
Normal file
|
@ -0,0 +1,9 @@
|
|||
MIT License
|
||||
|
||||
Copyright © 2024 EmptyStar <https://github.com/EmptyStar>
|
||||
|
||||
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.
|
1333
mods/asuna/asuna_core/biomes.lua
Normal file
1333
mods/asuna/asuna_core/biomes.lua
Normal file
File diff suppressed because it is too large
Load diff
38
mods/asuna/asuna_core/caves.lua
Normal file
38
mods/asuna/asuna_core/caves.lua
Normal file
|
@ -0,0 +1,38 @@
|
|||
minetest.set_mapgen_setting("mgv7_cave_width",0.0415,true)
|
||||
minetest.set_mapgen_setting("mgv7_cavern_limit",-48,true)
|
||||
minetest.set_mapgen_setting("mgv7_cavern_taper",64,true)
|
||||
minetest.set_mapgen_setting("mgv7_cavern_threshold",0.5,true)
|
||||
minetest.set_mapgen_setting("mgv7_large_cave_depth",0,true)
|
||||
minetest.set_mapgen_setting("mgv7_large_cave_flooded",0,true)
|
||||
minetest.set_mapgen_setting("mgv7_large_cave_num_min",0,true)
|
||||
minetest.set_mapgen_setting("mgv7_large_cave_num_max",0,true)
|
||||
minetest.set_mapgen_setting("mgv7_small_cave_num_min",0,true)
|
||||
minetest.set_mapgen_setting("mgv7_small_cave_num_max",0,true)
|
||||
|
||||
minetest.set_mapgen_setting_noiseparams("mgv7_np_cave1",{
|
||||
offset = 0.96,
|
||||
scale = 11.45,
|
||||
seed = 3141592653,
|
||||
spread = {
|
||||
x = 62,
|
||||
y = 32.75,
|
||||
z = 62,
|
||||
},
|
||||
octaves = 4,
|
||||
persistence = 0.44,
|
||||
lacunarity = 1.698,
|
||||
},true)
|
||||
|
||||
minetest.set_mapgen_setting_noiseparams("mgv7_np_cave2",{
|
||||
offset = 0,
|
||||
scale = 11.25,
|
||||
seed = 2718281828,
|
||||
spread = {
|
||||
x = 180,
|
||||
y = 32.75,
|
||||
z = 180,
|
||||
},
|
||||
octaves = 4,
|
||||
persistence = 0.675,
|
||||
lacunarity = 1.5,
|
||||
},true)
|
100
mods/asuna/asuna_core/climate.lua
Normal file
100
mods/asuna/asuna_core/climate.lua
Normal file
|
@ -0,0 +1,100 @@
|
|||
--[[
|
||||
Biome API noise settings
|
||||
]]
|
||||
|
||||
-- Set heat noise params
|
||||
minetest.set_mapgen_setting_noiseparams("mg_biome_np_heat",{
|
||||
flags = "default",
|
||||
lacunarity = 1,
|
||||
persistence = 0.925,
|
||||
seed = 5349,
|
||||
spread = {
|
||||
x = 2000,
|
||||
y = 2000,
|
||||
z = 2000,
|
||||
},
|
||||
scale = 42,
|
||||
octaves = 2,
|
||||
offset = 50,
|
||||
},true)
|
||||
|
||||
-- Set humidity noise params
|
||||
minetest.set_mapgen_setting_noiseparams("mg_biome_np_humidity",{
|
||||
flags = "default",
|
||||
lacunarity = 1,
|
||||
persistence = 0.925,
|
||||
seed = 842,
|
||||
spread = {
|
||||
x = 2000,
|
||||
y = 2000,
|
||||
z = 2000,
|
||||
},
|
||||
scale = 42,
|
||||
octaves = 2,
|
||||
offset = 50,
|
||||
},true)
|
||||
|
||||
-- Set heat blend noise params
|
||||
minetest.set_mapgen_setting_noiseparams("mg_biome_np_heat_blend",{
|
||||
flags = "default",
|
||||
lacunarity = 1.678,
|
||||
persistence = 0.625,
|
||||
seed = 13,
|
||||
spread = {
|
||||
x = 24,
|
||||
y = 24,
|
||||
z = 24,
|
||||
},
|
||||
scale = 0.525,
|
||||
octaves = 2,
|
||||
offset = 0,
|
||||
},true)
|
||||
|
||||
-- Set humidity blend noise params
|
||||
minetest.set_mapgen_setting_noiseparams("mg_biome_np_humidity_blend",{
|
||||
flags = "default",
|
||||
lacunarity = 1.678,
|
||||
persistence = 0.625,
|
||||
seed = 90003,
|
||||
spread = {
|
||||
x = 24,
|
||||
y = 24,
|
||||
z = 24,
|
||||
},
|
||||
scale = 0.525,
|
||||
octaves = 2,
|
||||
offset = 0,
|
||||
},true)
|
||||
|
||||
--[[
|
||||
Climate analysis command
|
||||
]]
|
||||
|
||||
-- Register climate analysis privilege
|
||||
minetest.register_privilege("climate",{
|
||||
description = "Privilege required to use the /climate command",
|
||||
give_to_singleplayer = false,
|
||||
give_to_admin = true,
|
||||
})
|
||||
|
||||
-- Register climate analysis command
|
||||
minetest.register_chatcommand("climate",{
|
||||
params = "",
|
||||
description = "analyze climate at current position",
|
||||
privs = { climate = true },
|
||||
func = function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
|
||||
if not minetest.check_player_privs("climate") then
|
||||
return false, "You do not have the 'climate' privilege necessary to use this command."
|
||||
end
|
||||
|
||||
local pos = player:get_pos()
|
||||
local data = minetest.get_biome_data(pos)
|
||||
if data then
|
||||
return true, "(" .. math.floor(pos.x) .. "," .. math.floor(pos.y) .. "," .. math.floor(pos.z) .. "): biome = " .. minetest.get_biome_name(data.biome) .. ", heat = " .. data.heat .. ", humidity = " .. data.humidity
|
||||
else
|
||||
return false, "No biome data for your current position!"
|
||||
end
|
||||
end
|
||||
})
|
816
mods/asuna/asuna_core/decor.lua
Normal file
816
mods/asuna/asuna_core/decor.lua
Normal file
|
@ -0,0 +1,816 @@
|
|||
asuna.decor = {}
|
||||
|
||||
--[[
|
||||
Flowers
|
||||
]]
|
||||
|
||||
-- Group flowers by color
|
||||
local flower_colors = {
|
||||
black = {
|
||||
"flowers:tulip_black",
|
||||
},
|
||||
white = {
|
||||
"beautiflowers:carla",
|
||||
"beautiflowers:cloe",
|
||||
"beautiflowers:genesis",
|
||||
"beautiflowers:gloria",
|
||||
"beautiflowers:hadassa",
|
||||
"beautiflowers:ingrid",
|
||||
"beautiflowers:irene",
|
||||
"beautiflowers:iris",
|
||||
"beautiflowers:ivette",
|
||||
"beautiflowers:michelle",
|
||||
"beautiflowers:suri",
|
||||
"flowers:dandelion_white",
|
||||
"herbs:achillea_white",
|
||||
"herbs:leontopodium_white",
|
||||
"herbs:leucanthemum_white",
|
||||
"herbs:trifolium_white",
|
||||
},
|
||||
blue = {
|
||||
"beautiflowers:beatriz",
|
||||
"beautiflowers:berta",
|
||||
"flowers:geranium",
|
||||
"herbs:centaurea",
|
||||
"herbs:campanula_blue",
|
||||
"herbs:digitalis_blue",
|
||||
"herbs:iris",
|
||||
"bakedclay:delphinium",
|
||||
},
|
||||
cyan = {
|
||||
"beautiflowers:thais",
|
||||
"beautiflowers:valentina",
|
||||
"beautiflowers:valeria",
|
||||
"beautiflowers:vera",
|
||||
"beautiflowers:victoria",
|
||||
"beautiflowers:virginia",
|
||||
"beautiflowers:xenia",
|
||||
"beautiflowers:zaida",
|
||||
},
|
||||
orange = {
|
||||
"beautiflowers:dafne",
|
||||
"beautiflowers:dana",
|
||||
"beautiflowers:delia",
|
||||
"beautiflowers:elena",
|
||||
"beautiflowers:erica",
|
||||
"beautiflowers:estela",
|
||||
"beautiflowers:eva",
|
||||
"beautiflowers:fabiola",
|
||||
"beautiflowers:fiona",
|
||||
"beautiflowers:gala",
|
||||
"flowers:tulip",
|
||||
},
|
||||
yellow = {
|
||||
"beautiflowers:ada",
|
||||
"beautiflowers:agnes",
|
||||
"beautiflowers:alicia",
|
||||
"beautiflowers:alma",
|
||||
"beautiflowers:amaia",
|
||||
"beautiflowers:anastasia",
|
||||
"beautiflowers:any",
|
||||
"flowers:dandelion_yellow",
|
||||
"farming:sunflower_8",
|
||||
"herbs:digitalis_yellow",
|
||||
"herbs:plantago",
|
||||
},
|
||||
purple = {
|
||||
"beautiflowers:arleth",
|
||||
"beautiflowers:astrid",
|
||||
"beautiflowers:belen",
|
||||
"beautiflowers:blanca",
|
||||
"beautiflowers:casandra",
|
||||
"beautiflowers:clara",
|
||||
"beautiflowers:claudia",
|
||||
"beautiflowers:minerva",
|
||||
"beautiflowers:miriam",
|
||||
"beautiflowers:nazareth",
|
||||
"beautiflowers:noemi",
|
||||
"beautiflowers:olga",
|
||||
"beautiflowers:paula",
|
||||
"beautiflowers:regina",
|
||||
"beautiflowers:rocio",
|
||||
"beautiflowers:sabrina",
|
||||
"beautiflowers:vanesa",
|
||||
"flowers:viola",
|
||||
"beautiflowers:xena",
|
||||
},
|
||||
red = {
|
||||
"beautiflowers:arcoiris",
|
||||
"beautiflowers:jennifer",
|
||||
"beautiflowers:lara",
|
||||
"beautiflowers:laura",
|
||||
"beautiflowers:lidia",
|
||||
"beautiflowers:lucia",
|
||||
"beautiflowers:mara",
|
||||
"beautiflowers:martina",
|
||||
"beautiflowers:melania",
|
||||
"beautiflowers:mireia",
|
||||
"beautiflowers:nadia",
|
||||
"beautiflowers:nerea",
|
||||
"beautiflowers:noelia",
|
||||
"flowers:rose",
|
||||
"herbs:dosera",
|
||||
"herbs:papaver_red",
|
||||
},
|
||||
pink = {
|
||||
"beautiflowers:caroline",
|
||||
"beautiflowers:cristina",
|
||||
"beautiflowers:diana",
|
||||
"beautiflowers:gisela",
|
||||
"beautiflowers:olimpia",
|
||||
"beautiflowers:oriana",
|
||||
"beautiflowers:pia",
|
||||
"beautiflowers:raquel",
|
||||
"beautiflowers:ruth",
|
||||
"beautiflowers:sandra",
|
||||
"beautiflowers:sara",
|
||||
"beautiflowers:silvia",
|
||||
"beautiflowers:sofia",
|
||||
"beautiflowers:sonia",
|
||||
"beautiflowers:talia",
|
||||
"herbs:antirrhinum",
|
||||
"herbs:trifolium_red",
|
||||
"bakedclay:thistle",
|
||||
"bakedclay:lazarus",
|
||||
"ethereal:lilac",
|
||||
},
|
||||
green = {
|
||||
"flowers:chrysanthemum_green",
|
||||
"beautiflowers:pasto_1",
|
||||
"beautiflowers:pasto_2",
|
||||
"beautiflowers:pasto_3",
|
||||
"beautiflowers:pasto_4",
|
||||
"beautiflowers:pasto_5",
|
||||
"beautiflowers:pasto_6",
|
||||
"beautiflowers:pasto_7",
|
||||
"beautiflowers:pasto_8",
|
||||
"beautiflowers:pasto_9",
|
||||
"beautiflowers:pasto_10",
|
||||
"bakedclay:mannagrass",
|
||||
},
|
||||
red_mushroom = {
|
||||
"flowers:mushroom_red",
|
||||
},
|
||||
brown_mushroom = {
|
||||
"flowers:mushroom_brown",
|
||||
"herbs:mushroom_boletus",
|
||||
"herbs:mushroom_cantharellus",
|
||||
"herbs:mushroom_macrolepiota",
|
||||
},
|
||||
odd_mushroom = {
|
||||
"herbs:mushroom_amanita_green",
|
||||
"herbs:mushroom_gyromitra",
|
||||
"herbs:mushroom_galerina",
|
||||
}
|
||||
}
|
||||
|
||||
-- Register flower decorations per biome
|
||||
local function cf(biome)
|
||||
local decor = {
|
||||
flowers = {},
|
||||
mushrooms = {},
|
||||
}
|
||||
|
||||
-- Generate list of flowers
|
||||
for _,flower in ipairs(biome.flowers or {}) do
|
||||
for _,flower in ipairs(flower_colors[flower]) do
|
||||
table.insert(decor.flowers,flower)
|
||||
end
|
||||
end
|
||||
|
||||
-- Generate list of mushrooms
|
||||
for _,mushroom in ipairs(biome.mushrooms or {}) do
|
||||
for _,mushroom in ipairs(flower_colors[mushroom .. "_mushroom"]) do
|
||||
table.insert(decor.mushrooms,mushroom)
|
||||
end
|
||||
end
|
||||
|
||||
return decor
|
||||
end
|
||||
|
||||
-- Do actual decoration registration after other mods are finished
|
||||
minetest.register_on_mods_loaded(function()
|
||||
-- Register shore grass
|
||||
local sandy_biomes = {}
|
||||
local desert_biomes = {
|
||||
desert = true,
|
||||
sandstone_desert = true,
|
||||
desert_shore = true,
|
||||
sandstone_desert_shore = true,
|
||||
desert_below = true,
|
||||
sandstone_desert_below = true,
|
||||
}
|
||||
for biome,def in pairs(asuna.biomes) do
|
||||
if def.shore == "default:sand" and
|
||||
(def.ocean == "temperate" or def.ocean == "tropical" or def.ocean == "cold") and
|
||||
not desert_biomes[biome]
|
||||
then
|
||||
table.insert(sandy_biomes,biome)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_decoration(asuna.biome_groups.shore.inject_decoration({
|
||||
deco_type = "simple",
|
||||
place_on = "default:sand",
|
||||
decoration = {"default:marram_grass_1","default:marram_grass_2","default:marram_grass_3"},
|
||||
y_min = 2,
|
||||
y_max = 2,
|
||||
sidelen = 16,
|
||||
noise_params = {
|
||||
offset = 0.004,
|
||||
scale = 0.0195,
|
||||
spread = {x = 11, y = 11, z = 11},
|
||||
seed = 69420,
|
||||
octaves = 1,
|
||||
},
|
||||
biomes = sandy_biomes,
|
||||
}))
|
||||
|
||||
minetest.register_decoration(asuna.biome_groups.shore.inject_decoration({
|
||||
deco_type = "simple",
|
||||
place_on = "default:sand",
|
||||
decoration = {"default:marram_grass_1","default:marram_grass_2","default:marram_grass_3"},
|
||||
y_min = 3,
|
||||
y_max = 4,
|
||||
sidelen = 16,
|
||||
noise_params = {
|
||||
offset = 0.075,
|
||||
scale = 0.175,
|
||||
spread = {x = 10, y = 10, z = 10},
|
||||
seed = 42069,
|
||||
octaves = 1,
|
||||
},
|
||||
biomes = sandy_biomes,
|
||||
}))
|
||||
|
||||
-- Register flowers and mushrooms
|
||||
for name,biome in pairs(asuna.biomes) do
|
||||
-- Get node groups for biome
|
||||
local decor = cf(biome)
|
||||
|
||||
-- Register flowers
|
||||
if #biome.flowers > 0 then
|
||||
minetest.register_decoration({
|
||||
name = "asuna_core:flowers_" .. name,
|
||||
deco_type = "simple",
|
||||
sidelen = 80,
|
||||
place_on = biome.nodes.extra and {biome.nodes[1],unpack(biome.nodes.extra)} or biome.nodes[1],
|
||||
noise_params = {
|
||||
offset = 0.006786,
|
||||
scale = 0.004175,
|
||||
spread = {x = 8, y = 8, z = 8},
|
||||
seed = 1999,
|
||||
octaves = 2,
|
||||
persist = 0.44,
|
||||
lacunarity = 0.75,
|
||||
},
|
||||
biomes = {name},
|
||||
y_max = 31000,
|
||||
y_min = 1,
|
||||
decoration = decor.flowers,
|
||||
})
|
||||
end
|
||||
|
||||
-- Register mushrooms
|
||||
if #biome.mushrooms > 0 then
|
||||
minetest.register_decoration({
|
||||
name = "asuna_core:mushrooms_" .. name,
|
||||
deco_type = "simple",
|
||||
sidelen = 8,
|
||||
place_on = biome.nodes.extra and {biome.nodes[1],unpack(biome.nodes.extra)} or biome.nodes[1],
|
||||
noise_params = {
|
||||
offset = -0.0069,
|
||||
scale = 0.027525,
|
||||
spread = {x = 8, y = 8, z = 8},
|
||||
seed = 60659,
|
||||
octaves = 2,
|
||||
persist = 0.7625,
|
||||
lacunarity = 0.6,
|
||||
},
|
||||
biomes = {name},
|
||||
y_max = 31000,
|
||||
y_min = 1,
|
||||
decoration = decor.mushrooms,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Special sunflower decor for the Plains biome
|
||||
minetest.register_decoration({
|
||||
name = "asuna_core:plains_special_sunflower",
|
||||
deco_type = "simple",
|
||||
place_on = {"default:dry_dirt_with_dry_grass"},
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.075,
|
||||
biomes = {"plains"},
|
||||
y_max = 31000,
|
||||
y_min = 1,
|
||||
decoration = "farming:sunflower_8",
|
||||
})
|
||||
|
||||
-- Special dense flower decor for the Prairie biome
|
||||
minetest.register_decoration({
|
||||
name = "asuna_core:prairie_special_flowers",
|
||||
deco_type = "simple",
|
||||
place_on = "prairie:prairie_dirt_with_grass",
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.265,
|
||||
biomes = {"prairie"},
|
||||
y_max = 31000,
|
||||
y_min = 1,
|
||||
decoration = cf({ flowers = {"blue","cyan","white","orange","yellow"} }).flowers,
|
||||
})
|
||||
|
||||
-- Special mushroom decor for the Mushroom biome
|
||||
minetest.register_decoration({
|
||||
name = "asuna_core:mushroom_special_mushrooms",
|
||||
deco_type = "simple",
|
||||
place_on = "ethereal:mushroom_dirt",
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.075,
|
||||
biomes = {"mushroom"},
|
||||
y_max = 31000,
|
||||
y_min = 1,
|
||||
decoration = cf({ mushrooms = {"odd","brown"} }).mushrooms,
|
||||
})
|
||||
|
||||
-- Bushes for certain grassy biomes
|
||||
minetest.register_decoration({
|
||||
name = "bushes:default_replacement",
|
||||
deco_type = "schematic",
|
||||
place_on = "default:dirt_with_grass",
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.00025,
|
||||
y_min = 2,
|
||||
y_max = 31000,
|
||||
biomes = {
|
||||
"grassland",
|
||||
"deciduous_forest",
|
||||
"grassytwo",
|
||||
"jumble",
|
||||
"marsh",
|
||||
},
|
||||
schematic = minetest.get_modpath("default") .. "/schematics/bush.mts",
|
||||
flags = "place_center_x,place_center_z",
|
||||
})
|
||||
|
||||
--[[
|
||||
Butterflies
|
||||
]]
|
||||
|
||||
if minetest.get_modpath("butterflies") then
|
||||
|
||||
minetest.register_decoration({
|
||||
name = "butterflies:butterfly",
|
||||
deco_type = "simple",
|
||||
place_on = "group:soil",
|
||||
place_offset_y = 1,
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.005,
|
||||
biomes = {
|
||||
"grassland",
|
||||
"deciduous_forest",
|
||||
"grassytwo",
|
||||
"prairie",
|
||||
"dorwinion",
|
||||
"jumble",
|
||||
"bamboo",
|
||||
"naturalbiomes:heath",
|
||||
"naturalbiomes:alpine",
|
||||
"everness:bamboo_forest",
|
||||
},
|
||||
y_max = 31000,
|
||||
y_min = 1,
|
||||
decoration = {
|
||||
"butterflies:butterfly_white",
|
||||
"butterflies:butterfly_red",
|
||||
"butterflies:butterfly_violet",
|
||||
},
|
||||
spawn_by = "group:flower",
|
||||
num_spawn_by = 1,
|
||||
})
|
||||
end
|
||||
|
||||
--[[
|
||||
Fireflies
|
||||
]]
|
||||
|
||||
if minetest.get_modpath("fireflies") then
|
||||
minetest.register_decoration({
|
||||
name = "fireflies:firefly_low",
|
||||
deco_type = "simple",
|
||||
place_on = "group:soil",
|
||||
place_offset_y = 2,
|
||||
sidelen = 16,
|
||||
noise_params = {
|
||||
offset = -0.005,
|
||||
scale = 0.015,
|
||||
spread = {x = 60, y = 20, z = 60},
|
||||
seed = 2112,
|
||||
octaves = 1,
|
||||
persistence = 0.75,
|
||||
flags = "eased"
|
||||
},
|
||||
biomes = {
|
||||
"deciduous_forest",
|
||||
"grassland",
|
||||
"grassytwo",
|
||||
"prairie",
|
||||
"dorwinion",
|
||||
"jumble",
|
||||
"swamp",
|
||||
"marsh",
|
||||
"naturalbiomes:alderswamp",
|
||||
"naturalbiomes:alpine",
|
||||
"naturalbiomes:bushland",
|
||||
"everness:bamboo_forest",
|
||||
},
|
||||
y_max = 31000,
|
||||
y_min = -1,
|
||||
place_offset_y = 2,
|
||||
decoration = "fireflies:hidden_firefly",
|
||||
})
|
||||
|
||||
minetest.register_decoration({
|
||||
name = "fireflies:firefly_low_bamboo_cave",
|
||||
deco_type = "simple",
|
||||
place_on = "everness:moss_block",
|
||||
place_offset_y = 2,
|
||||
sidelen = 16,
|
||||
fill_ratio = 0.0065,
|
||||
biomes = asuna.features.cave.bamboo,
|
||||
y_max = 0,
|
||||
y_min = -31000,
|
||||
place_offset_y = 1,
|
||||
decoration = "fireflies:hidden_firefly",
|
||||
})
|
||||
|
||||
minetest.register_decoration({
|
||||
name = "fireflies:firefly_low_dorwinion_cave",
|
||||
deco_type = "simple",
|
||||
place_on = "dorwinion:dorwinion_grass",
|
||||
place_offset_y = 2,
|
||||
sidelen = 16,
|
||||
fill_ratio = 0.0065,
|
||||
biomes = asuna.features.cave.dorwinion,
|
||||
y_max = 0,
|
||||
y_min = -31000,
|
||||
place_offset_y = 1,
|
||||
decoration = "fireflies:hidden_firefly",
|
||||
})
|
||||
end
|
||||
|
||||
--[[
|
||||
Large jungle trees
|
||||
]]
|
||||
|
||||
local chunksize = tonumber(minetest.get_mapgen_setting("chunksize"))
|
||||
if chunksize >= 5 then
|
||||
minetest.register_decoration({
|
||||
name = "default:emergent_jungle_tree",
|
||||
deco_type = "schematic",
|
||||
place_on = {
|
||||
"default:dirt_with_rainforest_litter",
|
||||
},
|
||||
sidelen = 80,
|
||||
noise_params = {
|
||||
offset = 0.0,
|
||||
scale = 0.0025,
|
||||
spread = {x = 200, y = 200, z = 200},
|
||||
seed = 2685,
|
||||
octaves = 3,
|
||||
persist = 0.7
|
||||
},
|
||||
biomes = {"rainforest"},
|
||||
y_max = 30000,
|
||||
y_min = 1,
|
||||
schematic = minetest.get_modpath("default") .. "/schematics/emergent_jungle_tree.mts",
|
||||
flags = "place_center_x, place_center_z",
|
||||
rotation = "random",
|
||||
place_offset_y = -4,
|
||||
})
|
||||
end
|
||||
|
||||
--[[
|
||||
Hanging vines
|
||||
]]
|
||||
|
||||
local soil_nodes = {}
|
||||
for _,soil_node in ipairs({
|
||||
"default:dirt",
|
||||
"default:dirt_with_grass",
|
||||
"default:dirt_with_rainforest_litter",
|
||||
"livingjungle:jungleground",
|
||||
"livingjungle:leafyjungleground",
|
||||
"naturalbiomes:alderswamp_litter",
|
||||
"naturalbiomes:alderswamp_dirt",
|
||||
"default:tree",
|
||||
"default:jungletree",
|
||||
"default:jungleleaves",
|
||||
}) do
|
||||
soil_nodes[minetest.get_content_id(soil_node)] = true
|
||||
end
|
||||
|
||||
local cids = {
|
||||
air = minetest.get_content_id("air"),
|
||||
vine = minetest.get_content_id("ethereal:vine"),
|
||||
water = minetest.get_content_id("default:water_source"), -- used for waterfalls below; unrelated to vines
|
||||
water_flowing = minetest.get_content_id("default:water_flowing"), -- used for cave liquids below; unrelated to vines
|
||||
lava = minetest.get_content_id("default:lava_source"), -- used for cave liquids below; unrelated to vines
|
||||
lava_flowing = minetest.get_content_id("default:lava_flowing"), -- used for cave liquids below; unrelated to vines
|
||||
stone = minetest.get_content_id("default:stone"),
|
||||
jungleleaves = minetest.get_content_id("default:jungleleaves"),
|
||||
}
|
||||
|
||||
local asuna_hanging_vines_fn = function(mapgen)
|
||||
-- Get provided values
|
||||
local pos = mapgen.pos
|
||||
local va = mapgen.voxelarea
|
||||
local vdata = mapgen.data
|
||||
local vparam2 = mapgen.param2
|
||||
|
||||
-- Get stride values and set position
|
||||
local ystride = va.ystride
|
||||
local zstride = va.zstride
|
||||
pos = va:index(pos.x,pos.y,pos.z)
|
||||
|
||||
-- Scan for dirt or surface nodes for a short distance above the position
|
||||
for above = 1, 2 do
|
||||
above = pos + above * ystride
|
||||
if soil_nodes[vdata[above]] then
|
||||
pos = above
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- List of cardinal directions relative to the current position
|
||||
local cardinal = {
|
||||
pos - 1,
|
||||
pos + 1,
|
||||
pos - zstride,
|
||||
pos + zstride,
|
||||
}
|
||||
|
||||
-- Iterate over cardinal positions and place vines at and below those positions
|
||||
for i = 1, 4 do
|
||||
local dir = cardinal[i]
|
||||
if vdata[dir] == cids.air then
|
||||
for below = 0, ((dir ^ 2 + (dir + pos) % 3) % 4 + 2) do
|
||||
below = dir - below * ystride
|
||||
if vdata[below] == cids.air then
|
||||
vdata[below] = cids.vine
|
||||
vparam2[below] = i + 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
abdecor.register_advanced_decoration("asuna_hanging_vines_jungletree",{
|
||||
target = {
|
||||
place_on = {
|
||||
"default:jungletree",
|
||||
},
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.3,
|
||||
biomes = {
|
||||
"rainforest",
|
||||
},
|
||||
y_max = 31000,
|
||||
y_min = 1,
|
||||
flags = "all_ceilings",
|
||||
},
|
||||
fn = function(mapgen)
|
||||
-- Get provided values
|
||||
local pos = mapgen.pos
|
||||
local va = mapgen.voxelarea
|
||||
local vdata = mapgen.data
|
||||
local vparam2 = mapgen.param2
|
||||
|
||||
-- Get stride values and set position
|
||||
local ystride = va.ystride
|
||||
local zstride = va.zstride
|
||||
pos = va:index(pos.x,pos.y,pos.z)
|
||||
|
||||
-- Check surrounding nodes for jungle leaves
|
||||
for x = -1, 1 do
|
||||
for z = -zstride, zstride, zstride do
|
||||
local lpos = pos + x + z
|
||||
if vdata[lpos] == cids.jungleleaves and (pos * x + z) % 3 > 0 then
|
||||
mapgen.pos = va:position(lpos)
|
||||
asuna_hanging_vines_fn(mapgen)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
flags = {
|
||||
param2 = true,
|
||||
}
|
||||
})
|
||||
|
||||
abdecor.register_advanced_decoration("asuna_hanging_vines",{
|
||||
target = {
|
||||
place_on = {
|
||||
"group:stone",
|
||||
"default:dirt",
|
||||
"default:jungletree",
|
||||
},
|
||||
spawn_by = "air",
|
||||
num_spawn_by = 5,
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.3,
|
||||
biomes = {
|
||||
"swamp",
|
||||
"naturalbiomes:alderswamp",
|
||||
"marsh",
|
||||
"rainforest",
|
||||
"jumble",
|
||||
"livingjungle:jungle",
|
||||
},
|
||||
y_max = 31000,
|
||||
y_min = 1,
|
||||
flags = "all_ceilings",
|
||||
},
|
||||
fn = asuna_hanging_vines_fn,
|
||||
flags = {
|
||||
param2 = true,
|
||||
},
|
||||
})
|
||||
|
||||
--[[
|
||||
Ocean waterfalls
|
||||
]]
|
||||
|
||||
local wall_stones = {
|
||||
"default:stone_with_coal",
|
||||
"default:stone_with_iron",
|
||||
"default:stone_with_tin",
|
||||
"default:stone_with_copper",
|
||||
"default:stone_with_gold",
|
||||
"default:stone_with_diamond",
|
||||
"default:stone_with_mese",
|
||||
}
|
||||
|
||||
for node,def in pairs(minetest.registered_nodes) do
|
||||
if def.groups and def.groups.stone and def.groups.stone > 0 then
|
||||
table.insert(wall_stones,node)
|
||||
end
|
||||
end
|
||||
|
||||
local valid_wall_stones = {}
|
||||
for _,node in ipairs(wall_stones) do
|
||||
valid_wall_stones[minetest.get_content_id(node)] = true
|
||||
end
|
||||
|
||||
abdecor.register_advanced_decoration("asuna_waterfalls",{
|
||||
target = {
|
||||
place_on = "default:water_source",
|
||||
spawn_by = wall_stones,
|
||||
num_spawn_by = 3,
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.11,
|
||||
biomes = asuna.biome_groups.shore,
|
||||
y_max = 1,
|
||||
y_min = 1,
|
||||
flags = "liquid_surface",
|
||||
},
|
||||
fn = function(mapgen)
|
||||
-- Get provided values
|
||||
local pos = mapgen.pos
|
||||
local va = mapgen.voxelarea
|
||||
local vdata = mapgen.data
|
||||
|
||||
-- Get stride values and adjust position
|
||||
local ystride = va.ystride
|
||||
local zstride = va.zstride
|
||||
pos = va:index(pos.x,pos.y + 1,pos.z)
|
||||
local too_low_pos = 0
|
||||
|
||||
-- Get stone wall direction
|
||||
local cardinal = {
|
||||
-1,
|
||||
-zstride,
|
||||
1,
|
||||
zstride,
|
||||
}
|
||||
|
||||
local found_stone = false
|
||||
local check_wall = nil
|
||||
for i = 1, 4 do
|
||||
local wallpos = pos + cardinal[i]
|
||||
local wallleft = cardinal[i % 4 + 1]
|
||||
local wallright = cardinal[(i + 2) % 4 + 1]
|
||||
check_wall = function(pos) -- is the entire row of wall nodes made of stone?
|
||||
return valid_wall_stones[vdata[pos]] and valid_wall_stones[vdata[pos + wallleft]] and valid_wall_stones[vdata[pos + wallright]] and true or false
|
||||
end
|
||||
if check_wall(wallpos) then
|
||||
pos = wallpos
|
||||
too_low_pos = pos
|
||||
found_stone = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Do nothing if no stone wall found
|
||||
if not found_stone then
|
||||
return
|
||||
end
|
||||
|
||||
-- Iterate above 'rows' of stone wall until we find something that isn't stone
|
||||
repeat
|
||||
pos = pos + ystride
|
||||
until not check_wall(pos)
|
||||
|
||||
-- Set two below stone position to water if higher than one node
|
||||
local placepos = pos - 2 * ystride
|
||||
if placepos > too_low_pos then
|
||||
vdata[placepos] = cids.water
|
||||
end
|
||||
end,
|
||||
flags = {
|
||||
liquid = true,
|
||||
},
|
||||
})
|
||||
|
||||
--[[
|
||||
Cave ceiling liquids
|
||||
]]
|
||||
|
||||
local enclosing_nodes = valid_wall_stones
|
||||
|
||||
abdecor.register_advanced_decoration("asuna_cave_liquids",{
|
||||
target = {
|
||||
place_on = {
|
||||
"group:stone",
|
||||
},
|
||||
sidelen = 80,
|
||||
spawn_by = {
|
||||
"group:stone",
|
||||
},
|
||||
num_spawn_by = 8,
|
||||
fill_ratio = 0.000015,
|
||||
y_max = -30,
|
||||
y_min = -31000,
|
||||
flags = "all_ceilings",
|
||||
},
|
||||
fn = function(mapgen)
|
||||
-- Get provided values
|
||||
local va = mapgen.voxelarea
|
||||
local vdata = mapgen.data
|
||||
local vparam2 = mapgen.param2
|
||||
local pos = mapgen.pos
|
||||
|
||||
-- Get stride values and set position
|
||||
local ystride = va.ystride
|
||||
local zstride = va.zstride
|
||||
local pos = va:index(pos.x,pos.y,pos.z)
|
||||
|
||||
-- Liquid must be enclosed to its sides and above
|
||||
for _,adjacent in ipairs({
|
||||
ystride,
|
||||
1,
|
||||
-1,
|
||||
zstride,
|
||||
-zstride,
|
||||
}) do
|
||||
if not enclosing_nodes[vdata[pos + adjacent]] then
|
||||
return -- liquid is not fully enclosed
|
||||
end
|
||||
end
|
||||
|
||||
-- Liquid must have sufficient clearance below
|
||||
-- Scanning from bottom up should typically fail faster than top down
|
||||
for below = pos - ystride * 8, pos - ystride, ystride do
|
||||
if vdata[below] ~= minetest.CONTENT_AIR then
|
||||
return -- not enough space between ceiling and ground
|
||||
end
|
||||
end
|
||||
|
||||
-- Fill the position and all air below with liquid based on climate + bias
|
||||
-- Dry/hot climates are more likely to be lava, vice-versa with water
|
||||
local liquid = (function()
|
||||
local heatmap = minetest.get_mapgen_object("heatmap") or {}
|
||||
local humiditymap = minetest.get_mapgen_object("humiditymap") or {}
|
||||
local pos2d = mapgen.index2d(mapgen.pos)
|
||||
local heat = heatmap[pos2d] or 50
|
||||
local humidity = humiditymap[pos2d] or 50
|
||||
local climate = 50 + (heat / 2 - 25) - (humidity / 2 - 25)
|
||||
local pos_random = (pos ^ 2 + pos) % 38 * (pos % 2 == 0 and 1 or -1) + climate -- not actually random but good enough
|
||||
return pos_random > 56 and {cids.lava,cids.lava_flowing} or {cids.water,cids.water_flowing} -- bias in favor of water
|
||||
end)()
|
||||
vdata[pos] = liquid[1]
|
||||
pos = pos - ystride
|
||||
while vdata[pos] == minetest.CONTENT_AIR do
|
||||
vdata[pos] = liquid[2]
|
||||
vparam2[pos] = 15
|
||||
pos = pos - ystride
|
||||
end
|
||||
end,
|
||||
flags = {
|
||||
liquid = true,
|
||||
param2 = true,
|
||||
},
|
||||
})
|
||||
end)
|
46
mods/asuna/asuna_core/init.lua
Normal file
46
mods/asuna/asuna_core/init.lua
Normal file
|
@ -0,0 +1,46 @@
|
|||
asuna = {
|
||||
modpath = core.get_modpath("asuna_core"),
|
||||
content = {
|
||||
nutrition = {
|
||||
enabled = core.settings:get_bool("asuna.content.nutrition.enabled",true),
|
||||
exhaustion_level = core.settings:get_bool("asuna.content.nutrition.enabled",true) and tonumber(core.settings:get("asuna.content.nutrition.exhaustion_level",160) or 160),
|
||||
starvation = core.settings:get_bool("asuna.content.nutrition.enabled",true) and core.settings:get_bool("asuna.content.nutrition.starvation",false),
|
||||
},
|
||||
wayfarer = {
|
||||
enabled = core.settings:get_bool("asuna.content.wayfarer.enabled",true),
|
||||
awards = core.settings:get_bool("asuna.content.wayfarer.enabled",true) and core.settings:get_bool("asuna.content.wayfarer.awards",true),
|
||||
loot_chests = core.settings:get_bool("asuna.content.wayfarer.enabled",true) and core.settings:get_bool("asuna.content.wayfarer.loot_chests",true),
|
||||
worldgate = core.settings:get_bool("asuna.content.wayfarer.enabled",true) and core.settings:get_bool("asuna.content.wayfarer.worldgate",true),
|
||||
},
|
||||
menagerie = {
|
||||
enabled = core.settings:get_bool("asuna.content.menagerie.enabled",true),
|
||||
animals = core.settings:get_bool("asuna.content.menagerie.enabled",true) and core.settings:get_bool("asuna.content.menagerie.animals",true),
|
||||
slimes = core.settings:get_bool("asuna.content.menagerie.enabled",true) and core.settings:get_bool("asuna.content.menagerie.slimes",true),
|
||||
},
|
||||
research = {
|
||||
enabled = core.settings:get_bool("asuna.content.research.enabled",true),
|
||||
},
|
||||
},
|
||||
settings = {
|
||||
particles = {
|
||||
amount = core.settings:get("asuna.settings.particles.amount","less") or "less",
|
||||
},
|
||||
mod_override_warnings = {
|
||||
enabled = core.settings:get_bool("asuna.settings.mod_override_warnings.enabled",true),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
local function runfile(file,condition)
|
||||
if condition == nil or condition then
|
||||
dofile(asuna.modpath .. "/" .. file .. ".lua")
|
||||
end
|
||||
end
|
||||
|
||||
runfile("biomes")
|
||||
runfile("terrain")
|
||||
runfile("climate")
|
||||
runfile("caves")
|
||||
runfile("decor")
|
||||
runfile("music")
|
||||
runfile("mod_override_warnings",asuna.settings.mod_override_warnings.enabled)
|
6
mods/asuna/asuna_core/mod.conf
Normal file
6
mods/asuna/asuna_core/mod.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
name = asuna_core
|
||||
title = Asuna Core
|
||||
description = The core mod that defines functionality specific to Asuna and its content
|
||||
author = EmptyStar
|
||||
depends = music_api
|
||||
# ephemeral_depends = abdecor, default, flowers, beautiflowers, herbs, bakedclay, fireflies, ethereal, badland, dorwinion, prairie, naturalbiomes, livingjungle, bambooforest, frost_land, japaneseforest, nightshade, terracotta, too_many_stones
|
46
mods/asuna/asuna_core/mod_override_warnings.lua
Normal file
46
mods/asuna/asuna_core/mod_override_warnings.lua
Normal file
|
@ -0,0 +1,46 @@
|
|||
local asuna_mod_path = core.get_game_info().path .. "/mods"
|
||||
local bundled_mods = core.get_dir_list(asuna_mod_path,true)
|
||||
local warn
|
||||
|
||||
if asuna.settings.mod_override_warnings.enabled then
|
||||
local messages = {}
|
||||
warn = function(mod)
|
||||
local message = "MOD OVERRIDE WARNING: Mod '" .. mod .. "' is enabled externally which overrides Asuna's version of this mod. This may cause issues."
|
||||
core.log("warning",message)
|
||||
table.insert(messages,core.colorize("#eeee00",message))
|
||||
end
|
||||
core.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
local privs = core.get_player_privs(name)
|
||||
if privs.server or privs.debug or name == "singleplayer" then
|
||||
for _,message in ipairs(messages) do
|
||||
core.chat_send_player(name,message)
|
||||
end
|
||||
end
|
||||
end)
|
||||
else
|
||||
warn = function(mod)
|
||||
core.log("warning","MOD OVERRIDE WARNING: Mod '" .. mod .. "' is enabled externally which overrides Asuna's version of this mod. This may cause issues.")
|
||||
end
|
||||
end
|
||||
|
||||
for _,mod in ipairs(bundled_mods) do
|
||||
local mods = { mod }
|
||||
local mpath = asuna_mod_path .. "/" .. mod
|
||||
local mfiles = core.get_dir_list(mpath,false)
|
||||
|
||||
for _,mfile in ipairs(mfiles) do
|
||||
if mfile:find("^modpack\\.") then
|
||||
mods = core.get_dir_list(mpath,true)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for _,mpath in ipairs(mods) do
|
||||
mod = mpath
|
||||
mpath = core.get_modpath(mpath)
|
||||
if mpath and not mpath:find("[\\/]games[\\/][^\\/]+[\\/]mods[\\/]") then
|
||||
warn(mod)
|
||||
end
|
||||
end
|
||||
end
|
105
mods/asuna/asuna_core/music.lua
Normal file
105
mods/asuna/asuna_core/music.lua
Normal file
|
@ -0,0 +1,105 @@
|
|||
--[[
|
||||
Day or night
|
||||
]]
|
||||
|
||||
music.register_track({
|
||||
name = "reparateur",
|
||||
length = 200 + 30,
|
||||
gain = 1.25,
|
||||
day = true,
|
||||
night = true,
|
||||
ymin = -12,
|
||||
ymax = 31000,
|
||||
})
|
||||
|
||||
music.register_track({
|
||||
name = "blood",
|
||||
length = 89 + 30,
|
||||
gain = 1,
|
||||
day = true,
|
||||
night = true,
|
||||
ymin = -12,
|
||||
ymax = 31000,
|
||||
})
|
||||
|
||||
--[[
|
||||
Daytime only
|
||||
]]
|
||||
|
||||
for track,length in pairs({
|
||||
castlesinthesky = 107,
|
||||
firefly = 152,
|
||||
bathedinthelight = 166,
|
||||
roquefortprolog = 85,
|
||||
meditatingbeat = 132,
|
||||
pond = 142,
|
||||
onefineday = 51,
|
||||
antarctica = 65,
|
||||
simplicity = 122,
|
||||
endtitles = 135,
|
||||
imagefilm033 = 121,
|
||||
}) do
|
||||
music.register_track({
|
||||
name = track,
|
||||
length = length + 30,
|
||||
gain = 1,
|
||||
day = true,
|
||||
night = false,
|
||||
ymin = -12,
|
||||
ymax = 31000,
|
||||
})
|
||||
end
|
||||
|
||||
--[[
|
||||
Nighttime only
|
||||
]]
|
||||
|
||||
for track,length in pairs({
|
||||
jul = 204,
|
||||
skyward = 149,
|
||||
thelongwayhome = 171,
|
||||
--moonlight = 176,
|
||||
--walkingstars = 172,
|
||||
hymn = 73,
|
||||
reverie = 136,
|
||||
atemubungen = 177,
|
||||
breezyreflections = 91,
|
||||
dreamsphere1 = 177,
|
||||
dreamsphere2 = 109,
|
||||
dreamsphere4 = 104,
|
||||
lonelyfish = 107,
|
||||
}) do
|
||||
music.register_track({
|
||||
name = track,
|
||||
length = length + 30,
|
||||
gain = 1,
|
||||
day = false,
|
||||
night = true,
|
||||
ymin = -12,
|
||||
ymax = 31000,
|
||||
})
|
||||
end
|
||||
|
||||
--[[
|
||||
Underground
|
||||
]]
|
||||
|
||||
for track,length in pairs({
|
||||
machina = 192,
|
||||
tearsinrain = 172,
|
||||
screensaver = 113,
|
||||
cobalt = 176,
|
||||
infinitepeace = 73,
|
||||
thevisitors = 160,
|
||||
sunriseonmars = 129,
|
||||
}) do
|
||||
music.register_track({
|
||||
name = track,
|
||||
length = length + 30,
|
||||
gain = 1,
|
||||
day = true,
|
||||
night = true,
|
||||
ymin = -31000,
|
||||
ymax = -12,
|
||||
})
|
||||
end
|
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_large_01.mts
Normal file
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_large_01.mts
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_large_02.mts
Normal file
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_large_02.mts
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_large_03.mts
Normal file
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_large_03.mts
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_medium_01.mts
Normal file
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_medium_01.mts
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_medium_02.mts
Normal file
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_medium_02.mts
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_medium_03.mts
Normal file
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_medium_03.mts
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_small_01.mts
Normal file
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_small_01.mts
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_small_02.mts
Normal file
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_small_02.mts
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_small_03.mts
Normal file
BIN
mods/asuna/asuna_core/schematics/boulders/boulder_small_03.mts
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
39
mods/asuna/asuna_core/sounds/music/CREDITS.md
Normal file
39
mods/asuna/asuna_core/sounds/music/CREDITS.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
All of the music in this mod is listed/credited below by author, license, and source. Each track followed by an asterisk (`*`) has been edited from its original form, often to trim and fade the end of the track.
|
||||
|
||||
- **Scott Buckley** -- [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/), <https://www.scottbuckley.com.au/>
|
||||
- Blood (blood.ogg)*
|
||||
- Castles In The Sky (castlesinthesky.ogg)*
|
||||
- Firefly (firefly.ogg)
|
||||
- Jul (jul.ogg)*
|
||||
- Machina (machina.ogg)*
|
||||
- Reparateur (reparateur.ogg)*
|
||||
- Skyward (skyward.ogg)*
|
||||
- Tears In Rain (tearsinrain.ogg)*
|
||||
- The Long Way Home (thelongwayhome.ogg)*
|
||||
- Cobalt (cobalt.ogg)*
|
||||
- Hymn (hymn.ogg)*
|
||||
- Reverie (reverie.ogg)*
|
||||
- Simplicity (simplicity.ogg)*
|
||||
- **Kevin MacLeod** -- [CC-BY 3.0](https://creativecommons.org/licenses/by/3.0/), <https://incompetech.com/>
|
||||
- Bathed in the Light (bathedinthelight.ogg)
|
||||
- **Kevin MacLeod** -- [CC0](https://creativecommons.org/publicdomain/zero/1.0/), <https://www.freepd.com/>
|
||||
- Screen Saver (screensaver.ogg)*
|
||||
- Roquefort Prolog (roquefortprolog.ogg)*
|
||||
- Infinite Peace (infinitepeace.ogg)*
|
||||
- Meditating Beat (meditatingbeat.ogg)*
|
||||
- **Rafael Krux** -- [CC0](https://creativecommons.org/publicdomain/zero/1.0/), <https://www.freepd.com/>
|
||||
- Pond (pond.ogg)*
|
||||
- **Jason Shaw** -- [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/legalcode), <https://audionautix.com/>
|
||||
- Antarctica (antarctica.ogg)*
|
||||
- One Fine Day (onefineday.ogg)*
|
||||
- The Visitors (thevisitors.ogg)*
|
||||
- Sunrise on Mars (sunriseonmars.ogg)*
|
||||
- **Sascha Ende** -- [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/legalcode), <https://filmmusic.io/>
|
||||
- Atemubüngen (atemubungen.ogg)*
|
||||
- Breezy Reflections (breezyreflections.ogg)*
|
||||
- Dreamsphere 1 (dreamsphere1.ogg)*
|
||||
- Dreamsphere 2 (dreamsphere2.ogg)*
|
||||
- Dreamsphere 4 (dreamsphere4.ogg)*
|
||||
- End Titles (endtitles.ogg)*
|
||||
- Image Film 033 (imagefilm033.ogg)*
|
||||
- Lonely Fish (lonelyfish.ogg)*
|
BIN
mods/asuna/asuna_core/sounds/music/antarctica.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/antarctica.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/atemubungen.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/atemubungen.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/bathedinthelight.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/bathedinthelight.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/blood.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/blood.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/breezyreflections.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/breezyreflections.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/castlesinthesky.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/castlesinthesky.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/cobalt.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/cobalt.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/dreamsphere1.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/dreamsphere1.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/dreamsphere2.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/dreamsphere2.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/dreamsphere4.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/dreamsphere4.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/endtitles.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/endtitles.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/firefly.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/firefly.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/hymn.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/hymn.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/imagefilm033.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/imagefilm033.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/infinitepeace.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/infinitepeace.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/jul.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/jul.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/lonelyfish.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/lonelyfish.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/machina.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/machina.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/meditatingbeat.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/meditatingbeat.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/onefineday.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/onefineday.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/pond.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/pond.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/reparateur.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/reparateur.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/reverie.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/reverie.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/roquefortprolog.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/roquefortprolog.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/screensaver.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/screensaver.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/simplicity.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/simplicity.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/skyward.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/skyward.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/sunriseonmars.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/sunriseonmars.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/tearsinrain.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/tearsinrain.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/thelongwayhome.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/thelongwayhome.ogg
Normal file
Binary file not shown.
BIN
mods/asuna/asuna_core/sounds/music/thevisitors.ogg
Normal file
BIN
mods/asuna/asuna_core/sounds/music/thevisitors.ogg
Normal file
Binary file not shown.
715
mods/asuna/asuna_core/terrain.lua
Normal file
715
mods/asuna/asuna_core/terrain.lua
Normal file
|
@ -0,0 +1,715 @@
|
|||
--[[
|
||||
Boulders
|
||||
- Should be registered before surface/terrain overrides
|
||||
]]
|
||||
|
||||
local function boulder(name,seed,nodes)
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
place_on = nodes,
|
||||
fill_ratio = 0.00000000000000001,
|
||||
y_min = 2,
|
||||
y_max = 31000,
|
||||
flags = "force_placement,place_center_x,place_center_z",
|
||||
schematic = asuna.modpath .. "/schematics/boulders/" .. name .. ".mts",
|
||||
rotation = "random",
|
||||
place_offset_y = 0
|
||||
})
|
||||
end
|
||||
|
||||
local seed = 90210
|
||||
|
||||
for _,name in ipairs({
|
||||
"cobblestone_boulder_small",
|
||||
"cobblestone_boulder_medium",
|
||||
}) do
|
||||
boulder(name,seed,{
|
||||
"default:dirt_with_dry_grass",
|
||||
"default:dry_dirt_with_dry_grass",
|
||||
"default:dirt_with_snow",
|
||||
"naturalbiomes:savannalitter",
|
||||
})
|
||||
seed = seed + 13
|
||||
end
|
||||
|
||||
for _,name in ipairs({
|
||||
"mossy_cobblestone_boulder_small",
|
||||
"mossy_cobblestone_boulder_medium",
|
||||
}) do
|
||||
boulder(name,seed,{
|
||||
"default:dirt_with_grass",
|
||||
"default:dirt_with_coniferous_litter",
|
||||
"ethereal:grove_dirt",
|
||||
"naturalbiomes:alpine_litter",
|
||||
"naturalbiomes:heath_litter",
|
||||
"naturalbiomes:heath_litter2",
|
||||
"naturalbiomes:heath_litter3",
|
||||
})
|
||||
seed = seed + 17
|
||||
end
|
||||
|
||||
for _,name in ipairs({
|
||||
"desert_boulder_small",
|
||||
"desert_boulder_medium",
|
||||
}) do
|
||||
boulder(name,seed,{
|
||||
"default:desert_sand",
|
||||
"default:sandstone",
|
||||
})
|
||||
seed = seed + 19
|
||||
end
|
||||
|
||||
--[[
|
||||
Terrain changes
|
||||
- Sweeping terrain changes that must be made before decorations are placed
|
||||
]]
|
||||
|
||||
-- Special decoration handling
|
||||
local mtrd = minetest.register_decoration
|
||||
minetest.register_decoration = function(def)
|
||||
-- Set all_floors for all surface decorations
|
||||
local flags = def.flags or ""
|
||||
if not (flags:find("all_") or flags:find("liquid_")) then
|
||||
def.flags = #flags > 0 and (flags .. ",all_floors") or "all_floors"
|
||||
end
|
||||
|
||||
-- Set negative y_min for select surface decorations
|
||||
if def.y_min == 1 and def.y_max and def.y_max > 1 and def.deco_type == "simple" then
|
||||
def.y_min = -20
|
||||
end
|
||||
|
||||
-- Ensure spawning in water for underwater decorations
|
||||
if def.y_max and def.y_max < 1 and not def.spawn_by and (def.place_on == "default:sand" or def.place_on[1] == "default:sand") then
|
||||
def.spawn_by = "default:water_source"
|
||||
def.num_spawn_by = 1
|
||||
end
|
||||
|
||||
-- Return original register_decoration call
|
||||
return mtrd(def)
|
||||
end
|
||||
|
||||
-- Surface nodes that should be propagated through surface stone
|
||||
local surface_spread = {
|
||||
"default:dirt_with_grass",
|
||||
"default:dry_dirt_with_dry_grass",
|
||||
"default:dirt_with_dry_grass",
|
||||
"default:dirt_with_rainforest_litter",
|
||||
"default:dirt_with_coniferous_litter",
|
||||
"naturalbiomes:savannalitter",
|
||||
"naturalbiomes:alpine_litter",
|
||||
"naturalbiomes:mediterran_litter",
|
||||
"naturalbiomes:alderswamp_litter",
|
||||
"naturalbiomes:outback_litter",
|
||||
"ethereal:grove_dirt",
|
||||
"ethereal:bamboo_dirt",
|
||||
"livingjungle:jungleground",
|
||||
"livingjungle:leafyjungleground",
|
||||
"ethereal:mushroom_dirt",
|
||||
"nightshade:nightshade_dirt_with_grass",
|
||||
"japaneseforest:japanese_dirt_with_grass",
|
||||
"bambooforest:dirt_with_bamboo",
|
||||
"dorwinion:dorwinion_grass",
|
||||
"badland:badland_grass",
|
||||
"frost_land:frost_land_grass",
|
||||
"prairie:prairie_dirt_with_grass",
|
||||
"everness:dirt_with_crystal_grass",
|
||||
"everness:dirt_with_cursed_grass",
|
||||
"everness:dirt_with_coral_grass",
|
||||
"ethereal:gray_dirt",
|
||||
"naturalbiomes:heath_litter",
|
||||
"naturalbiomes:bushland_bushlandlitter",
|
||||
"naturalbiomes:bushland_bushlandlitter2",
|
||||
"naturalbiomes:bushland_bushlandlitter3",
|
||||
}
|
||||
|
||||
-- Replace some surface stone with grass; also causes some biome ingress into caves
|
||||
for _,node in ipairs(surface_spread) do
|
||||
minetest.register_decoration({
|
||||
deco_type = "simple",
|
||||
place_on = {
|
||||
"group:stone",
|
||||
"default:stone_with_coal",
|
||||
"default:dirt",
|
||||
"default:silver_sand",
|
||||
"default:gravel",
|
||||
"everness:coral_desert_stone_with_coal",
|
||||
"everness:cursed_stone_carved_with_coal",
|
||||
"everness:crystal_stone_with_coal",
|
||||
},
|
||||
spawn_by = node,
|
||||
num_spawn_by = 1,
|
||||
sidelen = 4,
|
||||
y_min = 3,
|
||||
y_max = 31000,
|
||||
place_offset_y = -1,
|
||||
fill_ratio = 10,
|
||||
decoration = node,
|
||||
flags = "force_placement",
|
||||
})
|
||||
end
|
||||
|
||||
-- Ocean floor nodes that should be replaced with proper ocean floor
|
||||
local ocean_floor_replace = {
|
||||
"group:stone",
|
||||
"default:stone_with_coal",
|
||||
"everness:quartz_ore",
|
||||
"default:dirt",
|
||||
"default:dry_dirt",
|
||||
"default:gravel",
|
||||
"default:silver_sand",
|
||||
"default:dirt_with_grass",
|
||||
"default:dry_dirt_with_dry_grass",
|
||||
"default:dirt_with_dry_grass",
|
||||
"default:dirt_with_rainforest_litter",
|
||||
"default:dirt_with_coniferous_litter",
|
||||
"naturalbiomes:savannalitter",
|
||||
"naturalbiomes:alpine_litter",
|
||||
"naturalbiomes:mediterran_litter",
|
||||
"naturalbiomes:alderswamp_litter",
|
||||
"naturalbiomes:outback_litter",
|
||||
"ethereal:grove_dirt",
|
||||
"ethereal:bamboo_dirt",
|
||||
"livingjungle:jungleground",
|
||||
"livingjungle:leafyjungleground",
|
||||
"ethereal:mushroom_dirt",
|
||||
"nightshade:nightshade_dirt_with_grass",
|
||||
"japaneseforest:japanese_dirt_with_grass",
|
||||
"bambooforest:dirt_with_bamboo",
|
||||
"dorwinion:dorwinion_grass",
|
||||
"badland:badland_grass",
|
||||
"frost_land:frost_land_grass",
|
||||
"prairie:prairie_dirt_with_grass",
|
||||
"everness:dirt_with_crystal_grass",
|
||||
"everness:dirt_with_cursed_grass",
|
||||
"everness:coral_desert_stone_with_coal",
|
||||
"everness:cursed_stone_carved_with_coal",
|
||||
"everness:cursed_stone",
|
||||
"everness:crystal_stone_with_coal",
|
||||
}
|
||||
|
||||
-- Ocean floor generation function
|
||||
local function register_ocean_floor(name)
|
||||
-- Get above and shore biome names
|
||||
local above = name:sub(1,-7) -- to trim "_below" from the end of the biome name
|
||||
local shore = above .. "_shore"
|
||||
|
||||
-- Get biome
|
||||
local biome = asuna.biomes[name]
|
||||
|
||||
-- Register shore ocean floor terrain
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
place_on = ocean_floor_replace,
|
||||
sidelen = 80,
|
||||
fill_ratio = 10, -- fill all
|
||||
biomes = {name,shore,above},
|
||||
y_max = 0,
|
||||
y_min = 0,
|
||||
decoration = "default:stone",
|
||||
spawn_by = "default:water_source",
|
||||
num_spawn_by = 1,
|
||||
place_offset_y = -1,
|
||||
flags = "all_floors,force_placement",
|
||||
schematic = {
|
||||
size = {
|
||||
x = 1,
|
||||
y = 2,
|
||||
z = 1,
|
||||
},
|
||||
data = {
|
||||
{ name = "default:stone" , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.seabed , param1 = 255 , param2 = 0 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- Register ocean floor terrain
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
place_on = ocean_floor_replace,
|
||||
sidelen = 80,
|
||||
fill_ratio = 10, -- fill all
|
||||
biomes = {name,shore,above},
|
||||
y_max = -1,
|
||||
y_min = -10,
|
||||
decoration = "default:stone",
|
||||
spawn_by = "default:water_source",
|
||||
num_spawn_by = 1,
|
||||
place_offset_y = -3,
|
||||
flags = "all_floors,force_placement",
|
||||
schematic = {
|
||||
size = {
|
||||
x = 1,
|
||||
y = 4,
|
||||
z = 1,
|
||||
},
|
||||
data = {
|
||||
{ name = "default:stone" , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.seabed , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.seabed , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.seabed , param1 = 255 , param2 = 0 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- Register deep ocean floor terrain
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
place_on = ocean_floor_replace,
|
||||
sidelen = 80,
|
||||
fill_ratio = 10, -- fill all
|
||||
biomes = {name,shore,above},
|
||||
y_max = -11,
|
||||
y_min = -36,
|
||||
decoration = "default:stone",
|
||||
spawn_by = "default:water_source",
|
||||
num_spawn_by = 1,
|
||||
place_offset_y = -3,
|
||||
flags = "all_floors,force_placement",
|
||||
schematic = {
|
||||
size = {
|
||||
x = 1,
|
||||
y = 4,
|
||||
z = 1,
|
||||
},
|
||||
data = {
|
||||
{ name = "default:stone" , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.deep_seabed , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.deep_seabed , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.deep_seabed , param1 = 255 , param2 = 0 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- Replace underwater surface nodes below sea level
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
place_on = surface_spread,
|
||||
spawn_by = {
|
||||
"default:sand",
|
||||
"default:water_source",
|
||||
},
|
||||
num_spawn_by = 1,
|
||||
sidelen = 4,
|
||||
y_max = 0,
|
||||
y_min = -10,
|
||||
place_offset_y = -3,
|
||||
fill_ratio = 10,
|
||||
biomes = {name,shore,above},
|
||||
schematic = {
|
||||
size = {
|
||||
x = 1,
|
||||
y = 4,
|
||||
z = 1,
|
||||
},
|
||||
data = {
|
||||
{ name = "default:stone" , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.seabed , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.seabed , param1 = 255 , param2 = 0 },
|
||||
{ name = biome.seabed , param1 = 255 , param2 = 0 },
|
||||
},
|
||||
},
|
||||
flags = "all_floors,force_placement",
|
||||
})
|
||||
end
|
||||
|
||||
-- Generate ocean floor terrain
|
||||
local seed = 124
|
||||
for _,biome in ipairs(asuna.biome_groups.below) do
|
||||
register_ocean_floor(biome)
|
||||
end
|
||||
|
||||
-- Maximum pool limits
|
||||
local limits = {
|
||||
MAX_SCAN_DISTANCE = 3,
|
||||
MAX_DEPTH = 2,
|
||||
MAX_AREA = 89,
|
||||
}
|
||||
|
||||
-- Relevant content IDs
|
||||
local cids = nil
|
||||
minetest.register_on_mods_loaded(function() -- load after mapgen aliases are defined
|
||||
cids = {
|
||||
lava = minetest.get_content_id("mapgen_lava_source"),
|
||||
water = minetest.get_content_id("mapgen_water_source"),
|
||||
air = minetest.CONTENT_AIR,
|
||||
ignore = minetest.CONTENT_IGNORE,
|
||||
}
|
||||
end)
|
||||
|
||||
-- Array of flammable nodes to be avoided when placing lava along with invalid
|
||||
-- pool edge nodes
|
||||
local is_flammable = {}
|
||||
local is_invalid = {
|
||||
[minetest.CONTENT_AIR] = true
|
||||
}
|
||||
minetest.register_on_mods_loaded(function()
|
||||
for node,def in pairs(minetest.registered_nodes) do
|
||||
if def.groups and def.groups.flammable and def.groups.flammable > 0 then
|
||||
is_flammable[minetest.get_content_id(node)] = true
|
||||
is_invalid[minetest.get_content_id(node)] = true
|
||||
elseif def.floodable
|
||||
or def.drawtype == "airlike"
|
||||
or def.drawtype == "liquid"
|
||||
or def.drawtype == "flowingliquid"
|
||||
or def.buildable_to
|
||||
or def.walkable == false
|
||||
or (def.groups and def.groups.not_in_creative_inventory and def.groups.not_in_creative_inventory > 0)
|
||||
or node:find("_marker") -- mapgen marker names used by some mods
|
||||
then
|
||||
is_invalid[minetest.get_content_id(node)] = true
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- States that liquid pool nodes can be in
|
||||
local nodestate = {
|
||||
-- Invalid states
|
||||
OUT_OF_BOUNDS = 128, -- outside of voxelarea or ignore nodes
|
||||
INVALID = 64, -- nodes that cannot be part of a pool or pool borders
|
||||
UNSATISFIABLE = 32, -- pool nodes that cannot be filled with liquid
|
||||
MASK_INVALID = 128 + 64 + 32, -- combination of invalid states
|
||||
|
||||
-- Single nodes above the pool to be replaced with air
|
||||
ERASE = 16, -- surface nodes that have been flagged for erasure of nodes above
|
||||
MASK_ERASURE = 16 + 64, -- nodes that will be erased if the pool is generated
|
||||
|
||||
-- Directions
|
||||
POSITIVE_Z = 8,
|
||||
POSITIVE_X = 4,
|
||||
NEGATIVE_Z = 2,
|
||||
NEGATIVE_X = 1,
|
||||
MASK_SATISFIED = 8 + 4 + 2 + 1, -- combination of all directions
|
||||
|
||||
-- Blank state
|
||||
NONE = 0,
|
||||
}
|
||||
|
||||
-- Monotonic map-like pool 'class' to track nodes and node states
|
||||
local function Pool()
|
||||
local nodemap = {}
|
||||
local node_iterator = {} -- for fast, ordered, deterministic iteration
|
||||
local size = 0
|
||||
local scan_queue = {} -- for collecting non-terminated nodes to be scanned
|
||||
return {
|
||||
add = function(node,state)
|
||||
nodemap[node] = state
|
||||
table.insert(node_iterator,node)
|
||||
size = size + 1
|
||||
return state
|
||||
end,
|
||||
put = function(node,state)
|
||||
nodemap[node] = state
|
||||
return state
|
||||
end,
|
||||
get = function(node)
|
||||
return nodemap[node]
|
||||
end,
|
||||
foreach = function(start,fn)
|
||||
for i = start, size do
|
||||
if not fn(node_iterator[i]) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
size = function()
|
||||
return size
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
-- Register advanced decoration
|
||||
abdecor.register_advanced_decoration("asuna_cave_pools",{
|
||||
target = {
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.0000925,
|
||||
place_on = {
|
||||
"group:stone",
|
||||
"group:soil",
|
||||
"default:clay",
|
||||
"default:stone_with_coal_ore",
|
||||
"default:stone_with_iron_ore",
|
||||
"default:sand",
|
||||
"default:silver_sand",
|
||||
"default:desert_sand",
|
||||
"default:gravel",
|
||||
"default:coalblock",
|
||||
"caverealms:coal_dust",
|
||||
"everness:moss_block",
|
||||
"everness:forsaken_desert_sand",
|
||||
"everness:crystal_moss_block",
|
||||
"everness:emerald_ice",
|
||||
"everness:ancient_emerald_ice",
|
||||
"everness:dense_emerald_ice",
|
||||
"everness:frosted_ice",
|
||||
"everness:frosted_ice_translucent",
|
||||
"caverealms:stone_with_moss",
|
||||
"caverealms:stone_with_lichen",
|
||||
"caverealms:stone_with_algae",
|
||||
"caverealms:stone_with_salt",
|
||||
"caverealms:hot_cobble",
|
||||
},
|
||||
y_max = -36,
|
||||
y_min = -31000,
|
||||
flags = "all_floors",
|
||||
},
|
||||
fn = function(mapgen)
|
||||
-- Get provided values
|
||||
local va = mapgen.voxelarea
|
||||
local vdata = mapgen.data
|
||||
local pos = mapgen.pos
|
||||
|
||||
-- Get stride values and set position
|
||||
local ystride = va.ystride
|
||||
local zstride = va.zstride
|
||||
local pos = va:index(pos.x,pos.y,pos.z)
|
||||
|
||||
-- Determine pool liquid based on climate
|
||||
-- Dry/hot climates are more likely to be lava, vice-versa with water
|
||||
local liquid = (function()
|
||||
local heatmap = minetest.get_mapgen_object("heatmap") or {}
|
||||
local humiditymap = minetest.get_mapgen_object("humiditymap") or {}
|
||||
local pos2d = mapgen.index2d(mapgen.pos)
|
||||
local heat = heatmap[pos2d] or 50
|
||||
local humidity = humiditymap[pos2d] or 50
|
||||
local climate = 50 + (heat / 2 - 25) - (humidity / 2 - 25)
|
||||
local pos_random = PcgRandom(mapgen.seed):next(-29,29) + climate
|
||||
return pos_random > 50 and cids.lava or cids.water
|
||||
end)()
|
||||
|
||||
-- Create new pool for nodes
|
||||
local pool = Pool()
|
||||
|
||||
-- VoxelManip offset lookup by direction
|
||||
local adjacent = {
|
||||
[nodestate.POSITIVE_X] = 1,
|
||||
[nodestate.POSITIVE_Z] = zstride,
|
||||
[nodestate.NEGATIVE_X] = -1,
|
||||
[nodestate.NEGATIVE_Z] = -zstride,
|
||||
}
|
||||
|
||||
-- Recursive scanning function
|
||||
local function scan(node,direction,distance,depth)
|
||||
-- Get the node's state if it exists, else initialize it based on depth
|
||||
-- and pool size limit
|
||||
local state = pool.get(node) or pool.add(node,(function()
|
||||
if depth == 1 and pool.size() > limits.MAX_AREA then
|
||||
if is_invalid[vdata[node]] then
|
||||
return nodestate.INVALID
|
||||
else
|
||||
return nodestate.UNSATISFIABLE
|
||||
end
|
||||
else
|
||||
return nodestate.NONE
|
||||
end
|
||||
end)())
|
||||
|
||||
-- Return if this node is already in an invalid state
|
||||
if state > 31 then
|
||||
return bit.band(state,nodestate.MASK_INVALID)
|
||||
end
|
||||
|
||||
-- Return if this node is already satisfied in the given direction
|
||||
if bit.band(state,direction) ~= 0 then
|
||||
return direction
|
||||
end
|
||||
|
||||
-- Check if this node is out of bounds
|
||||
local content = vdata[node]
|
||||
if content == nil or content == cids.ignore then
|
||||
return nodestate.OUT_OF_BOUNDS
|
||||
end
|
||||
|
||||
-- Check the validity of this node
|
||||
if is_invalid[content] then
|
||||
return pool.put(node,nodestate.INVALID)
|
||||
end
|
||||
|
||||
-- Return unsatisfiable if the node below is invalid
|
||||
if is_invalid[vdata[node - ystride]] then
|
||||
return pool.put(node,nodestate.UNSATISFIABLE)
|
||||
end
|
||||
|
||||
-- Return solution if this node is beyond the max scan distance
|
||||
if distance > limits.MAX_SCAN_DISTANCE then
|
||||
return direction
|
||||
end
|
||||
|
||||
-- Checks based on depth
|
||||
local above = node + ystride
|
||||
if depth == 1 then
|
||||
-- Flag nodes above for erasure if the node above is solid and the node
|
||||
-- above that is air, but this node is unsatisfiable if both the node
|
||||
-- above and the node above that are solid
|
||||
if bit.band(state,nodestate.ERASE) == 0 and vdata[above] ~= cids.air then
|
||||
local above2 = above + ystride
|
||||
if vdata[above2] == cids.air then
|
||||
pool.add(above,nodestate.MASK_ERASURE)
|
||||
else
|
||||
-- Do not generate lava pools around flammable nodes that won't be
|
||||
-- erased
|
||||
if liquid == cids.lava and (is_flammable[vdata[above]] or is_flammable[vdata[above2]]) then
|
||||
return nodestate.OUT_OF_BOUNDS
|
||||
else
|
||||
return pool.put(node,nodestate.UNSATISFIABLE)
|
||||
end
|
||||
end
|
||||
state = bit.bor(state,nodestate.ERASE) -- flag this node as already having been checked for erasure
|
||||
end
|
||||
else
|
||||
-- At non-surface depths, the node above must have been fully satisfied
|
||||
-- in a previous scan
|
||||
if bit.band(pool.get(above) or nodestate.NONE,nodestate.MASK_SATISFIED) ~= nodestate.MASK_SATISFIED then
|
||||
return pool.put(node,nodestate.INVALID)
|
||||
end
|
||||
end
|
||||
|
||||
-- Scan neighbor in the given direction
|
||||
local neighbor = node + adjacent[direction]
|
||||
local nstate = scan(neighbor,direction,distance + 1,depth)
|
||||
|
||||
-- Return the direction if the neighbor is satisfied in the given direction
|
||||
if nstate == direction or nstate == nodestate.UNSATISFIABLE then
|
||||
pool.put(node,bit.bor(state,direction))
|
||||
return direction
|
||||
end
|
||||
|
||||
-- If neighbor is out of bounds, then the entire pool is invalid
|
||||
if nstate == nodestate.OUT_OF_BOUNDS then
|
||||
return nodestate.OUT_OF_BOUNDS
|
||||
end
|
||||
|
||||
-- If neighbor is invalid, then this node is unsatisfiable
|
||||
if nstate == nodestate.INVALID then
|
||||
return pool.put(node,nodestate.UNSATISFIABLE)
|
||||
end
|
||||
end
|
||||
|
||||
-- Initialize pool with the target position and perform the scan
|
||||
for depth = 1, limits.MAX_DEPTH do
|
||||
pool.add(pos - (depth - 1) * ystride,nodestate.NONE)
|
||||
local scan_count = 4 -- each of four -/+ x/z directions
|
||||
local i = 0
|
||||
local scan_start = pool.size() -- optimization to skip nodes from prior scans
|
||||
while i < scan_count do
|
||||
local previous_size = pool.size()
|
||||
local direction = bit.lshift(1,i % 4) -- cycle through directions
|
||||
if not pool.foreach(scan_start,function(node)
|
||||
return scan(node,direction,1,depth) ~= nodestate.OUT_OF_BOUNDS -- stop scanning immediately if out of bounds
|
||||
end) then
|
||||
return -- cannot render out of bounds pools
|
||||
end
|
||||
if pool.size() > previous_size then
|
||||
scan_count = scan_count + 1 -- new nodes need additional scans
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Fill the pool and erase nodes above
|
||||
pool.foreach(1,function(node)
|
||||
local state = pool.get(node)
|
||||
if bit.band(state,nodestate.MASK_SATISFIED) == nodestate.MASK_SATISFIED then
|
||||
vdata[node] = liquid
|
||||
elseif state == nodestate.MASK_ERASURE then
|
||||
vdata[node] = cids.air
|
||||
end
|
||||
return true
|
||||
end)
|
||||
end,
|
||||
})
|
||||
|
||||
--[[
|
||||
Schematics
|
||||
- Placed before other biome mods in order to mitigate interference from trees, etc.
|
||||
]]
|
||||
|
||||
local mpath = minetest.get_modpath("asuna_core")
|
||||
|
||||
-- Haunted house
|
||||
minetest.register_decoration({
|
||||
name = "asuna_core:everness_haunted_house_badland",
|
||||
deco_type = 'schematic',
|
||||
place_on = "badland:badland_grass",
|
||||
spawn_by = "badland:badland_grass",
|
||||
num_spawn_by = 8,
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.0000175,
|
||||
biomes = "badland",
|
||||
y_max = 31000,
|
||||
y_min = 7,
|
||||
place_offset_y = -1,
|
||||
schematic = mpath .. '/schematics/everness/everness_haunted_house_badland.mts',
|
||||
rotation = "random",
|
||||
flags = 'place_center_x,place_center_z,force_placement',
|
||||
})
|
||||
|
||||
-- Jungle temple
|
||||
minetest.register_decoration({
|
||||
name = "asuna_core:everness_jungle_temple_new",
|
||||
deco_type = 'schematic',
|
||||
place_on = "group:soil",
|
||||
spawn_by = "group:soil",
|
||||
num_spawn_by = 8,
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.0000275,
|
||||
biomes = {
|
||||
"rainforest",
|
||||
"livingjungle:jungle",
|
||||
},
|
||||
y_max = 31000,
|
||||
y_min = 8,
|
||||
place_offset_y = -3,
|
||||
schematic = mpath .. '/schematics/everness/everness_jungle_temple_new.mts',
|
||||
rotation = "random",
|
||||
flags = 'place_center_x,place_center_z,force_placement',
|
||||
})
|
||||
|
||||
-- Japanese shrine
|
||||
minetest.register_decoration({
|
||||
name = "asuna_core:everness_japanese_shrine_new",
|
||||
deco_type = 'schematic',
|
||||
place_on = "group:soil",
|
||||
spawn_by = "group:soil",
|
||||
num_spawn_by = 7,
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.0000175,
|
||||
biomes = {
|
||||
"bamboo",
|
||||
"japaneseforest",
|
||||
},
|
||||
y_max = 31000,
|
||||
y_min = 8,
|
||||
place_offset_y = -1,
|
||||
schematic = mpath .. '/schematics/everness/everness_japanese_shrine_new.mts',
|
||||
rotation = "random",
|
||||
flags = 'place_center_x,place_center_z,force_placement',
|
||||
})
|
||||
|
||||
-- Populate chests with loot
|
||||
local asuna_core_everness_dids = {}
|
||||
for _,decoration in ipairs({
|
||||
"asuna_core:everness_haunted_house_badland",
|
||||
"asuna_core:everness_jungle_temple_new",
|
||||
"asuna_core:everness_japanese_shrine_new",
|
||||
}) do
|
||||
local did = minetest.get_decoration_id(decoration)
|
||||
minetest.set_gen_notify({decoration = true},{did})
|
||||
asuna_core_everness_dids["decoration#" .. did] = true
|
||||
end
|
||||
|
||||
minetest.register_on_generated(function(minp,maxp)
|
||||
if maxp.y > 4 then
|
||||
local gennotify = minetest.get_mapgen_object("gennotify")
|
||||
for decoration_id,decorations in pairs(gennotify) do
|
||||
if asuna_core_everness_dids[decoration_id] then
|
||||
local chest_positions = minetest.find_nodes_in_area(minp,maxp,{ 'everness:chest' })
|
||||
if #chest_positions > 0 then
|
||||
Everness:populate_loot_chests(chest_positions)
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
Loading…
Add table
Add a link
Reference in a new issue