1
0
mirror of https://github.com/Splizard/minetest-mod-snow.git synced 2024-12-29 16:00:16 +01:00

Major changes, mapgen_v7 support, better falling snow, config.

This commit is contained in:
Splizard 2013-08-06 06:25:01 +00:00
parent f57ce08962
commit 6a5b25bda6
11 changed files with 886 additions and 496 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
config.txt
*~

View File

@ -1,10 +0,0 @@
--This file contains configuration options for snow mod.
--Enables falling snow.
snow.enable_snowfall = true
--Enables debuging.
snow.debug = false
--Enables smooth transition of biomes.
snow.smooth = true

165
falling_snow.lua Normal file
View File

@ -0,0 +1,165 @@
if snow.enable_snowfall then
--Weather for legacy versions of minetest.
local save_weather_legacy = function ()
local file = io.open(minetest.get_worldpath().."/weather_v6", "w+")
file:write(weather_legacy)
file:close()
end
local read_weather_legacy = function ()
local file = io.open(minetest.get_worldpath().."/weather_v6", "r")
if not file then return end
local readweather = file:read()
file:close()
return readweather
end
local weather_legacy = read_weather_legacy()
if snow.legacy then
minetest.register_globalstep(function(dtime)
if weather_legacy == "snow" then
if math.random(1, 10000) == 1 then
weather_legacy = "none"
save_weather_legacy()
end
else
if math.random(1, 50000) == 2 then
weather_legacy = "snow"
save_weather_legacy()
end
end
end)
end
--Get snow at position.
local get_snow = function(pos)
if snow.legacy then
--Legacy support.
if weather_legacy == "snow" then
local perlin1 = minetest.env:get_perlin(112,3, 0.5, 150)
if perlin1:get2d( {x=pos.x, y=pos.z} ) > 0.53 then
return true
else
return false
end
else
return false
end
else
if minetest.get_heat(pos) <= 0 and minetest.get_humidity(pos) > 65 then
return true
else
return false
end
end
end
local addvectors = vector and vector.add
if snow.legacy then
addvectors = function (v1, v2)
return {x=v1.x+v2.x, y=v1.y+v2.y, z=v1.z+v2.z}
end
end
--Returns a random position between minp and maxp.
local randpos = function (minp, maxp)
local x,y,z
if minp.x > maxp.x then
x = math.random(maxp.x,minp.x) else x = math.random(minp.x,maxp.x) end
y = minp.y
if minp.z > maxp.z then
z = math.random(maxp.z,minp.z) else z = math.random(minp.z,maxp.z) end
return {x=x,y=y,z=z}
end
local snow_fall=function (pos, player, animate)
local ground_y = nil
for y=pos.y+10,pos.y+20,1 do
local n = minetest.env:get_node({x=pos.x,y=y,z=pos.z}).name
if n ~= "air" and n ~= "ignore" then
return
end
end
for y=pos.y+10,pos.y-15,-1 do
local n = minetest.env:get_node({x=pos.x,y=y,z=pos.z}).name
if n ~= "air" and n ~= "ignore" then
ground_y = y
break
end
end
if not ground_y then return end
pos = {x=pos.x, y=ground_y, z=pos.z}
local spos = {x=pos.x, y=ground_y+10, z=pos.z}
if get_snow(pos) then
if animate then
local minp = addvectors(spos, {x=-9, y=3, z=-9})
local maxp = addvectors(spos, {x= 9, y=5, z= 9})
local vel = {x=0, y= -0.5, z=0}
local acc = {x=0, y= -0.5, z=0}
minetest.add_particlespawner(3, 0.5,
minp, maxp,
vel, vel,
acc, acc,
5, 5,
50, 50,
false, "weather_snow.png", player:get_player_name())
end
snow.place(pos, true)
end
end
-- Snow
minetest.register_globalstep(function(dtime)
for _, player in ipairs(minetest.get_connected_players()) do
local ppos = player:getpos()
local sminp = addvectors(ppos, {x=-20, y=0, z=-20})
local smaxp = addvectors(ppos, {x= 20, y=0, z= 20})
-- Make sure player is not in a cave/house...
if get_snow(ppos) and minetest.env:get_node_light(ppos, 0.5) == 15 then
local minp = addvectors(ppos, {x=-9, y=3, z=-9})
local maxp = addvectors(ppos, {x= 9, y=5, z= 9})
local minp_deep = addvectors(ppos, {x=-5, y=3.2, z=-5})
local maxp_deep = addvectors(ppos, {x= 5, y=1.6, z= 5})
local vel = {x=0, y= -0.5, z=0}
local acc = {x=0, y= -0.5, z=0}
minetest.add_particlespawner(5, 0.5,
minp, maxp,
vel, vel,
acc, acc,
5, 5,
25, 25,
false, "weather_snow.png", player:get_player_name())
minetest.add_particlespawner(4, 0.5,
minp_deep, maxp_deep,
vel, vel,
acc, acc,
4, 4,
25, 25,
false, "weather_snow.png", player:get_player_name())
if math.random(1,5) == 4 then
snow_fall(randpos(sminp, smaxp), player)
end
else
if math.random(1,5) == 4 then
snow_fall(randpos(sminp, smaxp), player, true)
end
end
end
end)
end

445
init.lua
View File

