add luscious
@ -5,6 +5,7 @@ mcore = {}
|
||||
give_initial_stuff = {}
|
||||
|
||||
-- dofiles for loading files required by "core"
|
||||
dofile(minetest.get_modpath("core").."/util.lua")
|
||||
dofile(minetest.get_modpath("core").."/sounds.lua")
|
||||
dofile(minetest.get_modpath("core").."/mapgen.lua")
|
||||
dofile(minetest.get_modpath("core").."/blocks.lua")
|
||||
|
Before Width: | Height: | Size: 388 B After Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 335 B |
Before Width: | Height: | Size: 481 B After Width: | Height: | Size: 467 B |
BIN
mods/core/textures/core_grass_side_ovl.png
Normal file
After Width: | Height: | Size: 410 B |
Before Width: | Height: | Size: 413 B After Width: | Height: | Size: 409 B |
4
mods/core/util.lua
Normal file
@ -0,0 +1,4 @@
|
||||
-- util.lua, part of solar plains core
|
||||
|
||||
-- by jordach
|
||||
|
15
mods/luscious/.luacheckrc
Normal file
@ -0,0 +1,15 @@
|
||||
unused_args = false
|
||||
allow_defined_top = true
|
||||
|
||||
read_globals = {
|
||||
"DIR_DELIM",
|
||||
"minetest", "core",
|
||||
"dump",
|
||||
"vector", "nodeupdate",
|
||||
"VoxelManip", "VoxelArea",
|
||||
"PseudoRandom", "ItemStack",
|
||||
"intllib",
|
||||
"default",
|
||||
table = { fields = { "copy", "getn" } }
|
||||
}
|
||||
|
1
mods/luscious/depends.txt
Normal file
@ -0,0 +1 @@
|
||||
core
|
1
mods/luscious/description.txt
Normal file
@ -0,0 +1 @@
|
||||
Bring color into the mgv7 mapgen world.
|
193
mods/luscious/init.lua
Normal file
@ -0,0 +1,193 @@
|
||||
|
||||
--[[
|
||||
|
||||
grass - biome colored grass
|
||||
|
||||
(C) LGPL-2.1+ Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
Textures are licensed according to their respective origin
|
||||
from github.com/minetest/minetest_game, generally CC-BY-SA-4.0
|
||||
or similar.
|
||||
|
||||
]]--
|
||||
|
||||
local wp = minetest.get_worldpath() .. "/luscious"
|
||||
minetest.mkdir(wp)
|
||||
|
||||
local mgp = minetest.get_mapgen_params()
|
||||
local chunksize = 16 * mgp.chunksize
|
||||
|
||||
local function cmpy(p2, y)
|
||||
if y > 0 then
|
||||
local h1 = p2 % 16
|
||||
local h2 = math.floor(p2 / 16) * 16
|
||||
|
||||
h1 = h1 - math.max(math.min(h1, math.floor(y / 16)), 0)
|
||||
return math.max(1, h1 + h2)
|
||||
else
|
||||
return math.max(1, p2)
|
||||
end
|
||||
end
|
||||
local function after_place_node(pos, placer, itemstack, pointed_thing)
|
||||
-- get chunk from pos
|
||||
local v = vector.apply(pos, function(a) return math.floor((a - 48) / chunksize) end)
|
||||
local o = vector.subtract(pos, vector.apply(v, function(a) return (a * chunksize) + 48 end))
|
||||
local l = o.z * (chunksize) + o.x
|
||||
local p = minetest.hash_node_position(v)
|
||||
|
||||
local f = io.open(wp .. "/" .. string.format("%d", p), "r")
|
||||
if not f then
|
||||
minetest.log("error", "unable to find map for " .. string.format("%d", p))
|
||||
return
|
||||
end
|
||||
|
||||
local z = f:read("*a")
|
||||
f:close()
|
||||
local map = minetest.decompress(z)
|
||||
|
||||
local node = minetest.get_node(pos)
|
||||
node.param2 = cmpy(string.byte(map, l + 1), pos.y)
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
|
||||
minetest.override_item("core:grass", {
|
||||
paramtype2 = "color",
|
||||
drawtype = "color",
|
||||
palette_index = 136,
|
||||
color = "#4ea44aff",
|
||||
palette = "luscious_grass_palette.png",
|
||||
tiles = {"core_grass.png", {name = "core_dirt.png", color = "white"}, "core_grass.png"},
|
||||
overlay_tiles = {"", "", {name = "core_grass_side_ovl.png", color = "white"}},
|
||||
place_param2 = 136,
|
||||
after_place_node = after_place_node,
|
||||
})
|
||||
|
||||
|
||||
minetest.override_item("core:oak_leaves", {
|
||||
paramtype2 = "color",
|
||||
palette_index = 136,
|
||||
palette = "luscious_oak_leaves.png",
|
||||
color = "#3e8948ff",
|
||||
place_param2 = 136,
|
||||
after_place_node = after_place_node,
|
||||
})
|
||||
|
||||
minetest.override_item("core:birch_leaves", {
|
||||
|
||||
paramtype2 = "color",
|
||||
palette_index = 136,
|
||||
palette = "luscious_birch_leaves.png",
|
||||
color = "#63c74dff",
|
||||
place_param2 = 136,
|
||||
after_place_node = after_place_node,
|
||||
})
|
||||
|
||||
for _, v in pairs({
|
||||
"core:grass_1",
|
||||
"core:grass_2",
|
||||
"core:grass_3",
|
||||
|
||||
}) do
|
||||
local def = minetest.registered_nodes[v]
|
||||
--local tile, _ = def.tiles[1]:gsub("default_", "luscious_")
|
||||
minetest.override_item(v, {
|
||||
paramtype2 = "color",
|
||||
palette_index = 136,
|
||||
palette = "luscious_grass_palette.png",
|
||||
color = "#4ea44aff",
|
||||
--tiles = {tile},
|
||||
place_param2 = 136,
|
||||
after_place_node = after_place_node,
|
||||
})
|
||||
end
|
||||
|
||||
-- content ids
|
||||
local cn = {
|
||||
["core:grass"] = 1,
|
||||
["core:grass_1"] = 1,
|
||||
["core:grass_2"] = 1,
|
||||
["core:grass_3"] = 1,
|
||||
|
||||
}
|
||||
local cs = {}
|
||||
for k, _ in pairs(cn) do
|
||||
cs[minetest.get_content_id(k)] = 1
|
||||
end
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||
local v = vector.apply(minp, function(a) return (a - 48) / chunksize end)
|
||||
local heatmap = minetest.get_mapgen_object("heatmap")
|
||||
local humiditymap = minetest.get_mapgen_object("humiditymap")
|
||||
local map = ""
|
||||
for i = 1, #heatmap do
|
||||
local h1 = heatmap[i]
|
||||
local h2 = humiditymap[i]
|
||||
h1 = math.floor(math.min(math.max(math.floor(h1), 0), 100) / 6.6)
|
||||
h2 = math.floor(math.min(math.max(math.floor(h2), 0), 100) / 6.6)
|
||||
map = map .. string.char(h1 + (h2 * 16))
|
||||
end
|
||||
local p = string.format("%d", minetest.hash_node_position(v))
|
||||
|
||||
local f = assert(io.open(wp .. "/" .. p, "w"), wp .. "/" .. p)
|
||||
f:write(minetest.compress(map))
|
||||
f:close()
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
|
||||
local data = vm:get_data()
|
||||
local p2data = vm:get_param2_data()
|
||||
for z = minp.z, maxp.z do
|
||||
for y = minp.y, maxp.y do
|
||||
local vi = area:index(minp.x, y, z)
|
||||
for x = minp.x, maxp.x do
|
||||
local vv = (x - minp.x) + ((z - minp.z) * chunksize)
|
||||
if cs[data[vi]] then
|
||||
local mv = cmpy(string.byte(map, vv + 1), y)
|
||||
p2data[vi] = mv
|
||||
end
|
||||
vi = vi + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
vm:set_param2_data(p2data)
|
||||
vm:write_to_map()
|
||||
end)
|
||||
|
||||
local function update_p2(pos, size)
|
||||
local minp = {x = pos.x - size[1], y = pos.y, z = pos.z - size[1]}
|
||||
local maxp = {x = pos.x + size[1], y = pos.y + size[2], z = pos.z + size[1]}
|
||||
for x = minp.x, maxp.x do
|
||||
for y = minp.y, maxp.y do
|
||||
for z = minp.z, maxp.z do
|
||||
local p = vector.new(x, y, z)
|
||||
local node = minetest.get_node(p)
|
||||
if cn[node.name] then
|
||||
after_place_node(p)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
|
||||
local saplings = {
|
||||
["default:sapling"] = {2, 8},
|
||||
["default:junglesapling"] = {2, 17},
|
||||
["default:pine_sapling"] = {2, 14},
|
||||
["default:acacia_sapling"] = {4, 8},
|
||||
["default:aspen_sapling"] = {2, 12},
|
||||
["default:bush_sapling"] = {1, 3},
|
||||
["default:acacia_bush_sapling"] = {1, 3},
|
||||
}
|
||||
|
||||
for k, v in pairs(saplings) do
|
||||
minetest.override_item(k, {
|
||||
on_timer = function(pos)
|
||||
default.grow_sapling(pos)
|
||||
update_p2(pos, v)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
--]]
|
1
mods/luscious/mod.conf
Normal file
@ -0,0 +1 @@
|
||||
name = luscious
|
68
mods/luscious/readme.md
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
## luscious
|
||||
|
||||
Makes your map luscious.
|
||||
|
||||
This mod heavily modifies your base landscape and modifies various
|
||||
nodes like dirt and leaves so that they become colored using node
|
||||
coloring.
|
||||
|
||||
The color selection of each node is decided based on the biome data,
|
||||
using heat and humidity. These are mapped on a 16x16 palette where
|
||||
the heat is mapped along the x axis from 0-15 and the humidity along
|
||||
the y axis with the same range. This gives us a total of 256 possible
|
||||
colorizations of each node.
|
||||
|
||||
Manual placing of the nodes, and sapling placement is also modified to
|
||||
make trees growing or manual placing of nodes also result in colorized
|
||||
nodes in the landscape.
|
||||
|
||||
## features
|
||||
|
||||
- Player placed blocks are properly colored.
|
||||
- Saplings that grow into trees color correctly.
|
||||
- separate palette to color leaves and grass.
|
||||
- should not break with texture packs, but you'll lose texture
|
||||
pack specific leaf and grass textures.
|
||||
- jungle dirt is replaced by dirt with grass.
|
||||
- dirt with dry grass is replaced by dirt with grass.
|
||||
- dirt with snow is replaced by dirt with grass.
|
||||
- dry grass is replaced with grass.
|
||||
|
||||
## bugs
|
||||
|
||||
- leaf decay is broken due to p2 usage
|
||||
- grass spread is broken or will place wrongly colored grass nodes
|
||||
- snowy pine trees are no longer generated, only regular pines
|
||||
|
||||
## palette
|
||||
|
||||
The large palette image is generated with:
|
||||
|
||||
```
|
||||
convert textures/luscious_grass_palette.png -filter point \
|
||||
-resize 256x256 textures/luscious_grass_palette_large.png
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
Create a new world, enable this mod. Do not use this mod in an existing
|
||||
world, ever.
|
||||
|
||||
## How does this work?
|
||||
|
||||
The biome data is available in a special thread when mapgen emerges
|
||||
new map blocks. This mod captures the biome heat and humidity values
|
||||
right as mapgen creates them and stores them permanently for later
|
||||
use. This is why you need to have a `luscious` folder in the world
|
||||
folder. In this folder, we store the heat & humidity param2 values
|
||||
for each node that needs coloring in an X-Z map (Y is discarded as
|
||||
biome data does not use Y and is not 3d noise, it's only 2D).
|
||||
|
||||
Once the biome data is known, we can retrieve it to set the correct
|
||||
p2 values when a player places any of the nodes that need coloring, or
|
||||
when a tree grows. This is also why the biome data needs to be stored
|
||||
on disk - otherwise it would be lost. The storage of the biome data
|
||||
is reasonably small - it is stored compressed and uses about 600 bytes
|
||||
or so per x, z chunk, which is small compared to the actual map.sqlite
|
||||
size. The data increases the size of your world by about 12% or so.
|
BIN
mods/luscious/textures/luscious_birch_leaves.png
Normal file
After Width: | Height: | Size: 443 B |
BIN
mods/luscious/textures/luscious_grass_palette.png
Normal file
After Width: | Height: | Size: 362 B |
BIN
mods/luscious/textures/luscious_oak_leaves.png
Normal file
After Width: | Height: | Size: 443 B |