From 6a5b25bda614cd56121daee2613270182239cc01 Mon Sep 17 00:00:00 2001 From: Splizard Date: Tue, 6 Aug 2013 06:25:01 +0000 Subject: [PATCH] Major changes, mapgen_v7 support, better falling snow, config. --- .gitignore | 2 + config.lua | 10 - falling_snow.lua | 165 +++++++++++++ init.lua | 469 +++++++++++++++++-------------------- mapgen.lua | 256 ++------------------ mapgen_v6.lua | 234 ++++++++++++++++++ mapgen_v7.lua | 148 ++++++++++++ schematics/pine.mts | Bin 0 -> 81 bytes textures/snow_snowball.png | Bin 372 -> 189 bytes textures/weather_snow.png | Bin 0 -> 2120 bytes util.lua | 98 ++++++++ 11 files changed, 886 insertions(+), 496 deletions(-) create mode 100644 .gitignore delete mode 100644 config.lua create mode 100644 falling_snow.lua create mode 100644 mapgen_v6.lua create mode 100644 mapgen_v7.lua create mode 100644 schematics/pine.mts create mode 100644 textures/weather_snow.png create mode 100644 util.lua diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..270ee86 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +config.txt +*~ diff --git a/config.lua b/config.lua deleted file mode 100644 index a7df578..0000000 --- a/config.lua +++ /dev/null @@ -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 diff --git a/falling_snow.lua b/falling_snow.lua new file mode 100644 index 0000000..fc30c6a --- /dev/null +++ b/falling_snow.lua @@ -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 diff --git a/init.lua b/init.lua index 849c028..c37262b 100644 --- a/init.lua +++ b/init.lua @@ -17,26 +17,11 @@ MA 02110-1301, USA. ]]-- -snow = {} +dofile(minetest.get_modpath("snow").."/util.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 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", { +local needles = { description = "Pine Needles", drawtype = "allfaces_optional", visual_scale = 1.3, @@ -46,11 +31,6 @@ minetest.register_node("snow:needles", { drop = { max_items = 1, items = { - { - -- player will get xmas tree with 1/50 chance - items = {'snow:xmas_tree'}, - rarity = 50, - }, { -- player will get sapling with 1/20 chance 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(), -}) +} + +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. 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(), }) @@ -178,13 +153,13 @@ minetest.register_craft({ --Snowballs ------------- -snowball_GRAVITY=9 -snowball_VELOCITY=19 +local snowball_GRAVITY=9 +local snowball_VELOCITY=19 --Shoot snowball. local snow_shoot_snowball=function (item, player, pointed_thing) 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() 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}) @@ -205,12 +180,12 @@ snow_snowball_ENTITY={ snow_snowball_ENTITY.on_step = function(self, dtime) self.timer=self.timer+dtime local pos = self.object:getpos() - local node = minetest.env:get_node(pos) + local node = minetest.get_node(pos) --Become item when hitting a node. if self.lastpos.x~=nil then --If there is no lastpos for some reason. if node.name ~= "air" then - minetest.env:place_node(self.lastpos,{name="snow:snow"}) + snow.place(pos) self.object:remove() end end @@ -226,61 +201,199 @@ minetest.register_craftitem("snow:snowball", { on_use = snow_shoot_snowball, }) ---Snow. -minetest.register_node("snow:snow", { - description = "Snow", - tiles = {"snow_snow.png"}, - drawtype = "nodebox", - sunlight_propagates = true, - paramtype = "light", - param2 = nil, - --param2 is reserved for what vegetation is hiding inside. - --mapgen defines the vegetation. - --1 = Moss - groups = {crumbly=3,melts=3}, - buildable_to = true, - drop = 'snow:snowball', - node_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, -0.35, 0.5} +for i=1,8 do + 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", + 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'}, + } + } }, - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, -0.35, 0.5} + 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'}, + } + } }, - }, - sounds = default.node_sound_dirt_defaults({ - footstep = {name="default_gravel_footstep", gain=0.45}, - }), - --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}) + leveled = 7, + drawtype = "nodebox", + node_box = { + type = "leveled", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.5+2/16, 0.5}, + }, + }, + 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, + }) +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 - 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 +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, - on_construct = function(pos, newnode) - pos.y = pos.y - 1 - local nodename = minetest.env:get_node(pos).name - if nodename == "default:dirt_with_grass" then - 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, -}) + 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. minetest.register_node("snow:dirt_with_snow", { @@ -290,80 +403,20 @@ minetest.register_node("snow:dirt_with_snow", { groups = {crumbly=3}, drop = 'default:dirt', 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. minetest.register_node("snow:snow_block", { description = "Snow", 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, groups = {crumbly=3,melts=2,falling_node=1}, drop = 'snow:snow_block', 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. @@ -437,20 +490,20 @@ minetest.register_abm({ action = function(pos, node, active_object_count, active_object_count_wider) local intensity = minetest.get_item_group(node.name,"melts") 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 local check_place = function(pos,node) - if minetest.env:get_node(pos).name == "air" then - minetest.env:place_node(pos,node) + if minetest.get_node(pos).name == "air" then + minetest.place_node(pos,node) 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,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 - minetest.env:add_node(pos,{name="default:water_flowing"}) + minetest.add_node(pos,{name="default:water_flowing"}) end nodeupdate(pos) end, @@ -464,7 +517,7 @@ minetest.register_abm({ interval = 20, chance = 4, 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, }) @@ -475,7 +528,7 @@ minetest.register_abm({ interval = 20, chance = 6, 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, }) @@ -498,93 +551,3 @@ minetest.register_abm({ snow.make_pine(pos,false,true) 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 diff --git a/mapgen.lua b/mapgen.lua index d76ea0f..582acf0 100644 --- a/mapgen.lua +++ b/mapgen.lua @@ -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 = { axiom="TABff", 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"}) 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 -) diff --git a/mapgen_v6.lua b/mapgen_v6.lua new file mode 100644 index 0000000..eb7acde --- /dev/null +++ b/mapgen_v6.lua @@ -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) diff --git a/mapgen_v7.lua b/mapgen_v7.lua new file mode 100644 index 0000000..8b5c929 --- /dev/null +++ b/mapgen_v7.lua @@ -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", +}) + diff --git a/schematics/pine.mts b/schematics/pine.mts new file mode 100644 index 0000000000000000000000000000000000000000..27dc57320393b949ac023733f7554082515cbcce GIT binary patch literal 81 zcmeYb3HD`RWMF3C0Ae6a%q(KyDbC9;x5`URP02|uX5dLlO-n4zDX}UkN=>bplbqnd i)Z;OMu_sYQErIE@VdK?BlXrZXl=M%5kwJbHgDL=Z^BJZ9 literal 0 HcmV?d00001 diff --git a/textures/snow_snowball.png b/textures/snow_snowball.png index 7c90ec760c54597d54bbcb3f13a0ab2fbd6ebff6..8a4a14a2f9cceb6cfb7e9a5092f09e3e14abd989 100644 GIT binary patch delta 134 zcmeyuw3l&$3O`$tx4R3&e-K=-clqRrigG!3S;ROcn7_IH+{eJc;N|J!7-G?zoFKt! zaj;%tN40#T=QSSV2Y=Z)q+NuUN-hytA~>7TMUu&wA&tXmzQ+0lV}>@zh7{%#Ts|{; mPe^(8an4X%#GKE<%y2;V*r)${Z%zlA%HZkh=d#Wzp$PzgtuF`w delta 345 zcmV-f0jB=F0rUcpB!3BTNLh0L01m?d01m?e$8V@)00007bV*G`2iyk(7BxBSB9L|f z009$8L_t(I%dL~mZi7G!gg+B<1PaQ%QQrTV2q-;NRRoPVL`he;2WMgVNiMCW6<*6T z9-B4%x9P)fH`V&2gE?p4dA@{~zE|x!I5$w_(6ko!{;q%|fqy8H0T+efV-5YI##^>j zcW&TVo5~4+s#QMh$Eu-)N&rqDBS}0ccyJ!}Q*e=+n(xaPOOi1^0=VDpQdX8&R<8%$ zwBUZsj{!cvz`1EsS(%z=gx708kR_lmD*E32V8eDI0NJch-GiFej#tvOh8f<0pJ-W) z)xznAN_=ep4pN&)WJ2Ic*5rp|y8_Y_L`19w5t)PLK>vG-d<0M4frv=ot8U|UAiy?; rEL|2{ER%Dpm(G@_KAHb)nf`3Q5y!0(MKk$=00000NkvXXu0mjfFcq7Y diff --git a/textures/weather_snow.png b/textures/weather_snow.png new file mode 100644 index 0000000000000000000000000000000000000000..8c44f7aff36360439073745ed99ede620c8093d4 GIT binary patch literal 2120 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4Yzkn25lDE4H!+#K5uy^@npa^Gy zM`SSr1Gg{;GcwGYBLNg-FY)wsWxvZT!Kr3`guwil(-P*aT6O)<_q?}``x>V_`tVtBLVf|0fRXGB zA%}ervu3MG+{m@%YC6R5iPw+8X*r84(-UckK@HU(rs_|~SJ-2rA*67BbKz30nn;zX z;;ZH-%oCg#o=Bh26l$nBe`F&YkDkU_%OIAYY)Z>Hm$NC{_hV4Vu`*C?sJY)boAKa^ zyxV7!9QMs+aQHT50Vl)HYYY#1StjKFFthMqE#5AvuU5<`^GWxRmV>8BY2Ponqj-0*M<%Z^tPFyCMa9DG6#Qtk@f@eaNE`smBMubDsb z&P=TI(&Dq12if1Z?XIQHdA^3s5OJvmsAd;XZczbWXg_KP+9hTJDK7hc4f{`+T3?vH&B3Ihg6h_b#(& z#(O2l`zAVxFkEE;5}T zoLC=OzhS=*M*@(xD6Ic_RV;a%--=bMzTcbQzs)o~CFz@{OGO3!|(Kc7|1R(-JT?#smr8axX3Ef^I_yk;!*_z@!vipUJR>nuOZ zm>3oc_i8de`TZ`2nZdp63RLiBaFZG^17WukMKqx(H1zlJ$oYpShl@Os{;|R0jKl`f zdCVu;YCiAHE$_5(O)6$FF>ODkx%l4RgIN zpPrs#>VEr^<|n@2+;+2zWlaRbs#WuZ3*PTtZpNr^U#emH-$gf*&cw+43uO?x56l|C z%)dvM@3(8PN<`%?-)iG2`A?)fwE5nvwJgbIaM-7xcW7^k!8VT>Ob+`Pfo?t4VY{p# z2AKO=#MtjUvi)RJXIOao;0w)zDNH~yUk){4P+3;6So2}m%Lgm==RN|a_(N*K!t5u^ zEf_iG_^kW02B;!oVkh&2{5cE)7KOm%jU@;`LI>XO*vTSa+$;o45nC*FxN4p-_haCg x%jd(XaQ{s9W|o>erjVrGD~wu7GBmvY!zdWFSn=4BY5E|OJYD@<);T3K0RU0DKWP8} literal 0 HcmV?d00001 diff --git a/util.lua b/util.lua new file mode 100644 index 0000000..b3f0b3b --- /dev/null +++ b/util.lua @@ -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