@ -17,26 +17,11 @@
MA 02110-1301, USA. MA 02110-1301, USA.
]]-- ]]--
snow = {} dofile(minetest.get_modpath("snow").."/util.lua")
dofile(minetest.get_modpath("snow").."/mapgen.lua") dofile(minetest.get_modpath("snow").."/mapgen.lua")
dofile(minetest.get_modpath("snow").."/config.lua") dofile(minetest.get_modpath("snow").."/falling_snow.lua")
--Replace leaves so snow gets removed on decay. local needles = {
local leaves = {}
for k,v in pairs(minetest.registered_nodes["default:leaves"]) do
leaves[k] = v
end
leaves.after_destruct = function(pos, node, digger)
pos.y = pos.y + 1
local nodename = minetest.env:get_node(pos).name
if nodename == "snow:snow" then
minetest.env:remove_node(pos)
end
end
minetest.register_node(":default:leaves", leaves)
--Pine leaves.
minetest.register_node("snow:needles", {
description = "Pine Needles", description = "Pine Needles",
drawtype = "allfaces_optional", drawtype = "allfaces_optional",
visual_scale = 1.3, visual_scale = 1.3,
@ -46,11 +31,6 @@ minetest.register_node("snow:needles", {
drop = { drop = {
max_items = 1, max_items = 1,
items = { items = {
{
-- player will get xmas tree with 1/50 chance
items = {'snow:xmas_tree'},
rarity = 50,
},
{ {
-- player will get sapling with 1/20 chance -- player will get sapling with 1/20 chance
items = {'snow:sapling_pine'}, items = {'snow:sapling_pine'},
@ -63,16 +43,19 @@ minetest.register_node("snow:needles", {
} }
} }
}, },
--Remove snow above leaves after decay.
after_destruct = function(pos, node, digger)
pos.y = pos.y + 1
local nodename = minetest.env:get_node(pos).name
if nodename == "snow:snow" then
minetest.env:remove_node(pos)
end
end,
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_leaves_defaults(),
}) }
if snow.christmas_content then
needles["drop"]["items"][3] = {
-- player will get xmas tree with 1/50 chance
items = {'snow:xmas_tree'},
rarity = 50,
}
end
--Pine leaves.
minetest.register_node("snow:needles", needles)
--Decorated Pine leaves. --Decorated Pine leaves.
minetest.register_node("snow:needles_decorated", { minetest.register_node("snow:needles_decorated", {
@ -101,14 +84,6 @@ minetest.register_node("snow:needles_decorated", {
} }
} }
}, },
--Remove snow above leaves after decay.
after_destruct = function(pos, node, digger)
pos.y = pos.y + 1
local nodename = minetest.env:get_node(pos).name
if nodename == "snow:snow" then
minetest.env:remove_node(pos)
end
end,
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_leaves_defaults(),
}) })
@ -178,13 +153,13 @@ minetest.register_craft({
--Snowballs --Snowballs
------------- -------------
snowball_GRAVITY=9 local snowball_GRAVITY=9
snowball_VELOCITY=19 local snowball_VELOCITY=19
--Shoot snowball. --Shoot snowball.
local snow_shoot_snowball=function (item, player, pointed_thing) local snow_shoot_snowball=function (item, player, pointed_thing)
local playerpos=player:getpos() local playerpos=player:getpos()
local obj=minetest.env:add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, "snow:snowball_entity") local obj=minetest.add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, "snow:snowball_entity")
local dir=player:get_look_dir() local dir=player:get_look_dir()
obj:setvelocity({x=dir.x*snowball_VELOCITY, y=dir.y*snowball_VELOCITY, z=dir.z*snowball_VELOCITY}) obj:setvelocity({x=dir.x*snowball_VELOCITY, y=dir.y*snowball_VELOCITY, z=dir.z*snowball_VELOCITY})
obj:setacceleration({x=dir.x*-3, y=-snowball_GRAVITY, z=dir.z*-3}) obj:setacceleration({x=dir.x*-3, y=-snowball_GRAVITY, z=dir.z*-3})
@ -205,12 +180,12 @@ snow_snowball_ENTITY={
snow_snowball_ENTITY.on_step = function(self, dtime) snow_snowball_ENTITY.on_step = function(self, dtime)
self.timer=self.timer+dtime self.timer=self.timer+dtime
local pos = self.object:getpos() local pos = self.object:getpos()
local node = minetest.env:get_node(pos) local node = minetest.get_node(pos)
--Become item when hitting a node. --Become item when hitting a node.
if self.lastpos.x~=nil then --If there is no lastpos for some reason. if self.lastpos.x~=nil then --If there is no lastpos for some reason.
if node.name ~= "air" then if node.name ~= "air" then
minetest.env:place_node(self.lastpos,{name="snow:snow"}) snow.place(pos)
self.object:remove() self.object:remove()
end end
end end
@ -226,61 +201,199 @@ minetest.register_craftitem("snow:snowball", {
on_use = snow_shoot_snowball, on_use = snow_shoot_snowball,
}) })
--Snow. for i=1,8 do
minetest.register_node("snow:snow", { local snow_box =
{
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -0.5 + i/9., 0.5}
}
minetest.register_node("snow:snow"..(tostring(i) ~= "1" and tostring(i) or ""), {
description = "Snow", description = "Snow",
tiles = {"snow_snow.png"}, tiles = {"snow_snow.png"},
drawtype = "nodebox", drawtype = "nodebox",
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
param2 = nil, paramtype2 == "leveled",
--param2 is reserved for what vegetation is hiding inside. groups = {crumbly=3,melts=3,falling_node=1,not_in_creative_inventory=1},
--mapgen defines the vegetation.
--1 = Moss
groups = {crumbly=3,melts=3},
buildable_to = true, buildable_to = true,
drop = 'snow:snowball', drop = {
max_items = 2,
items = {
{
-- player will get sapling with 1/20 chance
items = {'snow:moss'},
rarity = 20,
},
{
-- player will get leaves only if he get no saplings,
-- this is because max_items is 1
items = {'snow:snowball'},
}
}
},
leveled = 7*i,
drawtype = "nodebox",
node_box = snow_box,
sounds = default.node_sound_dirt_defaults({
footstep = {name="default_snow_footstep", gain=0.45},
}),
on_construct = function(pos)
pos.y = pos.y - 1
if minetest.get_node(pos).name == "default:dirt_with_grass" then
minetest.add_node(pos, {name="snow:dirt_with_snow"})
end
end,
after_destruct = function(pos)
pos.y = pos.y - 1
if minetest.get_node(pos).name == "snow:dirt_with_snow" then
minetest.add_node(pos, {name="default:dirt_with_grass"})
end
end,
})
end
if not snow.legacy then
--Snow.
minetest.register_node("snow:snow", {
description = "Snow",
tiles = {"snow_snow.png"},
drawtype = "nodebox",
sunlight_propagates = true,
paramtype = "light",
paramtype2 == "leveled",
groups = {crumbly=3,melts=3,falling_node=1,not_in_creative_inventory=1},
buildable_to = true,
drop = {
max_items = 2,
items = {
{
-- player will get sapling with 1/20 chance
items = {'snow:moss'},
rarity = 20,
},
{
-- player will get leaves only if he get no saplings,
-- this is because max_items is 1
items = {'snow:snowball'},
}
}
},
leveled = 7,
drawtype = "nodebox",
node_box = { node_box = {
type = "fixed", type = "leveled",
fixed = { fixed = {
{-0.5, -0.5, -0.5, 0.5, -0.35, 0.5} {-0.5, -0.5, -0.5, 0.5, -0.5+2/16, 0.5},
},
},
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, -0.35, 0.5}
}, },
}, },
sounds = default.node_sound_dirt_defaults({ sounds = default.node_sound_dirt_defaults({
footstep = {name="default_gravel_footstep", gain=0.45}, footstep = {name="default_snow_footstep", gain=0.45},
}), }),
--Update dirt node underneath snow. on_construct = function(pos)
after_destruct = function(pos, node, digger)
if node.param2 == 1 then
local n = minetest.env:get_node(pos).name
if n == "air" or n == "default:water_flowing" or n == "default:water_source" then
minetest.env:add_node(pos,{name="snow:moss",param2=1})
end
end
pos.y = pos.y - 1 pos.y = pos.y - 1
local nodename = minetest.env:get_node(pos).name if minetest.get_node(pos).name == "default:dirt_with_grass" then
if nodename == "snow:dirt_with_snow" then minetest.add_node(pos, {name="snow:dirt_with_snow"})
minetest.env:add_node(pos,{name="default:dirt_with_grass"})
end end
end, end,
on_construct = function(pos, newnode) after_destruct = function(pos)
pos.y = pos.y - 1 pos.y = pos.y - 1
local nodename = minetest.env:get_node(pos).name if minetest.get_node(pos).name == "snow:dirt_with_snow" then
if nodename == "default:dirt_with_grass" then minetest.add_node(pos, {name="default:dirt_with_grass"})
minetest.env:remove_node(pos)
minetest.env:add_node(pos,{name="snow:dirt_with_snow"})
elseif nodename == "air" then
pos.y = pos.y + 1
minetest.env:remove_node(pos)
end end
end, end,
}) })
else
minetest.add_node_level = function(pos, amount)
local node = minetest.get_node(pos)
if node.name == "snow:snow" then
minetest.add_node(pos,{name="snow:snow2"})
elseif node.name:find("snow:snow") and node.name:sub(-1)~="8" then
minetest.add_node(pos,{name="snow:snow"..tonumber(node.name:sub(-1))+1})
end
end
minetest.get_node_level = function(pos)
local node = minetest.get_node(pos)
if node.name == "snow:snow" then
return 7
elseif node.name:find("snow:snow") and node.name:sub(-1) then
return 7*(tonumber(node.name:sub(-1)))
end
end
end
function snow.place(pos)
local node = minetest.get_node(pos)
local drawtype = minetest.registered_nodes[node.name].drawtype
local bnode = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
if node.name:find("snow:snow") and minetest.get_node_level(pos) < 63 then
if minetest.get_item_group(bnode.name, "leafdecay") == 0 and snow.is_uneven(pos) ~= true then
minetest.add_node_level(pos, 7)
end
elseif node.name:find("snow:snow") and minetest.get_node_level(pos) == 63 then
local p = minetest.find_node_near(pos, 10, "default:dirt_with_grass")
if p and minetest.get_node_light(p, 0.5) == 15 then
minetest.add_node(p,{name="snow:snow"})
else
minetest.add_node(pos,{name="snow:snowblock"})
end
elseif node.name ~= "snow:ice" and node.name ~= "air" then
if drawtype == "normal" or drawtype == "allfaces_optional" then
minetest.add_node({x=pos.x,y=pos.y+1,z=pos.z}, {name="snow:snow"})
elseif drawtype == "plantlike" then
pos.y = pos.y - 1
if minetest.get_node(pos).name == "default:dirt_with_grass" then
minetest.add_node(pos, {name="snow:dirt_with_snow"})
end
end
end
end
--Checks if the snow level is even at any given pos.
--Smooth snow
local smooth_snow = snow.smooth_snow
snow.is_uneven = function(pos)
if smooth_snow then
local num = minetest.get_node_level(pos)
local get_node = minetest.get_node
local add_node = minetest.add_node
local found
local foundx
local foundy
for x=-1,1 do
for z=-1,1 do
local node = get_node({x=pos.x+x,y=pos.y,z=pos.z+z})
local bnode = get_node({x=pos.x+x,y=pos.y-1,z=pos.z+z})
local drawtype = minetest.registered_nodes[node.name].drawtype
if drawtype == "plantlike" then
if bnode.name == "default:dirt_with_grass" then
add_node({x=pos.x+x,y=pos.y-1,z=pos.z+z}, {name="snow:dirt_with_snow"})
return true
end
end
if (not(x == 0 and y == 0)) and node.name == "snow:snow" and minetest.get_node_level({x=pos.x+x,y=pos.y,z=pos.z+z}) < num then
found = true
foundx = x
foundz=z
elseif node.name == "air" and bnode.name ~= "air" then
if not (bnode.name:find("snow:snow")) then
snow.place({x=pos.x+x,y=pos.y,z=pos.z+z})
return true
end
end
end
end
if found then
local node = get_node({x=pos.x+foundx,y=pos.y,z=pos.z+foundz})
if snow.is_uneven({x=pos.x+foundx,y=pos.y,z=pos.z+foundz}) ~= true then
minetest.add_node_level({x=pos.x+foundx,y=pos.y,z=pos.z+foundz}, 7)
end
return true
end
end
end
--Snow with dirt. --Snow with dirt.
minetest.register_node("snow:dirt_with_snow", { minetest.register_node("snow:dirt_with_snow", {
@ -290,80 +403,20 @@ minetest.register_node("snow:dirt_with_snow", {
groups = {crumbly=3}, groups = {crumbly=3},
drop = 'default:dirt', drop = 'default:dirt',
sounds = default.node_sound_dirt_defaults({ sounds = default.node_sound_dirt_defaults({
footstep = {name="default_grass_footstep", gain=0.4}, footstep = {name="default_snow_footstep", gain=0.4},
}), }),
--Place snow above this node when placed.
after_place_node = function(pos, newnode)
pos.y = pos.y + 1
local nodename = minetest.env:get_node(pos).name
if nodename == "air" then
minetest.env:add_node(pos,{name="snow:snow"})
end
end,
}) })
--Gets rid of snow when the node underneath is dug.
local unsnowify = function(pos, node, digger)
if node.name == "default:dry_shrub" then
pos.y = pos.y - 1
local nodename = minetest.env:get_node(pos).name
if nodename == "snow:dirt_with_snow" then
minetest.env:add_node(pos,{name="default:dirt_with_grass"})
end
pos.y = pos.y + 1
end
pos.y = pos.y + 1
local nodename = minetest.env:get_node(pos).name
if nodename == "snow:snow" then
minetest.env:remove_node(pos)
local obj=minetest.env:add_entity({x=pos.x,y=pos.y,z=pos.z}, "snow:snowball_entity")
obj:setacceleration({x=0, y=-snowball_GRAVITY, z=0})
end
end
minetest.register_on_dignode(unsnowify)
--Snow block. --Snow block.
minetest.register_node("snow:snow_block", { minetest.register_node("snow:snow_block", {
description = "Snow", description = "Snow",
tiles = {"snow_snow.png"}, tiles = {"snow_snow.png"},
--param2 is reserved for what vegetation is hiding inside.
--mapgen defines the vegetation.
--1 = Moss
--2 = Papyrus
--3 = Dry shrub
is_ground_content = true, is_ground_content = true,
groups = {crumbly=3,melts=2,falling_node=1}, groups = {crumbly=3,melts=2,falling_node=1},
drop = 'snow:snow_block', drop = 'snow:snow_block',
sounds = default.node_sound_dirt_defaults({ sounds = default.node_sound_dirt_defaults({
footstep = {name="default_grass_footstep", gain=0.4}, footstep = {name="default_snow_footstep", gain=0.4},
}), }),
--Update dirt node underneath snow.
after_destruct = function(pos, node, digger)
if node.param2 == 1 then
local n = minetest.env:get_node(pos).name
if n == "air" or n == "default:water_flowing" or n == "default:water_source" then
minetest.env:add_node(pos,{name="snow:moss",param2=1})
end
elseif node.param2 == 2 then
local n = minetest.env:get_node(pos).name
if n == "air" or n == "default:water_flowing" or n == "default:water_source" then
minetest.env:add_node(pos,{name="default:papyrus"})
pos.y = pos.y + 1
local n = minetest.env:get_node(pos)
if n.name == "snow:snow_block" and n.param2 == 2 then
minetest.env:remove_node(pos)
pos.y = pos.y - 1
minetest.env:add_node(pos,{name="snow:snow_block",param2=2})
end
end
elseif node.param2 == 3 then
local n = minetest.env:get_node(pos).name
if n == "air" or n == "default:water_flowing" or n == "default:water_source" then
minetest.env:add_node(pos,{name="default:dry_shrub"})
end
end
end,
}) })
--Snow brick. --Snow brick.
@ -437,20 +490,20 @@ minetest.register_abm({
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local intensity = minetest.get_item_group(node.name,"melts") local intensity = minetest.get_item_group(node.name,"melts")
if intensity == 1 then if intensity == 1 then
minetest.env:add_node(pos,{name="default:water_source"}) minetest.add_node(pos,{name="default:water_source"})
elseif intensity == 2 then elseif intensity == 2 then
local check_place = function(pos,node) local check_place = function(pos,node)
if minetest.env:get_node(pos).name == "air" then if minetest.get_node(pos).name == "air" then
minetest.env:place_node(pos,node) minetest.place_node(pos,node)
end end
end end
minetest.env:add_node(pos,{name="default:water_flowing"}) minetest.add_node(pos,{name="default:water_flowing"})
check_place({x=pos.x+1,y=pos.y,z=pos.z},{name="default:water_flowing"}) check_place({x=pos.x+1,y=pos.y,z=pos.z},{name="default:water_flowing"})
check_place({x=pos.x-1,y=pos.y,z=pos.z},{name="default:water_flowing"}) check_place({x=pos.x-1,y=pos.y,z=pos.z},{name="default:water_flowing"})
check_place({x=pos.x,y=pos.y+1,z=pos.z},{name="default:water_flowing"}) check_place({x=pos.x,y=pos.y+1,z=pos.z},{name="default:water_flowing"})
check_place({x=pos.x,y=pos.y-1,z=pos.z},{name="default:water_flowing"}) check_place({x=pos.x,y=pos.y-1,z=pos.z},{name="default:water_flowing"})
elseif intensity == 3 then elseif intensity == 3 then
minetest.env:add_node(pos,{name="default:water_flowing"}) minetest.add_node(pos,{name="default:water_flowing"})
end end
nodeupdate(pos) nodeupdate(pos)
end, end,
@ -464,7 +517,7 @@ minetest.register_abm({
interval = 20, interval = 20,
chance = 4, chance = 4,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
minetest.env:add_node(pos,{name="snow:ice"}) minetest.add_node(pos,{name="snow:ice"})
end, end,
}) })
@ -475,7 +528,7 @@ minetest.register_abm({
interval = 20, interval = 20,
chance = 6, chance = 6,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
minetest.env:add_node(pos,{name="default:mossycobble"}) minetest.add_node(pos,{name="default:mossycobble"})
end, end,
}) })
@ -498,93 +551,3 @@ minetest.register_abm({
snow.make_pine(pos,false,true) snow.make_pine(pos,false,true)
end, end,
}) })
if snow.enable_snowfall then
--Snowing
snow_fall=function (pos)
local obj=minetest.env:add_entity(pos, "snow:fall_entity")
obj:setvelocity({x=0, y=-1, z=0})
end
-- The snowfall Entity
snow_fall_ENTITY={
physical = true,
timer=0,
textures = {"snow_snowfall.png"},
lastpos={},
collisionbox = {0,0,0,0,0,0},
}
-- snowfall_entity.on_step()--> called when snow is falling
snow_fall_ENTITY.on_step = function(self, dtime)
self.timer=self.timer+dtime
local pos = self.object:getpos()
local node = minetest.env:get_node(pos)
if self.lastpos and self.object:getvelocity().y == 0 then
if minetest.env:get_node({x=self.lastpos.x,z=self.lastpos.z,y=self.lastpos.y}).name == "snow:moss" then
minetest.env:add_node({x=self.lastpos.x,z=self.lastpos.z,y=self.lastpos.y},{name="snow:snow",param2=1})
self.object:remove()
return
end
minetest.env:place_node(self.lastpos,{name="snow:snow"})
self.object:remove()
end
if self.timer > 120 then
self.object:remove()
end
self.lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node
end
minetest.register_entity("snow:fall_entity", snow_fall_ENTITY)
--Regenerate Snow
minetest.register_abm({
nodenames = {"default:dirt_with_grass", "snow:moss"},
interval = 50,
chance = 150,
action = function(pos, node, active_object_count, active_object_count_wider)
--Check we are in the right biome
local env = minetest.env
local perlin1 = env:get_perlin(112,3, 0.5, 150)
local test = perlin1:get2d({x=pos.x, y=pos.z})
local in_biome = false
local smooth = snow.smooth
if smooth and (test > 0.73 or (test > 0.43 and math.random(0,29) > (0.73 - test) * 100 )) then
in_biome = true
elseif not smooth and test > 0.53 then
in_biome = true
end
if in_biome then
--Check if block is under cover
local ground_y = nil
for y=15,0,-1 do
if env:get_node({x=pos.x,y=y+pos.y,z=pos.z}).name ~= "air" then
ground_y = pos.y+y
break
end
end
if ground_y then
local n = env:get_node({x=pos.x,y=ground_y,z=pos.z})
if (n.name ~= "snow:snow" and n.name ~= "snow:snow_block" and n.name ~= "snow:ice" and n.name ~= "default:water_source" and n.name ~= "default:papyrus") then
local obj = minetest.env:get_objects_inside_radius({x=pos.x,y=ground_y+20,z=pos.z}, 15)
for i,v in pairs(obj) do
e = v:get_luaentity()
if e ~= nil and e.name == "snow:fall_entity" then
return
end
end
snow_fall({x=pos.x,y=ground_y+15,z=pos.z})
if snow.debug then
print("snowfall at x"..pos.x.." y"..pos.z)
end
end
end
end
end
})
end

