write something there
This commit is contained in:
commit
b4b6c08f4f
8546 changed files with 309825 additions and 0 deletions
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