View File

@ -1,3 +1,26 @@
local mgname = ""
--Identify the mapgen.
if minetest.register_on_mapgen_init then
minetest.register_on_mapgen_init(function(MapgenParams)
if MapgenParams.mgname then
mgname = MapgenParams.mgname
else
io.write("[MOD] Snow Biomes: WARNING! mapgen could not be identifyed!\n")
end
if mgname == "v7" then
--Load mapgen_v7 compatibility.
dofile(minetest.get_modpath("snow").."/mapgen_v7.lua")
else
--Load mapgen_v6 compatibility.
dofile(minetest.get_modpath("snow").."/mapgen_v6.lua")
end
end)
else
--Fall back to mapgen_v6.
dofile(minetest.get_modpath("snow").."/mapgen_v6.lua")
end
local pine_tree = { local pine_tree = {
axiom="TABff", axiom="TABff",
rules_a="[&T+f+ff+ff+ff+f]GA", rules_a="[&T+f+ff+ff+ff+f]GA",
@ -68,236 +91,3 @@ function snow.make_pine(pos,snow,xmas)
try_node({x=pos.x,y=pos.y+7,z=pos.z},{name="snow:snow"}) try_node({x=pos.x,y=pos.y+7,z=pos.z},{name="snow:snow"})
end end
end end
--Snow biomes are found at 0.53 and greater perlin noise.
minetest.register_on_generated(function(minp, maxp, seed)
if maxp.y >= -10 then
local debug = snow.debug
--Should make things a bit faster.
local env = minetest.env
--Get map specific perlin
local perlin1 = env:get_perlin(112,3, 0.5, 150)
-- Assume X and Z lengths are equal
local divlen = 16
local divs = (maxp.x-minp.x);
local x0 = minp.x
local z0 = minp.z
local x1 = maxp.x
local z1 = maxp.z
--Speed hack: checks the corners and middle of the chunk for "snow biome".
if not ( perlin1:get2d( {x=x0, y=z0} ) > 0.53 ) --top left
and not ( perlin1:get2d( { x = x0 + ( (x1-x0)/2), y=z0 } ) > 0.53 )--top middle
and not (perlin1:get2d({x=x1, y=z1}) > 0.53) --bottom right
and not (perlin1:get2d({x=x1, y=z0+((z1-z0)/2)}) > 0.53) --right middle
and not (perlin1:get2d({x=x0, y=z1}) > 0.53) --bottom left
and not (perlin1:get2d({x=x1, y=z0}) > 0.53) --top right
and not (perlin1:get2d({x=x0+((x1-x0)/2), y=z1}) > 0.53) --left middle
and not (perlin1:get2d({x=(x1-x0)/2, y=(z1-z0)/2}) > 0.53) --middle
and not (perlin1:get2d({x=x0, y=z1+((z1-z0)/2)}) > 0.53) then --bottom middle
return
end
--Choose a biome types.
local pr = PseudoRandom(seed+57)
local biome
--Land biomes
biome = pr:next(1, 5)
local snowy = biome == 1 --spawns alot of snow
local plain = biome == 2 --spawns not much
local alpine = biome == 3 --rocky terrain
-- biome == 4 or biome == 5 -- normal biome
--Water biomes
biome2 = pr:next(1, 5)
local cool = biome == 1 --only spawns ice on edge of water
local icebergs = biome == 2
local icesheet = biome == 3
local icecave = biome == 4
local icehole = biome == 5 --icesheet with holes
--Misc biome settings.
local icy = pr:next(1, 2) == 2 --If enabled spawns ice in sand instead of snow blocks.
local mossy = pr:next(1,2) == 1 --Spawns moss in snow.
local shrubs = pr:next(1,2) == 1 --Spawns dry shrubs in snow.
local pines = pr:next(1,2) == 1 --spawns pines.
--Debugging function
local biomeToString = function(num,num2)
local biome, biome2
if num == 1 then biome = "snowy"
elseif num == 2 then biome = "plain"
elseif num == 3 then biome = "alpine"
elseif num == 4 or num == 5 then biome = "normal"
else biome = "unknown "..num end
if num2 == 1 then biome2 = "cool"
elseif num2 == 2 then biome2 = "icebergs"
elseif num2 == 3 then biome2 = "icesheet"
elseif num2 == 4 then biome2 = "icecave"
elseif num2 == 5 then biome2 = "icehole"
else biome2 = "unknown "..num end
return biome, biome2
end
local make_pine = snow.make_pine
local smooth = snow.smooth
--Reseed random.
pr = PseudoRandom(seed+68)
if alpine then
local trees = env:find_nodes_in_area(minp, maxp, {"default:leaves","default:tree"})
for i,v in pairs(trees) do
env:remove_node(v)
end
end
--Loop through chunk.
for j=0,divs do
for i=0,divs do
local x = x0+i
local z = z0+j
--Check if we are in a "Snow biome"
local in_biome = false
local test = perlin1:get2d({x=x, y=z})
if smooth and (not snowy) and (test > 0.73 or (test > 0.43 and pr:next(0,29) > (0.73 - test) * 100 )) then
in_biome = true
elseif (not smooth or snowy) and test > 0.53 then
in_biome = true
end
if in_biome then
if not plain or pr:next(1,12) == 1 then
-- Find ground level (0...15)
local ground_y = nil
for y=maxp.y,minp.y+1,-1 do
if env:get_node({x=x,y=y,z=z}).name ~= "air" then
ground_y = y
break
end
end
-- Snowy biome stuff
local node = env:get_node({x=x,y=ground_y,z=z})
if ground_y and (node.name == "default:dirt_with_grass" or node.name == "default:junglegrass") then
local veg
if mossy and pr:next(1,10) == 1 then veg = 1 end
if alpine then
--Gets rid of dirt
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow",param2=veg})
for y=ground_y,-6,-1 do
if env:get_node({x=x,y=y,z=z}) and env:get_node({x=x,y=y,z=z}).name == "default:stone" then
break
else
env:add_node({x=x,y=y,z=z},{name="default:stone"})
end
end
elseif (shrubs and pr:next(1,28) == 1) or node.name == "default:junglegrass" then
--Spawns dry shrubs.
env:add_node({x=x,y=ground_y,z=z}, {name="snow:dirt_with_snow"})
if snowy then
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow_block", param2=3})
else
env:add_node({x=x,y=ground_y+1,z=z}, {name="default:dry_shrub"})
end
elseif pines and pr:next(1,36) == 1 then
--Spawns pines.
env:add_node({x=x,y=ground_y,z=z}, {name="default:dirt_with_grass"})
make_pine({x=x,y=ground_y+1,z=z},true)
elseif snowy then
--Spawns snow blocks.
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow_block"})
env:add_node({x=x,y=ground_y+2,z=z}, {name="snow:snow",param2=veg})
else
--Spawns snow.
env:add_node({x=x,y=ground_y,z=z}, {name="snow:dirt_with_snow"})
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow",param2=veg})
end
elseif ground_y and node.name == "default:sand" then
--Spawns ice in sand if icy, otherwise spawns snow on top.
if not icy then
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow"})
env:add_node({x=x,y=ground_y,z=z}, {name="snow:snow_block"})
else
env:add_node({x=x,y=ground_y,z=z}, {name="snow:ice"})
end
elseif ground_y and env:get_node({x=x,y=ground_y,z=z}).name == "default:leaves" then
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow"})
elseif ground_y and env:get_node({x=x,y=ground_y,z=z}).name == "default:papyrus" then
for i=ground_y, ground_y-4, -1 do
if env:get_node({x=x,y=i,z=z}).name == "default:papyrus" then
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow"})
env:add_node({x=x,y=i,z=z}, {name="snow:snow_block", param2=2})
end
end
elseif ground_y and node.name == "default:water_source" then
if not icesheet and not icecave and not icehole then
--Coastal ice.
local x1 = env:get_node({x=x+1,y=ground_y,z=z}).name
local z1 = env:get_node({x=x,y=ground_y,z=z+1}).name
local xz1 = env:get_node({x=x+1,y=ground_y,z=z+1}).name
local xz2 = env:get_node({x=x-1,y=ground_y,z=z-1}).name
local x2 = env:get_node({x=x-1,y=ground_y,z=z}).name
local z2 = env:get_node({x=x,y=ground_y,z=z-1}).name
local y = env:get_node({x=x,y=ground_y-1,z=z}).name
local rand = pr:next(1,4) == 1
if
((x1 and x1 ~= "default:water_source" and x1 ~= "snow:ice" and x1 ~= "air" and x1 ~= "ignore") or ((cool or icebergs) and x1 == "snow:ice" and rand)) or
((z1 and z1 ~= "default:water_source" and z1 ~= "snow:ice" and z1 ~= "air" and z1 ~= "ignore") or ((cool or icebergs) and z1 == "snow:ice" and rand)) or
((xz1 and xz1 ~= "default:water_source" and xz1 ~= "snow:ice" and xz1 ~= "air"and xz1 ~= "ignore") or ((cool or icebergs) and xz1 == "snow:ice" and rand)) or
((xz2 and xz2 ~= "default:water_source" and xz2 ~= "snow:ice" and xz2 ~= "air"and xz2 ~= "ignore") or ((cool or icebergs) and xz2 == "snow:ice" and rand)) or
((x2 and x2 ~= "default:water_source" and x2 ~= "snow:ice" and x2 ~= "air" and x2 ~= "ignore") or ((cool or icebergs) and x2 == "snow:ice" and rand)) or
((z2 and z2 ~= "default:water_source" and z2 ~= "snow:ice" and z2 ~= "air" and z2 ~= "ignore") or ((cool or icebergs) and z2 == "snow:ice" and rand)) or
(y ~= "default:water_source" and y ~= "snow:ice" and y ~= "air") or (pr:next(1,6) == 1 and icebergs) then
env:add_node({x=x,y=ground_y,z=z}, {name="snow:ice"})
end
else
--Icesheets, Broken icesheet, Icecaves
if (icehole and pr:next(1,10) > 1) or icecave or icesheet then
env:add_node({x=x,y=ground_y,z=z}, {name="snow:ice"})
end
if icecave then
--Gets rid of water underneath ice
for y=ground_y-1,-60,-1 do
if env:get_node({x=x,y=y,z=z}) and env:get_node({x=x,y=y,z=z}).name ~= "default:water_source" then
break
else
env:remove_node({x=x,y=y,z=z})
end
end
end
end
--~ elseif ground_y and node.name == "snow:snow" and node.name ~= "snow:ice" then
--~ --Abort genaration.
--~ local name = env:get_node({x=x,y=ground_y-1,z=z}).name
--~ if name ~= "default:leaves" and name ~= "snow:needles" then
--~ if debug then
--~ print(biomeToString(biome)..": snow found ABORTED!")
--~ end
--~ return
--~ end
end
end
end
end
end
if debug then
biome_string,biome2_string = biomeToString(biome,biome2)
print(biome_string.." and "..biome2_string..": Snow Biome Genarated near x"..minp.x.." z"..minp.z)
end
end
end
)

234
mapgen_v6.lua Normal file
View File

@ -0,0 +1,234 @@
--Snow biomes are found at 0.53 and greater perlin noise.
minetest.register_on_generated(function(minp, maxp, seed)
if maxp.y >= -10 and maxp.y > snow.min_height then
local debug = snow.debug
local min_height = snow.min_height
--Should make things a bit faster.
local env = minetest.env
--Get map specific perlin
local perlin1 = env:get_perlin(112,3, 0.5, 150)
-- Assume X and Z lengths are equal
local divlen = 16
local divs = (maxp.x-minp.x);
local x0 = minp.x
local z0 = minp.z
local x1 = maxp.x
local z1 = maxp.z
--Speed hack: checks the corners and middle of the chunk for "snow biome".
if not ( perlin1:get2d( {x=x0, y=z0} ) > 0.53 ) --top left
and not ( perlin1:get2d( { x = x0 + ( (x1-x0)/2), y=z0 } ) > 0.53 )--top middle
and not (perlin1:get2d({x=x1, y=z1}) > 0.53) --bottom right
and not (perlin1:get2d({x=x1, y=z0+((z1-z0)/2)}) > 0.53) --right middle
and not (perlin1:get2d({x=x0, y=z1}) > 0.53) --bottom left
and not (perlin1:get2d({x=x1, y=z0}) > 0.53) --top right
and not (perlin1:get2d({x=x0+((x1-x0)/2), y=z1}) > 0.53) --left middle
and not (perlin1:get2d({x=(x1-x0)/2, y=(z1-z0)/2}) > 0.53) --middle
and not (perlin1:get2d({x=x0, y=z1+((z1-z0)/2)}) > 0.53) then --bottom middle
return
end
--Choose a biome types.
local pr = PseudoRandom(seed+57)
local biome
--Land biomes
biome = pr:next(1, 5)
local snowy = biome == 1 --spawns alot of snow
local plain = biome == 2 --spawns not much
local alpine = biome == 3 --rocky terrain
-- biome == 4 or biome == 5 -- normal biome
--Water biomes
biome2 = pr:next(1, 5)
local cool = biome == 1 --only spawns ice on edge of water
local icebergs = biome == 2
local icesheet = biome == 3
local icecave = biome == 4
local icehole = biome == 5 --icesheet with holes
--Misc biome settings.
local icy = pr:next(1, 2) == 2 --If enabled spawns ice in sand instead of snow blocks.
local mossy = pr:next(1,2) == 1 --Spawns moss in snow.
local shrubs = pr:next(1,2) == 1 --Spawns dry shrubs in snow.
local pines = pr:next(1,2) == 1 --spawns pines.
--Debugging function
local biomeToString = function(num,num2)
local biome, biome2
if num == 1 then biome = "snowy"
elseif num == 2 then biome = "plain"
elseif num == 3 then biome = "alpine"
elseif num == 4 or num == 5 then biome = "normal"
else biome = "unknown "..num end
if num2 == 1 then biome2 = "cool"
elseif num2 == 2 then biome2 = "icebergs"
elseif num2 == 3 then biome2 = "icesheet"
elseif num2 == 4 then biome2 = "icecave"
elseif num2 == 5 then biome2 = "icehole"
else biome2 = "unknown "..num end
return biome, biome2
end
local make_pine = snow.make_pine
local smooth = snow.smooth_biomes
local legacy = snow.legacy
--Reseed random.
pr = PseudoRandom(seed+68)
if alpine then
local trees = env:find_nodes_in_area(minp, maxp, {"default:leaves","default:tree"})
for i,v in pairs(trees) do
env:remove_node(v)
end
end
--Loop through chunk.
for j=0,divs do
for i=0,divs do
local x = x0+i
local z = z0+j
--Check if we are in a "Snow biome"
local in_biome = false
local test = perlin1:get2d({x=x, y=z})
if smooth and (not snowy) and (test > 0.73 or (test > 0.43 and pr:next(0,29) > (0.73 - test) * 100 )) then
in_biome = true
elseif (not smooth or snowy) and test > 0.53 then
in_biome = true
end
if in_biome then
if not plain or pr:next(1,12) == 1 then
-- Find ground level (0...15)
local ground_y = nil
for y=maxp.y,minp.y+1,-1 do
if env:get_node({x=x,y=y,z=z}).name ~= "air" then
ground_y = y
break
end
end
if ground_y and ground_y > min_height then
-- Snowy biome stuff
local node = env:get_node({x=x,y=ground_y,z=z})
if ground_y and (node.name == "default:dirt_with_grass" or node.name == "default:junglegrass") then
local veg
if legacy and mossy and pr:next(1,10) == 1 then veg = 1 end
if alpine then
--Gets rid of dirt
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow", param2=veg})
for y=ground_y,-6,-1 do
if env:get_node({x=x,y=y,z=z}) and env:get_node({x=x,y=y,z=z}).name == "default:stone" then
break
else
env:add_node({x=x,y=y,z=z},{name="default:stone"})
end
end
elseif (shrubs and pr:next(1,28) == 1) or node.name == "default:junglegrass" then
--Spawns dry shrubs.
env:add_node({x=x,y=ground_y,z=z}, {name="snow:dirt_with_snow"})
if snowy then
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow_block"})
else
env:add_node({x=x,y=ground_y+1,z=z}, {name="default:dry_shrub"})
end
elseif pines and pr:next(1,36) == 1 then
--Spawns pines.
env:add_node({x=x,y=ground_y,z=z}, {name="default:dirt_with_grass"})
make_pine({x=x,y=ground_y+1,z=z},true)
elseif snowy then
--Spawns snow blocks.
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow_block"})
env:add_node({x=x,y=ground_y+2,z=z}, {name="snow:snow", param2=veg})
else
--Spawns snow.
env:add_node({x=x,y=ground_y,z=z}, {name="snow:dirt_with_snow"})
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow", param2=veg})
end
elseif ground_y and node.name == "default:sand" then
--Spawns ice in sand if icy, otherwise spawns snow on top.
if not icy then
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow"})
env:add_node({x=x,y=ground_y,z=z}, {name="snow:snow_block"})
else
env:add_node({x=x,y=ground_y,z=z}, {name="snow:ice"})
end
elseif ground_y and env:get_node({x=x,y=ground_y,z=z}).name == "default:leaves" then
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow"})
elseif ground_y and env:get_node({x=x,y=ground_y,z=z}).name == "default:papyrus" then
for i=ground_y, ground_y-4, -1 do
if env:get_node({x=x,y=i,z=z}).name == "default:papyrus" then
env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow"})
env:add_node({x=x,y=i,z=z}, {name="snow:snow_block", param2=2})
end
end
elseif ground_y and node.name == "default:water_source" then
if not icesheet and not icecave and not icehole then
--Coastal ice.
local x1 = env:get_node({x=x+1,y=ground_y,z=z}).name
local z1 = env:get_node({x=x,y=ground_y,z=z+1}).name
local xz1 = env:get_node({x=x+1,y=ground_y,z=z+1}).name
local xz2 = env:get_node({x=x-1,y=ground_y,z=z-1}).name
local x2 = env:get_node({x=x-1,y=ground_y,z=z}).name
local z2 = env:get_node({x=x,y=ground_y,z=z-1}).name
local y = env:get_node({x=x,y=ground_y-1,z=z}).name
local rand = pr:next(1,4) == 1
if
((x1 and x1 ~= "default:water_source" and x1 ~= "snow:ice" and x1 ~= "air" and x1 ~= "ignore") or ((cool or icebergs) and x1 == "snow:ice" and rand)) or
((z1 and z1 ~= "default:water_source" and z1 ~= "snow:ice" and z1 ~= "air" and z1 ~= "ignore") or ((cool or icebergs) and z1 == "snow:ice" and rand)) or
((xz1 and xz1 ~= "default:water_source" and xz1 ~= "snow:ice" and xz1 ~= "air"and xz1 ~= "ignore") or ((cool or icebergs) and xz1 == "snow:ice" and rand)) or
((xz2 and xz2 ~= "default:water_source" and xz2 ~= "snow:ice" and xz2 ~= "air"and xz2 ~= "ignore") or ((cool or icebergs) and xz2 == "snow:ice" and rand)) or
((x2 and x2 ~= "default:water_source" and x2 ~= "snow:ice" and x2 ~= "air" and x2 ~= "ignore") or ((cool or icebergs) and x2 == "snow:ice" and rand)) or
((z2 and z2 ~= "default:water_source" and z2 ~= "snow:ice" and z2 ~= "air" and z2 ~= "ignore") or ((cool or icebergs) and z2 == "snow:ice" and rand)) or
(y ~= "default:water_source" and y ~= "snow:ice" and y ~= "air") or (pr:next(1,6) == 1 and icebergs) then
env:add_node({x=x,y=ground_y,z=z}, {name="snow:ice"})
end
else
--Icesheets, Broken icesheet, Icecaves
if (icehole and pr:next(1,10) > 1) or icecave or icesheet then
env:add_node({x=x,y=ground_y,z=z}, {name="snow:ice"})
end
if icecave then
--Gets rid of water underneath ice
for y=ground_y-1,-60,-1 do
if env:get_node({x=x,y=y,z=z}) and env:get_node({x=x,y=y,z=z}).name ~= "default:water_source" then
break
else
env:remove_node({x=x,y=y,z=z})
end
end
end
end
--~ elseif ground_y and node.name == "snow:snow" and node.name ~= "snow:ice" then
--~ --Abort genaration.
--~ local name = env:get_node({x=x,y=ground_y-1,z=z}).name
--~ if name ~= "default:leaves" and name ~= "snow:needles" then
--~ if debug then
--~ print(biomeToString(biome)..": snow found ABORTED!")
--~ end
--~ return
--~ end
end
end
end
end
end
end
if debug then
biome_string,biome2_string = biomeToString(biome,biome2)
print(biome_string.." and "..biome2_string..": Snow Biome Genarated near x"..minp.x.." z"..minp.z)
end
end
end)

148
mapgen_v7.lua Normal file
View File

@ -0,0 +1,148 @@
minetest.register_biome({
name = "snow_biome_default",
node_top = "snow:dirt_with_snow",
depth_top = 1,
node_filler = "default:dirt",
depth_filler = 2,
height_min = snow.min_height,
height_max = snow.min_height+60,
heat_point = 10.0,
humidity_point = 40.0,
})
minetest.register_biome({
name = "snow_biome_forest",
node_top = "snow:dirt_with_snow",
depth_top = 1,
node_filler = "default:dirt",
depth_filler = 2,
height_min = snow.min_height,
height_max = snow.min_height+60,
heat_point = 10.0,
humidity_point = 55.0,
})
minetest.register_biome({
name = "snow_biome_lush",
node_top = "snow:dirt_with_snow",
depth_top = 1,
node_filler = "default:dirt",
depth_filler = 2,
height_min = snow.min_height,
height_max = snow.min_height+60,
heat_point = 10.0,
humidity_point = 70.0,
})
minetest.register_biome({
name = "snow_biome_alpine",
node_top = "default:stone",
depth_top = 1,
node_filler = "default:stone",
height_min = snow.min_height+60,
height_max = 31000,
heat_point = 10.0,
humidity_point = 40.0,
})
minetest.register_biome({
name = "base_normal",
height_min = 3,
height_max = 40,
heat_point = 40.0,
humidity_point = 40.0,
})
minetest.register_biome({
name = "snow_biome_sand",
node_top = "default:sand",
depth_top = 3,
node_filler = "default:stone",
depth_filler = 0,
height_min = -31000,
height_max = 2,
heat_point = 10.0,
humidity_point = 40.0,
})
--Pine tree.
minetest.register_decoration({
deco_type = "schematic",
place_on = "snow:dirt_with_snow",
sidelen = 16,
fill_ratio = 0.005,
biomes = {"snow_biome_default"},
schematic = minetest.get_modpath("snow").."/schematics/pine.mts",
flags = "place_center_x, place_center_z",
})
minetest.register_decoration({
deco_type = "schematic",
place_on = "snow:dirt_with_snow",
sidelen = 16,
fill_ratio = 0.05,
biomes = {"snow_biome_forest"},
schematic = minetest.get_modpath("snow").."/schematics/pine.mts",
flags = "place_center_x, place_center_z",
})
minetest.register_decoration({
deco_type = "schematic",
place_on = "snow:dirt_with_snow",
sidelen = 16,
fill_ratio = 0.1,
biomes = {"snow_biome_lush"},
schematic = minetest.get_modpath("snow").."/schematics/pine.mts",
flags = "place_center_x, place_center_z",
})
--Dry shrubs.
minetest.register_decoration({
deco_type = "simple",
place_on = "snow:dirt_with_snow",
sidelen = 16,
fill_ratio = 0.005,
biomes = {"snow_biome_default"},
decoration = "default:dry_shrub",
})
minetest.register_decoration({
deco_type = "simple",
place_on = "snow:dirt_with_snow",
sidelen = 16,
fill_ratio = 0.05,
biomes = {"snow_biome_forest", "snow_biome_lush"},
decoration = "default:dry_shrub",
})
--Snow.
minetest.register_decoration({
deco_type = "simple",
place_on = "snow:dirt_with_snow",
sidelen = 16,
fill_ratio = 10,
biomes = {"snow_biome_default", "snow_biome_forest", "snow_biome_lush"},
decoration = "snow:snow",
})
minetest.register_decoration({
deco_type = "simple",
place_on = "default:stone",
sidelen = 16,
fill_ratio = 10,
biomes = {"snow_biome_alpine"},
decoration = "snow:snow",
})

BIN
schematics/pine.mts Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

After

Width:  |  Height:  |  Size: 189 B

BIN
textures/weather_snow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

98
util.lua Normal file
View File

@ -0,0 +1,98 @@
--Global config and function table.
snow = {
legacy = true,
enable_snowfall = true,
debug = false,
smooth_biomes = true,
christmas_content = true,
smooth_snow = true,
min_height = 3,
}
--Config documentation.
local doc = {
legacy = "Whether you are running a legacy minetest version (auto-detected).",
enable_snowfall = "Enables falling snow.",
debug = "Enables debug output.",
smooth_biomes = "Enables smooth transition of biomes",
christmas_content = "Disable this to remove christmas saplings from being found.",
smooth_snow = "Disable this to stop snow from being smoothed.",
min_height = "The minumum height a snow biome will generate.",
}
--Manage config.
--Saves contents of config to file.
local function saveConfig(path, config, doc)
local file = io.open(path,"w")
if file then
for i,v in pairs(config) do
local t = type(v)
if t == "string" or t == "number" or t == "boolean" then
if doc and doc[i] then
file:write("# "..doc[i].."\n")
end
file:write(i.." = "..tostring(v).."\n")
end
end
end
end
--Loads config and returns config values inside table.
local function loadConfig(path)
local config = {}
local file = io.open(path,"r")
if file then
io.close(file)
for line in io.lines(path) do
if line:sub(1,1) ~= "#" then
i, v = line:match("^(%S*) = (%S*)")
if i and v then
if v == "true" then v = true end
if v == "false" then v = false end
if tonumber(v) then v = tonumber(v) end
config[i] = v
end
end
end
return config
else
--Create config file.
return nil
end
end
minetest.register_on_shutdown(function() saveConfig(minetest.get_modpath("snow").."/config.txt", snow, doc) end)
local config = loadConfig(minetest.get_modpath("snow").."/config.txt")
if config then
for i,v in pairs(config) do
snow[i] = v
end
else
saveConfig(minetest.get_modpath("snow").."/config.txt", snow, doc)
end
for i,v in pairs(snow) do
local t = type(v)
if t == "string" or t == "number" or t == "boolean" then
local v = minetest.setting_get("snow_"..i)
if v ~= nil then
if v == "true" then v = true end
if v == "false" then v = false end
if tonumber(v) then v = tonumber(v) end
snow[i] = v
end
end
end
--AUTO DETECT and/or OVERIDEN values--
--legacy--
--Detect if we are running the latest minetest.
if minetest.register_on_mapgen_init and minetest.get_heat and minetest.get_humidity then
snow.legacy = false
else
snow.legacy = true
end
if config and snow.legacy ~= config.legacy then
saveConfig(minetest.get_modpath("snow").."/config.txt", snow, doc)
end