From 266fde8ff2b7e6de51d0998329b8042b200fae09 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Tue, 15 Aug 2017 19:40:53 +0200 Subject: [PATCH 01/75] Import biomes, gt2mc2 and related files from mc2plus gt2mc2 contains aliases. This mod is temporary and should be removed later. Kudos to maikerumine! --- mods/ITEMS/mcl_core/schematics/acacia_log.mts | Bin 0 -> 65 bytes mods/ITEMS/mcl_core/schematics/apple_log.mts | Bin 0 -> 90 bytes mods/ITEMS/mcl_core/schematics/apple_tree.mts | Bin 0 -> 169 bytes mods/ITEMS/mcl_core/schematics/aspen_log.mts | Bin 0 -> 118 bytes mods/ITEMS/mcl_core/schematics/aspen_tree.mts | Bin 0 -> 174 bytes mods/ITEMS/mcl_core/schematics/jungle_log.mts | Bin 0 -> 96 bytes .../ITEMS/mcl_core/schematics/jungle_tree.mts | Bin 0 -> 255 bytes mods/ITEMS/mcl_core/schematics/pine_log.mts | Bin 0 -> 93 bytes mods/ITEMS/mcl_core/schematics/pine_tree.mts | Bin 0 -> 176 bytes mods/MAPGEN/mcl_biomes/LICENSE | 5 + mods/MAPGEN/mcl_biomes/README.md | 1 + mods/MAPGEN/mcl_biomes/description.txt | 1 + mods/MAPGEN/mcl_biomes/init.lua | 1477 ++++++++++++++++- mods/MISC/gt2mc2/LICENSE | 21 + mods/MISC/gt2mc2/craftitems.lua | 317 ++++ mods/MISC/gt2mc2/depends.txt | 2 + mods/MISC/gt2mc2/enchanted.lua | 55 + mods/MISC/gt2mc2/init.lua | 792 +++++++++ mods/MISC/gt2mc2/mob_items.lua | 161 ++ 19 files changed, 2778 insertions(+), 54 deletions(-) create mode 100644 mods/ITEMS/mcl_core/schematics/acacia_log.mts create mode 100644 mods/ITEMS/mcl_core/schematics/apple_log.mts create mode 100644 mods/ITEMS/mcl_core/schematics/apple_tree.mts create mode 100644 mods/ITEMS/mcl_core/schematics/aspen_log.mts create mode 100644 mods/ITEMS/mcl_core/schematics/aspen_tree.mts create mode 100644 mods/ITEMS/mcl_core/schematics/jungle_log.mts create mode 100644 mods/ITEMS/mcl_core/schematics/jungle_tree.mts create mode 100644 mods/ITEMS/mcl_core/schematics/pine_log.mts create mode 100644 mods/ITEMS/mcl_core/schematics/pine_tree.mts create mode 100644 mods/MAPGEN/mcl_biomes/LICENSE create mode 100644 mods/MAPGEN/mcl_biomes/README.md create mode 100644 mods/MAPGEN/mcl_biomes/description.txt create mode 100644 mods/MISC/gt2mc2/LICENSE create mode 100644 mods/MISC/gt2mc2/craftitems.lua create mode 100644 mods/MISC/gt2mc2/depends.txt create mode 100644 mods/MISC/gt2mc2/enchanted.lua create mode 100644 mods/MISC/gt2mc2/init.lua create mode 100644 mods/MISC/gt2mc2/mob_items.lua diff --git a/mods/ITEMS/mcl_core/schematics/acacia_log.mts b/mods/ITEMS/mcl_core/schematics/acacia_log.mts new file mode 100644 index 0000000000000000000000000000000000000000..037bca8c32152f0927ff027811e918e713872b91 GIT binary patch literal 65 zcmeYb3HD`RVPIxpVqmPVXJBGrPRuM~5Kc)=ODxSPu}Vx%OwLSi!+My r^K;{qit@|zD&{07Ffh9rq$DITeSY-%t>hC&9yvKV1x^N`IL0&pk~SOx literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/schematics/apple_tree.mts b/mods/ITEMS/mcl_core/schematics/apple_tree.mts new file mode 100644 index 0000000000000000000000000000000000000000..2bd57c1fc4aa36e2f03c6ac2989c86b575e2784e GIT binary patch literal 169 zcmeYb3HD`RVPIw8U|_AUx333b1{Mb9#LOZFzLeCo#L}D+tDMxtveaS*9vHu*C^eOV z7sg90D9A~zn3J5KAY|~UbqTW@n;Ki1!m(7jO*?%GVs}LLI9yhkv7z!xnS9~1iL!Mc zfByXWk%MXZu0Q`j{r>#<_3PJ)EX)Ch0blHyttRTn>-R5OXD7eA^7qsK$+O(|{cclY KU?`iQc@Y5CIz`$5 literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/schematics/aspen_log.mts b/mods/ITEMS/mcl_core/schematics/aspen_log.mts new file mode 100644 index 0000000000000000000000000000000000000000..180e6fd1be8b31d1578f057edd7e3fb3f321c5ed GIT binary patch literal 118 zcmeYb3HD`RVPIxpW?-zZuLm&`Gm996Qc}|rOLI!B5{nB`^Wsa2Qd1d3(sJ_4Q;UkN za!ZRdit_VwfConL(8Kfj7uzh~@`t8%Fjy!U5atfRbqF)(T F004eZD475N literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/schematics/aspen_tree.mts b/mods/ITEMS/mcl_core/schematics/aspen_tree.mts new file mode 100644 index 0000000000000000000000000000000000000000..429a831c775320ace3f86c566380abea4dafb162 GIT binary patch literal 174 zcmeYb3HD`RVPIw8V_>bXx3{maudlbS2T=^n49tm{MGPV-scDI&IVDz!#RaK(@j0o9 zWvRssLa3r8MX9M3bCMGla3!=jUpl&iHQ|}kZO2s-S_w+Ck8-3OJd@gV+i{J=A>At+ z>aW_lx88C2{UvFB{QUg>$*w#MT5ON13_9nsvi|=l`1Sv5$ybdowq;@h%vS@>>#{ID PeQ3m`!Nj2U&bk)>VJSnw literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/schematics/jungle_log.mts b/mods/ITEMS/mcl_core/schematics/jungle_log.mts new file mode 100644 index 0000000000000000000000000000000000000000..54fa16d175a053f47c4ee55d678b33dbf507f314 GIT binary patch literal 96 zcmeYb3HD`RVPIxpW?-zZuLm&_Gm996Qc}|rOLI!BvP$#Pb5cu+Qd1ek(sJ_4Q;UkN xa!ZRdit_Vw6`ad-u3#+J7Ghye@sV3=SAkanVYUmnPIiOd4|Nq6@07aW?QG3wsy}plve)RgSo%)He2ywuc` zoYZ0lK@`!FqSVxiId6laxegd`bnngRe;`=&WnJ}yU#fSvyh+#WP*iPE5NNn@I&AUE zW15+-`aTs+&bFT0ZD}9=KIG%OYh|LIUk}EHF1;4{%9&Hk<6OW3%jViI|9j Date: Tue, 15 Aug 2017 20:08:41 +0200 Subject: [PATCH 02/75] Generate vines and cocoas in non-v6 mapgens --- mods/MAPGEN/mcl_mapgen_core/init.lua | 229 ++++++++++++++------------- 1 file changed, 119 insertions(+), 110 deletions(-) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 612dc32a5..f3e928e68 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1057,117 +1057,9 @@ local GEN_MAX = mcl_vars.mg_lava_overworld_max or BEDROCK_MAX -- Buffer for LuaVoxelManip local lvm_buffer = {} --- Below the bedrock, generate air/void -minetest.register_on_generated(function(minp, maxp) - local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") - local data = vm:get_data(lvm_buffer) - local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) - local lvm_used = false - -- Generate bedrock and lava layers - if minp.y <= GEN_MAX then - local c_bedrock = minetest.get_content_id("mcl_core:bedrock") - local c_void = minetest.get_content_id("mcl_core:void") - local c_lava = minetest.get_content_id("mcl_core:lava_source") - local c_air = minetest.get_content_id("air") - - local max_y = math.min(maxp.y, GEN_MAX) - - for y = minp.y, max_y do - for x = minp.x, maxp.x do - for z = minp.z, maxp.z do - local p_pos = area:index(x, y, z) - local setdata = nil - if mcl_vars.mg_bedrock_is_rough then - -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer - -- This code assumes a bedrock height of 5 layers. - if y == BEDROCK_MAX then - -- 50% bedrock chance - if math.random(1,2) == 1 then setdata = c_bedrock end - elseif y == BEDROCK_MAX -1 then - -- 66.666...% - if math.random(1,3) <= 2 then setdata = c_bedrock end - elseif y == BEDROCK_MAX -2 then - -- 75% - if math.random(1,4) <= 3 then setdata = c_bedrock end - elseif y == BEDROCK_MAX -3 then - -- 90% - if math.random(1,10) <= 9 then setdata = c_bedrock end - elseif y == BEDROCK_MAX -4 then - -- 100% - setdata = c_bedrock - elseif y < BEDROCK_MIN then - setdata = c_void - end - else - -- Perfectly flat bedrock layer(s) - if y >= BEDROCK_MIN and y <= BEDROCK_MAX then - setdata = c_bedrock - elseif y < BEDROCK_MIN then - setdata = c_void - end - end - - if setdata then - data[p_pos] = setdata - lvm_used = true - elseif mcl_vars.mg_lava and y <= mcl_vars.mg_lava_overworld_max then - if data[p_pos] == c_air then - data[p_pos] = c_lava - end - lvm_used = true - end - end - end - end - end - - -- Put top snow on grassy snow blocks created by the v6 mapgen - -- This is because the snowy grass block must only be used when it is below snow or top snow - if mg_name == "v6" then - local c_top_snow = minetest.get_content_id("mcl_core:snow") - local snowdirt = minetest.find_nodes_in_area_under_air(minp, maxp, "mcl_core:dirt_with_grass_snow") - for n = 1, #snowdirt do - -- CHECKME: What happens at chunk borders? - local p_pos = area:index(snowdirt[n].x, snowdirt[n].y + 1, snowdirt[n].z) - if p_pos then - data[p_pos] = c_top_snow - end - end - if #snowdirt > 1 then - lvm_used = true - end - end - - if lvm_used then - vm:set_data(data) - vm:calc_lighting() - vm:update_liquids() - vm:write_to_map() - end - - -- Generate rare underground mushrooms - -- TODO: Make them appear in groups, use Perlin noise - if minp.y > 0 or maxp.y < -32 then - return - end - - local bpos - local stone = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_core:stone", "mcl_core:dirt", "mcl_core:mycelium", "mcl_core:podzol", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:stone_with_iron", "mcl_core:stone_with_gold"}) - - for n = 1, #stone do - bpos = {x = stone[n].x, y = stone[n].y + 1, z = stone[n].z } - - if math.random(1,1000) < 4 and minetest.get_node_light(bpos, 0.5) <= 12 then - if math.random(1,2) == 1 then - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) - else - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) - end - end - end - - -- Generate cocoas and vines at jungle trees (v6 only) +-- Generate cocoas and vines at jungle trees within the bounding box +local function generate_jungle_tree_decorations(minp, maxp) if minetest.get_mapgen_setting("mg_name") == "v6" then if maxp.y < 0 then @@ -1286,7 +1178,124 @@ minetest.register_on_generated(function(minp, maxp) end end end +end +-- Generate mushrooms in caves +local generate_underground_mushrooms = function(minp, maxp) + -- Generate rare underground mushrooms + -- TODO: Make them appear in groups, use Perlin noise + if minp.y > 0 or maxp.y < -32 then + return + end + + local bpos + local stone = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_core:stone", "mcl_core:dirt", "mcl_core:mycelium", "mcl_core:podzol", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:stone_with_iron", "mcl_core:stone_with_gold"}) + + for n = 1, #stone do + bpos = {x = stone[n].x, y = stone[n].y + 1, z = stone[n].z } + + if math.random(1,1000) < 4 and minetest.get_node_light(bpos, 0.5) <= 12 then + if math.random(1,2) == 1 then + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) + else + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) + end + end + end +end + + +-- Below the bedrock, generate air/void +minetest.register_on_generated(function(minp, maxp) + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local data = vm:get_data(lvm_buffer) + local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) + local lvm_used = false + + -- Generate bedrock and lava layers + if minp.y <= GEN_MAX then + local c_bedrock = minetest.get_content_id("mcl_core:bedrock") + local c_void = minetest.get_content_id("mcl_core:void") + local c_lava = minetest.get_content_id("mcl_core:lava_source") + local c_air = minetest.get_content_id("air") + + local max_y = math.min(maxp.y, GEN_MAX) + + for y = minp.y, max_y do + for x = minp.x, maxp.x do + for z = minp.z, maxp.z do + local p_pos = area:index(x, y, z) + local setdata = nil + if mcl_vars.mg_bedrock_is_rough then + -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer + -- This code assumes a bedrock height of 5 layers. + if y == BEDROCK_MAX then + -- 50% bedrock chance + if math.random(1,2) == 1 then setdata = c_bedrock end + elseif y == BEDROCK_MAX -1 then + -- 66.666...% + if math.random(1,3) <= 2 then setdata = c_bedrock end + elseif y == BEDROCK_MAX -2 then + -- 75% + if math.random(1,4) <= 3 then setdata = c_bedrock end + elseif y == BEDROCK_MAX -3 then + -- 90% + if math.random(1,10) <= 9 then setdata = c_bedrock end + elseif y == BEDROCK_MAX -4 then + -- 100% + setdata = c_bedrock + elseif y < BEDROCK_MIN then + setdata = c_void + end + else + -- Perfectly flat bedrock layer(s) + if y >= BEDROCK_MIN and y <= BEDROCK_MAX then + setdata = c_bedrock + elseif y < BEDROCK_MIN then + setdata = c_void + end + end + + if setdata then + data[p_pos] = setdata + lvm_used = true + elseif mcl_vars.mg_lava and y <= mcl_vars.mg_lava_overworld_max then + if data[p_pos] == c_air then + data[p_pos] = c_lava + end + lvm_used = true + end + end + end + end + end + + -- Put top snow on grassy snow blocks created by the v6 mapgen + -- This is because the snowy grass block must only be used when it is below snow or top snow + if mg_name == "v6" then + local c_top_snow = minetest.get_content_id("mcl_core:snow") + local snowdirt = minetest.find_nodes_in_area_under_air(minp, maxp, "mcl_core:dirt_with_grass_snow") + for n = 1, #snowdirt do + -- CHECKME: What happens at chunk borders? + local p_pos = area:index(snowdirt[n].x, snowdirt[n].y + 1, snowdirt[n].z) + if p_pos then + data[p_pos] = c_top_snow + end + end + if #snowdirt > 1 then + lvm_used = true + end + end + + if lvm_used then + vm:set_data(data) + vm:calc_lighting() + vm:update_liquids() + vm:write_to_map() + end + + generate_underground_mushrooms(minp, maxp) + generate_jungle_tree_decorations(minp, maxp) end) From f7f6a89d642be8e97ac6446a986cb0ffc89bf75a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Tue, 15 Aug 2017 20:10:25 +0200 Subject: [PATCH 03/75] Spawn fake moss stone boulder in taiga only --- mods/MAPGEN/mcl_biomes/init.lua | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index f195bcab1..a1861582a 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -660,19 +660,20 @@ local function register_biomelike_ores() ore_type = "blob", ore = "mcl_core:mossycobble", wherein = "mcl_core:podzol", - clust_scarcity = 16 * 16 * 16, - clust_size = 3, - y_min = 25, - y_max = 31000, - noise_threshold = 0.0, - noise_params = { - offset = 0.5, - scale = 0.2, - spread = {x = 3, y = 3, z = 3}, - seed = 17676, - octaves = 1, - persist = 0.0 - }, + biomes = {"taiga"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 3, + y_min = 25, + y_max = 31000, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 3, y = 3, z = 3}, + seed = 17676, + octaves = 1, + persist = 0.0 + }, }) --mcl_core STRATA From 91b92a2cfdfae2fe30cb77584a3ad9ac190a3ca5 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 14:06:01 +0200 Subject: [PATCH 04/75] Fix some realm bugs --- mods/MAPGEN/mcl_biomes/init.lua | 12 +++++------- mods/MAPGEN/mcl_mapgen_core/init.lua | 8 +++++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index a1861582a..a84ad616d 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1078,7 +1078,6 @@ local function register_biomelike_ores() }, }) - end @@ -1487,7 +1486,7 @@ local function register_decorations() deco_type = "simple", place_on = {"mcl_nether:netherrack"}, sidelen = 80, - fill_ratio = 0.4, + fill_ratio = 0.01, biomes = {"nether"}, y_min = -6000, y_max = 31000, @@ -1498,20 +1497,19 @@ local function register_decorations() deco_type = "simple", place_on = {"mcl_nether:netherrack"}, sidelen = 80, - fill_ratio = 0.3, + fill_ratio = 0.01, biomes = {"nether"}, y_min = -6000, y_max = 31000, decoration = "mcl_mushrooms:mushroom_brown", }) - -- FIXME: Does the placement of eternal fire and nether wart actually work? - --Fire + --Eternal Fire minetest.register_decoration({ deco_type = "simple", place_on = {"mcl_nether:netherrack"}, - sidelen = 8, - fill_ratio = 0.9, + sidelen = 16, + fill_ratio = 0.2, biomes = {"nether"}, y_min = -6000, y_max = 31000, diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index f3e928e68..4fc9b3293 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1244,14 +1244,16 @@ minetest.register_on_generated(function(minp, maxp) elseif y == BEDROCK_MAX -4 then -- 100% setdata = c_bedrock - elseif y < BEDROCK_MIN then + elseif y < BEDROCK_MIN and y > -1000 then setdata = c_void + elseif y > 1000 and y < 2000 then + setdata = c_stone end else -- Perfectly flat bedrock layer(s) if y >= BEDROCK_MIN and y <= BEDROCK_MAX then setdata = c_bedrock - elseif y < BEDROCK_MIN then + elseif y < BEDROCK_MIN and y > -1000 then setdata = c_void end end @@ -1259,7 +1261,7 @@ minetest.register_on_generated(function(minp, maxp) if setdata then data[p_pos] = setdata lvm_used = true - elseif mcl_vars.mg_lava and y <= mcl_vars.mg_lava_overworld_max then + elseif mcl_vars.mg_lava and y <= mcl_vars.mg_lava_overworld_max and y >= mcl_vars.mg_overworld_min then if data[p_pos] == c_air then data[p_pos] = c_lava end From 860155e5c1a8c35584d57cc9d19844b27136feb2 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 15:29:05 +0200 Subject: [PATCH 05/75] Set proper realm boundaries --- mods/CORE/mcl_init/init.lua | 33 ++++++++++++++-- mods/CORE/mcl_util/init.lua | 37 ++++++++++++++---- mods/MAPGEN/mcl_mapgen_core/init.lua | 58 ++++++++++++++++++---------- 3 files changed, 96 insertions(+), 32 deletions(-) diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index 59945973f..28da089ad 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -12,15 +12,25 @@ mcl_vars.inventory_header = mcl_vars.gui_slots .. mcl_vars.gui_bg local mg_name = minetest.get_mapgen_setting("mg_name") local minecraft_height_limit = 256 if mg_name ~= "flat" then - mcl_vars.mg_overworld_min = -62 - mcl_vars.mg_overworld_max = mcl_vars.mg_overworld_min + minecraft_height_limit + --[[ Realm stacking (h is for height) + - Overworld (h>=256) + - Void (h>=1000) + - Realm Barrier (h=11), to allow escaping the End + - End (h>=256) + - Void (h>=1000) + - Nether (h=128) + - Void (h>=1000) + ]] - -- 1 flat bedrock layer with 4 rough layers above + -- Overworld + mcl_vars.mg_overworld_min = -62 + mcl_vars.mg_overworld_max_official = mcl_vars.mg_overworld_min + minecraft_height_limit mcl_vars.mg_bedrock_overworld_min = mcl_vars.mg_overworld_min mcl_vars.mg_bedrock_overworld_max = mcl_vars.mg_bedrock_overworld_min + 4 mcl_vars.mg_lava_overworld_max = mcl_vars.mg_overworld_min + 10 mcl_vars.mg_lava = true mcl_vars.mg_bedrock_is_rough = true + else local ground = minetest.get_mapgen_setting("mgflat_ground_level") ground = tonumber(ground) @@ -33,13 +43,28 @@ else else mcl_vars.mg_overworld_min = ground - 3 end - mcl_vars.mg_overworld_max = mcl_vars.mg_overworld_min + minecraft_height_limit + mcl_vars.mg_overworld_max_official = mcl_vars.mg_overworld_min + minecraft_height_limit mcl_vars.mg_bedrock_overworld_min = mcl_vars.mg_overworld_min mcl_vars.mg_bedrock_overworld_max = mcl_vars.mg_bedrock_overworld_min mcl_vars.mg_lava = false mcl_vars.mg_bedrock_is_rough = false end +mcl_vars.mg_overworld_max = math.huge + +-- The Nether +mcl_vars.mg_nether_min = -29000 +mcl_vars.mg_nether_max = mcl_vars.mg_nether_min + 128 +mcl_vars.mg_bedrock_nether_bottom_min = mcl_vars.mg_nether_min +mcl_vars.mg_bedrock_nether_bottom_max = mcl_vars.mg_bedrock_nether_bottom_min + 4 +mcl_vars.mg_bedrock_nether_top_max = mcl_vars.mg_nether_max +mcl_vars.mg_bedrock_nether_top_min = mcl_vars.mg_bedrock_nether_top_max - 4 + +-- The End +mcl_vars.mg_end_min = mcl_vars.mg_nether_max + 2000 +mcl_vars.mg_end_max_official = mcl_vars.mg_end_min + minecraft_height_limit +mcl_vars.mg_end_max = mcl_vars.mg_overworld_min - 2000 + -- Set default stack sizes minetest.nodedef_default.stack_max = 64 minetest.craftitemdef_default.stack_max = 64 diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 2da93dd7d..95b9f7f6c 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -335,9 +335,23 @@ end -- 1st return value: true if pos is in void -- 2nd return value: true if it is in the deadly part of the void function mcl_util.is_in_void(pos) - local void, void_deadly - void = pos.y < mcl_vars.mg_overworld_min - void_deadly = pos.y < mcl_vars.mg_overworld_min - 64 + local void = + not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or + (pos.y < mcl_vars.mg_nether_max and pos.y > mcl_vars.mg_nether_min) or + (pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min)) + + local void_deadly = false + local deadly_tolerance = 64 -- the player must be this many nodes “deep” into the void to be damaged + if void then + -- Overworld → Void → End → Void → Nether → Void + if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then + void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance + elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max then + void_deadly = pos.y < mcl_vars.mg_end_min - deadly_tolerance + elseif pos.y < mcl_vars.mg_nether_min then + void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance + end + end return void, void_deadly end @@ -351,6 +365,10 @@ end function mcl_util.y_to_layer(y) if y >= mcl_vars.mg_overworld_min then return y - mcl_vars.mg_overworld_min, "overworld" + elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max then + return y - mcl_vars.mg_nether_min, "nether" + elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then + return y - mcl_vars.mg_end_min, "end" else return nil, "void" end @@ -359,10 +377,15 @@ end -- Takes a Minecraft layer and a “dimension” name -- and returns the corresponding Y coordinate for -- MineClone 2. --- minecraft_dimension parameter is ignored at the moment --- TODO: Implement dimensions -function mcl_util.layer_to_y(layer, minecraft_dimension) - return layer + mcl_vars.mg_overworld_min +-- mc_dimension is one of "overworld", "nether", "end" (default: "overworld"). +function mcl_util.layer_to_y(layer, mc_dimension) + if mc_dimension == "overworld" or mc_dimension == nil then + return layer + mcl_vars.mg_overworld_min + elseif mc_dimension == "nether" then + return layer + mcl_vars.mg_nether_min + elseif mc_dimension == "end" then + return layer + mcl_vars.mg_end_min + end end -- Returns a on_place function for plants diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 4fc9b3293..159176c71 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1227,33 +1227,49 @@ minetest.register_on_generated(function(minp, maxp) local p_pos = area:index(x, y, z) local setdata = nil if mcl_vars.mg_bedrock_is_rough then - -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer - -- This code assumes a bedrock height of 5 layers. - if y == BEDROCK_MAX then - -- 50% bedrock chance - if math.random(1,2) == 1 then setdata = c_bedrock end - elseif y == BEDROCK_MAX -1 then - -- 66.666...% - if math.random(1,3) <= 2 then setdata = c_bedrock end - elseif y == BEDROCK_MAX -2 then - -- 75% - if math.random(1,4) <= 3 then setdata = c_bedrock end - elseif y == BEDROCK_MAX -3 then - -- 90% - if math.random(1,10) <= 9 then setdata = c_bedrock end - elseif y == BEDROCK_MAX -4 then - -- 100% + local is_bedrock = function(y) + -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer + -- This code assumes a bedrock height of 5 layers. + + local diff = mcl_vars.mg_bedrock_overworld_max - y -- Overworld bedrock + local ndiff1 = mcl_vars.mg_bedrock_nether_bottom_max - y -- Nether bedrock, bottom + local ndiff2 = mcl_vars.mg_bedrock_nether_top_max - y -- Nether bedrock, ceiling + + local top + if diff == 0 or ndiff1 == 0 or ndiff2 == 4 then + -- 50% bedrock chance + top = 2 + elseif diff == 1 or ndiff1 == 1 or ndiff2 == 3 then + -- 66.666...% + top = 3 + elseif diff == 2 or ndiff1 == 2 or ndiff2 == 2 then + -- 75% + top = 4 + elseif diff == 3 or ndiff1 == 3 or ndiff2 == 1 then + -- 90% + top = 10 + elseif diff == 4 or ndiff1 == 4 or ndiff2 == 0 then + -- 100% + return true + else + -- Not in bedrock layer + return false + end + + return math.random(1, top) <= top-1 + end + if is_bedrock(y) then setdata = c_bedrock - elseif y < BEDROCK_MIN and y > -1000 then + elseif mcl_util.is_in_void({x=x,y=y,z=z}) then setdata = c_void - elseif y > 1000 and y < 2000 then - setdata = c_stone end else -- Perfectly flat bedrock layer(s) - if y >= BEDROCK_MIN and y <= BEDROCK_MAX then + if (y >= mcl_vars.mg_bedrock_overworld_min and y <= mcl_vars.mg_bedrock_overworld_max) or + (y >= mcl_vars.mg_bedrock_nether_bottom_min or y <= mcl_vars.mg_bedrock_bottom_max) or + (y >= mcl_vars.mg_bedrock_nether_top_min or y <= mcl_vars.mg_bedrock_top_max) then setdata = c_bedrock - elseif y < BEDROCK_MIN and y > -1000 then + elseif mcl_util.is_in_void({x=x,y=y,z=z}) then setdata = c_void end end From 41f45d8c38191861e6c671931d0839c57efeb70a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 15:40:12 +0200 Subject: [PATCH 06/75] Update sky blackening when player's in void --- mods/PLAYER/mcl_playerplus/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 88cae8319..6517158a2 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -152,14 +152,14 @@ minetest.register_globalstep(function(dtime) end -- Apply black sky in the Void and deal Void damage - if pos.y < mcl_vars.mg_bedrock_overworld_max then + local void, void_deadly = mcl_util.is_in_void(pos) + if void then -- Player reached the void, set black sky box player:set_sky("#000000", "plain", nil, false) -- FIXME: Sky handling in MCL2 is held together with lots of duct tape. -- This only works beause weather_pack currently does not touch the sky for players below the height used for this check. -- There should be a real skybox API. end - local void, void_deadly = mcl_util.is_in_void(pos) if void_deadly then -- Player is deep into the void, deal void damage if player:get_hp() > 0 then From b7c12e82e4baf63e103d9e36dc255cf86ff9282c Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 16:22:28 +0200 Subject: [PATCH 07/75] Fix basic Nether generation --- mods/MAPGEN/mcl_biomes/init.lua | 281 +++++++++++---------------- mods/MAPGEN/mcl_mapgen_core/init.lua | 4 +- 2 files changed, 113 insertions(+), 172 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index a84ad616d..c0b8cf3de 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -13,8 +13,8 @@ local function register_classic_superflat_biome() node_filler = "mcl_core:dirt", depth_filler = 3, node_stone = "mcl_core:dirt", - y_min = -512, - y_max = 512, + y_min = mcl_vars.mg_overworld_min - 512, + y_max = mcl_vars.mg_overworld_max, heat_point = 50, humidity_point = 50, }) @@ -23,6 +23,7 @@ end -- All mapgens except mgv6, flat and singlenode local function register_biomes() + local upper_limit = mcl_vars.mg_overworld_max --[[ OVERWORLD ]] -- Icesheet @@ -54,7 +55,7 @@ local function register_biomes() depth_filler = 3, node_water_top = "mcl_core:ice", depth_water_top = 10, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = -9, heat_point = 0, humidity_point = 73, @@ -95,7 +96,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:gravel", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = -4, heat_point = 0, humidity_point = 40, @@ -124,7 +125,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:stone", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = 1, heat_point = 26, humidity_point = 72, @@ -155,7 +156,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:stone", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = 4, heat_point = 13, humidity_point = 79, @@ -200,7 +201,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:stone", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = 0, heat_point = 26, humidity_point = 45, @@ -244,7 +245,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:stone", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = 0, heat_point = 47, humidity_point = 73, --was 70 @@ -289,7 +290,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:stone", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = -2, heat_point = 33, humidity_point = 44, --was 68 @@ -321,7 +322,7 @@ local function register_biomes() node_stone = "mcl_core:stone", node_riverbed = "mcl_core:stone", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = 0, heat_point = 64, humidity_point = 37, --was 16 @@ -353,7 +354,7 @@ local function register_biomes() node_stone = "mcl_core:stone", node_riverbed = "mcl_core:stone", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = 4, heat_point = 57, humidity_point = 0, --was 0 @@ -384,7 +385,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:stone", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = 4, heat_point = 26, humidity_point = 0, --was 0 @@ -399,7 +400,7 @@ local function register_biomes() depth_filler = 1, node_stone = "mcl_colorblocks:hardened_clay_orange", y_min = -35, - y_max = 31000, + y_max = upper_limit, heat_point = 88, humidity_point = 20, --was 40 }) @@ -442,7 +443,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:stone", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = -2, heat_point = 50, humidity_point = 46, --was 42 @@ -486,7 +487,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:sand", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = -2, heat_point = 90, humidity_point = 91, @@ -515,7 +516,7 @@ local function register_biomes() depth_filler = 3, node_riverbed = "mcl_core:coarse_dirt", depth_riverbed = 2, - y_min = -112, + y_min = mcl_vars.mg_overworld_min, y_max = 0, heat_point = 99, humidity_point = 99, @@ -533,7 +534,7 @@ local function register_biomes() node_riverbed = "mcl_core:stone", depth_riverbed = 2, y_min = 56, - y_max = 900, + y_max = upper_limit, heat_point = -13, humidity_point = 30, }) @@ -543,8 +544,8 @@ local function register_biomes() -- Underground in Overworld minetest.register_biome({ name = "underground", - y_min = -31000, - y_max = -10000, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_util.y_to_layer(61), heat_point = 50, humidity_point = 50, }) @@ -553,98 +554,42 @@ local function register_biomes() --[[ REALMS ]] -- TODO: Make these work in v6, too. - -- Separation void 1 - minetest.register_biome({ - name = "void_1", - node_stone = "mcl_core:void", - y_min = -2989, - y_max = -82, - heat_point = 50, - humidity_point = 50, - }) - --[[ THE NETHER ]] - minetest.register_biome({ - name = "nether_roof", - node_stone = "mcl_core:bedrock", - y_min = -3000, - y_max = -2990, - heat_point = 50, - humidity_point = 50, - }) minetest.register_biome({ name = "nether", node_filler = "mcl_nether:netherrack", - node_stone = "mcl_nether:netherrack", - y_min = -3369, - y_max = -3001, + node_stone = "mcl_nether:netherrack", + y_min = mcl_vars.mg_nether_min, + -- FIXME: For some reason the Nether stops generating early if this constant is not added. + -- Figure out why. + y_max = mcl_vars.mg_nether_max + 80, heat_point = 50, humidity_point = 50, }) - -- TODO: Different lava algorithm - minetest.register_biome({ - name = "nether_lava", - node_filler = "mcl_nether:nether_lava_source", - node_stone = "mcl_nether:nether_lava_source", - y_min = -3399, - y_max = -3370, - heat_point = 50, - humidity_point = 50, - }) - - minetest.register_biome({ - name = "nether_floor", - node_filler = "mcl_core:bedrock", - node_stone = "mcl_core:bedrock", - y_min = -3430, - y_max = -3400, - heat_point = 50, - humidity_point = 50, - }) - - -- Separation void 2 - minetest.register_biome({ - name = "void_2", - node_stone = "mcl_core:void", - y_min = -4900, - y_max = -3431, - heat_point = 50, - humidity_point = 50, - }) - - + -- TODO: Giant Nether lava seas --[[ The End ]] minetest.register_biome({ name = "end", node_filler = "mcl_end:end_stone", - node_stone = "air", - y_min = -6200, - y_max = -6000, + node_stone = "mcl_end:end_stone", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max, heat_point = 50, humidity_point = 50, }) - -- Separation void 3 - minetest.register_biome({ - name = "void_3", - node_stone = "mcl_core:void", - y_min = -6700, - y_max = -6201, - heat_point = 50, - humidity_point = 50, - }) - - -- Realm barrier to separate the top of the End realm with the separation void + -- Realm barrier to separate the top of the End realm from the void below the Overworld + -- TODO: Implement differently minetest.register_biome({ name = "end_barrier", node_filler = "mcl_core:realm_barrier", node_stone = "mcl_core:realm_barrier", - y_min = -6800, - y_max = -6701, + y_min = mcl_vars.mg_end_max + 1, + y_max = mcl_vars.mg_end_max + 12, heat_point = 50, humidity_point = 50, }) @@ -899,26 +844,23 @@ local function register_biomelike_ores() minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:quartz_ore", - --wherein = "mcl_nether:rack", - wherein = {"mcl_nether:netherrack","mcl_core:stone"}, + wherein = {"mcl_nether:netherrack"}, clust_scarcity = 10*10*10, clust_num_ores = 6, clust_size = 5, - y_min = -3390, - y_max = -3000, - --y_max = NETHER_DEPTH, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, }) -- Soul sand minetest.register_ore({ ore_type = "sheet", ore = "mcl_nether:soul_sand", - wherein = {"mcl_nether:netherrack", "mcl_core:lava_source", - "mcl_core:redsandstone"}, + wherein = {"mcl_nether:netherrack"}, clust_scarcity = 13 * 13 * 13, clust_size = 5, - y_min = -3390, - y_max = -3000, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -934,12 +876,11 @@ local function register_biomelike_ores() minetest.register_ore({ ore_type = "sheet", ore = "mcl_nether:magma", - wherein = {"mcl_nether:netherrack", "mcl_core:lava_source", - "mcl_core:redsandstone"}, + wherein = {"mcl_nether:netherrack", "mcl_core:lava_source"}, clust_scarcity = 13 * 13 * 13, clust_size = 5, - y_min = -3390, - y_max = -3000, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -957,11 +898,11 @@ local function register_biomelike_ores() minetest.register_ore({ ore_type = "blob", ore = "mcl_nether:glowstone", - wherein = {"mcl_nether:netherrack", "mcl_portals:nether_air"}, + wherein = {"mcl_nether:netherrack"}, clust_scarcity = 26 * 26 * 26, clust_size = 5, - y_min = -3390, - y_max = -3000, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -981,8 +922,8 @@ local function register_biomelike_ores() wherein = {"mcl_nether:netherrack"}, clust_scarcity = 16 * 16 * 16, clust_size = 5, - y_min = -3390, - y_max = -3000, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -999,12 +940,12 @@ local function register_biomelike_ores() minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:nether_lava_source", - wherein = "mcl_nether:netherrack", - clust_scarcity =12 *12 * 12, + wherein = {"mcl_nether:netherrack", "air"}, + clust_scarcity = 12 *12 * 12, clust_num_ores = 2, clust_size = 2, - y_min = -3390, - y_max = -3000, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_min + 15, }) @@ -1016,20 +957,21 @@ local function register_biomelike_ores() clust_scarcity =12 *22 * 12, clust_num_ores = 5, clust_size = 5, - y_min = -3390, - y_max = -3000, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, }) -- Generate holes in Nether + -- TODO: Is this a good idea? minetest.register_ore({ ore_type = "sheet", ore = "air", - wherein ={"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack"}, clust_scarcity = 1, clust_num_ores = 32, clust_size = 10, - y_min = -3390, - y_max = -3000, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, noise_threshold = 0.2, noise_params = {offset=0, scale=15, spread={x=130, y=130, z=130}, seed=24, octaves=3, persist=0.70} }) @@ -1043,11 +985,11 @@ local function register_biomelike_ores() minetest.register_ore({ ore_type = "blob", ore = "mcl_end:end_stone", - wherein = {"mcl_core:void", "air"}, + wherein = {"air", "mcl_core:stone"}, clust_scarcity = 30 * 30 * 30, clust_size = 17, - y_min = -5750, - y_max = -5701, + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -1062,11 +1004,11 @@ local function register_biomelike_ores() minetest.register_ore({ ore_type = "scatter", ore = "mcl_end:end_stone", - wherein = {"mcl_core:void", "air"}, + wherein = {"air", "mcl_core:stone"}, clust_scarcity = 30 * 30 * 30, clust_size = 34, - y_min = -5780, - y_max = -5711, + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -1479,54 +1421,6 @@ local function register_decorations() y_max = 31000, decoration = "mcl_core:mossycobble", }) - - --Nether Decorations - --Red Mushroom - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_nether:netherrack"}, - sidelen = 80, - fill_ratio = 0.01, - biomes = {"nether"}, - y_min = -6000, - y_max = 31000, - decoration = "mcl_mushrooms:mushroom_red", - }) - --Brown Mushroom - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_nether:netherrack"}, - sidelen = 80, - fill_ratio = 0.01, - biomes = {"nether"}, - y_min = -6000, - y_max = 31000, - decoration = "mcl_mushrooms:mushroom_brown", - }) - - --Eternal Fire - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_nether:netherrack"}, - sidelen = 16, - fill_ratio = 0.2, - biomes = {"nether"}, - y_min = -6000, - y_max = 31000, - decoration = "mcl_fire:eternal_fire", - }) - -- Nether Wart - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_nether:soul_sand"}, - sidelen = 80, - fill_ratio = 0.1, - biomes = {"nether"}, - y_min = -6000, - y_max = 31000, - decoration = "mcl_nether:nether_wart", - }) - -- Cactus minetest.register_decoration({ @@ -1605,6 +1499,55 @@ local function register_decorations() height = 1, }) + + --[[ NETHER decorations ]] + + -- Red Mushroom + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack"}, + sidelen = 80, + fill_ratio = 0.01, + biomes = {"nether"}, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + decoration = "mcl_mushrooms:mushroom_red", + }) + -- Brown Mushroom + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack"}, + sidelen = 80, + fill_ratio = 0.01, + biomes = {"nether"}, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + decoration = "mcl_mushrooms:mushroom_brown", + }) + + -- Eternal Fire + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack"}, + sidelen = 16, + fill_ratio = 0.2, + biomes = {"nether"}, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + decoration = "mcl_fire:eternal_fire", + }) + -- Nether Wart + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:soul_sand"}, + sidelen = 80, + fill_ratio = 0.1, + biomes = {"nether"}, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + decoration = "mcl_nether:nether_wart", + }) + end diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 159176c71..3f9699079 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1050,9 +1050,7 @@ end) -- Generate bedrock layer or layers -local BEDROCK_MIN = mcl_vars.mg_bedrock_overworld_min -local BEDROCK_MAX = mcl_vars.mg_bedrock_overworld_max -local GEN_MAX = mcl_vars.mg_lava_overworld_max or BEDROCK_MAX +local GEN_MAX = mcl_vars.mg_lava_overworld_max or mcl_vars.mg_bedrock_overworld_max -- Buffer for LuaVoxelManip local lvm_buffer = {} From d90b59c9188d7c6d9a4a220ff14b34a3c2a8da5f Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 17:01:16 +0200 Subject: [PATCH 08/75] Tweak Nether ore and lava generation --- mods/CORE/mcl_init/init.lua | 1 + mods/MAPGEN/mcl_biomes/init.lua | 98 ++++++++++++---------------- mods/MAPGEN/mcl_mapgen_core/init.lua | 10 ++- 3 files changed, 51 insertions(+), 58 deletions(-) diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index 28da089ad..87918932a 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -59,6 +59,7 @@ mcl_vars.mg_bedrock_nether_bottom_min = mcl_vars.mg_nether_min mcl_vars.mg_bedrock_nether_bottom_max = mcl_vars.mg_bedrock_nether_bottom_min + 4 mcl_vars.mg_bedrock_nether_top_max = mcl_vars.mg_nether_max mcl_vars.mg_bedrock_nether_top_min = mcl_vars.mg_bedrock_nether_top_max - 4 +mcl_vars.mg_lava_nether_max = mcl_vars.mg_nether_min + 31 -- The End mcl_vars.mg_end_min = mcl_vars.mg_nether_max + 2000 diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index c0b8cf3de..1bc21ab55 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -554,7 +554,6 @@ local function register_biomes() --[[ REALMS ]] -- TODO: Make these work in v6, too. - --[[ THE NETHER ]] minetest.register_biome({ @@ -565,34 +564,24 @@ local function register_biomes() -- FIXME: For some reason the Nether stops generating early if this constant is not added. -- Figure out why. y_max = mcl_vars.mg_nether_max + 80, - heat_point = 50, - humidity_point = 50, + heat_point = 100, + humidity_point = 0, }) - -- TODO: Giant Nether lava seas - --[[ The End ]] + --[[ THE END ]] minetest.register_biome({ name = "end", node_filler = "mcl_end:end_stone", node_stone = "mcl_end:end_stone", y_min = mcl_vars.mg_end_min, - y_max = mcl_vars.mg_end_max, + -- FIXME: For some reason the Nether stops generating early if this constant is not added. + -- Figure out why. + y_max = mcl_vars.mg_end_max + 80, heat_point = 50, humidity_point = 50, }) - -- Realm barrier to separate the top of the End realm from the void below the Overworld - -- TODO: Implement differently - minetest.register_biome({ - name = "end_barrier", - node_filler = "mcl_core:realm_barrier", - node_stone = "mcl_core:realm_barrier", - y_min = mcl_vars.mg_end_max + 1, - y_max = mcl_vars.mg_end_max + 12, - heat_point = 50, - humidity_point = 50, - }) end @@ -841,17 +830,6 @@ local function register_biomelike_ores() --[[ NETHER GENERATION ]] - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_nether:quartz_ore", - wherein = {"mcl_nether:netherrack"}, - clust_scarcity = 10*10*10, - clust_num_ores = 6, - clust_size = 5, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - }) - -- Soul sand minetest.register_ore({ ore_type = "sheet", @@ -860,7 +838,7 @@ local function register_biomelike_ores() clust_scarcity = 13 * 13 * 13, clust_size = 5, y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, + y_max = mcl_util.layer_to_y(64, "nether"), noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -874,34 +852,24 @@ local function register_biomelike_ores() -- Magma blocks minetest.register_ore({ - ore_type = "sheet", - ore = "mcl_nether:magma", - wherein = {"mcl_nether:netherrack", "mcl_core:lava_source"}, - clust_scarcity = 13 * 13 * 13, - clust_size = 5, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - noise_threshold = 0.0, - noise_params = { - offset = 0.5, - scale = 0.1, - spread = {x = 5, y = 5, z = 5}, - seed = 2316, - octaves = 1, - persist = 0.0 - }, + ore_type = "blob", + ore = "mcl_nether:magma", + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 15*15*15, + clust_num_ores = 33, + clust_size = 5, + y_min = mcl_util.layer_to_y(23, "nether"), + y_max = mcl_util.layer_to_y(37, "nether"), }) - -- Glowstone - minetest.register_ore({ ore_type = "blob", ore = "mcl_nether:glowstone", wherein = {"mcl_nether:netherrack"}, clust_scarcity = 26 * 26 * 26, clust_size = 5, - y_min = mcl_vars.mg_nether_min, + y_min = mcl_vars.mg_lava_nether_max + 10, y_max = mcl_vars.mg_nether_max, noise_threshold = 0.0, noise_params = { @@ -914,21 +882,42 @@ local function register_biomelike_ores() }, }) - -- Gravel + -- Nether quartz + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:quartz_ore", + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 850, + clust_num_ores = 4, -- MC cluster amount: 4-10 + clust_size = 3, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:quartz_ore", + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 1650, + clust_num_ores = 8, -- MC cluster amount: 4-10 + clust_size = 4, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + -- Gravel (Nether) minetest.register_ore({ ore_type = "sheet", ore = "mcl_core:gravel", wherein = {"mcl_nether:netherrack"}, clust_scarcity = 16 * 16 * 16, clust_size = 5, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, + y_min = mcl_util.layer_to_y(63, "nether"), + y_max = mcl_util.layer_to_y(65, "nether"), noise_threshold = 0.0, noise_params = { offset = 0.5, scale = 0.2, - spread = {x = 5, y = 5, z = 5}, + spread = {x = 5, y = 1, z = 5}, seed = 766, octaves = 1, persist = 0.0 @@ -936,11 +925,10 @@ local function register_biomelike_ores() }) -- Lava in the Nether - minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:nether_lava_source", - wherein = {"mcl_nether:netherrack", "air"}, + wherein = {"mcl_nether:netherrack"}, clust_scarcity = 12 *12 * 12, clust_num_ores = 2, clust_size = 2, @@ -949,7 +937,7 @@ local function register_biomelike_ores() }) - --Fire in the Nether + -- Fire in the Nether minetest.register_ore({ ore_type = "scatter", ore = "mcl_fire:eternal_fire", diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 3f9699079..6e2dda738 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1215,6 +1215,7 @@ minetest.register_on_generated(function(minp, maxp) local c_bedrock = minetest.get_content_id("mcl_core:bedrock") local c_void = minetest.get_content_id("mcl_core:void") local c_lava = minetest.get_content_id("mcl_core:lava_source") + local c_nether_lava = minetest.get_content_id("mcl_nether:nether_lava_source") local c_air = minetest.get_content_id("air") local max_y = math.min(maxp.y, GEN_MAX) @@ -1275,11 +1276,14 @@ minetest.register_on_generated(function(minp, maxp) if setdata then data[p_pos] = setdata lvm_used = true - elseif mcl_vars.mg_lava and y <= mcl_vars.mg_lava_overworld_max and y >= mcl_vars.mg_overworld_min then - if data[p_pos] == c_air then + elseif mcl_vars.mg_lava and data[p_pos] == c_air then + if y <= mcl_vars.mg_lava_overworld_max and y >= mcl_vars.mg_overworld_min then data[p_pos] = c_lava + lvm_used = true + elseif y <= mcl_vars.mg_lava_nether_max and y >= mcl_vars.mg_nether_min then + data[p_pos] = c_nether_lava + lvm_used = true end - lvm_used = true end end end From ffef7535677670b35279d2a598ea867b3784d9ef Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 17:08:33 +0200 Subject: [PATCH 09/75] Add lava springs into the Nether --- mods/MAPGEN/mcl_biomes/init.lua | 41 +++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 1bc21ab55..dbaf05b61 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -924,18 +924,49 @@ local function register_biomelike_ores() }, }) - -- Lava in the Nether + -- Lava springs in the Nether minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:nether_lava_source", wherein = {"mcl_nether:netherrack"}, - clust_scarcity = 12 *12 * 12, - clust_num_ores = 2, - clust_size = 2, + clust_scarcity = 500, + clust_num_ores = 1, + clust_size = 1, y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_min + 15, + y_max = mcl_vars.mg_lava_nether_max + 1, }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:nether_lava_source", + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 1000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_vars.mg_lava_nether_max + 2, + y_max = mcl_vars.mg_lava_nether_max + 12, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:nether_lava_source", + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 2000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_vars.mg_lava_nether_max + 13, + y_max = mcl_vars.mg_lava_nether_max + 48, + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:nether_lava_source", + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 3500, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_vars.mg_lava_nether_max + 49, + y_max = mcl_vars.mg_nether_max, + }) -- Fire in the Nether minetest.register_ore({ From c429d1af83286e58585d4c474265f272f5bdd996 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 17:31:28 +0200 Subject: [PATCH 10/75] Improve gravel generation in Nether --- mods/MAPGEN/mcl_biomes/init.lua | 68 ++++++++++++++++----------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index dbaf05b61..4dc6e25c1 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -829,6 +829,18 @@ local function register_biomelike_ores() --[[ NETHER GENERATION ]] + -- Generate holes in Nether + -- TODO: Is this a good idea? + minetest.register_ore({ + ore_type = "puff", + ore = "air", + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 666, + clust_size = 4, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + noise_params = {offset=0, scale=15, spread={x=130, y=130, z=130}, seed=24, octaves=3, persist=0.60} + }) -- Soul sand minetest.register_ore({ @@ -882,6 +894,26 @@ local function register_biomelike_ores() }, }) + -- Gravel (Nether) + minetest.register_ore({ + ore_type = "sheet", + ore = "mcl_core:gravel", + wherein = {"mcl_nether:netherrack"}, + column_height_min = 1, + column_height_max = 1, + y_min = mcl_util.layer_to_y(63, "nether"), + y_max = mcl_util.layer_to_y(65, "nether"), + noise_threshold = 0.0, + noise_params = { + offset = 0.0, + scale = 0.2, + spread = {x = 50, y = 50, z = 50}, + seed = 766, + octaves = 1, + persist = 0.6, + }, + }) + -- Nether quartz minetest.register_ore({ ore_type = "scatter", @@ -904,26 +936,6 @@ local function register_biomelike_ores() y_max = mcl_vars.mg_nether_max, }) - -- Gravel (Nether) - minetest.register_ore({ - ore_type = "sheet", - ore = "mcl_core:gravel", - wherein = {"mcl_nether:netherrack"}, - clust_scarcity = 16 * 16 * 16, - clust_size = 5, - y_min = mcl_util.layer_to_y(63, "nether"), - y_max = mcl_util.layer_to_y(65, "nether"), - noise_threshold = 0.0, - noise_params = { - offset = 0.5, - scale = 0.2, - spread = {x = 5, y = 1, z = 5}, - seed = 766, - octaves = 1, - persist = 0.0 - }, - }) - -- Lava springs in the Nether minetest.register_ore({ ore_type = "scatter", @@ -980,22 +992,6 @@ local function register_biomelike_ores() y_max = mcl_vars.mg_nether_max, }) - -- Generate holes in Nether - -- TODO: Is this a good idea? - minetest.register_ore({ - ore_type = "sheet", - ore = "air", - wherein = {"mcl_nether:netherrack"}, - clust_scarcity = 1, - clust_num_ores = 32, - clust_size = 10, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - noise_threshold = 0.2, - noise_params = {offset=0, scale=15, spread={x=130, y=130, z=130}, seed=24, octaves=3, persist=0.70} - }) - - --[[ THE END ]] -- Generate fake End From f9e880e21093c4e4db0abf8ab0a58d9616222c16 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 18:49:46 +0200 Subject: [PATCH 11/75] Make buckets work correctly in the Nether * Water bucket can't place water in Nether * Empty bucket can take Nether lava * Lava bucket places Nether lava in Nether --- mods/ITEMS/mcl_buckets/init.lua | 115 +++++++++++++++++++------------- 1 file changed, 68 insertions(+), 47 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index fe3ee332d..3d00f3dcb 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -1,8 +1,6 @@ -- Minetest 0.4 mod: bucket -- See README.txt for licensing and other information. -local LIQUID_MAX = 8 --The number of water levels when liquid_finite is enabled - minetest.register_alias("bucket:bucket_empty", "mcl_buckets:bucket_empty") minetest.register_alias("bucket:bucket_water", "mcl_buckets:bucket_water") minetest.register_alias("bucket:bucket_lava", "mcl_buckets:bucket_lava") @@ -39,18 +37,29 @@ local sound_take = function(itemname, pos) end -- Register a new liquid --- source = name of the source node --- flowing = name of the flowing node --- itemname = name of the new bucket item (or nil if liquid is not takeable) +-- source_place = a string or function. +-- * string: name of the node to place +-- * function(pos): will returns name of the node to place with pos being the placement position +-- source_take = table of liquid source node names to take +-- itemname = itemstring of the new bucket item (or nil if liquid is not takeable) -- inventory_image = texture of the new bucket item (ignored if itemname == nil) --- This function can be called from any mod (that depends on bucket). -function mcl_buckets.register_liquid(source, flowing, itemname, inventory_image, name, longdesc, usagehelp) - mcl_buckets.liquids[source] = { - source = source, - flowing = flowing, - itemname = itemname, - } - mcl_buckets.liquids[flowing] = mcl_buckets.liquids[source] +-- name = user-visible bucket description +-- longdesc = long explanatory description (for help) +-- usagehelp = short usage explanation (for help) +-- extra_check = optional function(pos) which can returns false to avoid placing the liquid +-- +-- This function can be called from any mod (which depends on this one) +function mcl_buckets.register_liquid(source_place, source_take, itemname, inventory_image, name, longdesc, usagehelp, extra_check) + for i=1, #source_take do + mcl_buckets.liquids[source_take[i]] = { + source_place = source_place, + source_take = source_take[i], + itemname = itemname, + } + if type(source_place) == "string" then + mcl_buckets.liquids[source_place] = mcl_buckets.liquids[source_take[i]] + end + end if itemname ~= nil then minetest.register_craftitem(itemname, { @@ -67,43 +76,38 @@ function mcl_buckets.register_liquid(source, flowing, itemname, inventory_image, end local node = minetest.get_node(pointed_thing.under) + local place_pos = pointed_thing.under local nn = node.name -- Call on_rightclick if the pointed node defines it if user and not user:get_player_control().sneak then if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then - return minetest.registered_nodes[nn].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + return minetest.registered_nodes[nn].on_rightclick(place_pos, node, user, itemstack) or itemstack end end - local place_liquid = function(pos, node, source, flowing, fullness) - sound_place(source, pos) - if math.floor(fullness/128) == 1 or (not minetest.settings:get_bool("liquid_finite")) then - minetest.add_node(pos, {name=source, param2=fullness}) - return - elseif node.name == flowing then - fullness = fullness + node.param2 - elseif node.name == source then - fullness = LIQUID_MAX - end - - if fullness >= LIQUID_MAX then - minetest.add_node(pos, {name=source, param2=LIQUID_MAX}) - else - minetest.add_node(pos, {name=flowing, param2=fullness}) - end + local place_liquid = function(pos, itemstring) + local fullness = minetest.registered_nodes[itemstring].liquid_range + sound_place(itemstring, pos) + minetest.add_node(pos, {name=itemstring, param2=fullness}) end + local node_place + if type(source_place) == "function" then + node_place = source_place(place_pos) + else + node_place = source_place + end -- Check if pointing to a buildable node - local fullness = tonumber(itemstack:get_metadata()) - if not fullness then fullness = LIQUID_MAX end local item = itemstack:get_name() - if item == "mcl_buckets:bucket_water" and + if extra_check and extra_check(place_pos) == false then + -- Fail placement of liquid + elseif item == "mcl_buckets:bucket_water" and (nn == "mcl_cauldrons:cauldron" or nn == "mcl_cauldrons:cauldron_1" or nn == "mcl_cauldrons:cauldron_2") then -- Put water into cauldron - minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron_3"}) + minetest.set_node(place_pos, {name="mcl_cauldrons:cauldron_3"}) sound_place("mcl_core:water_source", pos) elseif item == "mcl_buckets:bucket_water" and nn == "mcl_cauldrons:cauldron_3" then @@ -111,12 +115,12 @@ function mcl_buckets.register_liquid(source, flowing, itemname, inventory_image, elseif minetest.registered_nodes[nn] and minetest.registered_nodes[nn].buildable_to then -- buildable; replace the node local pns = user:get_player_name() - if minetest.is_protected(pointed_thing.under, pns) then + if minetest.is_protected(place_pos, pns) then return itemstack end - place_liquid(pointed_thing.under, node, source, flowing, fullness) - if mod_doc and doc.entry_exists("nodes", source) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", source) + place_liquid(place_pos, node_place) + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) end else -- not buildable to; place the liquid above @@ -127,9 +131,9 @@ function mcl_buckets.register_liquid(source, flowing, itemname, inventory_image, if minetest.is_protected(pointed_thing.above, pn) then return itemstack end - place_liquid(pointed_thing.above, node, source, flowing, fullness) - if mod_doc and doc.entry_exists("nodes", source) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", source) + place_liquid(pointed_thing.above, node_place) + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) end else -- do not remove the bucket with the liquid @@ -188,8 +192,7 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { -- Check if pointing to a liquid source liquiddef = mcl_buckets.liquids[nn] local new_bucket - if liquiddef ~= nil and liquiddef.itemname ~= nil and (nn == liquiddef.source or - (nn == liquiddef.flowing and minetest.settings:get_bool("liquid_finite"))) then + if liquiddef ~= nil and liquiddef.itemname ~= nil and (nn == liquiddef.source_take) then -- Fill bucket, but not in Creative Mode if not minetest.settings:get_bool("creative_mode") then @@ -234,19 +237,37 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { }) if mod_mcl_core then + -- Water bucket mcl_buckets.register_liquid( "mcl_core:water_source", - "mcl_core:water_flowing", + {"mcl_core:water_source"}, "mcl_buckets:bucket_water", "bucket_water.png", "Water Bucket", "A bucket can be used to collect and release liquids. This one is filled with water.", - "Right-click on any block to empty the bucket and put a water source on this spot." + "Right-click on any block to empty the bucket and put a water source on this spot.", + function(pos) + local _, dim = mcl_util.y_to_layer(pos.y) + if dim == "nether" then + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}) + return false + else + return true + end + end ) + -- Lava bucket mcl_buckets.register_liquid( - "mcl_core:lava_source", - "mcl_core:lava_flowing", + function(pos) + local _, dim = mcl_util.y_to_layer(pos.y) + if dim == "nether" then + return "mcl_nether:nether_lava_source" + else + return "mcl_core:lava_source" + end + end, + {"mcl_core:lava_source", "mcl_nether:nether_lava_source"}, "mcl_buckets:bucket_lava", "bucket_lava.png", "Lava Bucket", From 6e93424f032144c9a98886d38692391bf3ac8286 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 18:56:39 +0200 Subject: [PATCH 12/75] Fix broken Overworld --- mods/CORE/mcl_init/init.lua | 2 +- mods/MAPGEN/mcl_biomes/init.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index 87918932a..ebf106e19 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -50,7 +50,7 @@ else mcl_vars.mg_bedrock_is_rough = false end -mcl_vars.mg_overworld_max = math.huge +mcl_vars.mg_overworld_max = 31000 -- The Nether mcl_vars.mg_nether_min = -29000 diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 4dc6e25c1..90cd3e15a 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -545,7 +545,7 @@ local function register_biomes() minetest.register_biome({ name = "underground", y_min = mcl_vars.mg_overworld_min, - y_max = mcl_util.y_to_layer(61), + y_max = mcl_util.layer_to_y(61), heat_point = 50, humidity_point = 50, }) From 895fc7d757f7c341d9e78812fba2d544eaf03447 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 16 Aug 2017 22:08:17 +0200 Subject: [PATCH 13/75] Update mobs_mc and update gameconfig This updates and fixes mob spawn height for new realms. Also: Small zombie pigman size fixed. --- mods/ENTITIES/mobs_mc/0_gameconfig.lua | 23 +++++++++++++++++-- mods/ENTITIES/mobs_mc/bat.lua | 2 +- mods/ENTITIES/mobs_mc/blaze.lua | 4 ++-- mods/ENTITIES/mobs_mc/chicken.lua | 2 +- mods/ENTITIES/mobs_mc/cow+mooshroom.lua | 5 ++-- mods/ENTITIES/mobs_mc/creeper.lua | 2 +- mods/ENTITIES/mobs_mc/enderman.lua | 11 +++++---- mods/ENTITIES/mobs_mc/ghast.lua | 4 ++-- mods/ENTITIES/mobs_mc/guardian.lua | 2 +- mods/ENTITIES/mobs_mc/guardian_elder.lua | 2 +- mods/ENTITIES/mobs_mc/horse.lua | 5 ++-- mods/ENTITIES/mobs_mc/llama.lua | 2 +- mods/ENTITIES/mobs_mc/ocelot.lua | 5 ++-- mods/ENTITIES/mobs_mc/parrot.lua | 2 +- mods/ENTITIES/mobs_mc/pig.lua | 2 +- mods/ENTITIES/mobs_mc/polar_bear.lua | 6 +---- mods/ENTITIES/mobs_mc/rabbit.lua | 3 +++ mods/ENTITIES/mobs_mc/sheep.lua | 2 +- mods/ENTITIES/mobs_mc/shulker.lua | 7 +----- mods/ENTITIES/mobs_mc/skeleton+stray.lua | 11 ++++++--- mods/ENTITIES/mobs_mc/skeleton_wither.lua | 3 ++- mods/ENTITIES/mobs_mc/slime+magma_cube.lua | 24 ++++++++++++-------- mods/ENTITIES/mobs_mc/spider.lua | 3 +-- mods/ENTITIES/mobs_mc/squid.lua | 2 +- mods/ENTITIES/mobs_mc/villager.lua | 3 +-- mods/ENTITIES/mobs_mc/villager_zombie.lua | 5 +--- mods/ENTITIES/mobs_mc/witch.lua | 2 +- mods/ENTITIES/mobs_mc/wolf.lua | 2 +- mods/ENTITIES/mobs_mc/zombie.lua | 9 ++++---- mods/ENTITIES/mobs_mc/zombiepig.lua | 12 +++++----- mods/ENTITIES/mobs_mc_gameconfig/depends.txt | 1 + mods/ENTITIES/mobs_mc_gameconfig/init.lua | 20 ++++++++++++++++ 32 files changed, 113 insertions(+), 75 deletions(-) create mode 100644 mods/ENTITIES/mobs_mc_gameconfig/depends.txt diff --git a/mods/ENTITIES/mobs_mc/0_gameconfig.lua b/mods/ENTITIES/mobs_mc/0_gameconfig.lua index 692f6245d..410719f67 100644 --- a/mods/ENTITIES/mobs_mc/0_gameconfig.lua +++ b/mods/ENTITIES/mobs_mc/0_gameconfig.lua @@ -249,8 +249,9 @@ mobs_mc.spawn = { desert = { "default:desert_sand", "group:sand" }, jungle = { "default:dirt_with_rainforest_litter", "default:jungleleaves", "default:junglewood", "mcl_core:jungleleaves", "mcl_core:junglewood" }, snow = { "default:snow", "default:snowblock", "default:dirt_with_snow" }, - end_city = { "default:cobble", "mcl_end:purpur_block", "mcl_end:end_stone", "mcl_portals:void"}, + end_city = { "default:sandstonebrick", "mcl_end:purpur_block", "mcl_end:end_stone" }, wolf = { mobs_mc.items.grass_block, "default:dirt_with_rainforest_litter", "default:dirt", "default:dirt_with_snow", "default:snow", "default:snowblock" }, + village = { "mg_villages:road" }, -- These probably don't need overrides mushroom_island = { mobs_mc.items.mycelium, "mcl_core:mycelium" }, @@ -260,13 +261,31 @@ mobs_mc.spawn = { water = { mobs_mc.items.water_source, "mcl_core:water_source", "default:water_source" }, } +-- This table contains important spawn height references for the mob spawn height. +-- Please base your mob spawn height on these numbers to keep things clean. +mobs_mc.spawn_height = { + water = tonumber(minetest.setting_get("water_level")) or 0, -- Water level in the Overworld + + -- Overworld boundaries (inclusive) + overworld_min = -2999, + overworld_max = 31000, + + -- Nether boundaries (inclusive) + nether_min = -3369, + nether_max = -3000, + + -- End boundaries (inclusive) + end_min = -6200, + end_max = -6000, +} + mobs_mc.misc = { shears_wear = 276, -- Wear to add per shears usage (238 uses) } -- Item name overrides from mobs_mc_gameconfig (if present) if minetest.get_modpath("mobs_mc_gameconfig") and mobs_mc.override then - local tables = {"items", "follow", "replace", "spawn", "misc"} + local tables = {"items", "follow", "replace", "spawn", "spawn_height", "misc"} for t=1, #tables do local tbl = tables[t] if mobs_mc.override[tbl] then diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index 5de504f84..5e6b9aa97 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -54,7 +54,7 @@ else end -- Spawn on solid blocks at or below Sea level and the selected light level -mobs:spawn_specific("mobs_mc:bat", mobs_mc.spawn.solid,{"air"},0, maxlight, 20, 5000, 2, -500, 0) +mobs:spawn_specific("mobs_mc:bat", mobs_mc.spawn.solid, {"air"}, 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 767d5760f..3af101055 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -71,8 +71,8 @@ mobs:register_mob("mobs_mc:blaze", { blood_amount = 0, }) -mobs:register_spawn("mobs_mc:blaze", mobs_mc.spawn.nether_fortress, minetest.LIGHT_MAX+1, 0, 5000, 1, -1000, true) - +mobs:spawn_specific("mobs_mc:blaze", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) + -- Blaze fireball mobs:register_arrow("mobs_mc:blaze_fireball", { visual = "sprite", diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 09f6ee26f..cd8a22b2b 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -95,7 +95,7 @@ mobs:register_mob("mobs_mc:chicken", { }) --spawn -mobs:register_spawn("mobs_mc:chicken", mobs_mc.spawn.grassland, minetest.LIGHT_MAX+1, 9, 17000, 3, 31000) +mobs:spawn_specific("mobs_mc:chicken", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0) diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 83bfd8539..f7f2d47be 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -134,9 +134,8 @@ mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) -- Spawning -mobs:register_spawn("mobs_mc:cow", mobs_mc.spawn.grassland, minetest.LIGHT_MAX+1, 9, 17000, 20, 31000) -mobs:register_spawn("mobs_mc:mooshroom", mobs_mc.spawn.mushroom_island, minetest.LIGHT_MAX+1, 9, 17000, 10, 31000) - +mobs:spawn_specific("mobs_mc:cow", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 20, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:mooshroom", mobs_mc.spawn.mushroom_island, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- compatibility mobs:alias_mob("mobs_animal:cow", "mobs_mc:cow") diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 6f481b402..b8ba9e2cd 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -122,7 +122,7 @@ mobs:register_mob("mobs_mc:creeper", { }) -mobs:spawn_specific("mobs_mc:creeper", mobs_mc.spawn.solid, {"air"},0, 7, 20, 16500, 1, -310, 31000) +mobs:spawn_specific("mobs_mc:creeper", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- compatibility mobs:alias_mob("mobs:creeper", "mobs_mc:creeper") diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 5b0d236be..1161cb002 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -146,12 +146,13 @@ mobs:register_mob("mobs_mc:enderman", { }) +-- End spawn +mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 4, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +-- Overworld spawn +mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 9000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +-- Nether spawn (rare) +mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) ---spawn on solid blocks -mobs:register_spawn("mobs_mc:enderman", mobs_mc.spawn.desert, 7, 0, 9000, -31000, 31000) ---mobs:register_spawn("mobs_mc:enderman", mobs_mc.end_city, minetest.LIGHT_MAX+1, 0, 9000, -31000, -5000) -mobs:spawn_specific("mobs_mc:enderman", "mcl_end:end_stone", {"air"}, 0, minetest.LIGHT_MAX+1, 5, 20, 2, -31000, -5000) -mobs:spawn_specific("mobs_mc:enderman", "mcl_end:end_stone", {"mcl_portals:void"}, 0, minetest.LIGHT_MAX+1, 5, 20, 2, -31000, -5000) -- spawn eggs mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 3b71a1b06..f12006476 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -77,8 +77,8 @@ mobs:register_mob("mobs_mc:ghast", { }) ---mobs:register_spawn("mobs_mc:ghast", {"default:flowing_lava", "nether:rack","air"}, 17, -1, 5000, 1, -2000) -mobs:spawn_specific("mobs_mc:ghast", mobs_mc.spawn.nether, {"air"},0, minetest.LIGHT_MAX+1, 0, 18000, 2, -3610, -2100) +mobs:spawn_specific("mobs_mc:ghast", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) + -- fireball (weapon) mobs:register_arrow(":mobs_monster:fireball", { visual = "sprite", diff --git a/mods/ENTITIES/mobs_mc/guardian.lua b/mods/ENTITIES/mobs_mc/guardian.lua index 73063129f..de9cac1dd 100644 --- a/mods/ENTITIES/mobs_mc/guardian.lua +++ b/mods/ENTITIES/mobs_mc/guardian.lua @@ -81,7 +81,7 @@ mobs:register_mob("mobs_mc:guardian", { blood_amount = 0, }) -mobs:register_spawn("mobs_mc:guardian", mobs_mc.spawn.water, minetest.LIGHT_MAX+1, 0, 5000, 2, -1000, true) +mobs:spawn_specific("mobs_mc:guardian", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water - 10) -- spawn eggs mobs:register_egg("mobs_mc:guardian", S("Guardian"), "mobs_mc_spawn_icon_guardian.png", 0) diff --git a/mods/ENTITIES/mobs_mc/guardian_elder.lua b/mods/ENTITIES/mobs_mc/guardian_elder.lua index 9b74aca07..27e21c450 100644 --- a/mods/ENTITIES/mobs_mc/guardian_elder.lua +++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua @@ -86,7 +86,7 @@ mobs:register_mob("mobs_mc:guardian_elder", { blood_amount = 0, }) -mobs:register_spawn("mobs_mc:guardian_elder", mobs_mc.spawn.water, minetest.LIGHT_MAX+1, 0, 5000, 2, -1000, true) +mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-18) -- spawn eggs mobs:register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "mobs_mc_spawn_icon_guardian_elder.png", 0) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 34c29ede5..7672eb66e 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -330,9 +330,8 @@ mobs:register_mob("mobs_mc:mule", mule) --=========================== --Spawn Function -mobs:register_spawn("mobs_mc:horse", mobs_mc.spawn.grassland_savanna, minetest.LIGHT_MAX+1, 0, 15000, 12, 31000) -mobs:register_spawn("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, minetest.LIGHT_MAX+1, 0, 15000, 12, 31000) - +mobs:spawn_specific("mobs_mc:horse", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 12, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 12, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -- compatibility mobs:alias_mob("mobs:horse", "mobs_mc:horse") diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 82c251195..d689993d4 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -139,7 +139,7 @@ mobs:register_mob("mobs_mc:llama", { }) --spawn -mobs:register_spawn("mobs_mc:llama", mobs_mc.spawn.savanna, minetest.LIGHT_MAX+1, 0, 15000, 1, 40) +mobs:spawn_specific("mobs_mc:llama", mobs_mc.spawn.savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index cd9e2e3a6..e1c11e8cd 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -140,12 +140,13 @@ local base_spawn_chance = 5000 mobs:spawn({ name = "mobs_mc:ocelot", nodes = mobs_mc.spawn.jungle, + neighbors = {"air"}, light_max = minetest.LIGHT_MAX+1, light_min = 0, chance = math.ceil(base_spawn_chance * 1.5), -- emulates 1/3 spawn failure rate active_object_count = 12, - min_height = 1, -- Right above ocean level - max_height = 31000, + min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level + max_height = mobs_mc.spawn_height.overworld_max, on_spawn = function(self, pos) --[[ Note: Minecraft has a 1/3 spawn failure rate. In this mod it is emulated by reducing the spawn rate accordingly (see above). ]] diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 21e1b965c..e030d16fb 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -89,7 +89,7 @@ mobs:register_mob("mobs_mc:parrot", { --spawn -- TODO: Increase spawn chance if polished -mobs:spawn_specific("mobs_mc:parrot", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX+1, 20, 20000, 2, 15, 20) +--mobs:spawn_specific("mobs_mc:parrot", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 30000, 1, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0) diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index aa4944f9b..05481544b 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -168,7 +168,7 @@ mobs:register_mob("mobs_mc:pig", { end, }) -mobs:register_spawn("mobs_mc:pig", mobs_mc.spawn.grassland, minetest.LIGHT_MAX+1, 9, 15000, 30, 31000) +mobs:spawn_specific("mobs_mc:pig", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 15000, 30, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- compatibility mobs:alias_mob("mobs:pig", "mobs_mc:pig") diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index 24858bcb9..8028655a3 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -69,13 +69,9 @@ mobs:register_mob("mobs_mc:polar_bear", { mobs:alias_mob("mobs_mc:polarbear", "mobs_mc:polar_bear") -mobs:register_spawn("mobs_mc:polar_bear", mobs_mc.spawn.snow, minetest.LIGHT_MAX+1, 0, 7000, 3, 31000) - +mobs:spawn_specific("mobs_mc:polar_bear", mobs_mc.spawn.snow, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn egg - - - mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0) diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index c937d86cd..5e1b2b526 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -104,10 +104,13 @@ mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) local spawn = { name = "mobs_mc:rabbit", + neighbors = {"air"}, chance = 15000, active_object_count = 99, min_light = 0, max_light = minetest.LIGHT_MAX+1, + min_height = mobs_mc.spawn_height.overworld_min, + max_height = mobs_mc.spawn_height.overworld_max, } local spawn_desert = table.copy(spawn) diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index 48176e721..bfc8ac0f4 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -202,7 +202,7 @@ mobs:register_mob("mobs_mc:sheep", { if mobs:capture_mob(self, clicker, 0, 5, 70, false, nil) then return end end, }) -mobs:register_spawn("mobs_mc:sheep", mobs_mc.spawn.grassland, minetest.LIGHT_MAX+1, 0, 15000, 3, 31000) +mobs:spawn_specific("mobs_mc:sheep", mobs_mc.spawn.grassland, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- compatibility mobs:alias_mob("mobs_animal:sheep", "mobs_mc:sheep") diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index f91739957..8c7792930 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -83,12 +83,7 @@ mobs:register_arrow("mobs_mc:shulkerbullet", { mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) ---mobs:spawn_specific("mobs_mc:shulker", mobs_mc.spawn.end_city, 0, minetest.LIGHT_MAX+1, 5, 3, 1, -31000, -5000) -mobs:spawn_specific("mobs_mc:shulker", "mcl_end:purpur_block", {"air"}, 0, minetest.LIGHT_MAX+1, 5, 20, 2, -31000, -5000) -mobs:spawn_specific("mobs_mc:shulker", "mcl_end:purpur_block", {"mcl_portals:void"}, 0, minetest.LIGHT_MAX+1, 5, 20, 2, -31000, -5000) - - - +mobs:spawn_specific("mobs_mc:shulker", "mcl_end:purpur_block", {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) if minetest.settings:get_bool("log_mods") then minetest.log("action", "MC Shulkers loaded") diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index 183c95687..7632adcd7 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -122,10 +122,15 @@ mobs:register_mob("mobs_mc:stray", stray) -- compatibility mobs:alias_mob("mobs:skeleton", "mobs_mc:skeleton") ---spawn -mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.solid,{"air"}, 0, 7, 20, 17000, 2, -110, 31000) +-- Overworld spawn +mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +-- Nether spawn +mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) + +-- Stray spawn -- TODO: Spawn directly under the sky -mobs:spawn_specific("mobs_mc:stray", mobs_mc.spawn.snow, {"air"}, 0, 7, 20, 19000, 2, -110, 31000) +mobs:spawn_specific("mobs_mc:stray", mobs_mc.spawn.snow, {"air"}, 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) + -- spawn eggs mobs:register_egg("mobs_mc:skeleton", S("Skeleton"), "mobs_mc_spawn_icon_skeleton.png", 0) diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index fbf94ba85..400fa5094 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -94,7 +94,8 @@ mobs:register_mob("mobs_mc:witherskeleton", { }) --spawn -mobs:register_spawn("mobs_mc:witherskeleton", mobs_mc.spawn.nether_fortress, 7, 0, 5000, 3, -3000, true) +mobs:spawn_specific("mobs_mc:witherskeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) + -- spawn eggs mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index ecd4e64aa..e0c9d58a9 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -118,11 +118,12 @@ slime_tiny.on_die = nil mobs:register_mob("mobs_mc:slime_tiny", slime_tiny) +local smin = mobs_mc.spawn_height.overworld_min +local smax = mobs_mc.spawn_height.water - 23 -mobs:register_spawn("mobs_mc:slime_tiny", mobs_mc.spawn.solid, minetest.LIGHT_MAX+1, 0, 35000, 4, -12) -mobs:register_spawn("mobs_mc:slime_small", mobs_mc.spawn.solid, minetest.LIGHT_MAX+1, 0, 35000, 4, -12) -mobs:register_spawn("mobs_mc:slime_big", mobs_mc.spawn.solid, minetest.LIGHT_MAX+1, 0, 35000, 4, -12) - +mobs:spawn_specific("mobs_mc:slime_tiny", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_small", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_big", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) -- Magma cube local magma_cube_big = { @@ -240,14 +241,17 @@ magma_cube_tiny.on_die = nil mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) +local mmin = mobs_mc.spawn_height.nether_min +local mmax = mobs_mc.spawn_height.nether_max -mobs:register_spawn("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether, minetest.LIGHT_MAX+1, 0, 15000, 4, -1000) -mobs:register_spawn("mobs_mc:magma_cube_small", mobs_mc.spawn.nether, minetest.LIGHT_MAX+1, 0, 15500, 4, -1000) -mobs:register_spawn("mobs_mc:magma_cube_big", mobs_mc.spawn.nether, minetest.LIGHT_MAX+1, 0, 16000, 4, -1000) +mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) + +mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) -mobs:register_spawn("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, minetest.LIGHT_MAX+1, 0, 11000, 4, -1000) -mobs:register_spawn("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, minetest.LIGHT_MAX+1, 0, 11100, 4, -1000) -mobs:register_spawn("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, minetest.LIGHT_MAX+1, 0, 11200, 4, -1000) -- Compability mobs:alias_mob("mobs_mc:greensmall", "mobs_mc:slime_tiny") diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index bb2f2db70..73f37cc66 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -77,8 +77,7 @@ cave_spider.walk_velocity = 4.1 mobs:register_mob("mobs_mc:cave_spider", cave_spider) -mobs:register_spawn("mobs_mc:spider", mobs_mc.spawn.solid, 7, 0, 19500, 2, 3000) - +mobs:spawn_specific("mobs_mc:spider", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- compatibility mobs:alias_mob("mobs:spider", "mobs_mc:spider") diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index c1b291eb9..2ab401d1b 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -60,7 +60,7 @@ mobs:register_mob("mobs_mc:squid", { -- Spawn near the water surface -local water = tonumber(minetest.settings:get("water_level")) or 0 +local water = mobs_mc.spawn_height.water --name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height mobs:spawn_specific("mobs_mc:squid", mobs_mc.spawn.water, {mobs_mc.items.water_source}, 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 246011444..76a728e2f 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -168,8 +168,7 @@ mobs:register_mob("mobs_mc:villager", { ]] }) ---mobs:register_spawn("mobs_mc:villager", {"default:gravel"}, 7, -1, 4090, 4, 31000) -mobs:register_spawn("mobs_mc:villager", {"mg_villages:road"}, minetest.LIGHT_MAX+1, -1,8000, 4, 31000) +mobs:spawn_specific("mobs_mc:villager", mobs_mc.spawn.village, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8000, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) -- compatibility mobs:alias_mob("mobs:villager", "mobs_mc:villager") diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index e5094f2ee..b5c079c87 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -83,11 +83,8 @@ mobs:register_mob("mobs_mc:villager_zombie", { fear_height = 5, }) ---mobs:register_spawn("mobs_mc:villager", {"default:gravel"}, 7, -1, 4090, 4, 31000) -mobs:register_spawn("mobs_mc:villager_zombie", {"mg_villages:road"}, 7, -1, 4090, 4, 31000) - - +mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.village, {"air"}, 0, 7, 30, 4090, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0) diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index 99ec2eb0c..85abbdc2e 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -110,7 +110,7 @@ mobs:register_arrow(":mobs:potion_arrow", { }) -- TODO: Spawn when witch works properly ---mobs:spawn_specific("mobs_mc:witch", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, 1, 30) +--mobs:spawn_specific("mobs_mc:witch", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.spawn_height.water-6, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:witch", S("Witch"), "mobs_mc_spawn_icon_witch.png", 0) diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index cf17b3b59..7f22ce907 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -207,7 +207,7 @@ end mobs:register_mob("mobs_mc:dog", dog) -- Spawn -mobs:register_spawn("mobs_mc:wolf", mobs_mc.spawn.wolf, minetest.LIGHT_MAX+1, 0, 9000, 20, 31000) +mobs:spawn_specific("mobs_mc:wolf", mobs_mc.spawn.wolf, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 9000, 20, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -- Compatibility mobs:alias_mob("mobs:wolf", "mobs_mc:wolf") diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index 8d2dda473..4408a7beb 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -122,12 +122,11 @@ mobs:register_mob("mobs_mc:baby_husk", baby_husk) -- Spawning -mobs:register_spawn("mobs_mc:zombie", mobs_mc.spawn.solid, 7, 0, 6000, 4, 31000) +mobs:spawn_specific("mobs_mc:zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:register_spawn("mobs_mc:baby_zombie", mobs_mc.spawn.solid, 7, 0, 60000, 4, 31000) -mobs:register_spawn("mobs_mc:husk", mobs_mc.spawn.desert, 7, 0, 6500, 4, 31000) -mobs:register_spawn("mobs_mc:baby_husk", mobs_mc.spawn.desert, 7, 0, 65000, 4, 31000) - +mobs:spawn_specific("mobs_mc:baby_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:baby_husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Compatibility mobs:alias_mob("mobs:zombie", "mobs_mc:zombie") diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua index 6b2ad65e4..3661ec47f 100644 --- a/mods/ENTITIES/mobs_mc/zombiepig.lua +++ b/mods/ENTITIES/mobs_mc/zombiepig.lua @@ -80,7 +80,7 @@ mobs:register_mob("mobs_mc:pigman", pigman) local baby_pigman = table.copy(pigman) baby_pigman.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} -baby_pigman.visual_size = {x=0.5, y=0.5} +baby_pigman.visual_size = {x=pigman.visual_size.x/2, y=pigman.visual_size.y/2} baby_pigman.textures = {{"mobs_mc_zombie_pigman.png"}} baby_pigman.walk_velocity = 1.2 baby_pigman.run_velocity = 2.4 @@ -88,13 +88,13 @@ baby_pigman.light_damage = 0 mobs:register_mob("mobs_mc:baby_pigman", baby_pigman) +-- Regular spawning in the Nether +mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:register_spawn("mobs_mc:baby_pigman", mobs_mc.spawn.nether, minetest.LIGHT_MAX+1, 0, 100000, 4, 31000) +mobs:spawn_specific("mobs_mc:baby_pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) ---mobs:register_spawn("mobs_mc:pigman", {"nether:rack"}, 17, -1, 5000, 3, -2000) -mobs:register_spawn("mobs_mc:pigman", mobs_mc.spawn.nether, minetest.LIGHT_MAX+1, 0, 6000, 3, -2000) -mobs:register_spawn("mobs_mc:pigman", mobs_mc.spawn.nether_portal, minetest.LIGHT_MAX+1, 0, 500, 4, 31000) -mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air", "mcl_portals:nether_air"},0, minetest.LIGHT_MAX+1, 7, 9000, 2, -31000, 31000) +-- Spawning in Nether portals in the Overworld +mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- compatibility mobs:alias_mob("mobs:pigman", "mobs_mc:pigman") diff --git a/mods/ENTITIES/mobs_mc_gameconfig/depends.txt b/mods/ENTITIES/mobs_mc_gameconfig/depends.txt new file mode 100644 index 000000000..3b355984e --- /dev/null +++ b/mods/ENTITIES/mobs_mc_gameconfig/depends.txt @@ -0,0 +1 @@ +mcl_init diff --git a/mods/ENTITIES/mobs_mc_gameconfig/init.lua b/mods/ENTITIES/mobs_mc_gameconfig/init.lua index e598d3fd8..a8f403f17 100644 --- a/mods/ENTITIES/mobs_mc_gameconfig/init.lua +++ b/mods/ENTITIES/mobs_mc_gameconfig/init.lua @@ -179,6 +179,26 @@ mobs_mc.override.spawn = { jungle = { "mcl_core:podzol", "mcl_core:jungletree", "mcl_core:jungleleaves", "mcl_flowers:fern" }, snow = { "mcl_core:snow", "mcl_core:snowblock", "mcl_core:dirt_with_grass_snow" }, end_city = { "mcl_end:purpur_block" }, + nether = { "mcl_nether:netherrack", "mcl_nether:quartz_ore" }, + -- Netherrack added because there are no Nether fortresses yet. TODO: Remove netherrac from list as soon they're available + nether_fortress = { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, wolf = { mobs_mc.override.items.grass_block, "mcl_core:dirt", "mcl_core:dirt_with_grass_snow", "mcl_core:snow", "mcl_core:snowblock", "mcl_core:podzol" }, } +-- This table contains important spawn height references for the mob spawn height. +mobs_mc.override.spawn_height = { + water = tonumber(minetest.setting_get("water_level")) or 0, -- Water level in the Overworld + + -- Overworld boundaries (inclusive) + overworld_min = mcl_vars.mg_overworld_min, + overworld_max = mcl_vars.mg_overworld_max, + + -- Nether boundaries (inclusive) + nether_min = mcl_vars.mg_nether_min, + nether_max = mcl_vars.mg_nether_max, + + -- End boundaries (inclusive) + end_min = mcl_vars.mg_end_min, + end_max = mcl_vars.mg_end_max, +} + From 657851125f57467dee1d8f86af0db8d748691d9b Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 00:16:29 +0200 Subject: [PATCH 14/75] Add nether and end portal (WIP) New mod: mcl_portals, based on maikerumine's work --- mods/MAPGEN/mcl_portals/LICENSE | 7 + mods/MAPGEN/mcl_portals/README.md | 9 + mods/MAPGEN/mcl_portals/depends.txt | 7 + mods/MAPGEN/mcl_portals/description.txt | 1 + mods/MAPGEN/mcl_portals/init.lua | 10 + mods/MAPGEN/mcl_portals/mod.conf | 1 + mods/MAPGEN/mcl_portals/portal_end.lua | 385 ++++++++++++++++ mods/MAPGEN/mcl_portals/portal_nether.lua | 416 ++++++++++++++++++ .../textures/mcl_portals_end_portal.png | Bin 0 -> 8925 bytes .../textures/mcl_portals_particle.png | Bin 0 -> 226 bytes .../textures/mcl_portals_portal.png | Bin 0 -> 8960 bytes 11 files changed, 836 insertions(+) create mode 100644 mods/MAPGEN/mcl_portals/LICENSE create mode 100644 mods/MAPGEN/mcl_portals/README.md create mode 100644 mods/MAPGEN/mcl_portals/depends.txt create mode 100644 mods/MAPGEN/mcl_portals/description.txt create mode 100644 mods/MAPGEN/mcl_portals/init.lua create mode 100644 mods/MAPGEN/mcl_portals/mod.conf create mode 100644 mods/MAPGEN/mcl_portals/portal_end.lua create mode 100644 mods/MAPGEN/mcl_portals/portal_nether.lua create mode 100644 mods/MAPGEN/mcl_portals/textures/mcl_portals_end_portal.png create mode 100644 mods/MAPGEN/mcl_portals/textures/mcl_portals_particle.png create mode 100644 mods/MAPGEN/mcl_portals/textures/mcl_portals_portal.png diff --git a/mods/MAPGEN/mcl_portals/LICENSE b/mods/MAPGEN/mcl_portals/LICENSE new file mode 100644 index 000000000..ece42d0aa --- /dev/null +++ b/mods/MAPGEN/mcl_portals/LICENSE @@ -0,0 +1,7 @@ +The MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/MAPGEN/mcl_portals/README.md b/mods/MAPGEN/mcl_portals/README.md new file mode 100644 index 000000000..09b4f3110 --- /dev/null +++ b/mods/MAPGEN/mcl_portals/README.md @@ -0,0 +1,9 @@ +# Portals mod for MineClone 2 +## How to create portals + +Nether portal: Build an upright frame of obsidian, 4 blocks wide and 5 blocks high, and use a flint and steel inside it. +End portal: Build an upright frame of red nether brick blocks, 4 blocks wide and 5 blocks high, and use an eye of ender inside it. + +## Credits +Created by maikerumine and Wuzzy. +License: MIT License (see `LICENSE`). diff --git a/mods/MAPGEN/mcl_portals/depends.txt b/mods/MAPGEN/mcl_portals/depends.txt new file mode 100644 index 000000000..fbb8a6e2d --- /dev/null +++ b/mods/MAPGEN/mcl_portals/depends.txt @@ -0,0 +1,7 @@ +mcl_init +mcl_util +mcl_core +mcl_fire +mcl_nether +mcl_end +doc? diff --git a/mods/MAPGEN/mcl_portals/description.txt b/mods/MAPGEN/mcl_portals/description.txt new file mode 100644 index 000000000..fe84531f3 --- /dev/null +++ b/mods/MAPGEN/mcl_portals/description.txt @@ -0,0 +1 @@ +Adds buildable portals to the Nether and End dimensions. diff --git a/mods/MAPGEN/mcl_portals/init.lua b/mods/MAPGEN/mcl_portals/init.lua new file mode 100644 index 000000000..cf4716c40 --- /dev/null +++ b/mods/MAPGEN/mcl_portals/init.lua @@ -0,0 +1,10 @@ +-- Load files + +-- Nether portal: +-- Obsidian frame, activated by flint and steel +dofile(minetest.get_modpath("mcl_portals").."/portal_nether.lua") + +-- End portal (W.I.P): +-- Red nether brick block frame, activated by an eye of ender +dofile(minetest.get_modpath("mcl_portals").."/portal_end.lua") + diff --git a/mods/MAPGEN/mcl_portals/mod.conf b/mods/MAPGEN/mcl_portals/mod.conf new file mode 100644 index 000000000..e82fbe6c1 --- /dev/null +++ b/mods/MAPGEN/mcl_portals/mod.conf @@ -0,0 +1 @@ +name = mcl_portals diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua new file mode 100644 index 000000000..2de6174f3 --- /dev/null +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -0,0 +1,385 @@ +-- Parameters + +local END_DEPTH = mcl_vars.mg_end_min +local TCAVE = 0.6 +local nobj_cave = nil +-- 3D noise + +local np_cave = { + offset = 0, + scale = 1, + spread = {x = 384, y = 128, z = 384}, -- squashed 3:1 + seed = 59033, + octaves = 5, + persist = 0.7 +} + +-- Nodes +minetest.register_node("mcl_portals:portal_end", { + description = "End Portal", + tiles = { + "blank.png", + "blank.png", + "blank.png", + "blank.png", + { + name = "mcl_portals_end_portal.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + { + name = "mcl_portals_end_portal.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + use_texture_alpha = true, + walkable = false, + diggable = false, + pointable = false, + buildable_to = false, + is_ground_content = false, + drop = "", + -- This is 15 in MC. + light_source = 14, + post_effect_color = {a = 192, r = 0, g = 0, b = 0}, + alpha = 192, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.1, 0.5, 0.5, 0.1}, + }, + }, + groups = {not_in_creative_inventory = 1} +}) + +local function build_end_portal(pos, target3) + local p = {x = pos.x - 1, y = pos.y - 1, z = pos.z} + local p1 = {x = pos.x - 1, y = pos.y - 1, z = pos.z} + local p2 = {x = p1.x + 3, y = p1.y + 4, z = p1.z} + + for i = 1, 4 do + minetest.set_node(p, {name = "mcl_nether:red_nether_brick"}) + p.y = p.y + 1 + end + for i = 1, 3 do + minetest.set_node(p, {name = "mcl_nether:red_nether_brick"}) + p.x = p.x + 1 + end + for i = 1, 4 do + minetest.set_node(p, {name = "mcl_nether:red_nether_brick"}) + p.y = p.y - 1 + end + for i = 1, 3 do + minetest.set_node(p, {name = "mcl_nether:red_nether_brick"}) + p.x = p.x - 1 + end + + for x = p1.x, p2.x do + for y = p1.y, p2.y do + p = {x = x, y = y, z = p1.z} + if not (x == p1.x or x == p2.x or y == p1.y or y == p2.y) then + minetest.set_node(p, {name = "mcl_portals:portal_end", param2 = 0}) + end + local meta = minetest.get_meta(p) + meta:set_string("p1", minetest.pos_to_string(p1)) + meta:set_string("p2", minetest.pos_to_string(p2)) + meta:set_string("target3", minetest.pos_to_string(target3)) + + if y ~= p1.y then + for z = -2, 2 do + if z ~= 0 then + p.z = p.z + z + if minetest.registered_nodes[ + minetest.get_node(p).name].is_ground_content then + minetest.remove_node(p) + end + p.z = p.z - z + end + end + end + end + end +end + +local function find_end_target3_y2(target3_x, target3_z) + local start_y = END_DEPTH + math.random(20, 120) -- Search start + local nobj_cave_point = minetest.get_perlin(np_cave) + local air = 0 -- Consecutive air nodes found + + for y = start_y, start_y - 120, -1 do + local nval_cave = nobj_cave_point:get3d({x = target3_x, y = y, z = target3_z}) + + if nval_cave > TCAVE then -- Cavern + air = air + 1 + else -- Not cavern, check if 4 nodes of space above + if air >= 4 then + return y + 2 + else -- Not enough space, reset air to zero + air = 0 + end + end + end + + return start_y -- Fallback +end + +local function move_check2(p1, max, dir) + local p = {x = p1.x, y = p1.y, z = p1.z} + local d = math.abs(max - p1[dir]) / (max - p1[dir]) + + while p[dir] ~= max do + p[dir] = p[dir] + d + if minetest.get_node(p).name ~= "mcl_nether:red_nether_brick" then + return false + end + end + + return true +end + +local function check_end_portal(p1, p2) + if p1.x ~= p2.x then + if not move_check2(p1, p2.x, "x") then + return false + end + if not move_check2(p2, p1.x, "x") then + return false + end + elseif p1.z ~= p2.z then + if not move_check2(p1, p2.z, "z") then + return false + end + if not move_check2(p2, p1.z, "z") then + return false + end + else + return false + end + + if not move_check2(p1, p2.y, "y") then + return false + end + if not move_check2(p2, p1.y, "y") then + return false + end + + return true +end + +local function is_end_portal(pos) + for d = -3, 3 do + for y = -4, 4 do + local px = {x = pos.x + d, y = pos.y + y, z = pos.z} + local pz = {x = pos.x, y = pos.y + y, z = pos.z + d} + + if check_end_portal(px, {x = px.x + 3, y = px.y + 4, z = px.z}) then + return px, {x = px.x + 3, y = px.y + 4, z = px.z} + end + if check_end_portal(pz, {x = pz.x, y = pz.y + 4, z = pz.z + 3}) then + return pz, {x = pz.x, y = pz.y + 4, z = pz.z + 3} + end + end + end +end + +local function make_end_portal(pos) + local p1, p2 = is_end_portal(pos) + if not p1 or not p2 then + return false + end + + for d = 1, 2 do + for y = p1.y + 1, p2.y - 1 do + local p + if p1.z == p2.z then + p = {x = p1.x + d, y = y, z = p1.z} + else + p = {x = p1.x, y = y, z = p1.z + d} + end + if minetest.get_node(p).name ~= "air" then + return false + end + end + end + + local param2 + if p1.z == p2.z then + param2 = 0 + else + param2 = 1 + end + + local target3 = {x = p1.x, y = p1.y, z = p1.z} + target3.x = target3.x + 1 + if target3.y < END_DEPTH then + target3.y = math.random(-52, 100) + else + target3.y = find_end_target3_y2(target3.x, target3.z) + end + + for d = 0, 3 do + for y = p1.y, p2.y do + local p = {} + if param2 == 0 then + p = {x = p1.x + d, y = y, z = p1.z} + else + p = {x = p1.x, y = y, z = p1.z + d} + end + if minetest.get_node(p).name == "air" then + minetest.set_node(p, {name = "mcl_portals:portal_end", param2 = param2}) + end + local meta = minetest.get_meta(p) + meta:set_string("p1", minetest.pos_to_string(p1)) + meta:set_string("p2", minetest.pos_to_string(p2)) + meta:set_string("target3", minetest.pos_to_string(target3)) + end + end + + return true +end + +minetest.register_abm({ + label = "End portal teleportation", + nodenames = {"mcl_portals:portal_end"}, + interval = 1, + chance = 2, + action = function(pos, node) + for _,obj in ipairs(minetest.get_objects_inside_radius(pos,1)) do --maikerumine added for objects to travel + local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel + if obj:is_player() or lua_entity then + local meta = minetest.get_meta(pos) + local target3 = minetest.string_to_pos(meta:get_string("target3")) + if target3 then + -- force emerge of target3 area + minetest.get_voxel_manip():read_from_map(target3, target3) + if not minetest.get_node_or_nil(target3) then + minetest.emerge_area( + vector.subtract(target3, 4), vector.add(target3, 4)) + end + -- teleport the player + minetest.after(3, function(obj, pos, target3) + local objpos = obj:getpos() + if objpos == nil then return end --maikerumine added for objects to travel + objpos.y = objpos.y + 0.1 -- Fix some glitches at -8000. FIXME: WTF? + if minetest.get_node(objpos).name ~= "mcl_portals:portal_end" then + return + end + + obj:setpos(target3) + minetest.sound_play("tng_transporter1", {pos=target3,gain=0.5,max_hear_distance = 8,}) -- maikerumine added sound when travel + + local function check_and_build_end_portal(pos, target3) + local n = minetest.get_node_or_nil(target3) + if n and n.name ~= "mcl_portals:portal_end" then + build_end_portal(target3, pos) + minetest.after(2, check_and_build_end_portal, pos, target3) + minetest.after(4, check_and_build_end_portal, pos, target3) + elseif not n then + minetest.after(1, check_and_build_end_portal, pos, target3) + end + end + + minetest.after(1, check_and_build_end_portal, pos, target3) + + end, obj, pos, target3) + end + end + end + end, +}) + + +--[[ ITEM OVERRIDES ]] + +-- Frame material +minetest.override_item("mcl_nether:red_nether_brick", { + on_destruct = function(pos) + local meta = minetest.get_meta(pos) + local p1 = minetest.string_to_pos(meta:get_string("p1")) + local p2 = minetest.string_to_pos(meta:get_string("p2")) + local target3 = minetest.string_to_pos(meta:get_string("target3")) + if not p1 or not p2 then + return + end + + for x = p1.x, p2.x do + for y = p1.y, p2.y do + for z = p1.z, p2.z do + local nn = minetest.get_node({x = x, y = y, z = z}).name + if nn == "mcl_nether:red_nether_brick" or nn == "mcl_portals:portal_end" then + if nn == "mcl_portals:portal_end" then + minetest.remove_node({x = x, y = y, z = z}) + end + local m = minetest.get_meta({x = x, y = y, z = z}) + m:set_string("p1", "") + m:set_string("p2", "") + m:set_string("target3", "") + end + end + end + end + + meta = minetest.get_meta(target3) + if not meta then + return + end + p1 = minetest.string_to_pos(meta:get_string("p1")) + p2 = minetest.string_to_pos(meta:get_string("p2")) + if not p1 or not p2 then + return + end + + for x = p1.x, p2.x do + for y = p1.y, p2.y do + for z = p1.z, p2.z do + local nn = minetest.get_node({x = x, y = y, z = z}).name + if nn == "mcl_nether:red_nether_brick" or nn == "mcl_portals:portal_end" then + if nn == "mcl_portals:portal_end" then + minetest.remove_node({x = x, y = y, z = z}) + end + local m = minetest.get_meta({x = x, y = y, z = z}) + m:set_string("p1", "") + m:set_string("p2", "") + m:set_string("target3", "") + end + end + end + end + end, +}) + +-- Portal opener +minetest.override_item("mcl_end:ender_eye", { + _doc_items_longdesc = "An eye of ander can be used to open a portal to the End.", + _doc_items_usagehelp = "To open an End portal, place an upright frame of red nether brick blocks with a length of 4 and a height of 5 blocks, leaving only air in the center. After placing this frame, use the nether quartz on the frame.", + on_place = function(itemstack, user, pointed_thing) + local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] --new + + minetest.sound_play( + "fire_flint_and_steel", + {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8} + ) + if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_nether:red_nether_brick" then + make_end_portal(pointed_thing.under) + end + + if not minetest.setting_getbool("creative_mode") and used == true then + itemstack:take_item() -- 1 use + end + return itemstack + end, +}) + diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua new file mode 100644 index 000000000..94ed0986c --- /dev/null +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -0,0 +1,416 @@ +-- Parameters + +local NETHER_DEPTH = mcl_vars.mg_nether_min +local TCAVE = 0.6 +local nobj_cave = nil + +-- 3D noise +local np_cave = { + offset = 0, + scale = 1, + spread = {x = 384, y = 128, z = 384}, + seed = 59033, + octaves = 5, + persist = 0.7 +} + +minetest.register_node("mcl_portals:portal", { + description = "Nether Portal", + tiles = { + "blank.png", + "blank.png", + "blank.png", + "blank.png", + { + name = "mcl_portals_portal.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.5, + }, + }, + { + name = "mcl_portals_portal.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.5, + }, + }, + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + use_texture_alpha = true, + walkable = false, + diggable = false, + pointable = false, + buildable_to = false, + is_ground_content = false, + drop = "", + light_source = 11, + post_effect_color = {a = 180, r = 128, g = 23, b = 23}, + alpha = 192, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.1, 0.5, 0.5, 0.1}, + }, + }, + groups = {not_in_creative_inventory = 1} +}) + + + +-- Functions +--Build arrival portal +local function build_portal(pos, target) + local p = {x = pos.x - 1, y = pos.y - 1, z = pos.z} + local p1 = {x = pos.x - 1, y = pos.y - 1, z = pos.z} + local p2 = {x = p1.x + 3, y = p1.y + 4, z = p1.z} + + for i = 1, 4 do + minetest.set_node(p, {name = "mcl_core:obsidian"}) + p.y = p.y + 1 + end + for i = 1, 3 do + minetest.set_node(p, {name = "mcl_core:obsidian"}) + p.x = p.x + 1 + end + for i = 1, 4 do + minetest.set_node(p, {name = "mcl_core:obsidian"}) + p.y = p.y - 1 + end + for i = 1, 3 do + minetest.set_node(p, {name = "mcl_core:obsidian"}) + p.x = p.x - 1 + end + + for x = p1.x, p2.x do + for y = p1.y, p2.y do + p = {x = x, y = y, z = p1.z} + if not (x == p1.x or x == p2.x or y == p1.y or y == p2.y) then + minetest.set_node(p, {name = "mcl_portals:portal", param2 = 0}) + end + local meta = minetest.get_meta(p) + meta:set_string("p1", minetest.pos_to_string(p1)) + meta:set_string("p2", minetest.pos_to_string(p2)) + meta:set_string("target", minetest.pos_to_string(target)) + + if y ~= p1.y then + for z = -2, 2 do + if z ~= 0 then + p.z = p.z + z + if minetest.registered_nodes[ + minetest.get_node(p).name].is_ground_content then + minetest.remove_node(p) + end + p.z = p.z - z + end + end + end + end + end +end + +local function find_nether_target_y(target_x, target_z) + local start_y = NETHER_DEPTH + math.random(38, 117) -- Search start + local nobj_cave_point = minetest.get_perlin(np_cave) + local air = 4 + + for y = start_y, start_y -117, -1 do + local nval_cave = nobj_cave_point:get3d({x = target_x, y = y, z = target_z}) + + if nval_cave > TCAVE then -- Cavern + air = air + 1 + else -- Not cavern, check if 4 nodes of space above + if air >= 4 then + return y + 2 + else -- Not enough space, reset air to zero + air = 0 + end + end + end + + return start_y -- Fallback +end + +local function move_check(p1, max, dir) + local p = {x = p1.x, y = p1.y, z = p1.z} + local d = math.abs(max - p1[dir]) / (max - p1[dir]) + + while p[dir] ~= max do + p[dir] = p[dir] + d + if minetest.get_node(p).name ~= "mcl_core:obsidian" then + return false + end + end + + return true +end + +local function check_portal(p1, p2) + if p1.x ~= p2.x then + if not move_check(p1, p2.x, "x") then + return false + end + if not move_check(p2, p1.x, "x") then + return false + end + elseif p1.z ~= p2.z then + if not move_check(p1, p2.z, "z") then + return false + end + if not move_check(p2, p1.z, "z") then + return false + end + else + return false + end + + if not move_check(p1, p2.y, "y") then + return false + end + if not move_check(p2, p1.y, "y") then + return false + end + + return true +end + +local function is_portal(pos) + for d = -3, 3 do + for y = -4, 4 do + local px = {x = pos.x + d, y = pos.y + y, z = pos.z} + local pz = {x = pos.x, y = pos.y + y, z = pos.z + d} + + if check_portal(px, {x = px.x + 3, y = px.y + 4, z = px.z}) then + return px, {x = px.x + 3, y = px.y + 4, z = px.z} + end + if check_portal(pz, {x = pz.x, y = pz.y + 4, z = pz.z + 3}) then + return pz, {x = pz.x, y = pz.y + 4, z = pz.z + 3} + end + end + end +end + +local function make_portal(pos) + local p1, p2 = is_portal(pos) + if not p1 or not p2 then + return false + end + + for d = 1, 2 do + for y = p1.y + 1, p2.y - 1 do + local p + if p1.z == p2.z then + p = {x = p1.x + d, y = y, z = p1.z} + else + p = {x = p1.x, y = y, z = p1.z + d} + end + if minetest.get_node(p).name ~= "air" then + return false + end + end + end + + local param2 + if p1.z == p2.z then + param2 = 0 + else + param2 = 1 + end + + local target = {x = p1.x, y = p1.y, z = p1.z} + target.x = target.x + 1 + if target.y < NETHER_DEPTH then + target.y = math.random(-52, 100) + else + target.y = find_nether_target_y(target.x, target.z) + end + + for d = 0, 3 do + for y = p1.y, p2.y do + local p = {} + if param2 == 0 then + p = {x = p1.x + d, y = y, z = p1.z} + else + p = {x = p1.x, y = y, z = p1.z + d} + end + if minetest.get_node(p).name == "air" + then + minetest.set_node(p, {name = "mcl_portals:portal", param2 = param2}) + end + local meta = minetest.get_meta(p) + meta:set_string("p1", minetest.pos_to_string(p1)) + meta:set_string("p2", minetest.pos_to_string(p2)) + meta:set_string("target", minetest.pos_to_string(target)) + end + end + + return true +end + + +minetest.register_abm({ + label = "Nether portal teleportation and particles", + nodenames = {"mcl_portals:portal"}, + interval = 1, + chance = 2, + action = function(pos, node) + minetest.add_particlespawner( + 32, --amount + 4, --time + {x = pos.x - 0.25, y = pos.y - 0.25, z = pos.z - 0.25}, --minpos + {x = pos.x + 0.25, y = pos.y + 0.25, z = pos.z + 0.25}, --maxpos + {x = -0.8, y = -0.8, z = -0.8}, --minvel + {x = 0.8, y = 0.8, z = 0.8}, --maxvel + {x = 0, y = 0, z = 0}, --minacc + {x = 0, y = 0, z = 0}, --maxacc + 0.5, --minexptime + 1, --maxexptime + 1, --minsize + 2, --maxsize + false, --collisiondetection + "mcl_portals_particle.png" --texture + ) + for _,obj in ipairs(minetest.get_objects_inside_radius(pos,1)) do --maikerumine added for objects to travel + local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel + if obj:is_player() or lua_entity then + local meta = minetest.get_meta(pos) + local target = minetest.string_to_pos(meta:get_string("target")) + if target then + -- force emerge of target area + minetest.get_voxel_manip():read_from_map(target, target) + if not minetest.get_node_or_nil(target) then + minetest.emerge_area( + vector.subtract(target, 4), vector.add(target, 4)) + end + -- teleport the player + minetest.after(3, function(obj, pos, target) + local objpos = obj:getpos() if objpos == nil then return end --maikerumine added for objects to travel + objpos.y = objpos.y + 0.1 -- Fix some glitches at -8000 + if minetest.get_node(objpos).name ~= "mcl_portals:portal" then + return + end + + obj:setpos(target) + minetest.sound_play("tng_transporter1", {pos=target,gain=0.5,max_hear_distance = 8,}) --maikerumine added sound when travel + local function check_and_build_portal(pos, target) + local n = minetest.get_node_or_nil(target) + if n and n.name ~= "mcl_portals:portal" then + build_portal(target, pos) + minetest.after(2, check_and_build_portal, pos, target) + minetest.after(4, check_and_build_portal, pos, target) + elseif not n then + minetest.after(1, check_and_build_portal, pos, target) + end + end + + minetest.after(1, check_and_build_portal, pos, target) + + end, obj, pos, target) + end + end + end + end, +}) + + +--[[ ITEM OVERRIDES ]] + +-- Frame material +minetest.override_item("mcl_core:obsidian", { + on_destruct = function(pos) + local meta = minetest.get_meta(pos) + local p1 = minetest.string_to_pos(meta:get_string("p1")) + local p2 = minetest.string_to_pos(meta:get_string("p2")) + local target = minetest.string_to_pos(meta:get_string("target")) + if not p1 or not p2 then + return + end + + for x = p1.x, p2.x do + for y = p1.y, p2.y do + for z = p1.z, p2.z do + local nn = minetest.get_node({x = x, y = y, z = z}).name + if nn == "mcl_core:obsidian" or nn == "mcl_portals:portal" then + if nn == "mcl_portals:portal" then + minetest.remove_node({x = x, y = y, z = z}) + end + local m = minetest.get_meta({x = x, y = y, z = z}) + m:set_string("p1", "") + m:set_string("p2", "") + m:set_string("target", "") + end + end + end + end + + meta = minetest.get_meta(target) + if not meta then + return + end + p1 = minetest.string_to_pos(meta:get_string("p1")) + p2 = minetest.string_to_pos(meta:get_string("p2")) + if not p1 or not p2 then + return + end + + for x = p1.x, p2.x do + for y = p1.y, p2.y do + for z = p1.z, p2.z do + local nn = minetest.get_node({x = x, y = y, z = z}).name + if nn == "mcl_core:obsidian" or nn == "mcl_portals:portal" then + if nn == "mcl_portals:portal" then + minetest.remove_node({x = x, y = y, z = z}) + end + local m = minetest.get_meta({x = x, y = y, z = z}) + m:set_string("p1", "") + m:set_string("p2", "") + m:set_string("target", "") + end + end + end + end + end, +}) + +-- Portal opener +minetest.override_item("mcl_fire:flint_and_steel", { + _doc_items_longdesc = "Flint and steel is a tool to start fires, ignite blocks and open portals.", + _doc_items_usagehelp = "Rightclick the surface of a block to attempt to light a fire in front of it. On netherrack it will start an eternal fire. Using it on TNT will ignite it. To open a Nether portal, place an upright frame of obsidian with a length of 4 and a height of 5 blocks, leaving only air in the center. After placing this frame, use the flint and steel on inside of the frame.", + on_place = function(itemstack, user, pointed_thing) + local idef = itemstack:get_definition() + minetest.sound_play( + "fire_flint_and_steel", + {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8} + ) + local used = false + + if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_core:obsidian" then + done = make_portal(pointed_thing.under) + else + if pointed_thing.type == "node" then + local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] + if nodedef._on_ignite then + nodedef._on_ignite(pointed_thing.under, user) + else + mcl_fire.set_fire(pointed_thing) + end + used = true + end + end + if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then + minetest.sound_play(idef.sound.breaks, {pos=user:getpos(), gain=0.5}) + end + if not minetest.setting_getbool("creative_mode") and used == true then + itemstack:add_wear(65535/65) -- 65 uses + end + return itemstack + end, +}) + diff --git a/mods/MAPGEN/mcl_portals/textures/mcl_portals_end_portal.png b/mods/MAPGEN/mcl_portals/textures/mcl_portals_end_portal.png new file mode 100644 index 0000000000000000000000000000000000000000..975be7f7de9b688a3c2701e0f41c36883568a00a GIT binary patch literal 8925 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 literal 0 HcmV?d00001 diff --git a/mods/MAPGEN/mcl_portals/textures/mcl_portals_particle.png b/mods/MAPGEN/mcl_portals/textures/mcl_portals_particle.png new file mode 100644 index 0000000000000000000000000000000000000000..56a5b78c42392a3cac53daffe6ace26f490de837 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0y~yVBi2@4mJh`h9ms@x)~T4*pj^6T^Rm@;DWu&Co?cG za29w(7Bet#3xhBt!>l~~ps`Gk#*Sv(5?8B^jKQR1ARo12Y;fRVd0xXQcgyYH^;xVr>|xLT-?FecxO}|_i{qW}Lpf#4 z@?M34w+_eTH8=ZgJ{QEuyedG_so`+C)1EeyvS-38^14KyDO}D;on28K@Zv$g-bqcF W|8>ijBr-5CFnGH9xvXt(|8-y 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 a^Zg$;^U2=YvD>-;0000 Date: Thu, 17 Aug 2017 01:01:09 +0200 Subject: [PATCH 15/75] Add portal teleportation sound --- mods/MAPGEN/mcl_portals/README.md | 8 +++++++- mods/MAPGEN/mcl_portals/portal_end.lua | 8 +++++--- mods/MAPGEN/mcl_portals/portal_nether.lua | 8 ++++++-- .../sounds/mcl_portals_teleport.ogg | Bin 0 -> 111849 bytes 4 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 mods/MAPGEN/mcl_portals/sounds/mcl_portals_teleport.ogg diff --git a/mods/MAPGEN/mcl_portals/README.md b/mods/MAPGEN/mcl_portals/README.md index 09b4f3110..77c5c0efa 100644 --- a/mods/MAPGEN/mcl_portals/README.md +++ b/mods/MAPGEN/mcl_portals/README.md @@ -6,4 +6,10 @@ End portal: Build an upright frame of red nether brick blocks, 4 blocks wide and ## Credits Created by maikerumine and Wuzzy. -License: MIT License (see `LICENSE`). +Code license: MIT License (see `LICENSE`). + +Texture license: See main MineClone 2 directory. + +License of sound: [CC BY 3.0](http://creativecommons.org/licenses/by/3.0/) +Authors: [FreqMan](https://freesound.org/people/FreqMan/) and Wuzzy +Source: diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index 2de6174f3..c5d4d5b25 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -278,9 +278,7 @@ minetest.register_abm({ return end - obj:setpos(target3) - minetest.sound_play("tng_transporter1", {pos=target3,gain=0.5,max_hear_distance = 8,}) -- maikerumine added sound when travel - + -- Build destination local function check_and_build_end_portal(pos, target3) local n = minetest.get_node_or_nil(target3) if n and n.name ~= "mcl_portals:portal_end" then @@ -294,6 +292,10 @@ minetest.register_abm({ minetest.after(1, check_and_build_end_portal, pos, target3) + -- Teleport + obj:setpos(target3) + minetest.sound_play("mcl_portals_teleport", {pos=target3, gain=0.5, max_hear_distance = 16}) + end, obj, pos, target3) end end diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index 94ed0986c..7070f2492 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -297,8 +297,7 @@ minetest.register_abm({ return end - obj:setpos(target) - minetest.sound_play("tng_transporter1", {pos=target,gain=0.5,max_hear_distance = 8,}) --maikerumine added sound when travel + -- Build target portal local function check_and_build_portal(pos, target) local n = minetest.get_node_or_nil(target) if n and n.name ~= "mcl_portals:portal" then @@ -312,6 +311,11 @@ minetest.register_abm({ minetest.after(1, check_and_build_portal, pos, target) + -- Teleport + obj:setpos(target) + minetest.sound_play("mcl_portals_teleport", {pos=target, gain=0.5, max_hear_distance = 16}) + + end, obj, pos, target) end end diff --git a/mods/MAPGEN/mcl_portals/sounds/mcl_portals_teleport.ogg b/mods/MAPGEN/mcl_portals/sounds/mcl_portals_teleport.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b943a83257712856cef64dfb16cc689428188c0b GIT binary patch literal 111849 zcmce+byQqU(=WOq2^K841rHM3CAhl`3@!nJ2MF$x;O-Dy2bbUuA-MYxoM3|!+~F>g z=Xt;PoV(UJ_pjTlr>3i`Wvc2|yJfbrxw#qu5B!rDsBJZ$idH&%AK^&hTE_=%&NjNt=^)v-e#zpai|*gPZIzR zc>c%B*_NpV|F3MOon-od&mtE6Zvhc_K%~!}q|csO5=7nSz=-(A!uz$;uCjBgW{DS)L3{kb@+S`gf-101%S1L7qCEdOE^~p1PS`jFUFi z8LFN}+f@8D?T-gPjuNh?JC4#1ru1Z|jHfz|%A%%1{+8Ua(h$pwCsQ3q31R8zy@W>T zj-!^7sffjMT4|1>+T*EPMNK$qj-#OoX|#1s>VL=k2NuN!>7$)|ztSB?L+8`1n~?R> z9Y?P}q#uqTKh^#3@DTxk=SDvXdNaO|dq*J{<4_b(#FIKjqsM2n_0#8*Mn*}=75l4z z2x%csU;b!L4gdj|e^C4{`2*#@D9(=ydpk&1Gt553_(aOOM)~)?bzzF5veiz?F>=jl zm_*iXWja>y$yh_`pgIhY1dtp(AW)Qy)qkVh#&O71M5GL1Bf9} z1pHAX!8n4gFWp~B4Ee8v|BW1boW59+fmmw!YHGzv#*q_F2@F2UGz7L6%aMdf-GL zSNe=`Y&}%qmEVRtXCzEEQ~K166p%f0BUOwSh=omX!T|srIsm}oiRDl*!29vS0pZl{ zq_QUhaU1TOiZ~QuNd=*#W7v|JG+`1`oH?mU1@4q%*pjKVVG62TMyZ+GDKt|~;DX{3 zJ?$ilmQ31InkjYtg5r`7nn@Hx001y5b10^og>jB>hUQxS;A9%%P)wys{g)L~Re$QM zpayQL*!$ruIH3;C{T~(%0Aw=Fo*G-G(ql(E)!?!PTChsEq^KyMJ1cM*h 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 H^#K0|Z{qt7 literal 0 HcmV?d00001 From 41380ad281f904fcc504dcb4e8895bda84db675d Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 01:09:32 +0200 Subject: [PATCH 16/75] Save portal noise --- mods/MAPGEN/mcl_portals/portal_end.lua | 6 ++++-- mods/MAPGEN/mcl_portals/portal_nether.lua | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index c5d4d5b25..0a8c5c8c9 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -116,11 +116,13 @@ end local function find_end_target3_y2(target3_x, target3_z) local start_y = END_DEPTH + math.random(20, 120) -- Search start - local nobj_cave_point = minetest.get_perlin(np_cave) + if not nobj_cave then + nobj_cave = minetest.get_perlin(np_cave) + end local air = 0 -- Consecutive air nodes found for y = start_y, start_y - 120, -1 do - local nval_cave = nobj_cave_point:get3d({x = target3_x, y = y, z = target3_z}) + local nval_cave = nobj_cave:get3d({x = target3_x, y = y, z = target3_z}) if nval_cave > TCAVE then -- Cavern air = air + 1 diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index 7070f2492..9705e2895 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -118,11 +118,13 @@ end local function find_nether_target_y(target_x, target_z) local start_y = NETHER_DEPTH + math.random(38, 117) -- Search start - local nobj_cave_point = minetest.get_perlin(np_cave) + if not nobj_cave then + nobj_cave = minetest.get_perlin(np_cave) + end local air = 4 for y = start_y, start_y -117, -1 do - local nval_cave = nobj_cave_point:get3d({x = target_x, y = y, z = target_z}) + local nval_cave = nobj_cave:get3d({x = target_x, y = y, z = target_z}) if nval_cave > TCAVE then -- Cavern air = air + 1 From 05657fae9e0d240c1f48791298f326130f42439a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 01:10:00 +0200 Subject: [PATCH 17/75] Don't play ignite sound for ender eye fail --- mods/MAPGEN/mcl_portals/portal_end.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index 0a8c5c8c9..a1c6906f0 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -372,12 +372,12 @@ minetest.override_item("mcl_end:ender_eye", { on_place = function(itemstack, user, pointed_thing) local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] --new - minetest.sound_play( - "fire_flint_and_steel", - {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8} - ) if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_nether:red_nether_brick" then make_end_portal(pointed_thing.under) + minetest.sound_play( + "fire_flint_and_steel", + {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8} + ) end if not minetest.setting_getbool("creative_mode") and used == true then From 1f840e4cfc6994b3d975cbdd0ebad6baa45fad75 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 01:11:06 +0200 Subject: [PATCH 18/75] More portal opener fixes --- mods/MAPGEN/mcl_portals/portal_end.lua | 7 ++++--- mods/MAPGEN/mcl_portals/portal_nether.lua | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index a1c6906f0..cc2dc8b96 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -372,17 +372,18 @@ minetest.override_item("mcl_end:ender_eye", { on_place = function(itemstack, user, pointed_thing) local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] --new + -- If used on frame, open portal if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_nether:red_nether_brick" then make_end_portal(pointed_thing.under) minetest.sound_play( "fire_flint_and_steel", {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8} ) + if not minetest.setting_getbool("creative_mode") and used == true then + itemstack:take_item() -- 1 use + end end - if not minetest.setting_getbool("creative_mode") and used == true then - itemstack:take_item() -- 1 use - end return itemstack end, }) diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index 9705e2895..c8c875eb0 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -398,7 +398,7 @@ minetest.override_item("mcl_fire:flint_and_steel", { local used = false if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_core:obsidian" then - done = make_portal(pointed_thing.under) + make_portal(pointed_thing.under) else if pointed_thing.type == "node" then local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] From ec0219c66e93640069d85c38f8ecd404d92cab4c Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 01:19:47 +0200 Subject: [PATCH 19/75] Use frame of quartz block for End portal instead --- mods/MAPGEN/mcl_portals/portal_end.lua | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index cc2dc8b96..1119814c8 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -14,6 +14,9 @@ local np_cave = { persist = 0.7 } +-- Portal frame material +local portal_frame = "mcl_nether:quartz_block" + -- Nodes minetest.register_node("mcl_portals:portal_end", { description = "End Portal", @@ -71,19 +74,19 @@ local function build_end_portal(pos, target3) local p2 = {x = p1.x + 3, y = p1.y + 4, z = p1.z} for i = 1, 4 do - minetest.set_node(p, {name = "mcl_nether:red_nether_brick"}) + minetest.set_node(p, {name = portal_frame}) p.y = p.y + 1 end for i = 1, 3 do - minetest.set_node(p, {name = "mcl_nether:red_nether_brick"}) + minetest.set_node(p, {name = portal_frame}) p.x = p.x + 1 end for i = 1, 4 do - minetest.set_node(p, {name = "mcl_nether:red_nether_brick"}) + minetest.set_node(p, {name = portal_frame}) p.y = p.y - 1 end for i = 1, 3 do - minetest.set_node(p, {name = "mcl_nether:red_nether_brick"}) + minetest.set_node(p, {name = portal_frame}) p.x = p.x - 1 end @@ -144,7 +147,7 @@ local function move_check2(p1, max, dir) while p[dir] ~= max do p[dir] = p[dir] + d - if minetest.get_node(p).name ~= "mcl_nether:red_nether_brick" then + if minetest.get_node(p).name ~= portal_frame then return false end end @@ -309,7 +312,7 @@ minetest.register_abm({ --[[ ITEM OVERRIDES ]] -- Frame material -minetest.override_item("mcl_nether:red_nether_brick", { +minetest.override_item(portal_frame, { on_destruct = function(pos) local meta = minetest.get_meta(pos) local p1 = minetest.string_to_pos(meta:get_string("p1")) @@ -323,7 +326,7 @@ minetest.override_item("mcl_nether:red_nether_brick", { for y = p1.y, p2.y do for z = p1.z, p2.z do local nn = minetest.get_node({x = x, y = y, z = z}).name - if nn == "mcl_nether:red_nether_brick" or nn == "mcl_portals:portal_end" then + if nn == portal_frame or nn == "mcl_portals:portal_end" then if nn == "mcl_portals:portal_end" then minetest.remove_node({x = x, y = y, z = z}) end @@ -350,7 +353,7 @@ minetest.override_item("mcl_nether:red_nether_brick", { for y = p1.y, p2.y do for z = p1.z, p2.z do local nn = minetest.get_node({x = x, y = y, z = z}).name - if nn == "mcl_nether:red_nether_brick" or nn == "mcl_portals:portal_end" then + if nn == portal_frame or nn == "mcl_portals:portal_end" then if nn == "mcl_portals:portal_end" then minetest.remove_node({x = x, y = y, z = z}) end @@ -368,12 +371,12 @@ minetest.override_item("mcl_nether:red_nether_brick", { -- Portal opener minetest.override_item("mcl_end:ender_eye", { _doc_items_longdesc = "An eye of ander can be used to open a portal to the End.", - _doc_items_usagehelp = "To open an End portal, place an upright frame of red nether brick blocks with a length of 4 and a height of 5 blocks, leaving only air in the center. After placing this frame, use the nether quartz on the frame.", + _doc_items_usagehelp = "To open an End portal, place an upright frame of quartz blocks with a length of 4 and a height of 5 blocks, leaving only air in the center. After placing this frame, use the eye of ender on the frame.", on_place = function(itemstack, user, pointed_thing) local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] --new -- If used on frame, open portal - if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_nether:red_nether_brick" then + if pointed_thing.under and minetest.get_node(pointed_thing.under).name == portal_frame then make_end_portal(pointed_thing.under) minetest.sound_play( "fire_flint_and_steel", From 54dc6e8ffbcefa99c22dc1faf68e39d83365f3aa Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 01:33:36 +0200 Subject: [PATCH 20/75] Remove some portal hackery --- mods/MAPGEN/mcl_portals/portal_end.lua | 5 ++--- mods/MAPGEN/mcl_portals/portal_nether.lua | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index 1119814c8..d9cc1b64d 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -274,11 +274,11 @@ minetest.register_abm({ minetest.emerge_area( vector.subtract(target3, 4), vector.add(target3, 4)) end + -- teleport the player minetest.after(3, function(obj, pos, target3) local objpos = obj:getpos() if objpos == nil then return end --maikerumine added for objects to travel - objpos.y = objpos.y + 0.1 -- Fix some glitches at -8000. FIXME: WTF? if minetest.get_node(objpos).name ~= "mcl_portals:portal_end" then return end @@ -289,13 +289,12 @@ minetest.register_abm({ if n and n.name ~= "mcl_portals:portal_end" then build_end_portal(target3, pos) minetest.after(2, check_and_build_end_portal, pos, target3) - minetest.after(4, check_and_build_end_portal, pos, target3) elseif not n then minetest.after(1, check_and_build_end_portal, pos, target3) end end - minetest.after(1, check_and_build_end_portal, pos, target3) + check_and_build_end_portal(pos, target3) -- Teleport obj:setpos(target3) diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index c8c875eb0..21526e2e0 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -294,7 +294,6 @@ minetest.register_abm({ -- teleport the player minetest.after(3, function(obj, pos, target) local objpos = obj:getpos() if objpos == nil then return end --maikerumine added for objects to travel - objpos.y = objpos.y + 0.1 -- Fix some glitches at -8000 if minetest.get_node(objpos).name ~= "mcl_portals:portal" then return end @@ -305,13 +304,12 @@ minetest.register_abm({ if n and n.name ~= "mcl_portals:portal" then build_portal(target, pos) minetest.after(2, check_and_build_portal, pos, target) - minetest.after(4, check_and_build_portal, pos, target) elseif not n then minetest.after(1, check_and_build_portal, pos, target) end end - minetest.after(1, check_and_build_portal, pos, target) + check_and_build_portal(pos, target) -- Teleport obj:setpos(target) From acad50ae5ff147db0b1c511dd44ebd043be9afaf Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 01:58:17 +0200 Subject: [PATCH 21/75] Allow to teleport back to overworld --- mods/MAPGEN/mcl_portals/portal_end.lua | 7 +++---- mods/MAPGEN/mcl_portals/portal_nether.lua | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index d9cc1b64d..c476890b2 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -1,6 +1,5 @@ -- Parameters -local END_DEPTH = mcl_vars.mg_end_min local TCAVE = 0.6 local nobj_cave = nil -- 3D noise @@ -118,7 +117,7 @@ local function build_end_portal(pos, target3) end local function find_end_target3_y2(target3_x, target3_z) - local start_y = END_DEPTH + math.random(20, 120) -- Search start + local start_y = mcl_vars.mg_end_min + math.random(20, 120) -- Search start if not nobj_cave then nobj_cave = minetest.get_perlin(np_cave) end @@ -229,8 +228,8 @@ local function make_end_portal(pos) local target3 = {x = p1.x, y = p1.y, z = p1.z} target3.x = target3.x + 1 - if target3.y < END_DEPTH then - target3.y = math.random(-52, 100) + if target3.y < mcl_vars.mg_end_max and target3.y > mcl_vars.mg_end_min then + target3.y = math.random(mcl_vars.mg_overworld_min + 40, mcl_vars.mg_overworld_min + 96) else target3.y = find_end_target3_y2(target3.x, target3.z) end diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index 21526e2e0..bf96af874 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -1,6 +1,5 @@ -- Parameters -local NETHER_DEPTH = mcl_vars.mg_nether_min local TCAVE = 0.6 local nobj_cave = nil @@ -117,7 +116,7 @@ local function build_portal(pos, target) end local function find_nether_target_y(target_x, target_z) - local start_y = NETHER_DEPTH + math.random(38, 117) -- Search start + local start_y = mcl_vars.mg_nether_min + math.random(38, 117) -- Search start if not nobj_cave then nobj_cave = minetest.get_perlin(np_cave) end @@ -228,8 +227,8 @@ local function make_portal(pos) local target = {x = p1.x, y = p1.y, z = p1.z} target.x = target.x + 1 - if target.y < NETHER_DEPTH then - target.y = math.random(-52, 100) + if target.y < mcl_vars.mg_nether_max and target.y > mcl_vars.mg_nether_min then + target.y = math.random(mcl_vars.mg_overworld_min + 40, mcl_vars.mg_overworld_min + 96) else target.y = find_nether_target_y(target.x, target.z) end From 272c456499207a655e5e0ab9406478e52f1a5f6a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 02:17:45 +0200 Subject: [PATCH 22/75] Portals are piston stoppers --- mods/ITEMS/REDSTONE/mesecons_mvps/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua index 8c1718e04..89d51b035 100644 --- a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua @@ -203,3 +203,5 @@ mesecon:register_mvps_stopper("mesecons_solarpanel:solar_panel_inverted_off") mesecon:register_mvps_stopper("mesecons_solarpanel:solar_panel_inverted_on") mesecon:register_mvps_stopper("mesecons_noteblock:noteblock") mesecon:register_mvps_stopper("3d_armor_stand:armor_stand") +mesecon:register_mvps_stopper("mcl_portals:portal") +mesecon:register_mvps_stopper("mcl_portals:portal_end") From 6018f0c7cdd2bba93219f330350e456e75d1848b Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 03:27:31 +0200 Subject: [PATCH 23/75] Proper portal behaviour WRT explosions --- mods/MAPGEN/mcl_portals/portal_end.lua | 109 ++++++++++----------- mods/MAPGEN/mcl_portals/portal_nether.lua | 111 +++++++++++----------- 2 files changed, 110 insertions(+), 110 deletions(-) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index c476890b2..c97ecd0a8 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -16,6 +16,52 @@ local np_cave = { -- Portal frame material local portal_frame = "mcl_nether:quartz_block" +-- Destroy portal if pos (portal frame or portal node) got destroyed +local destroy_portal = function(pos) + -- Deactivate Nether portal + local meta = minetest.get_meta(pos) + local p1 = minetest.string_to_pos(meta:get_string("p1")) + local p2 = minetest.string_to_pos(meta:get_string("p2")) + if not p1 or not p2 then + return + end + + local first = true + + -- p1 metadata of first node + local mp1 + for x = p1.x, p2.x do + for y = p1.y, p2.y do + for z = p1.z, p2.z do + local p = vector.new(x, y, z) + local m = minetest.get_meta(p) + if first then + --[[ Only proceed if the first node still has metadata. + If it doesn't have metadata, another node propably triggred the delection + routine earlier, so we bail out earlier to avoid an infinite cascade + of on_destroy events. ]] + mp1 = minetest.string_to_pos(m:get_string("p1")) + if not mp1 then + return + end + end + local nn = minetest.get_node(p).name + if nn == portal_frame or nn == "mcl_portals:portal_end" then + -- Remove portal nodes, but not myself + if nn == "mcl_portals:portal_end" and not vector.equals(p, pos) then + minetest.remove_node(p) + end + -- Clear metadata of portal nodes and the frame + m:set_string("p1", "") + m:set_string("p2", "") + m:set_string("target", "") + end + first = false + end + end + end +end + -- Nodes minetest.register_node("mcl_portals:portal_end", { description = "End Portal", @@ -64,7 +110,11 @@ minetest.register_node("mcl_portals:portal_end", { {-0.5, -0.5, -0.1, 0.5, 0.5, 0.1}, }, }, - groups = {not_in_creative_inventory = 1} + groups = {not_in_creative_inventory = 1}, + on_destruct = destroy_portal, + + _mcl_hardness = -1, + _mcl_blast_resistance = 18000000, }) local function build_end_portal(pos, target3) @@ -311,59 +361,7 @@ minetest.register_abm({ -- Frame material minetest.override_item(portal_frame, { - on_destruct = function(pos) - local meta = minetest.get_meta(pos) - local p1 = minetest.string_to_pos(meta:get_string("p1")) - local p2 = minetest.string_to_pos(meta:get_string("p2")) - local target3 = minetest.string_to_pos(meta:get_string("target3")) - if not p1 or not p2 then - return - end - - for x = p1.x, p2.x do - for y = p1.y, p2.y do - for z = p1.z, p2.z do - local nn = minetest.get_node({x = x, y = y, z = z}).name - if nn == portal_frame or nn == "mcl_portals:portal_end" then - if nn == "mcl_portals:portal_end" then - minetest.remove_node({x = x, y = y, z = z}) - end - local m = minetest.get_meta({x = x, y = y, z = z}) - m:set_string("p1", "") - m:set_string("p2", "") - m:set_string("target3", "") - end - end - end - end - - meta = minetest.get_meta(target3) - if not meta then - return - end - p1 = minetest.string_to_pos(meta:get_string("p1")) - p2 = minetest.string_to_pos(meta:get_string("p2")) - if not p1 or not p2 then - return - end - - for x = p1.x, p2.x do - for y = p1.y, p2.y do - for z = p1.z, p2.z do - local nn = minetest.get_node({x = x, y = y, z = z}).name - if nn == portal_frame or nn == "mcl_portals:portal_end" then - if nn == "mcl_portals:portal_end" then - minetest.remove_node({x = x, y = y, z = z}) - end - local m = minetest.get_meta({x = x, y = y, z = z}) - m:set_string("p1", "") - m:set_string("p2", "") - m:set_string("target3", "") - end - end - end - end - end, + on_destruct = destroy_portal, }) -- Portal opener @@ -376,6 +374,9 @@ minetest.override_item("mcl_end:ender_eye", { -- If used on frame, open portal if pointed_thing.under and minetest.get_node(pointed_thing.under).name == portal_frame then make_end_portal(pointed_thing.under) + if minetest.get_modpath("doc") then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal_end") + end minetest.sound_play( "fire_flint_and_steel", {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8} diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index bf96af874..0ce368273 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -13,6 +13,52 @@ local np_cave = { persist = 0.7 } +-- Destroy portal if pos (portal frame or portal node) got destroyed +local destroy_portal = function(pos) + -- Deactivate Nether portal + local meta = minetest.get_meta(pos) + local p1 = minetest.string_to_pos(meta:get_string("p1")) + local p2 = minetest.string_to_pos(meta:get_string("p2")) + if not p1 or not p2 then + return + end + + local first = true + + -- p1 metadata of first node + local mp1 + for x = p1.x, p2.x do + for y = p1.y, p2.y do + for z = p1.z, p2.z do + local p = vector.new(x, y, z) + local m = minetest.get_meta(p) + if first then + --[[ Only proceed if the first node still has metadata. + If it doesn't have metadata, another node propably triggred the delection + routine earlier, so we bail out earlier to avoid an infinite cascade + of on_destroy events. ]] + mp1 = minetest.string_to_pos(m:get_string("p1")) + if not mp1 then + return + end + end + local nn = minetest.get_node(p).name + if nn == "mcl_core:obsidian" or nn == "mcl_portals:portal" then + -- Remove portal nodes, but not myself + if nn == "mcl_portals:portal" and not vector.equals(p, pos) then + minetest.remove_node(p) + end + -- Clear metadata of portal nodes and the frame + m:set_string("p1", "") + m:set_string("p2", "") + m:set_string("target", "") + end + first = false + end + end + end +end + minetest.register_node("mcl_portals:portal", { description = "Nether Portal", tiles = { @@ -59,11 +105,13 @@ minetest.register_node("mcl_portals:portal", { {-0.5, -0.5, -0.1, 0.5, 0.5, 0.1}, }, }, - groups = {not_in_creative_inventory = 1} + groups = {not_in_creative_inventory = 1}, + on_destruct = destroy_portal, + + _mcl_hardness = -1, + _mcl_blast_resistance = 0, }) - - -- Functions --Build arrival portal local function build_portal(pos, target) @@ -327,59 +375,7 @@ minetest.register_abm({ -- Frame material minetest.override_item("mcl_core:obsidian", { - on_destruct = function(pos) - local meta = minetest.get_meta(pos) - local p1 = minetest.string_to_pos(meta:get_string("p1")) - local p2 = minetest.string_to_pos(meta:get_string("p2")) - local target = minetest.string_to_pos(meta:get_string("target")) - if not p1 or not p2 then - return - end - - for x = p1.x, p2.x do - for y = p1.y, p2.y do - for z = p1.z, p2.z do - local nn = minetest.get_node({x = x, y = y, z = z}).name - if nn == "mcl_core:obsidian" or nn == "mcl_portals:portal" then - if nn == "mcl_portals:portal" then - minetest.remove_node({x = x, y = y, z = z}) - end - local m = minetest.get_meta({x = x, y = y, z = z}) - m:set_string("p1", "") - m:set_string("p2", "") - m:set_string("target", "") - end - end - end - end - - meta = minetest.get_meta(target) - if not meta then - return - end - p1 = minetest.string_to_pos(meta:get_string("p1")) - p2 = minetest.string_to_pos(meta:get_string("p2")) - if not p1 or not p2 then - return - end - - for x = p1.x, p2.x do - for y = p1.y, p2.y do - for z = p1.z, p2.z do - local nn = minetest.get_node({x = x, y = y, z = z}).name - if nn == "mcl_core:obsidian" or nn == "mcl_portals:portal" then - if nn == "mcl_portals:portal" then - minetest.remove_node({x = x, y = y, z = z}) - end - local m = minetest.get_meta({x = x, y = y, z = z}) - m:set_string("p1", "") - m:set_string("p2", "") - m:set_string("target", "") - end - end - end - end - end, + on_destruct = destroy_portal, }) -- Portal opener @@ -396,6 +392,9 @@ minetest.override_item("mcl_fire:flint_and_steel", { if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_core:obsidian" then make_portal(pointed_thing.under) + if minetest.get_modpath("doc") then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal") + end else if pointed_thing.type == "node" then local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] From 29873b96c1f980c0e6a80da71d6b13810aeae152 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 03:43:26 +0200 Subject: [PATCH 24/75] Rename portal node metadata --- mods/MAPGEN/mcl_portals/portal_end.lua | 30 +++++++++++++---------- mods/MAPGEN/mcl_portals/portal_nether.lua | 30 +++++++++++++---------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index c97ecd0a8..3fa1de6b3 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -20,8 +20,8 @@ local portal_frame = "mcl_nether:quartz_block" local destroy_portal = function(pos) -- Deactivate Nether portal local meta = minetest.get_meta(pos) - local p1 = minetest.string_to_pos(meta:get_string("p1")) - local p2 = minetest.string_to_pos(meta:get_string("p2")) + local p1 = minetest.string_to_pos(meta:get_string("portal_frame1")) + local p2 = minetest.string_to_pos(meta:get_string("portal_frame2")) if not p1 or not p2 then return end @@ -40,7 +40,7 @@ local destroy_portal = function(pos) If it doesn't have metadata, another node propably triggred the delection routine earlier, so we bail out earlier to avoid an infinite cascade of on_destroy events. ]] - mp1 = minetest.string_to_pos(m:get_string("p1")) + mp1 = minetest.string_to_pos(m:get_string("portal_frame1")) if not mp1 then return end @@ -52,9 +52,9 @@ local destroy_portal = function(pos) minetest.remove_node(p) end -- Clear metadata of portal nodes and the frame - m:set_string("p1", "") - m:set_string("p2", "") - m:set_string("target", "") + m:set_string("portal_frame1", "") + m:set_string("portal_frame2", "") + m:set_string("portal_target", "") end first = false end @@ -146,9 +146,9 @@ local function build_end_portal(pos, target3) minetest.set_node(p, {name = "mcl_portals:portal_end", param2 = 0}) end local meta = minetest.get_meta(p) - meta:set_string("p1", minetest.pos_to_string(p1)) - meta:set_string("p2", minetest.pos_to_string(p2)) - meta:set_string("target3", minetest.pos_to_string(target3)) + meta:set_string("portal_frame1", minetest.pos_to_string(p1)) + meta:set_string("portal_frame2", minetest.pos_to_string(p2)) + meta:set_string("portal_target", minetest.pos_to_string(target3)) if y ~= p1.y then for z = -2, 2 do @@ -296,9 +296,13 @@ local function make_end_portal(pos) minetest.set_node(p, {name = "mcl_portals:portal_end", param2 = param2}) end local meta = minetest.get_meta(p) - meta:set_string("p1", minetest.pos_to_string(p1)) - meta:set_string("p2", minetest.pos_to_string(p2)) - meta:set_string("target3", minetest.pos_to_string(target3)) + + -- Portal frame corners + meta:set_string("portal_frame1", minetest.pos_to_string(p1)) + meta:set_string("portal_frame2", minetest.pos_to_string(p2)) + + -- Portal target coordinates + meta:set_string("portal_target", minetest.pos_to_string(target3)) end end @@ -315,7 +319,7 @@ minetest.register_abm({ local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel if obj:is_player() or lua_entity then local meta = minetest.get_meta(pos) - local target3 = minetest.string_to_pos(meta:get_string("target3")) + local target3 = minetest.string_to_pos(meta:get_string("portal_target")) if target3 then -- force emerge of target3 area minetest.get_voxel_manip():read_from_map(target3, target3) diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index 0ce368273..974565398 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -17,8 +17,8 @@ local np_cave = { local destroy_portal = function(pos) -- Deactivate Nether portal local meta = minetest.get_meta(pos) - local p1 = minetest.string_to_pos(meta:get_string("p1")) - local p2 = minetest.string_to_pos(meta:get_string("p2")) + local p1 = minetest.string_to_pos(meta:get_string("portal_frame1")) + local p2 = minetest.string_to_pos(meta:get_string("portal_frame2")) if not p1 or not p2 then return end @@ -37,7 +37,7 @@ local destroy_portal = function(pos) If it doesn't have metadata, another node propably triggred the delection routine earlier, so we bail out earlier to avoid an infinite cascade of on_destroy events. ]] - mp1 = minetest.string_to_pos(m:get_string("p1")) + mp1 = minetest.string_to_pos(m:get_string("portal_frame1")) if not mp1 then return end @@ -49,9 +49,9 @@ local destroy_portal = function(pos) minetest.remove_node(p) end -- Clear metadata of portal nodes and the frame - m:set_string("p1", "") - m:set_string("p2", "") - m:set_string("target", "") + m:set_string("portal_frame1", "") + m:set_string("portal_frame2", "") + m:set_string("portal_target", "") end first = false end @@ -143,9 +143,9 @@ local function build_portal(pos, target) minetest.set_node(p, {name = "mcl_portals:portal", param2 = 0}) end local meta = minetest.get_meta(p) - meta:set_string("p1", minetest.pos_to_string(p1)) - meta:set_string("p2", minetest.pos_to_string(p2)) - meta:set_string("target", minetest.pos_to_string(target)) + meta:set_string("portal_frame1", minetest.pos_to_string(p1)) + meta:set_string("portal_frame2", minetest.pos_to_string(p2)) + meta:set_string("portal_target", minetest.pos_to_string(target)) if y ~= p1.y then for z = -2, 2 do @@ -294,9 +294,13 @@ local function make_portal(pos) minetest.set_node(p, {name = "mcl_portals:portal", param2 = param2}) end local meta = minetest.get_meta(p) - meta:set_string("p1", minetest.pos_to_string(p1)) - meta:set_string("p2", minetest.pos_to_string(p2)) - meta:set_string("target", minetest.pos_to_string(target)) + + -- Portal frame corners + meta:set_string("portal_frame1", minetest.pos_to_string(p1)) + meta:set_string("portal_frame2", minetest.pos_to_string(p2)) + + -- Portal target coordinates + meta:set_string("portal_target", minetest.pos_to_string(target)) end end @@ -330,7 +334,7 @@ minetest.register_abm({ local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel if obj:is_player() or lua_entity then local meta = minetest.get_meta(pos) - local target = minetest.string_to_pos(meta:get_string("target")) + local target = minetest.string_to_pos(meta:get_string("portal_target")) if target then -- force emerge of target area minetest.get_voxel_manip():read_from_map(target, target) From 817c52f92f053359d8d56ca77d3e9be607558609 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 04:12:34 +0200 Subject: [PATCH 25/75] Fix bugs in flint and ssteel and ender eye --- mods/ITEMS/mcl_fire/flint_and_steel.lua | 6 ++-- mods/ITEMS/mcl_fire/init.lua | 3 +- mods/ITEMS/mcl_tnt/init.lua | 4 +-- mods/MAPGEN/mcl_portals/portal_end.lua | 33 +++++++++++------- mods/MAPGEN/mcl_portals/portal_nether.lua | 42 +++++------------------ 5 files changed, 35 insertions(+), 53 deletions(-) diff --git a/mods/ITEMS/mcl_fire/flint_and_steel.lua b/mods/ITEMS/mcl_fire/flint_and_steel.lua index 8902c1604..91e46861b 100644 --- a/mods/ITEMS/mcl_fire/flint_and_steel.lua +++ b/mods/ITEMS/mcl_fire/flint_and_steel.lua @@ -1,8 +1,8 @@ -- Flint and Steel minetest.register_tool("mcl_fire:flint_and_steel", { description = "Flint and Steel", - _doc_items_longdesc = "Flint and steel is a tool to start fires and ignite blocks.", - _doc_items_usagehelp = "Rightclick the surface of a block to attempt to light a fire in front of it. On netherrack and magma blocks it will start an eternal fire. Using it on TNT will ignite it.", + _doc_items_longdesc = "Flint and steel is a tool to start fires, ignite blocks and open portals.", + _doc_items_usagehelp = "Rightclick the surface of a block to attempt to light a fire in front of it. On netherrack it will start an eternal fire. Using it on TNT will ignite it. To open a Nether portal, place an upright frame of obsidian with a length of 4 and a height of 5 blocks, leaving only air in the center. After placing this frame, use the flint and steel on inside of the frame.", inventory_image = "mcl_fire_flint_and_steel.png", liquids_pointable = false, stack_max = 1, @@ -25,7 +25,7 @@ minetest.register_tool("mcl_fire:flint_and_steel", { if pointed_thing.type == "node" then local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] if nodedef and nodedef._on_ignite then - nodedef._on_ignite(pointed_thing.under, user) + nodedef._on_ignite(user, pointed_thing) else mcl_fire.set_fire(pointed_thing) end diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua index 7c542c73e..0f0313a9d 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -376,7 +376,8 @@ local eternal_override = { minetest.remove_node(pos) end end, - _on_ignite = function(pos, player) + _on_ignite = function(player, pointed_thing) + local pos = pointed_thing.under local flame_pos = {x = pos.x, y = pos.y + 1, z = pos.z} if minetest.get_node(flame_pos).name == "air" then minetest.set_node(flame_pos, {name = "mcl_fire:eternal_fire"}) diff --git a/mods/ITEMS/mcl_tnt/init.lua b/mods/ITEMS/mcl_tnt/init.lua index 4d0f59961..3e9a3c01f 100644 --- a/mods/ITEMS/mcl_tnt/init.lua +++ b/mods/ITEMS/mcl_tnt/init.lua @@ -71,8 +71,8 @@ minetest.register_node("mcl_tnt:tnt", { mesecons = {effector = { action_on = tnt.ignite }}, - _on_ignite = function(pos, player) - tnt.ignite(pos) + _on_ignite = function(player, pointed_thing) + tnt.ignite(pointed_thing.under) end, sounds = sounds, }) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index 3fa1de6b3..81c2aad6f 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -373,20 +373,27 @@ minetest.override_item("mcl_end:ender_eye", { _doc_items_longdesc = "An eye of ander can be used to open a portal to the End.", _doc_items_usagehelp = "To open an End portal, place an upright frame of quartz blocks with a length of 4 and a height of 5 blocks, leaving only air in the center. After placing this frame, use the eye of ender on the frame.", on_place = function(itemstack, user, pointed_thing) - local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] --new - - -- If used on frame, open portal - if pointed_thing.under and minetest.get_node(pointed_thing.under).name == portal_frame then - make_end_portal(pointed_thing.under) - if minetest.get_modpath("doc") then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal_end") + -- Use pointed node's on_rightclick function first, if present + local node = minetest.get_node(pointed_thing.under) + if user and not user:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack end - minetest.sound_play( - "fire_flint_and_steel", - {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8} - ) - if not minetest.setting_getbool("creative_mode") and used == true then - itemstack:take_item() -- 1 use + end + + -- If used on portal frame, open a portal + if pointed_thing.under and node.name == portal_frame then + local opened = make_end_portal(pointed_thing.under) + if opened then + if minetest.get_modpath("doc") then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal_end") + end + minetest.sound_play( + "fire_flint_and_steel", + {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 16}) + if not minetest.settings:get_bool("creative_mode") then + itemstack:take_item() -- 1 use + end end end diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index 974565398..09ac74c42 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -380,43 +380,17 @@ minetest.register_abm({ -- Frame material minetest.override_item("mcl_core:obsidian", { on_destruct = destroy_portal, -}) - --- Portal opener -minetest.override_item("mcl_fire:flint_and_steel", { - _doc_items_longdesc = "Flint and steel is a tool to start fires, ignite blocks and open portals.", - _doc_items_usagehelp = "Rightclick the surface of a block to attempt to light a fire in front of it. On netherrack it will start an eternal fire. Using it on TNT will ignite it. To open a Nether portal, place an upright frame of obsidian with a length of 4 and a height of 5 blocks, leaving only air in the center. After placing this frame, use the flint and steel on inside of the frame.", - on_place = function(itemstack, user, pointed_thing) - local idef = itemstack:get_definition() - minetest.sound_play( - "fire_flint_and_steel", - {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8} - ) - local used = false - - if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_core:obsidian" then - make_portal(pointed_thing.under) - if minetest.get_modpath("doc") then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal") - end + _on_ignite = function(user, pointed_thing) + local pos = pointed_thing.under + local portal_placed = make_portal(pos) + if portal_placed and minetest.get_modpath("doc") then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal") else - if pointed_thing.type == "node" then - local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] - if nodedef._on_ignite then - nodedef._on_ignite(pointed_thing.under, user) - else - mcl_fire.set_fire(pointed_thing) - end - used = true + local node = minetest.get_node(pointed_thing.above) + if node.name ~= "mcl_portals:portal" then + mcl_fire.set_fire(pointed_thing) end end - if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then - minetest.sound_play(idef.sound.breaks, {pos=user:getpos(), gain=0.5}) - end - if not minetest.setting_getbool("creative_mode") and used == true then - itemstack:add_wear(65535/65) -- 65 uses - end - return itemstack end, }) From 3e3e9f39314e1b852c136436f912bf90b4aa0e63 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 04:21:59 +0200 Subject: [PATCH 26/75] Fix player pos detection in portals --- mods/MAPGEN/mcl_portals/portal_end.lua | 3 +++ mods/MAPGEN/mcl_portals/portal_nether.lua | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index 81c2aad6f..75ef9415f 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -331,6 +331,9 @@ minetest.register_abm({ -- teleport the player minetest.after(3, function(obj, pos, target3) local objpos = obj:getpos() + -- If player stands, player is at ca. something+0.5 + -- which might cause precision problems, so we used ceil. + objpos.y = math.ceil(objpos.y) if objpos == nil then return end --maikerumine added for objects to travel if minetest.get_node(objpos).name ~= "mcl_portals:portal_end" then return diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index 09ac74c42..e99cace5f 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -344,7 +344,14 @@ minetest.register_abm({ end -- teleport the player minetest.after(3, function(obj, pos, target) - local objpos = obj:getpos() if objpos == nil then return end --maikerumine added for objects to travel + local objpos = obj:getpos() + if objpos == nil then + return + end + -- If player stands, player is at ca. something+0.5 + -- which might cause precision problems, so we used ceil. + objpos.y = math.ceil(objpos.y) + if minetest.get_node(objpos).name ~= "mcl_portals:portal" then return end From 5c5c2ea1095a82a2ba9beef08b0b53c383cb45b3 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 04:36:08 +0200 Subject: [PATCH 27/75] Fix portal corner metadata being able to be killed This was possible by re-using the same frame for multiple portals. --- mods/MAPGEN/mcl_portals/portal_end.lua | 8 ++++++++ mods/MAPGEN/mcl_portals/portal_nether.lua | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/MAPGEN/mcl_portals/portal_end.lua index 75ef9415f..126e7ae32 100644 --- a/mods/MAPGEN/mcl_portals/portal_end.lua +++ b/mods/MAPGEN/mcl_portals/portal_end.lua @@ -199,6 +199,14 @@ local function move_check2(p1, max, dir) if minetest.get_node(p).name ~= portal_frame then return false end + -- Abort if any of the portal frame blocks already has metadata. + -- This mod does not yet portals which neighbor each other directly. + -- TODO: Reorganize the way how portal frame coordinates are stored. + local meta = minetest.get_meta(p) + local p1 = meta:get_string("portal_frame1") + if minetest.string_to_pos(p1) ~= nil then + return false + end end return true diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/MAPGEN/mcl_portals/portal_nether.lua index e99cace5f..3e6b28021 100644 --- a/mods/MAPGEN/mcl_portals/portal_nether.lua +++ b/mods/MAPGEN/mcl_portals/portal_nether.lua @@ -196,6 +196,14 @@ local function move_check(p1, max, dir) if minetest.get_node(p).name ~= "mcl_core:obsidian" then return false end + -- Abort if any of the portal frame blocks already has metadata. + -- This mod does not yet portals which neighbor each other directly. + -- TODO: Reorganize the way how portal frame coordinates are stored. + local meta = minetest.get_meta(p) + local p1 = meta:get_string("portal_frame1") + if minetest.string_to_pos(p1) ~= nil then + return false + end end return true From 02f46da152fdfb466ba5fdfd8ea7f9b0d6555c0a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 04:56:14 +0200 Subject: [PATCH 28/75] Fix some bugs WRT eternal fire spawning --- mods/ITEMS/mcl_fire/init.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua index 0f0313a9d..45eb44972 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -379,8 +379,11 @@ local eternal_override = { _on_ignite = function(player, pointed_thing) local pos = pointed_thing.under local flame_pos = {x = pos.x, y = pos.y + 1, z = pos.z} - if minetest.get_node(flame_pos).name == "air" then + local fn = minetest.get_node(flame_pos) + if fn.name == "air" and not minetest.is_protected(flame_pos, "fire") and pointed_thing.under.y < pointed_thing.above.y then minetest.set_node(flame_pos, {name = "mcl_fire:eternal_fire"}) + else + mcl_fire.set_fire(pointed_thing) end end, } @@ -393,7 +396,7 @@ end -- Set pointed_thing on (normal) fire mcl_fire.set_fire = function(pointed_thing) local n = minetest.get_node(pointed_thing.above) - if n.name ~= "" and n.name == "air" and not minetest.is_protected(pointed_thing.above, "fire") then + if n.name == "air" and not minetest.is_protected(pointed_thing.above, "fire") then minetest.add_node(pointed_thing.above, {name="mcl_fire:fire"}) end end From 073b55365a95aded022569437c0b71bf3a78623c Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 05:28:02 +0200 Subject: [PATCH 29/75] Remove buggy Nether holes --- mods/MAPGEN/mcl_biomes/init.lua | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 90cd3e15a..601498587 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -829,18 +829,6 @@ local function register_biomelike_ores() --[[ NETHER GENERATION ]] - -- Generate holes in Nether - -- TODO: Is this a good idea? - minetest.register_ore({ - ore_type = "puff", - ore = "air", - wherein = {"mcl_nether:netherrack"}, - clust_scarcity = 666, - clust_size = 4, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - noise_params = {offset=0, scale=15, spread={x=130, y=130, z=130}, seed=24, octaves=3, persist=0.60} - }) -- Soul sand minetest.register_ore({ From 4ac023a6aea18fcfa7ea6c51ba9edaf207319010 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 05:35:06 +0200 Subject: [PATCH 30/75] Make magma blocks more common --- mods/MAPGEN/mcl_biomes/init.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 601498587..4dfadfee1 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -855,8 +855,18 @@ local function register_biomelike_ores() ore_type = "blob", ore = "mcl_nether:magma", wherein = {"mcl_nether:netherrack"}, - clust_scarcity = 15*15*15, - clust_num_ores = 33, + clust_scarcity = 14*14*14, + clust_num_ores = 35, + clust_size = 4, + y_min = mcl_util.layer_to_y(23, "nether"), + y_max = mcl_util.layer_to_y(37, "nether"), + }) + minetest.register_ore({ + ore_type = "blob", + ore = "mcl_nether:magma", + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 9*9*9, + clust_num_ores = 50, clust_size = 5, y_min = mcl_util.layer_to_y(23, "nether"), y_max = mcl_util.layer_to_y(37, "nether"), From 04ec0929a8e644c5880c3a653120c2851afa2088 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 13:39:25 +0200 Subject: [PATCH 31/75] Move mcl_portals to ITEMS --- mods/{MAPGEN => ITEMS}/mcl_portals/LICENSE | 0 mods/{MAPGEN => ITEMS}/mcl_portals/README.md | 0 mods/{MAPGEN => ITEMS}/mcl_portals/depends.txt | 0 mods/{MAPGEN => ITEMS}/mcl_portals/description.txt | 0 mods/{MAPGEN => ITEMS}/mcl_portals/init.lua | 0 mods/{MAPGEN => ITEMS}/mcl_portals/mod.conf | 0 mods/{MAPGEN => ITEMS}/mcl_portals/portal_end.lua | 0 .../{MAPGEN => ITEMS}/mcl_portals/portal_nether.lua | 0 .../mcl_portals/sounds/mcl_portals_teleport.ogg | Bin .../mcl_portals/textures/mcl_portals_end_portal.png | Bin .../mcl_portals/textures/mcl_portals_particle.png | Bin .../mcl_portals/textures/mcl_portals_portal.png | Bin 12 files changed, 0 insertions(+), 0 deletions(-) rename mods/{MAPGEN => ITEMS}/mcl_portals/LICENSE (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/README.md (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/depends.txt (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/description.txt (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/init.lua (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/mod.conf (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/portal_end.lua (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/portal_nether.lua (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/sounds/mcl_portals_teleport.ogg (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/textures/mcl_portals_end_portal.png (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/textures/mcl_portals_particle.png (100%) rename mods/{MAPGEN => ITEMS}/mcl_portals/textures/mcl_portals_portal.png (100%) diff --git a/mods/MAPGEN/mcl_portals/LICENSE b/mods/ITEMS/mcl_portals/LICENSE similarity index 100% rename from mods/MAPGEN/mcl_portals/LICENSE rename to mods/ITEMS/mcl_portals/LICENSE diff --git a/mods/MAPGEN/mcl_portals/README.md b/mods/ITEMS/mcl_portals/README.md similarity index 100% rename from mods/MAPGEN/mcl_portals/README.md rename to mods/ITEMS/mcl_portals/README.md diff --git a/mods/MAPGEN/mcl_portals/depends.txt b/mods/ITEMS/mcl_portals/depends.txt similarity index 100% rename from mods/MAPGEN/mcl_portals/depends.txt rename to mods/ITEMS/mcl_portals/depends.txt diff --git a/mods/MAPGEN/mcl_portals/description.txt b/mods/ITEMS/mcl_portals/description.txt similarity index 100% rename from mods/MAPGEN/mcl_portals/description.txt rename to mods/ITEMS/mcl_portals/description.txt diff --git a/mods/MAPGEN/mcl_portals/init.lua b/mods/ITEMS/mcl_portals/init.lua similarity index 100% rename from mods/MAPGEN/mcl_portals/init.lua rename to mods/ITEMS/mcl_portals/init.lua diff --git a/mods/MAPGEN/mcl_portals/mod.conf b/mods/ITEMS/mcl_portals/mod.conf similarity index 100% rename from mods/MAPGEN/mcl_portals/mod.conf rename to mods/ITEMS/mcl_portals/mod.conf diff --git a/mods/MAPGEN/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua similarity index 100% rename from mods/MAPGEN/mcl_portals/portal_end.lua rename to mods/ITEMS/mcl_portals/portal_end.lua diff --git a/mods/MAPGEN/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua similarity index 100% rename from mods/MAPGEN/mcl_portals/portal_nether.lua rename to mods/ITEMS/mcl_portals/portal_nether.lua diff --git a/mods/MAPGEN/mcl_portals/sounds/mcl_portals_teleport.ogg b/mods/ITEMS/mcl_portals/sounds/mcl_portals_teleport.ogg similarity index 100% rename from mods/MAPGEN/mcl_portals/sounds/mcl_portals_teleport.ogg rename to mods/ITEMS/mcl_portals/sounds/mcl_portals_teleport.ogg diff --git a/mods/MAPGEN/mcl_portals/textures/mcl_portals_end_portal.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_end_portal.png similarity index 100% rename from mods/MAPGEN/mcl_portals/textures/mcl_portals_end_portal.png rename to mods/ITEMS/mcl_portals/textures/mcl_portals_end_portal.png diff --git a/mods/MAPGEN/mcl_portals/textures/mcl_portals_particle.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_particle.png similarity index 100% rename from mods/MAPGEN/mcl_portals/textures/mcl_portals_particle.png rename to mods/ITEMS/mcl_portals/textures/mcl_portals_particle.png diff --git a/mods/MAPGEN/mcl_portals/textures/mcl_portals_portal.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_portal.png similarity index 100% rename from mods/MAPGEN/mcl_portals/textures/mcl_portals_portal.png rename to mods/ITEMS/mcl_portals/textures/mcl_portals_portal.png From 556370c4039c37f242d94f48fd1f316ba84eb07c Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 13:40:39 +0200 Subject: [PATCH 32/75] Add portal textures to conversion list --- tools/Texture_Conversion_Table.csv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/Texture_Conversion_Table.csv b/tools/Texture_Conversion_Table.csv index a938e79bc..836004a0f 100644 --- a/tools/Texture_Conversion_Table.csv +++ b/tools/Texture_Conversion_Table.csv @@ -843,3 +843,5 @@ Source path,Source file,Target path,Target file,xs,ys,xl,yl,xt,yt /assets/minecraft/textures/entity/banner,base.png,/mods/ITEMS/mcl_banners/textures,mcl_banners_base.png,,,,,, /assets/minecraft/textures/items,banner_base.png,/mods/ITEMS/mcl_banners/textures,mcl_banners_item_base.png,,,,,, /assets/minecraft/textures/items,banner_overlay.png,/mods/ITEMS/mcl_banners/textures,mcl_banners_item_overlay.png,,,,,, +/assets/minecraft/textures/blocks,portal.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_portal.png,,,,,, +/assets/minecraft/textures/entity,end_portal.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_end_portal.png,,,,,, From f2bee2286f364c8acb1f37b52a617d2d23c9216c Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 13:53:54 +0200 Subject: [PATCH 33/75] Make fire charge a normal igniter, too --- mods/ITEMS/mcl_fire/fire_charge.lua | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/mods/ITEMS/mcl_fire/fire_charge.lua b/mods/ITEMS/mcl_fire/fire_charge.lua index dc3af8dd0..83612b870 100644 --- a/mods/ITEMS/mcl_fire/fire_charge.lua +++ b/mods/ITEMS/mcl_fire/fire_charge.lua @@ -15,17 +15,16 @@ minetest.register_craftitem("mcl_fire:fire_charge", { end end + -- Ignite/light fire if pointed_thing.type == "node" then - if minetest.get_node(pointed_thing.under).name == "mcl_tnt:tnt" then - tnt.ignite(pointed_thing.under) - if not minetest.settings:get_bool("creative_mode") then - itemstack:take_item() - end + local nodedef = minetest.registered_nodes[node.name] + if nodedef and nodedef._on_ignite then + nodedef._on_ignite(user, pointed_thing) else mcl_fire.set_fire(pointed_thing) - if not minetest.settings:get_bool("creative_mode") then - itemstack:take_item() - end + end + if not minetest.settings:get_bool("creative_mode") then + itemstack:take_item() end end return itemstack From 130f05b9cd39c30f9606b690234d7173d6918278 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 15:08:07 +0200 Subject: [PATCH 34/75] Nether portals now work without corners, too --- mods/ITEMS/mcl_portals/portal_nether.lua | 57 ++++++++++++++---------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 3e6b28021..1378bc015 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -23,17 +23,17 @@ local destroy_portal = function(pos) return end - local first = true + local counter = 1 - -- p1 metadata of first node local mp1 for x = p1.x, p2.x do for y = p1.y, p2.y do for z = p1.z, p2.z do local p = vector.new(x, y, z) local m = minetest.get_meta(p) - if first then - --[[ Only proceed if the first node still has metadata. + if counter == 2 then + --[[ Only proceed if the second node still has metadata. + (first node is a corner and not needed for the portal) If it doesn't have metadata, another node propably triggred the delection routine earlier, so we bail out earlier to avoid an infinite cascade of on_destroy events. ]] @@ -53,7 +53,7 @@ local destroy_portal = function(pos) m:set_string("portal_frame2", "") m:set_string("portal_target", "") end - first = false + counter = counter + 1 end end end @@ -139,13 +139,15 @@ local function build_portal(pos, target) for x = p1.x, p2.x do for y = p1.y, p2.y do p = {x = x, y = y, z = p1.z} - if not (x == p1.x or x == p2.x or y == p1.y or y == p2.y) then - minetest.set_node(p, {name = "mcl_portals:portal", param2 = 0}) + if not ((x == p1.x or x == p2.x) and (y == p1.y or y == p2.y)) then + if not (x == p1.x or x == p2.x or y == p1.y or y == p2.y) then + minetest.set_node(p, {name = "mcl_portals:portal", param2 = 0}) + end + local meta = minetest.get_meta(p) + meta:set_string("portal_frame1", minetest.pos_to_string(p1)) + meta:set_string("portal_frame2", minetest.pos_to_string(p2)) + meta:set_string("portal_target", minetest.pos_to_string(target)) end - local meta = minetest.get_meta(p) - meta:set_string("portal_frame1", minetest.pos_to_string(p1)) - meta:set_string("portal_frame2", minetest.pos_to_string(p2)) - meta:set_string("portal_target", minetest.pos_to_string(target)) if y ~= p1.y then for z = -2, 2 do @@ -189,20 +191,25 @@ end local function move_check(p1, max, dir) local p = {x = p1.x, y = p1.y, z = p1.z} - local d = math.abs(max - p1[dir]) / (max - p1[dir]) + local d = math.sign(max - p1[dir]) + local min = p[dir] - while p[dir] ~= max do - p[dir] = p[dir] + d - if minetest.get_node(p).name ~= "mcl_core:obsidian" then + for k = min, max, d do + p[dir] = k + local node = minetest.get_node(p) + -- Check for obsidian (except at corners) + if k ~= min and k ~= max and node.name ~= "mcl_core:obsidian" then return false end -- Abort if any of the portal frame blocks already has metadata. -- This mod does not yet portals which neighbor each other directly. -- TODO: Reorganize the way how portal frame coordinates are stored. - local meta = minetest.get_meta(p) - local p1 = meta:get_string("portal_frame1") - if minetest.string_to_pos(p1) ~= nil then - return false + if node.name == "mcl_core:obsidian" then + local meta = minetest.get_meta(p) + local pframe1 = meta:get_string("portal_frame1") + if minetest.string_to_pos(pframe1) ~= nil then + return false + end end end @@ -289,16 +296,17 @@ local function make_portal(pos) target.y = find_nether_target_y(target.x, target.z) end - for d = 0, 3 do - for y = p1.y, p2.y do - local p = {} + local dmin, dmax, ymin, ymax = 0, 3, p1.y, p2.y + for d = dmin, dmax do + for y = ymin, ymax do + if not ((d == dmin or d == dmax) and (y == ymin or y == ymax)) then + local p if param2 == 0 then p = {x = p1.x + d, y = y, z = p1.z} else p = {x = p1.x, y = y, z = p1.z + d} end - if minetest.get_node(p).name == "air" - then + if minetest.get_node(p).name == "air" then minetest.set_node(p, {name = "mcl_portals:portal", param2 = param2}) end local meta = minetest.get_meta(p) @@ -311,6 +319,7 @@ local function make_portal(pos) meta:set_string("portal_target", minetest.pos_to_string(target)) end end + end return true end From 3318c2f5f3de3183d49037d52f2ccfc8b02bfd53 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 15:20:10 +0200 Subject: [PATCH 35/75] Move Nether portal frame size into vars --- mods/ITEMS/mcl_portals/portal_nether.lua | 29 +++++++++++++++--------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 1378bc015..221af24ac 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -3,6 +3,12 @@ local TCAVE = 0.6 local nobj_cave = nil +-- Portal frame sizes +local FRAME_SIZE_X_MIN = 4 +local FRAME_SIZE_Y_MIN = 5 +local FRAME_SIZE_X_MAX = 23 +local FRAME_SIZE_Y_MAX = 23 + -- 3D noise local np_cave = { offset = 0, @@ -119,19 +125,19 @@ local function build_portal(pos, target) local p1 = {x = pos.x - 1, y = pos.y - 1, z = pos.z} local p2 = {x = p1.x + 3, y = p1.y + 4, z = p1.z} - for i = 1, 4 do + for i = 1, FRAME_SIZE_Y_MIN - 1 do minetest.set_node(p, {name = "mcl_core:obsidian"}) p.y = p.y + 1 end - for i = 1, 3 do + for i = 1, FRAME_SIZE_X_MIN - 1 do minetest.set_node(p, {name = "mcl_core:obsidian"}) p.x = p.x + 1 end - for i = 1, 4 do + for i = 1, FRAME_SIZE_Y_MIN - 1 do minetest.set_node(p, {name = "mcl_core:obsidian"}) p.y = p.y - 1 end - for i = 1, 3 do + for i = 1, FRAME_SIZE_X_MIN - 1 do minetest.set_node(p, {name = "mcl_core:obsidian"}) p.x = p.x - 1 end @@ -246,16 +252,17 @@ local function check_portal(p1, p2) end local function is_portal(pos) - for d = -3, 3 do - for y = -4, 4 do + local xsize, ysize = FRAME_SIZE_X_MIN-1, FRAME_SIZE_Y_MIN-1 + for d = -xsize, xsize do + for y = -ysize, ysize do local px = {x = pos.x + d, y = pos.y + y, z = pos.z} local pz = {x = pos.x, y = pos.y + y, z = pos.z + d} - if check_portal(px, {x = px.x + 3, y = px.y + 4, z = px.z}) then - return px, {x = px.x + 3, y = px.y + 4, z = px.z} + if check_portal(px, {x = px.x + xsize, y = px.y + ysize, z = px.z}) then + return px, {x = px.x + xsize, y = px.y + ysize, z = px.z} end - if check_portal(pz, {x = pz.x, y = pz.y + 4, z = pz.z + 3}) then - return pz, {x = pz.x, y = pz.y + 4, z = pz.z + 3} + if check_portal(pz, {x = pz.x, y = pz.y + ysize, z = pz.z + xsize}) then + return pz, {x = pz.x, y = pz.y + ysize, z = pz.z + xsize} end end end @@ -296,7 +303,7 @@ local function make_portal(pos) target.y = find_nether_target_y(target.x, target.z) end - local dmin, dmax, ymin, ymax = 0, 3, p1.y, p2.y + local dmin, dmax, ymin, ymax = 0, FRAME_SIZE_X_MIN - 1, p1.y, p2.y for d = dmin, dmax do for y = ymin, ymax do if not ((d == dmin or d == dmax) and (y == ymin or y == ymax)) then From 6dbd120397b30457de3e998e4422145eb5cef331 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 16:03:26 +0200 Subject: [PATCH 36/75] Fix End portal crash --- mods/ITEMS/mcl_portals/portal_end.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 126e7ae32..44f0e1436 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -339,10 +339,12 @@ minetest.register_abm({ -- teleport the player minetest.after(3, function(obj, pos, target3) local objpos = obj:getpos() + if objpos == nil then + return + end -- If player stands, player is at ca. something+0.5 -- which might cause precision problems, so we used ceil. objpos.y = math.ceil(objpos.y) - if objpos == nil then return end --maikerumine added for objects to travel if minetest.get_node(objpos).name ~= "mcl_portals:portal_end" then return end From 14678af2ed71c844f60eb8aba179a32992aba50e Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 18:14:49 +0200 Subject: [PATCH 37/75] Portals: Fix rapid back-and-forth teleportation --- mods/ITEMS/mcl_portals/portal_end.lua | 22 ++++++++++++++++++++-- mods/ITEMS/mcl_portals/portal_nether.lua | 20 +++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 44f0e1436..d21c3ac9b 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -12,10 +12,14 @@ local np_cave = { octaves = 5, persist = 0.7 } - -- Portal frame material local portal_frame = "mcl_nether:quartz_block" +-- Table of objects (including players) which recently teleported by a +-- End portal. Those objects have a brief cooloff period before they +-- can teleport again. This prevents annoying back-and-forth teleportation. +local portal_cooloff = {} + -- Destroy portal if pos (portal frame or portal node) got destroyed local destroy_portal = function(pos) -- Deactivate Nether portal @@ -326,6 +330,10 @@ minetest.register_abm({ for _,obj in ipairs(minetest.get_objects_inside_radius(pos,1)) do --maikerumine added for objects to travel local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel if obj:is_player() or lua_entity then + -- No rapid back-and-forth teleportatio + if portal_cooloff[obj] then + return + end local meta = minetest.get_meta(pos) local target3 = minetest.string_to_pos(meta:get_string("portal_target")) if target3 then @@ -336,8 +344,12 @@ minetest.register_abm({ vector.subtract(target3, 4), vector.add(target3, 4)) end - -- teleport the player + -- teleport the object minetest.after(3, function(obj, pos, target3) + -- No rapid back-and-forth teleportatio + if portal_cooloff[obj] then + return + end local objpos = obj:getpos() if objpos == nil then return @@ -366,6 +378,12 @@ minetest.register_abm({ obj:setpos(target3) minetest.sound_play("mcl_portals_teleport", {pos=target3, gain=0.5, max_hear_distance = 16}) + -- Enable teleportation cooloff to prevent frequent back-and-forth teleportation + portal_cooloff[obj] = true + minetest.after(3, function(o) + portal_cooloff[o] = false + end, obj) + end, obj, pos, target3) end end diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 221af24ac..02430b231 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -19,6 +19,11 @@ local np_cave = { persist = 0.7 } +-- Table of objects (including players) which recently teleported by a +-- Nether portal. Those objects have a brief cooloff period before they +-- can teleport again. This prevents annoying back-and-forth teleportation. +local portal_cooloff = {} + -- Destroy portal if pos (portal frame or portal node) got destroyed local destroy_portal = function(pos) -- Deactivate Nether portal @@ -357,6 +362,10 @@ minetest.register_abm({ for _,obj in ipairs(minetest.get_objects_inside_radius(pos,1)) do --maikerumine added for objects to travel local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel if obj:is_player() or lua_entity then + -- Prevent quick back-and-forth teleportation + if portal_cooloff[obj] then + return + end local meta = minetest.get_meta(pos) local target = minetest.string_to_pos(meta:get_string("portal_target")) if target then @@ -366,8 +375,12 @@ minetest.register_abm({ minetest.emerge_area( vector.subtract(target, 4), vector.add(target, 4)) end - -- teleport the player + -- teleport the object minetest.after(3, function(obj, pos, target) + -- Prevent quick back-and-forth teleportation + if portal_cooloff[obj] then + return + end local objpos = obj:getpos() if objpos == nil then return @@ -397,6 +410,11 @@ minetest.register_abm({ obj:setpos(target) minetest.sound_play("mcl_portals_teleport", {pos=target, gain=0.5, max_hear_distance = 16}) + -- Enable teleportation cooloff for 4 seconds, to prevent back-and-forth teleportation + portal_cooloff[obj] = true + minetest.after(4, function(o) + portal_cooloff[o] = false + end, obj) end, obj, pos, target) end From c178a60a6b7170592ecf18bf066d1e6fc11303d8 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 18:41:58 +0200 Subject: [PATCH 38/75] Add portal help texts --- mods/ITEMS/mcl_portals/portal_end.lua | 2 ++ mods/ITEMS/mcl_portals/portal_nether.lua | 3 +++ 2 files changed, 5 insertions(+) diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index d21c3ac9b..990bba30d 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -69,6 +69,8 @@ end -- Nodes minetest.register_node("mcl_portals:portal_end", { description = "End Portal", + _doc_items_longdesc = "An End portal teleports creatures and objects to the mysterious End dimension (and back!).", + _doc_items_usagehelp = "Stand in the portal for a moment to activate the teleportation. Entering such a portal for the first time will create a new portal in your destination. End portal which were built in the End will lead back to the Overworld. An End portal is destroyed if any of its surrounding frame blocks is destroyed.", tiles = { "blank.png", "blank.png", diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 02430b231..93e53c9da 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -72,6 +72,9 @@ end minetest.register_node("mcl_portals:portal", { description = "Nether Portal", + _doc_items_longdesc = "A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!", + _doc_items_usagehelp = "Stand in the portal for a moment to activate the teleportation. Entering a Nether portal for the first time will also create a new portal in the other dimension. If a Nether portal has been built in the Nether, it will lead to the Overworld. A Nether portal is destroyed if the any of the obsidian which surrounds it is destroyed, or if it was caught in an explosion.", + tiles = { "blank.png", "blank.png", From 987ad8eaf470a104565b7cb811f7ca7ae114dda5 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 19:05:13 +0200 Subject: [PATCH 39/75] Add portal help texts, rewrite help of other items --- mods/ITEMS/mcl_fire/flint_and_steel.lua | 4 ++-- mods/ITEMS/mcl_portals/portal_end.lua | 8 ++++++-- mods/ITEMS/mcl_portals/portal_nether.lua | 7 ++++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/mods/ITEMS/mcl_fire/flint_and_steel.lua b/mods/ITEMS/mcl_fire/flint_and_steel.lua index 91e46861b..9737c3adf 100644 --- a/mods/ITEMS/mcl_fire/flint_and_steel.lua +++ b/mods/ITEMS/mcl_fire/flint_and_steel.lua @@ -1,8 +1,8 @@ -- Flint and Steel minetest.register_tool("mcl_fire:flint_and_steel", { description = "Flint and Steel", - _doc_items_longdesc = "Flint and steel is a tool to start fires, ignite blocks and open portals.", - _doc_items_usagehelp = "Rightclick the surface of a block to attempt to light a fire in front of it. On netherrack it will start an eternal fire. Using it on TNT will ignite it. To open a Nether portal, place an upright frame of obsidian with a length of 4 and a height of 5 blocks, leaving only air in the center. After placing this frame, use the flint and steel on inside of the frame.", + _doc_items_longdesc = "Flint and steel is a tool to start fires and ignite blocks.", + _doc_items_usagehelp = "Rightclick the surface of a block to attempt to light a fire in front of it or ignite the block. A few blocks have an unique reaction when ignited.", inventory_image = "mcl_fire_flint_and_steel.png", liquids_pointable = false, stack_max = 1, diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 990bba30d..21f6be544 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -396,15 +396,19 @@ minetest.register_abm({ --[[ ITEM OVERRIDES ]] +local portal_open_help = "To open an End portal, place an upright frame of quartz blocks with a length of 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, use an eye of ender on the frame. The eye of ender is destroyed in the process." + -- Frame material minetest.override_item(portal_frame, { + _doc_items_longdesc = "A block of quartz can be used to create End portals.", + _doc_items_usagehelp = portal_open_help, on_destruct = destroy_portal, }) -- Portal opener minetest.override_item("mcl_end:ender_eye", { - _doc_items_longdesc = "An eye of ander can be used to open a portal to the End.", - _doc_items_usagehelp = "To open an End portal, place an upright frame of quartz blocks with a length of 4 and a height of 5 blocks, leaving only air in the center. After placing this frame, use the eye of ender on the frame.", + _doc_items_longdesc = "An eye of ender can be used to open End portals.", + _doc_items_usagehelp = portal_open_help, on_place = function(itemstack, user, pointed_thing) -- Use pointed node's on_rightclick function first, if present local node = minetest.get_node(pointed_thing.under) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 93e53c9da..7789de420 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -429,8 +429,13 @@ minetest.register_abm({ --[[ ITEM OVERRIDES ]] --- Frame material +local longdesc = minetest.registered_nodes["mcl_core:obsidian"]._doc_items_longdesc +longdesc = longdesc .. "\n" .. "Obsidian is also used as the frame of Nether portals." +local usagehelp = "To open a Nether portal, place an upright frame of obsidian with a width of 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, ignite the obsidian with an appropriate tool, such as flint of steel." + minetest.override_item("mcl_core:obsidian", { + _doc_items_longdesc = longdesc, + _doc_items_usagehelp = usagehelp, on_destruct = destroy_portal, _on_ignite = function(user, pointed_thing) local pos = pointed_thing.under From b2171b7f2589684dafdbedffd68912bac13bda7b Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 19:17:42 +0200 Subject: [PATCH 40/75] Remove some temp. recipes and lift some WIP items --- mods/MISC/mcl_temp_helper_recipes/depends.txt | 4 +- mods/MISC/mcl_temp_helper_recipes/init.lua | 62 ++----------------- mods/MISC/mcl_wip/init.lua | 2 - 3 files changed, 9 insertions(+), 59 deletions(-) diff --git a/mods/MISC/mcl_temp_helper_recipes/depends.txt b/mods/MISC/mcl_temp_helper_recipes/depends.txt index 7e0cdd5dd..a1ce09984 100644 --- a/mods/MISC/mcl_temp_helper_recipes/depends.txt +++ b/mods/MISC/mcl_temp_helper_recipes/depends.txt @@ -1,4 +1,6 @@ mcl_core mcl_mobitems -mcl_dye mcl_end +mcl_nether +mcl_ocean +xpanes diff --git a/mods/MISC/mcl_temp_helper_recipes/init.lua b/mods/MISC/mcl_temp_helper_recipes/init.lua index 87388b24d..0209f1761 100644 --- a/mods/MISC/mcl_temp_helper_recipes/init.lua +++ b/mods/MISC/mcl_temp_helper_recipes/init.lua @@ -18,12 +18,12 @@ minetest.register_craft({ }) minetest.register_craft({ - output = "mcl_core:redsand 8", - recipe = { - { "mcl_core:sand", "mcl_core:sand", "mcl_core:sand" }, - { "mcl_core:sand", "mcl_dye:red", "mcl_core:sand" }, - { "mcl_core:sand", "mcl_core:sand", "mcl_core:sand" }, - } + output = "mcl_end:end_stone", + recipe = { + { "mcl_core:sandstone", "mcl_core:stone", "mcl_core:sandstone" }, + { "mcl_core:stone", "mcl_core:sandstone", "mcl_core:stone" }, + { "mcl_core:sandstone", "mcl_core:stone", "mcl_core:sandstone" }, + }, }) minetest.register_craft({ @@ -48,23 +48,6 @@ minetest.register_craft({ }, }) -minetest.register_craft({ - output = "mcl_end:end_stone", - recipe = { - { "mcl_core:sandstone", "mcl_core:stone", "mcl_core:sandstone" }, - { "mcl_core:stone", "mcl_core:sandstone", "mcl_core:stone" }, - { "mcl_core:sandstone", "mcl_core:stone", "mcl_core:sandstone" }, - }, -}) - -minetest.register_craft({ - output = "mcl_mobitems:blaze_rod", - recipe = { - { "mcl_fire:flint_and_steel", "mcl_fire:flint_and_steel", "mcl_fire:flint_and_steel"}, - { "mcl_fire:flint_and_steel", "mcl_core:stick", "mcl_fire:flint_and_steel" }, - { "mcl_fire:flint_and_steel", "mcl_fire:flint_and_steel", "mcl_fire:flint_and_steel"}, - } -}) minetest.register_craft({ output = "mcl_mobitems:shulker_shell", recipe = { @@ -74,15 +57,6 @@ minetest.register_craft({ } }) -minetest.register_craft({ - output = "mcl_nether:quartz", - recipe = { - {"group:sand", "group:sand", "group:sand"}, - {"group:sand", "group:sand", "group:sand"}, - {"group:sand", "group:sand", "group:sand"}, - } -}) - minetest.register_craft({ output = "mcl_nether:nether_wart_item", recipe = { @@ -92,30 +66,6 @@ minetest.register_craft({ } }) -minetest.register_craft({ - type = "shapeless", - output = "mcl_nether:netherrack", - recipe = {"mcl_core:stone", "group:redsandstone"}, -}) - -minetest.register_craft({ - output = "mcl_nether:glowstone_dust", - recipe = { - {"mcl_torches:torch", "mcl_torches:torch", "mcl_torches:torch",}, - {"mcl_torches:torch", "mcl_core:coalblock", "mcl_torches:torch",}, - {"mcl_torches:torch", "mcl_torches:torch", "mcl_torches:torch",}, - }, -}) - -minetest.register_craft({ - output = "mcl_nether:soul_sand", - recipe = { - {"mcl_core:redsand","mcl_nether:netherrack","mcl_core:redsand"}, - {"mcl_nether:netherrack","mcl_core:redsand","mcl_nether:netherrack"}, - {"mcl_core:redsand","mcl_nether:netherrack","mcl_core:redsand"}, - }, -}) - minetest.register_craft({ output = "3d_armor:helmet_chain", recipe = { diff --git a/mods/MISC/mcl_wip/init.lua b/mods/MISC/mcl_wip/init.lua index bb29c9a65..8ed0d9579 100644 --- a/mods/MISC/mcl_wip/init.lua +++ b/mods/MISC/mcl_wip/init.lua @@ -4,7 +4,6 @@ local wip_items = { "mcl_anvils:anvil_damage_2", "mcl_core:darksapling", "mcl_core:apple_gold", - "mcl_end:ender_eye", "mcl_end:chorus_fruit", "mcl_end:chorus_flower", "mcl_end:chorus_flower_dead", @@ -15,7 +14,6 @@ local wip_items = { "gemalde:node_1", "mcl_observers:observer", "mcl_chests:trapped_chest", - "mobs_mc:llama", "mobs_mc:totem", "mcl_paintings:painting", } From 3fefbf5fc4ba597247c99aa9de6263a3595cc6c9 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 19:59:43 +0200 Subject: [PATCH 41/75] Add realm barrier between End and Overworld void --- mods/CORE/mcl_init/init.lua | 3 +++ mods/ITEMS/mcl_core/nodes_misc.lua | 2 ++ mods/MAPGEN/mcl_mapgen_core/init.lua | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index ebf106e19..091d9cb1c 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -65,6 +65,9 @@ mcl_vars.mg_lava_nether_max = mcl_vars.mg_nether_min + 31 mcl_vars.mg_end_min = mcl_vars.mg_nether_max + 2000 mcl_vars.mg_end_max_official = mcl_vars.mg_end_min + minecraft_height_limit mcl_vars.mg_end_max = mcl_vars.mg_overworld_min - 2000 +-- Realm barrier used to safely separate the End from the void below the Overworld +mcl_vars.mg_realm_barrier_overworld_end_max = mcl_vars.mg_end_max +mcl_vars.mg_realm_barrier_overworld_end_min = mcl_vars.mg_end_max - 11 -- Set default stack sizes minetest.nodedef_default.stack_max = 64 diff --git a/mods/ITEMS/mcl_core/nodes_misc.lua b/mods/ITEMS/mcl_core/nodes_misc.lua index 81274a49a..3c1c51f3a 100644 --- a/mods/ITEMS/mcl_core/nodes_misc.lua +++ b/mods/ITEMS/mcl_core/nodes_misc.lua @@ -153,6 +153,8 @@ minetest.register_node("mcl_core:realm_barrier", { wield_image = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX", tiles = { "blank.png" }, stack_max = 64, + -- To avoid players getting stuck forever between realms + damage_per_second = 8, sunlight_propagates = true, is_ground_content = false, pointable = false, diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 6e2dda738..0b8999cf0 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1215,6 +1215,7 @@ minetest.register_on_generated(function(minp, maxp) local c_bedrock = minetest.get_content_id("mcl_core:bedrock") local c_void = minetest.get_content_id("mcl_core:void") local c_lava = minetest.get_content_id("mcl_core:lava_source") + local c_realm_barrier = minetest.get_content_id("mcl_core:realm_barrier") local c_nether_lava = minetest.get_content_id("mcl_nether:nether_lava_source") local c_air = minetest.get_content_id("air") @@ -1276,6 +1277,7 @@ minetest.register_on_generated(function(minp, maxp) if setdata then data[p_pos] = setdata lvm_used = true + -- Big lava seas by replacing air below a certain height elseif mcl_vars.mg_lava and data[p_pos] == c_air then if y <= mcl_vars.mg_lava_overworld_max and y >= mcl_vars.mg_overworld_min then data[p_pos] = c_lava @@ -1284,6 +1286,10 @@ minetest.register_on_generated(function(minp, maxp) data[p_pos] = c_nether_lava lvm_used = true end + -- Realm barrier between the Overworld void and the End + elseif y >= mcl_vars.mg_realm_barrier_overworld_end_min and y <= mcl_vars.mg_realm_barrier_overworld_end_max then + data[p_pos] = c_realm_barrier + lvm_used = true end end end From c97a14e96900d4d1fba5fec1a50a20ac6e7d367a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 20:22:30 +0200 Subject: [PATCH 42/75] Explode bed when used in End or Nether --- mods/ITEMS/mcl_beds/depends.txt | 2 ++ mods/ITEMS/mcl_beds/functions.lua | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/mods/ITEMS/mcl_beds/depends.txt b/mods/ITEMS/mcl_beds/depends.txt index 53f5b7c50..93b5fc03e 100644 --- a/mods/ITEMS/mcl_beds/depends.txt +++ b/mods/ITEMS/mcl_beds/depends.txt @@ -1,3 +1,5 @@ mcl_sounds? +mcl_util? mcl_wool? mcl_dye? +mcl_tnt? diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index cbb2c3c09..5f8e4daf0 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -136,6 +136,17 @@ function mcl_beds.skip_night() end function mcl_beds.on_rightclick(pos, player) + if minetest.get_modpath("mcl_init") then + local _, dim = mcl_util.y_to_layer(pos.y) + if dim == "nether" or dim == "end" then + -- Bed goes BOOM in the Nether or End. + minetest.remove_node(pos) + if minetest.get_modpath("mcl_tnt") then + tnt.boom(pos, {radius = 4, damage_radius = 4}) + end + return + end + end local name = player:get_player_name() local ppos = player:getpos() local tod = minetest.get_timeofday() * 24000 From c7fc3845c193123db105f5fcb30bb3332842e956 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 20:40:55 +0200 Subject: [PATCH 43/75] Disable compass+clock updates in Nether, End, Void --- mods/ITEMS/mcl_clock/depends.txt | 3 ++- mods/ITEMS/mcl_clock/init.lua | 14 +++++++++----- mods/ITEMS/mcl_compass/depends.txt | 1 + mods/ITEMS/mcl_compass/init.lua | 26 +++++++++++++++----------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/mods/ITEMS/mcl_clock/depends.txt b/mods/ITEMS/mcl_clock/depends.txt index 0430af2c8..bf2f4ce73 100644 --- a/mods/ITEMS/mcl_clock/depends.txt +++ b/mods/ITEMS/mcl_clock/depends.txt @@ -1,3 +1,4 @@ -mcl_core +mcl_init +mcl_util mesecons doc? diff --git a/mods/ITEMS/mcl_clock/init.lua b/mods/ITEMS/mcl_clock/init.lua index c011b1ee2..6a40630ce 100644 --- a/mods/ITEMS/mcl_clock/init.lua +++ b/mods/ITEMS/mcl_clock/init.lua @@ -76,11 +76,15 @@ minetest.register_globalstep(function(dtime) local players = minetest.get_connected_players() for p, player in ipairs(players) do for s, stack in ipairs(player:get_inventory():get_list("main")) do - local count = stack:get_count() - if stack:get_name() == mcl_clock.stereotype then - player:get_inventory():set_stack("main", s, "mcl_clock:clock_"..now.." "..count) - elseif string.sub(stack:get_name(), 1, 16) == "mcl_clock:clock_" then - player:get_inventory():set_stack("main", s, "mcl_clock:clock_"..now.." "..count) + local _, dim = mcl_util.y_to_layer(player:getpos().y) + -- Clocks do not work in the End, Nether or the Void + if dim ~= "end" and dim ~= "nether" and dim ~= "void" then + local count = stack:get_count() + if stack:get_name() == mcl_clock.stereotype then + player:get_inventory():set_stack("main", s, "mcl_clock:clock_"..now.." "..count) + elseif string.sub(stack:get_name(), 1, 16) == "mcl_clock:clock_" then + player:get_inventory():set_stack("main", s, "mcl_clock:clock_"..now.." "..count) + end end end end diff --git a/mods/ITEMS/mcl_compass/depends.txt b/mods/ITEMS/mcl_compass/depends.txt index 0430af2c8..53ee1117a 100644 --- a/mods/ITEMS/mcl_compass/depends.txt +++ b/mods/ITEMS/mcl_compass/depends.txt @@ -1,3 +1,4 @@ mcl_core +mcl_util mesecons doc? diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index b033c2b47..8c230b223 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -26,18 +26,22 @@ minetest.register_globalstep(function(dtime) end end local pos = player:getpos() - local dir = player:get_look_horizontal() - local angle_north = math.deg(math.atan2(spawn.x - pos.x, spawn.z - pos.z)) - if angle_north < 0 then angle_north = angle_north + 360 end - local angle_dir = -math.deg(dir) - local angle_relative = (angle_north - angle_dir + 180) % 360 - local compass_image = math.floor((angle_relative/11.25) + 0.5)%32 + local _, dim = mcl_util.y_to_layer(pos.y) + -- Compasses do not work in the End, Nether or the Void + if dim ~= "end" and dim ~= "nether" and dim ~= "void" then + local dir = player:get_look_horizontal() + local angle_north = math.deg(math.atan2(spawn.x - pos.x, spawn.z - pos.z)) + if angle_north < 0 then angle_north = angle_north + 360 end + local angle_dir = -math.deg(dir) + local angle_relative = (angle_north - angle_dir + 180) % 360 + local compass_image = math.floor((angle_relative/11.25) + 0.5)%32 - for j,stack in ipairs(player:get_inventory():get_list("main")) do - if minetest.get_item_group(stack:get_name(), "compass") ~= 0 and - minetest.get_item_group(stack:get_name(), "compass")-1 ~= compass_image then - local count = stack:get_count() - player:get_inventory():set_stack("main", j, ItemStack("mcl_compass:"..compass_image.." "..count)) + for j,stack in ipairs(player:get_inventory():get_list("main")) do + if minetest.get_item_group(stack:get_name(), "compass") ~= 0 and + minetest.get_item_group(stack:get_name(), "compass")-1 ~= compass_image then + local count = stack:get_count() + player:get_inventory():set_stack("main", j, ItemStack("mcl_compass:"..compass_image.." "..count)) + end end end end From 39f4573294d68f4307daca8c46cb9b47324734e3 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 21:26:09 +0200 Subject: [PATCH 44/75] Randomly spin compass and clock in VoidNetherEnd --- mods/ITEMS/mcl_clock/init.lua | 43 +++++++++++++++++-------- mods/ITEMS/mcl_compass/init.lua | 57 +++++++++++++++++++++------------ 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/mods/ITEMS/mcl_clock/init.lua b/mods/ITEMS/mcl_clock/init.lua index 6a40630ce..48bced175 100644 --- a/mods/ITEMS/mcl_clock/init.lua +++ b/mods/ITEMS/mcl_clock/init.lua @@ -12,10 +12,17 @@ mcl_clock.stereotype = "mcl_clock:clock" local watch = {} watch.old_time = -1 --- Image of all 64 possible faces +local clock_frames = 64 + +-- Timer for random clock spinning +local random_timer = 0.0 +local random_timer_trigger = 1.0 -- random clock spinning tick in seconds. Increase if there are performance problems +local random_frame = math.random(0, clock_frames-1) + +-- Image of all possible faces watch.images = {} -for frame=0,63 do - table.insert(watch.images, "mcl_clock_clock.png^[verticalframe:64:"..frame) +for frame=0, clock_frames-1 do + table.insert(watch.images, "mcl_clock_clock.png^[verticalframe:"..clock_frames..":"..frame) end local function round(num) @@ -23,9 +30,9 @@ local function round(num) end function watch.get_clock_frame() - local t = 64 * minetest.get_timeofday() + local t = clock_frames * minetest.get_timeofday() t = round(t) - if t == 64 then t = 0 end + if t == clock_frames then t = 0 end return tostring(t) end @@ -65,6 +72,12 @@ local force_clock_update_timer = 0 minetest.register_globalstep(function(dtime) local now = watch.get_clock_frame() force_clock_update_timer = force_clock_update_timer + dtime + random_timer = random_timer + dtime + -- This causes the random spinning of the clock + if random_timer >= random_timer_trigger then + random_frame = (random_frame + math.random(-4, 4)) % clock_frames + random_timer = 0 + end if watch.old_time == now and force_clock_update_timer < 60 then return @@ -77,14 +90,18 @@ minetest.register_globalstep(function(dtime) for p, player in ipairs(players) do for s, stack in ipairs(player:get_inventory():get_list("main")) do local _, dim = mcl_util.y_to_layer(player:getpos().y) + local frame -- Clocks do not work in the End, Nether or the Void - if dim ~= "end" and dim ~= "nether" and dim ~= "void" then - local count = stack:get_count() - if stack:get_name() == mcl_clock.stereotype then - player:get_inventory():set_stack("main", s, "mcl_clock:clock_"..now.." "..count) - elseif string.sub(stack:get_name(), 1, 16) == "mcl_clock:clock_" then - player:get_inventory():set_stack("main", s, "mcl_clock:clock_"..now.." "..count) - end + if dim == "end" or dim == "nether" or dim == "void" then + frame = random_frame + else + frame = now + end + local count = stack:get_count() + if stack:get_name() == mcl_clock.stereotype then + player:get_inventory():set_stack("main", s, "mcl_clock:clock_"..frame.." "..count) + elseif minetest.get_item_group(stack:get_name(), "clock") ~= 0 then + player:get_inventory():set_stack("main", s, "mcl_clock:clock_"..frame.." "..count) end end end @@ -111,7 +128,7 @@ minetest.register_craft({ watch.register_item(mcl_clock.stereotype, watch.images[1], true, 1) -- Faces -for a=0,63,1 do +for a=0,clock_frames-1,1 do local b = a if b > 31 then b = b - 32 diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 8c230b223..ff9db2aeb 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -1,9 +1,23 @@ mcl_compass = {} +local compass_frames = 32 + local default_spawn_settings = minetest.settings:get("static_spawnpoint") +-- Timer for random compass spinning +local random_timer = 0 +local random_timer_trigger = 0.5 -- random compass spinning tick in seconds. Increase if there are performance problems + +local random_frame = math.random(0, compass_frames-1) + minetest.register_globalstep(function(dtime) + random_timer = random_timer + dtime local players = minetest.get_connected_players() + + if random_timer >= random_timer_trigger then + random_frame = (random_frame + math.random(-1, 1)) % compass_frames + random_timer = 0 + end for i,player in ipairs(players) do local function has_compass(player) for _,stack in ipairs(player:get_inventory():get_list("main")) do @@ -14,34 +28,37 @@ minetest.register_globalstep(function(dtime) return false end if has_compass(player) then - local spawn = {x=0,y=0,z=0} - local s = minetest.settings:get("static_spawnpoint") - if s then - local numbers = string.split(s, ",") - spawn.x = tonumber(numbers[1]) - spawn.y = tonumber(numbers[2]) - spawn.z = tonumber(numbers[3]) - if type(spawn.x) ~= "number" and type(spawn.y) ~= "number" and type(spawn.z) ~= "number" then - spawn = {x=0,y=0,z=0} - end - end local pos = player:getpos() local _, dim = mcl_util.y_to_layer(pos.y) + local compass_image -- Compasses do not work in the End, Nether or the Void - if dim ~= "end" and dim ~= "nether" and dim ~= "void" then + if dim == "end" or dim == "nether" or dim == "void" then + compass_image = random_frame + else + local spawn = {x=0,y=0,z=0} + local s = minetest.settings:get("static_spawnpoint") + if s then + local numbers = string.split(s, ",") + spawn.x = tonumber(numbers[1]) + spawn.y = tonumber(numbers[2]) + spawn.z = tonumber(numbers[3]) + if type(spawn.x) ~= "number" and type(spawn.y) ~= "number" and type(spawn.z) ~= "number" then + spawn = {x=0,y=0,z=0} + end + end local dir = player:get_look_horizontal() local angle_north = math.deg(math.atan2(spawn.x - pos.x, spawn.z - pos.z)) if angle_north < 0 then angle_north = angle_north + 360 end local angle_dir = -math.deg(dir) local angle_relative = (angle_north - angle_dir + 180) % 360 - local compass_image = math.floor((angle_relative/11.25) + 0.5)%32 + compass_image = math.floor((angle_relative/11.25) + 0.5) % compass_frames + end - for j,stack in ipairs(player:get_inventory():get_list("main")) do - if minetest.get_item_group(stack:get_name(), "compass") ~= 0 and - minetest.get_item_group(stack:get_name(), "compass")-1 ~= compass_image then - local count = stack:get_count() - player:get_inventory():set_stack("main", j, ItemStack("mcl_compass:"..compass_image.." "..count)) - end + for j,stack in ipairs(player:get_inventory():get_list("main")) do + if minetest.get_item_group(stack:get_name(), "compass") ~= 0 and + minetest.get_item_group(stack:get_name(), "compass")-1 ~= compass_image then + local count = stack:get_count() + player:get_inventory():set_stack("main", j, ItemStack("mcl_compass:"..compass_image.." "..count)) end end end @@ -49,7 +66,7 @@ minetest.register_globalstep(function(dtime) end) local images = {} -for frame=0,31 do +for frame = 0, compass_frames-1 do local s = string.format("%02d", frame) table.insert(images, "mcl_compass_compass_"..s..".png") end From 974db128672f20b4eaf331d784659cbf447f8e2d Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 23:14:02 +0200 Subject: [PATCH 45/75] Register dimension stuff independent of mapgen --- mods/MAPGEN/mcl_biomes/init.lua | 32 +++++++++++++++++----------- mods/MAPGEN/mcl_mapgen_core/init.lua | 4 ++-- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 4dfadfee1..c3af70d65 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1,7 +1,6 @@ -- --- Register biomes for mapgens other than v6 --- EXPERIMENTAL! +-- Register biomes -- local function register_classic_superflat_biome() @@ -549,13 +548,13 @@ local function register_biomes() heat_point = 50, humidity_point = 50, }) +end - +-- Register biomes of non-Overworld biomes +local function register_dimension_biomes() --[[ REALMS ]] - -- TODO: Make these work in v6, too. --[[ THE NETHER ]] - minetest.register_biome({ name = "nether", node_filler = "mcl_nether:netherrack", @@ -569,20 +568,18 @@ local function register_biomes() }) --[[ THE END ]] - minetest.register_biome({ name = "end", node_filler = "mcl_end:end_stone", node_stone = "mcl_end:end_stone", - y_min = mcl_vars.mg_end_min, - -- FIXME: For some reason the Nether stops generating early if this constant is not added. + -- FIXME: For some reason the End stops generating early if this constant is not added. -- Figure out why. + y_min = mcl_vars.mg_end_min, y_max = mcl_vars.mg_end_max + 80, heat_point = 50, humidity_point = 50, }) - end -- Register “fake” ores directly related to the biomes @@ -826,7 +823,10 @@ local function register_biomelike_ores() noise_threshold = 0.0, noise_params = {offset=0, scale=1, spread= {x=3100, y=3100, z=3100}, seed=23, octaves=3, persist=0.70} , }) +end +-- Non-Overworld ores +local function register_dimension_ores() --[[ NETHER GENERATION ]] @@ -1513,6 +1513,10 @@ local function register_decorations() }) +end + +-- Decorations in non-Overworld dimensions +local function register_dimension_decorations() --[[ NETHER decorations ]] -- Red Mushroom @@ -1560,10 +1564,8 @@ local function register_decorations() y_max = mcl_vars.mg_nether_max, decoration = "mcl_nether:nether_wart", }) - end - -- -- Detect mapgen to select functions -- @@ -1582,4 +1584,10 @@ elseif mg_name == "flat" then minetest.clear_registered_schematics() register_classic_superflat_biome() end --- v6 decorations are handled in mcl_mapgen_core + +-- Non-overworld stuff is registered independently +register_dimension_biomes() +register_dimension_ores() +register_dimension_decorations() + +-- Overworld decorations for v6 are handled in mcl_mapgen_core diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 0b8999cf0..07ffa36cb 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1266,8 +1266,8 @@ minetest.register_on_generated(function(minp, maxp) else -- Perfectly flat bedrock layer(s) if (y >= mcl_vars.mg_bedrock_overworld_min and y <= mcl_vars.mg_bedrock_overworld_max) or - (y >= mcl_vars.mg_bedrock_nether_bottom_min or y <= mcl_vars.mg_bedrock_bottom_max) or - (y >= mcl_vars.mg_bedrock_nether_top_min or y <= mcl_vars.mg_bedrock_top_max) then + (y >= mcl_vars.mg_bedrock_nether_bottom_min and y <= mcl_vars.mg_bedrock_nether_bottom_max) or + (y >= mcl_vars.mg_bedrock_nether_top_min and y <= mcl_vars.mg_bedrock_nether_top_max) then setdata = c_bedrock elseif mcl_util.is_in_void({x=x,y=y,z=z}) then setdata = c_void From dc1cb9b65983cb7083bfe647ebca0210544e99f5 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 Aug 2017 23:58:35 +0200 Subject: [PATCH 46/75] The Nether is now supported in v6, too --- mods/MAPGEN/mcl_biomes/init.lua | 27 +++++++++++++----------- mods/MAPGEN/mcl_mapgen_core/init.lua | 31 +++++++++++++++++++++------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index c3af70d65..7f03f2b43 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -834,7 +834,9 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "sheet", ore = "mcl_nether:soul_sand", - wherein = {"mcl_nether:netherrack"}, + -- Note: Stone is included only for v6 mapgen support. Netherrack is not generated naturally + -- in v6, but instead set with the on_generated function in mcl_mapgen_core. + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 13 * 13 * 13, clust_size = 5, y_min = mcl_vars.mg_nether_min, @@ -854,7 +856,7 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "blob", ore = "mcl_nether:magma", - wherein = {"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 14*14*14, clust_num_ores = 35, clust_size = 4, @@ -876,7 +878,7 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "blob", ore = "mcl_nether:glowstone", - wherein = {"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 26 * 26 * 26, clust_size = 5, y_min = mcl_vars.mg_lava_nether_max + 10, @@ -896,7 +898,7 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "sheet", ore = "mcl_core:gravel", - wherein = {"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, column_height_min = 1, column_height_max = 1, y_min = mcl_util.layer_to_y(63, "nether"), @@ -916,7 +918,7 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:quartz_ore", - wherein = {"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 850, clust_num_ores = 4, -- MC cluster amount: 4-10 clust_size = 3, @@ -926,7 +928,7 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:quartz_ore", - wherein = {"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 1650, clust_num_ores = 8, -- MC cluster amount: 4-10 clust_size = 4, @@ -938,7 +940,7 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:nether_lava_source", - wherein = {"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 500, clust_num_ores = 1, clust_size = 1, @@ -949,7 +951,7 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:nether_lava_source", - wherein = {"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 1000, clust_num_ores = 1, clust_size = 1, @@ -960,7 +962,7 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:nether_lava_source", - wherein = {"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 2000, clust_num_ores = 1, clust_size = 1, @@ -970,7 +972,7 @@ local function register_dimension_ores() minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:nether_lava_source", - wherein = {"mcl_nether:netherrack"}, + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 3500, clust_num_ores = 1, clust_size = 1, @@ -978,11 +980,12 @@ local function register_dimension_ores() y_max = mcl_vars.mg_nether_max, }) - -- Fire in the Nether + -- Fire in the Nether (hacky) + -- FIXME: Remove this when fire as decoration is available minetest.register_ore({ ore_type = "scatter", ore = "mcl_fire:eternal_fire", - wherein = "mcl_nether:netherrack", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity =12 *22 * 12, clust_num_ores = 5, clust_size = 5, diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 07ffa36cb..777fc3e75 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -594,8 +594,8 @@ minetest.register_ore({ clust_scarcity = monster_egg_scarcity, clust_num_ores = 3, clust_size = 2, - y_min = -31000, - y_max = 31000, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, -- TODO: Limit by biome }) @@ -1058,7 +1058,7 @@ local lvm_buffer = {} -- Generate cocoas and vines at jungle trees within the bounding box local function generate_jungle_tree_decorations(minp, maxp) - if minetest.get_mapgen_setting("mg_name") == "v6" then + if mg_name == "v6" then if maxp.y < 0 then return @@ -1213,10 +1213,16 @@ minetest.register_on_generated(function(minp, maxp) -- Generate bedrock and lava layers if minp.y <= GEN_MAX then local c_bedrock = minetest.get_content_id("mcl_core:bedrock") + local c_stone = minetest.get_content_id("mcl_core:stone") + local c_dirt = minetest.get_content_id("mcl_core:dirt") + local c_sand = minetest.get_content_id("mcl_core:sand") local c_void = minetest.get_content_id("mcl_core:void") local c_lava = minetest.get_content_id("mcl_core:lava_source") - local c_realm_barrier = minetest.get_content_id("mcl_core:realm_barrier") + local c_soul_sand = minetest.get_content_id("mcl_nether:soul_sand") + local c_netherrack = minetest.get_content_id("mcl_nether:netherrack") local c_nether_lava = minetest.get_content_id("mcl_nether:nether_lava_source") + local c_end_stone = minetest.get_content_id("mcl_end:end_stone") + local c_realm_barrier = minetest.get_content_id("mcl_core:realm_barrier") local c_air = minetest.get_content_id("air") local max_y = math.min(maxp.y, GEN_MAX) @@ -1260,8 +1266,6 @@ minetest.register_on_generated(function(minp, maxp) end if is_bedrock(y) then setdata = c_bedrock - elseif mcl_util.is_in_void({x=x,y=y,z=z}) then - setdata = c_void end else -- Perfectly flat bedrock layer(s) @@ -1269,14 +1273,14 @@ minetest.register_on_generated(function(minp, maxp) (y >= mcl_vars.mg_bedrock_nether_bottom_min and y <= mcl_vars.mg_bedrock_nether_bottom_max) or (y >= mcl_vars.mg_bedrock_nether_top_min and y <= mcl_vars.mg_bedrock_nether_top_max) then setdata = c_bedrock - elseif mcl_util.is_in_void({x=x,y=y,z=z}) then - setdata = c_void end end if setdata then data[p_pos] = setdata lvm_used = true + elseif mcl_util.is_in_void({x=x,y=y,z=z}) then + setdata = c_void -- Big lava seas by replacing air below a certain height elseif mcl_vars.mg_lava and data[p_pos] == c_air then if y <= mcl_vars.mg_lava_overworld_max and y >= mcl_vars.mg_overworld_min then @@ -1290,6 +1294,17 @@ minetest.register_on_generated(function(minp, maxp) elseif y >= mcl_vars.mg_realm_barrier_overworld_end_min and y <= mcl_vars.mg_realm_barrier_overworld_end_max then data[p_pos] = c_realm_barrier lvm_used = true + -- Nether and End support for v6 because v6 does not support the biomes API + elseif mg_name == "v6" then + if y <= mcl_vars.mg_nether_max and y >= mcl_vars.mg_nether_min then + if data[p_pos] == c_stone then + data[p_pos] = c_netherrack + elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then + data[p_pos] = c_soul_sand + end + elseif y <= mcl_vars.mg_end_max and y >= mcl_vars.mg_end_min and (data[p_pos] == c_stone or data[p_pos] == c_dirt or data[p_pos] == c_sand) then + data[p_pos] = c_end_stone + end end end end From c01c3c5871adb353cddcfe815fda1e1d8de3700f Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 00:36:31 +0200 Subject: [PATCH 47/75] Replace water with lava in the Nether --- mods/MAPGEN/mcl_mapgen_core/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 777fc3e75..a737405ae 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1218,6 +1218,7 @@ minetest.register_on_generated(function(minp, maxp) local c_sand = minetest.get_content_id("mcl_core:sand") local c_void = minetest.get_content_id("mcl_core:void") local c_lava = minetest.get_content_id("mcl_core:lava_source") + local c_water = minetest.get_content_id("mcl_core:water_source") local c_soul_sand = minetest.get_content_id("mcl_nether:soul_sand") local c_netherrack = minetest.get_content_id("mcl_nether:netherrack") local c_nether_lava = minetest.get_content_id("mcl_nether:nether_lava_source") @@ -1290,6 +1291,9 @@ minetest.register_on_generated(function(minp, maxp) data[p_pos] = c_nether_lava lvm_used = true end + -- Water in the Nether? No way! + elseif data[p_pos] == c_water and y <= mcl_vars.mg_nether_max and y >= mcl_vars.mg_nether_min then + data[p_pos] = c_nether_lava -- Realm barrier between the Overworld void and the End elseif y >= mcl_vars.mg_realm_barrier_overworld_end_min and y <= mcl_vars.mg_realm_barrier_overworld_end_max then data[p_pos] = c_realm_barrier From f13aa521f64e7c35e9949a617537805903f9f22c Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 00:53:07 +0200 Subject: [PATCH 48/75] Make magma blocks much more common --- mods/MAPGEN/mcl_biomes/init.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 7f03f2b43..6fa287792 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -857,9 +857,9 @@ local function register_dimension_ores() ore_type = "blob", ore = "mcl_nether:magma", wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, - clust_scarcity = 14*14*14, - clust_num_ores = 35, - clust_size = 4, + clust_scarcity = 8*8*8, + clust_num_ores = 45, + clust_size = 6, y_min = mcl_util.layer_to_y(23, "nether"), y_max = mcl_util.layer_to_y(37, "nether"), }) @@ -867,9 +867,9 @@ local function register_dimension_ores() ore_type = "blob", ore = "mcl_nether:magma", wherein = {"mcl_nether:netherrack"}, - clust_scarcity = 9*9*9, - clust_num_ores = 50, - clust_size = 5, + clust_scarcity = 10*10*10, + clust_num_ores = 65, + clust_size = 8, y_min = mcl_util.layer_to_y(23, "nether"), y_max = mcl_util.layer_to_y(37, "nether"), }) From 28a085ae9828716844bc6ca36b78913aa5b1d353 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 00:53:23 +0200 Subject: [PATCH 49/75] Fix broken mapgen overrides in mcl_mapgen_core --- mods/MAPGEN/mcl_mapgen_core/init.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index a737405ae..5b82d1b85 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1282,6 +1282,7 @@ minetest.register_on_generated(function(minp, maxp) lvm_used = true elseif mcl_util.is_in_void({x=x,y=y,z=z}) then setdata = c_void + lvm_used = true -- Big lava seas by replacing air below a certain height elseif mcl_vars.mg_lava and data[p_pos] == c_air then if y <= mcl_vars.mg_lava_overworld_max and y >= mcl_vars.mg_overworld_min then @@ -1294,6 +1295,7 @@ minetest.register_on_generated(function(minp, maxp) -- Water in the Nether? No way! elseif data[p_pos] == c_water and y <= mcl_vars.mg_nether_max and y >= mcl_vars.mg_nether_min then data[p_pos] = c_nether_lava + lvm_used = true -- Realm barrier between the Overworld void and the End elseif y >= mcl_vars.mg_realm_barrier_overworld_end_min and y <= mcl_vars.mg_realm_barrier_overworld_end_max then data[p_pos] = c_realm_barrier @@ -1303,11 +1305,14 @@ minetest.register_on_generated(function(minp, maxp) if y <= mcl_vars.mg_nether_max and y >= mcl_vars.mg_nether_min then if data[p_pos] == c_stone then data[p_pos] = c_netherrack + lvm_used = true elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then data[p_pos] = c_soul_sand + lvm_used = true end elseif y <= mcl_vars.mg_end_max and y >= mcl_vars.mg_end_min and (data[p_pos] == c_stone or data[p_pos] == c_dirt or data[p_pos] == c_sand) then data[p_pos] = c_end_stone + lvm_used = true end end end From 29119d2e2ce6f3bcd6d157360612cd2ee1a480f4 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 02:42:26 +0200 Subject: [PATCH 50/75] Generate floating islands in the End --- mods/ITEMS/mcl_portals/portal_end.lua | 8 +++- mods/MAPGEN/mcl_biomes/init.lua | 68 ++++++++++++++------------- mods/MAPGEN/mcl_mapgen_core/init.lua | 9 ++-- 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 21f6be544..0be9e68bb 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -2,6 +2,10 @@ local TCAVE = 0.6 local nobj_cave = nil + +local SPAWN_MIN = mcl_vars.mg_end_min+70 +local SPAWN_MAX = mcl_vars.mg_end_min+98 + -- 3D noise local np_cave = { @@ -173,13 +177,13 @@ local function build_end_portal(pos, target3) end local function find_end_target3_y2(target3_x, target3_z) - local start_y = mcl_vars.mg_end_min + math.random(20, 120) -- Search start + local start_y = math.random(SPAWN_MIN, SPAWN_MAX) -- Search start if not nobj_cave then nobj_cave = minetest.get_perlin(np_cave) end local air = 0 -- Consecutive air nodes found - for y = start_y, start_y - 120, -1 do + for y = start_y, SPAWN_MIN, -1 do local nval_cave = nobj_cave:get3d({x = target3_x, y = y, z = target3_z}) if nval_cave > TCAVE then -- Cavern diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 6fa287792..291d759a7 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -570,12 +570,14 @@ local function register_dimension_biomes() --[[ THE END ]] minetest.register_biome({ name = "end", + node_stone = "air", node_filler = "mcl_end:end_stone", - node_stone = "mcl_end:end_stone", + node_water = "mcl_end:end_stone", + node_river_water = "air", -- FIXME: For some reason the End stops generating early if this constant is not added. -- Figure out why. y_min = mcl_vars.mg_end_min, - y_max = mcl_vars.mg_end_max + 80, + y_max = mcl_vars.mg_end_max, heat_point = 50, humidity_point = 50, }) @@ -609,7 +611,7 @@ local function register_biomelike_ores() --mcl_core STRATA minetest.register_ore({ - ore_type = "sheet", + ore_type = "blob", ore = "mcl_core:stone", wherein = {"mcl_colorblocks:hardened_clay_orange"}, clust_scarcity = 1, @@ -996,44 +998,46 @@ local function register_dimension_ores() --[[ THE END ]] -- Generate fake End - -- TODO: Remove both "ores" when there's a better End + -- TODO: Remove both "ores" when there's a better End generator minetest.register_ore({ - ore_type = "blob", + ore_type = "sheet", ore = "mcl_end:end_stone", - wherein = {"air", "mcl_core:stone"}, - clust_scarcity = 30 * 30 * 30, - clust_size = 17, - y_min = mcl_vars.mg_end_min, - y_max = mcl_vars.mg_end_max, - noise_threshold = 0.0, - noise_params = { - offset = 0.5, - scale = 0.1, - spread = {x = 5, y = 5, z = 5}, - seed = 16, - octaves = 1, - persist = 0.0 + wherein = {"air"}, + y_min = mcl_vars.mg_end_min+64, + y_max = mcl_vars.mg_end_min+94, + column_height_min = 6, + column_height_max = 7, + column_midpoint_factor = 0.0, + noise_params = { + offset = -2, + scale = 8, + spread = {x=100, y=100, z=100}, + seed = 2999, + octaves = 5, + persist = 0.55, }, + noise_threshold = 0, }) minetest.register_ore({ - ore_type = "scatter", + ore_type = "sheet", ore = "mcl_end:end_stone", - wherein = {"air", "mcl_core:stone"}, - clust_scarcity = 30 * 30 * 30, - clust_size = 34, - y_min = mcl_vars.mg_end_min, - y_max = mcl_vars.mg_end_max, - noise_threshold = 0.0, - noise_params = { - offset = 0.5, - scale = 0.1, - spread = {x = 70, y = 15, z = 70}, - seed = 16, - octaves = 1, - persist = 0.0 + wherein = {"air"}, + y_min = mcl_vars.mg_end_min+64, + y_max = mcl_vars.mg_end_min+94, + column_height_min = 4, + column_height_max = 4, + column_midpoint_factor = 0.0, + noise_params = { + offset = -4, + scale = 3, + spread = {x=200, y=200, z=200}, + seed = 5390, + octaves = 5, + persist = 0.6, }, + noise_threshold = 0, }) end diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 5b82d1b85..68687d971 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1300,7 +1300,11 @@ minetest.register_on_generated(function(minp, maxp) elseif y >= mcl_vars.mg_realm_barrier_overworld_end_min and y <= mcl_vars.mg_realm_barrier_overworld_end_max then data[p_pos] = c_realm_barrier lvm_used = true - -- Nether and End support for v6 because v6 does not support the biomes API + -- Clear the End + elseif y <= mcl_vars.mg_end_max and y >= mcl_vars.mg_end_min then + --data[p_pos] = c_air + --lvm_used = true + -- Nether support for v6 because v6 does not support the biomes API elseif mg_name == "v6" then if y <= mcl_vars.mg_nether_max and y >= mcl_vars.mg_nether_min then if data[p_pos] == c_stone then @@ -1310,9 +1314,6 @@ minetest.register_on_generated(function(minp, maxp) data[p_pos] = c_soul_sand lvm_used = true end - elseif y <= mcl_vars.mg_end_max and y >= mcl_vars.mg_end_min and (data[p_pos] == c_stone or data[p_pos] == c_dirt or data[p_pos] == c_sand) then - data[p_pos] = c_end_stone - lvm_used = true end end end From 0a0e66a3248c68262c770b761d0043765ed78489 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 02:57:57 +0200 Subject: [PATCH 51/75] Build obsidian platforms for end portal --- mods/ITEMS/mcl_portals/portal_end.lua | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 0be9e68bb..bc26faf90 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -160,15 +160,19 @@ local function build_end_portal(pos, target3) meta:set_string("portal_frame2", minetest.pos_to_string(p2)) meta:set_string("portal_target", minetest.pos_to_string(target3)) - if y ~= p1.y then - for z = -2, 2 do - if z ~= 0 then - p.z = p.z + z + for z = -2, 2 do + if z ~= 0 then + local newp = {x=p.x, y=p.y, z=p.z+z} + if y ~= p1.y then if minetest.registered_nodes[ - minetest.get_node(p).name].is_ground_content then - minetest.remove_node(p) + minetest.get_node(newp).name].is_ground_content then + minetest.remove_node(newp) end - p.z = p.z - z + else + if minetest.get_node(newp).name == "air" then + minetest.set_node(newp, {name="mcl_core:obsidian"}) + end + end end end From e30719a3bb02634ab9fe8f52b1b7994fa521ad67 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 13:28:20 +0200 Subject: [PATCH 52/75] Fix some mapgen bugs WRT The End --- mods/MAPGEN/mcl_biomes/init.lua | 4 ++-- mods/MAPGEN/mcl_mapgen_core/init.lua | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 291d759a7..dc2b63f34 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -571,8 +571,8 @@ local function register_dimension_biomes() minetest.register_biome({ name = "end", node_stone = "air", - node_filler = "mcl_end:end_stone", - node_water = "mcl_end:end_stone", + node_filler = "air", + node_water = "air", node_river_water = "air", -- FIXME: For some reason the End stops generating early if this constant is not added. -- Figure out why. diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 68687d971..a9ef2f97f 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1222,7 +1222,6 @@ minetest.register_on_generated(function(minp, maxp) local c_soul_sand = minetest.get_content_id("mcl_nether:soul_sand") local c_netherrack = minetest.get_content_id("mcl_nether:netherrack") local c_nether_lava = minetest.get_content_id("mcl_nether:nether_lava_source") - local c_end_stone = minetest.get_content_id("mcl_end:end_stone") local c_realm_barrier = minetest.get_content_id("mcl_core:realm_barrier") local c_air = minetest.get_content_id("air") @@ -1281,7 +1280,7 @@ minetest.register_on_generated(function(minp, maxp) data[p_pos] = setdata lvm_used = true elseif mcl_util.is_in_void({x=x,y=y,z=z}) then - setdata = c_void + data[p_pos] = c_void lvm_used = true -- Big lava seas by replacing air below a certain height elseif mcl_vars.mg_lava and data[p_pos] == c_air then @@ -1300,11 +1299,7 @@ minetest.register_on_generated(function(minp, maxp) elseif y >= mcl_vars.mg_realm_barrier_overworld_end_min and y <= mcl_vars.mg_realm_barrier_overworld_end_max then data[p_pos] = c_realm_barrier lvm_used = true - -- Clear the End - elseif y <= mcl_vars.mg_end_max and y >= mcl_vars.mg_end_min then - --data[p_pos] = c_air - --lvm_used = true - -- Nether support for v6 because v6 does not support the biomes API + -- Nether and End support for v6 because v6 does not support the biomes API elseif mg_name == "v6" then if y <= mcl_vars.mg_nether_max and y >= mcl_vars.mg_nether_min then if data[p_pos] == c_stone then @@ -1314,6 +1309,11 @@ minetest.register_on_generated(function(minp, maxp) data[p_pos] = c_soul_sand lvm_used = true end + elseif y <= mcl_vars.mg_end_max and y >= mcl_vars.mg_end_min then + if data[p_pos] == c_stone or data[p_pos] == c_dirt or data[p_pos] == c_sand then + data[p_pos] = c_air + lvm_used = true + end end end end From b157c09a4e27aa89fab763842d0435f41f9511fb Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 13:56:26 +0200 Subject: [PATCH 53/75] Replace water in the End --- mods/MAPGEN/mcl_mapgen_core/init.lua | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index a9ef2f97f..29f1ff1bf 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1291,10 +1291,18 @@ minetest.register_on_generated(function(minp, maxp) data[p_pos] = c_nether_lava lvm_used = true end - -- Water in the Nether? No way! - elseif data[p_pos] == c_water and y <= mcl_vars.mg_nether_max and y >= mcl_vars.mg_nether_min then - data[p_pos] = c_nether_lava - lvm_used = true + -- Water in the Nether or End? No way! + elseif data[p_pos] == c_water then + if y <= mcl_vars.mg_nether_max and y >= mcl_vars.mg_nether_min then + data[p_pos] = c_nether_lava + lvm_used = true + elseif y <= mcl_vars.mg_end_min + 104 and y >= mcl_vars.mg_end_min + 40 then + data[p_pos] = c_end_stone + lvm_used = true + elseif y <= mcl_vars.mg_end_max and y >= mcl_vars.mg_end_min then + data[p_pos] = c_air + lvm_used = true + end -- Realm barrier between the Overworld void and the End elseif y >= mcl_vars.mg_realm_barrier_overworld_end_min and y <= mcl_vars.mg_realm_barrier_overworld_end_max then data[p_pos] = c_realm_barrier @@ -1338,6 +1346,13 @@ minetest.register_on_generated(function(minp, maxp) end end + if minp.y >= mcl_vars.mg_end_min and maxp.y <= mcl_vars.mg_end_max then +-- local min, max = table.copy(minp), table.copy(maxp) +-- min.y = math.max(minp.y, mcl_vars.mg_end_min) +-- max.y = math.min(maxp.y, mcl_vars.mg_end_max) + vm:set_lighting({day=14, night=14}) + lvm_used = true + end if lvm_used then vm:set_data(data) vm:calc_lighting() From 12df4c98b47f3d16af3a69d2e999d30416bea9c0 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 14:07:35 +0200 Subject: [PATCH 54/75] Minor mcl_biomes refactor --- mods/MAPGEN/mcl_biomes/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index dc2b63f34..898c082bf 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -559,6 +559,8 @@ local function register_dimension_biomes() name = "nether", node_filler = "mcl_nether:netherrack", node_stone = "mcl_nether:netherrack", + node_water = "air", + node_river_water = "air", y_min = mcl_vars.mg_nether_min, -- FIXME: For some reason the Nether stops generating early if this constant is not added. -- Figure out why. @@ -574,8 +576,6 @@ local function register_dimension_biomes() node_filler = "air", node_water = "air", node_river_water = "air", - -- FIXME: For some reason the End stops generating early if this constant is not added. - -- Figure out why. y_min = mcl_vars.mg_end_min, y_max = mcl_vars.mg_end_max, heat_point = 50, From cb1dbcb2db3c45a8cf0f3cf19fefd0b19eacf57e Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 14:10:49 +0200 Subject: [PATCH 55/75] Explain weird End lighting --- mods/MAPGEN/mcl_mapgen_core/init.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 29f1ff1bf..6bb4fac06 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1346,10 +1346,9 @@ minetest.register_on_generated(function(minp, maxp) end end + -- Set high light level in the End. This is very hacky and messes up the shadows below the End islands. + -- FIXME: Find a better way to do light. if minp.y >= mcl_vars.mg_end_min and maxp.y <= mcl_vars.mg_end_max then --- local min, max = table.copy(minp), table.copy(maxp) --- min.y = math.max(minp.y, mcl_vars.mg_end_min) --- max.y = math.min(maxp.y, mcl_vars.mg_end_max) vm:set_lighting({day=14, night=14}) lvm_used = true end From a1ed8380c01dae6adf666497b99acccc58282a54 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 14:19:43 +0200 Subject: [PATCH 56/75] Weather overwrites sky in Overworld only --- mods/ENVIRONMENT/weather_pack/skycolor.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mods/ENVIRONMENT/weather_pack/skycolor.lua b/mods/ENVIRONMENT/weather_pack/skycolor.lua index 6fe3870b1..0131c2383 100644 --- a/mods/ENVIRONMENT/weather_pack/skycolor.lua +++ b/mods/ENVIRONMENT/weather_pack/skycolor.lua @@ -74,7 +74,8 @@ skycolor = { players = skycolor.utils.get_players(players) for _, player in ipairs(players) do local pos = player:getpos() - if pos.y >= mcl_vars.mg_bedrock_overworld_max then + local _, dim = mcl_util.y_to_layer(pos.y) + if dim == "overworld" then player:set_sky(color, "plain", nil, true) end end @@ -112,7 +113,8 @@ skycolor = { local players = skycolor.utils.get_players(nil) for _, player in ipairs(players) do local pos = player:getpos() - if pos.y >= mcl_vars.mg_bedrock_overworld_max then + local _, dim = mcl_util.y_to_layer(pos.y) + if dim == "overworld" then player:set_sky(color, "plain", nil, true) end end @@ -125,7 +127,8 @@ skycolor = { local players = skycolor.utils.get_players(players) for _, player in ipairs(players) do local pos = player:getpos() - if pos.y >= mcl_vars.mg_bedrock_overworld_max then + local _, dim = mcl_util.y_to_layer(pos.y) + if dim == "overworld" then player:set_sky(nil, "regular", nil, true) end end From edfa125d3881b75cc84ea3979c5a28ad7b99de18 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 14:54:17 +0200 Subject: [PATCH 57/75] Set black sky in Nether and End --- mods/PLAYER/mcl_playerplus/init.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 6517158a2..3f6cc1818 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -153,12 +153,13 @@ minetest.register_globalstep(function(dtime) -- Apply black sky in the Void and deal Void damage local void, void_deadly = mcl_util.is_in_void(pos) - if void then - -- Player reached the void, set black sky box + local _, dim = mcl_util.y_to_layer(pos.y) + -- Set dimension skies. + -- FIXME: Sky handling in MCL2 is held together with lots of duct tape. + -- This only works beause weather_pack currently does not touch the sky for players below the height used for this check. + -- There should be a real skybox API. + if dim == "void" or dim == "nether" or dim == "end" then player:set_sky("#000000", "plain", nil, false) - -- FIXME: Sky handling in MCL2 is held together with lots of duct tape. - -- This only works beause weather_pack currently does not touch the sky for players below the height used for this check. - -- There should be a real skybox API. end if void_deadly then -- Player is deep into the void, deal void damage From 4927bcdc4ef729900580e8527c48144de45766e8 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 15:11:43 +0200 Subject: [PATCH 58/75] Make Nether sky reddish --- mods/PLAYER/mcl_playerplus/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 3f6cc1818..c33e6edd3 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -158,8 +158,10 @@ minetest.register_globalstep(function(dtime) -- FIXME: Sky handling in MCL2 is held together with lots of duct tape. -- This only works beause weather_pack currently does not touch the sky for players below the height used for this check. -- There should be a real skybox API. - if dim == "void" or dim == "nether" or dim == "end" then + if dim == "void" or dim == "end" then player:set_sky("#000000", "plain", nil, false) + elseif dim == "nether" then + player:set_sky("#300810", "plain", nil, false) end if void_deadly then -- Player is deep into the void, deal void damage From 75d6806782309a8bdf7016a3b3b19562ea3ac6dc Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 15:32:08 +0200 Subject: [PATCH 59/75] Tweak spawning of shulkers and endermen --- mods/ENTITIES/mobs_mc/enderman.lua | 2 +- mods/ENTITIES/mobs_mc/shulker.lua | 2 +- mods/ENTITIES/mobs_mc_gameconfig/init.lua | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 1161cb002..8f687b506 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -147,7 +147,7 @@ mobs:register_mob("mobs_mc:enderman", { -- End spawn -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 4, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 18, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) -- Overworld spawn mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 9000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Nether spawn (rare) diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index 8c7792930..aed2d2433 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -83,7 +83,7 @@ mobs:register_arrow("mobs_mc:shulkerbullet", { mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) -mobs:spawn_specific("mobs_mc:shulker", "mcl_end:purpur_block", {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific("mobs_mc:shulker", mobs_mc.spawn.end_city, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) if minetest.settings:get_bool("log_mods") then minetest.log("action", "MC Shulkers loaded") diff --git a/mods/ENTITIES/mobs_mc_gameconfig/init.lua b/mods/ENTITIES/mobs_mc_gameconfig/init.lua index a8f403f17..124352db7 100644 --- a/mods/ENTITIES/mobs_mc_gameconfig/init.lua +++ b/mods/ENTITIES/mobs_mc_gameconfig/init.lua @@ -178,7 +178,8 @@ mobs_mc.override.spawn = { desert = { "group:sand" }, jungle = { "mcl_core:podzol", "mcl_core:jungletree", "mcl_core:jungleleaves", "mcl_flowers:fern" }, snow = { "mcl_core:snow", "mcl_core:snowblock", "mcl_core:dirt_with_grass_snow" }, - end_city = { "mcl_end:purpur_block" }, + -- End stone added for shulkers because End cities don't generate yet + end_city = { "mcl_end:end_stone", "mcl_end:purpur_block" }, nether = { "mcl_nether:netherrack", "mcl_nether:quartz_ore" }, -- Netherrack added because there are no Nether fortresses yet. TODO: Remove netherrac from list as soon they're available nether_fortress = { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, From 6b2da70ff7d9727108725977bf860fd6f368024f Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 15:39:27 +0200 Subject: [PATCH 60/75] Add End sky texture --- mods/PLAYER/mcl_playerplus/init.lua | 5 ++++- .../textures/mcl_playerplus_end_sky.png | Bin 0 -> 98877 bytes tools/Texture_Conversion_Table.csv | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 mods/PLAYER/mcl_playerplus/textures/mcl_playerplus_end_sky.png diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index c33e6edd3..a4f7473d8 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -158,8 +158,11 @@ minetest.register_globalstep(function(dtime) -- FIXME: Sky handling in MCL2 is held together with lots of duct tape. -- This only works beause weather_pack currently does not touch the sky for players below the height used for this check. -- There should be a real skybox API. - if dim == "void" or dim == "end" then + if dim == "void" then player:set_sky("#000000", "plain", nil, false) + elseif dim == "end" then + local t = "mcl_playerplus_end_sky.png" + player:set_sky("#000000", "skybox", {t,t,t,t,t,t}, false) elseif dim == "nether" then player:set_sky("#300810", "plain", nil, false) end diff --git a/mods/PLAYER/mcl_playerplus/textures/mcl_playerplus_end_sky.png b/mods/PLAYER/mcl_playerplus/textures/mcl_playerplus_end_sky.png new file mode 100644 index 0000000000000000000000000000000000000000..e9671f3dc2007ce354a423bf65bfc4af80422eec GIT binary patch literal 98877 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

ni+vK6Di_&*T28n zG}xET(1hACV@?kjKe9QBBTC{vlI@+dsmCv>*+ez}Z2wL^5dUD#j*cW1#q25k#pYWWxx85frNf(dOeORvo~-MIO0GC`Gio)8~kE@$yB^^ z;miNmnsh#@Mzo4>A|jy|6xJ4a1jpnQb~Xli<6-G(Yw4DL>IpxD{maArAE9dQp8OJb zEydnUjGVC37+)4&+O^dBvd9!w-HL!|7|7&LbcCm7|EwoKvv zkz6!%V=YO}7z}3Q_J1!PbkN%D>>*!Dt7i-%*&Q!Wn)RmC|brp zX*M+a7wpi~IXTOxUpOpxn8wc+?Y&ned0i3oQ39yT+~`d`x-RPWZ;#%uT12)8EGp!1 z1CUVlr?WIn@kF%6>{rOf8!N`Mx;%pt0EGiW$f9%2+|lR)mzJo(hi}=nerjSvpDdVo z`76QFjevcK*E!-7XOMr`zhZqW1O?xNNUMO9|1t3X=dP7cAsgPtcjuSw643?g5GS2s zVD&|1(yvK-mLa*xnhPs#v7rpvP_W-oW-4o4;sAnwZ)7FOZofGHq$0Y=+0kYC~)=M4k zp?}=y9>r$AS(==<6Z>wNK$T6*%(*v8M9{zZdiFRQhAkSU+9g7gmQlh8=s1l|QFQAl zi2f65iUz){zLH@PN*z4AA%#$a@D&I!eCc!sw7clQS)vqss!Ouasd3mvz-H)M$Y6*` zZ+5Dupvw2k7af7^{p$$WfmSSj*)-)mQ2NsD0T}>}d(fNL=0x!=R{l=~yi*p|^+u~N z+>k;Vmm2aZ+$4fK3CGT2KOhvbQG@@lGvIH9y_jxB*{TR=R@-&$ZI-5@(!}S(b&R?g zU|Aod-!Hlu@)vj{igcUei&3iAWpU&r^I#X}co)OfZ^pf8f*zk;M95z#cLiCT9Z|Ql z7KUgL3`^JNH49;uzs$&xToYA;|5k7gB4D>GjEO|43LRDIvJ_zYk6$ zS`-v+Iy1+8Zj`T8U4-|&T6&%tr@0Q1~oRdqqefnyeyLVxT>9WrdO z@a6`t$wSTqhG>i&&>PLpRCT$aME=WDgsW@iU_-oFPK3+T<7kZs$%)fnTXm@7?Y2qx zJ`ODnZL`T{(-H6lDYn6>K|bkFc?b&LJtz|~;`zEJ@SgMkt~iW8ci}S-CR8NPq5*lh z4x)x*1^q{J=-U$+hJNH?JJ2^YJ>6h^DREEG`J%g}MdrC}WlO+V_0ff^AwX}4U=mlH z|GJ<_W>CfTtK$EstM-c+A{Yt)b;(6%s7rgDX9^VQYq~5kg6l#B5)z?|g0!lc9DuX; zjd5=T+jP0DbD#&?95!8TS>=c75oe)Die$FCVprLfAYE;CzFBR#KOJ}PGw}W?GzC|t zm$z-zl3+(yUKz+A14s$FAIb53Id)&~A5CSc{pVAg+x=QRFJ`Zu3yEPiXoZ@fDcLaw z3cXxP>Ed5gN7suLSeF!k)&+hH$dkE--(p9B6c{Jzem%FY$-Emy%k;{{43HQ_^ea~Q0$6QL0c)Gr zhK+-zP3^vs8b4v-q9AjTt8)>(1iqD*vDXn<#9#{(pk;_+)nfUU5HI=FD?@K1+)6|&~xbj-R3i?(b zac9#e0xxXxwTWDiF>R7Wi?1Mgx_eA{_yf zg#4Z=nbYHcap+pY>Z)S)G;k;~#}-j{t~M+XO~|A5D^ad(o9JJtaez4%Dy~^M|u1cH!&zl zPgx+{)!z~7z-GOm%L{cb2V~1$_;bF$sa+mlfmgxTzm@vraY;{LE&4lFOGz_^+~I!l z)8m#bJ9I699I&hvr0VLLy1%*N&Fs3*U~8&{O1{;Ht#J#7rDImX_+PA`ZrY|RILX%E z{BprNuXb~C0_4kP@fUoWwoyJc^h@5%rLqbAbS7;7wh}^v64yX7*KBBy^1eHVqKV^DR730M6E3ff8TVBFv7w8 zvQ;msx^8Q>)Ft|NsxI{qXnf9!htu6cDD$QLS>c+28kzp$EYcM}a`R@phv~vFxA6Se z(btPEDy)u;U6Ow9%->*S2?xQ<-`(ctVyB+mB8HAzr&1)2{kP)E;!K%lg%6DAHijt4 zoOe;~lx#Pi!t!9_-@$`4r`k0q)xt_Ck%ZxE9dtbbfn&0*$EMXhu$evEACb7`!4le% z(^F5gNEGTOo)2eBQ|iP=o~Vd@0e?Wt+(I&ZMH*F84t7%))@_X^I%_013Iu;jVA$BK zk40}+?!-&zm`AUgDiT3_JN}wC8+@d7S_b%eD2CEYT$da;iwgY=xrezCiy{&!hG`PGs zDsT16#zVaS3J|ib6{T2;0Zi4W(dw01w1+Jh{QNL1`t;ygTi} zt$A}N_+}sN_=esAI>>}#ojLmUg$&#gXr`85LtUR8BTz_F{bteZ@wOU2yn9@XXw=`; z+WBmZu($~X-V;ezu-ohcAIBL+AKLbBwdrCp&aGtcJjufIC}&7bbv;5r@BkuLA|6M4&k%_&xgAcx#{+3-c%aTsWRJTF zAk)dZ796!1s}SBMYub8IC<8u<2w9qczZ9)>=AF8Zg2tsh*kb*x_UhVW|Bu8KPY~Qy z2JcM(FYvOBRz>@nhx-AUf32>}sij1&>svr`$G3wl-0eyQU3cP@sfvr>C``z{(-#mkiPK>hn@7W=rPB zOinL0T!xLp=q#5yh}@W5+rOi|;U6!=Av+6s`sC&ecwHGHyE?#;kyz_SFYyn%(hhR3 z2zADY&l$y6Gj+%ARlD`!{IOLzPt>eakK6Kk2HC78r*gug-M1&3>{*1_OT|;S_3^=r zQlmiF?+s6L0z^=VV1!-v7Z$%05;8p$y=XeYix{U|Gd%Vx1tyl3IDh9?@_^K3?Nd>f zQe1zGS+Bl>E?=Rz>TM6NGO@TaZe|7jELyVyW4tpx|Tu zn@)oTZ4x?AtRm~*c|Hj?8sU{DAqirRFzArsB%;(rVzqa+xz)Qy{%(nFVFEe2Vqo9867dy`(vOe<>x|Yq|3X?3+Pa3!< zYfd7uK$^JDxgcU9cBwPi_enEFWM4>a%Dn^|(aRXdSMdgUSB*i8dl_ z-DDB^kRQDei`6_sUdV`MAi{6%XVM^Zu1|$QVCtu$C@@)>baOG*)Uufq>gJJobWQ)) zJIh$Uq~Y)X>~(=e?9-0jjXO(=F*iyJ=GJiSX6$QFqBR@jbmj(^^kYjPN3xCvjDEgVQdSzw-HYBMXSwenArGFxn zF-XQD?UOLgHB}sD2_dN$2f1z;y?7kxZmCEdVfp9D*ZXfvUhRWtNKagq=^B={d0r}E z4M{o;8_G**Ufc+3F5U4SDok-6D2Nqxw}dlWkWr=&Lrqsv(3_<@Le;7Hzj5$>%-cgB z5Gb(3%4PSAOQi>WDT)c1MDRr|CkrobM3n+$;xAP4YL0*1E{#u*h!f57oLx^ww9}dw zbT}%eJMct;eaxCZ6O62S`-lW)eLt+8%SwjgX$ywp5ppN>s)HF>JJNq@?eWv|^PA;C z<vOQV@#VQZgPR0zCV%(_?igTl%nlNbnpVy2ijF5f zOx&dP_gG<=`Gvh-v|N`6#1w#M{;{DVps9y1eNRw1W-c54AXDqjN~QK>#@}9eYm03T zF~>aj9GvLyz>;a^fG~xwoyHW%=jbYpUrtkPyL6Y`NhxB;+xpDSq9y0sKp|)Y{Iulu z=@R)D(EXn~P~m;6F)9;@6#Z)B%?arD-j8~AKE}jWf_Z!dbkwa{$>R6AKNVWhGwXb! zuH01sRm0hWkq(m~Zc=l}rU)|yo*h4*;$cXaAGYf&$W9T{FGb*s_k&5@YLod+6 z@z07|Q!k%cqu8-6W^?-4MSjr5VIHESLZ)G^UpJizUhTeppML;?CM9>G>EB{ipWMZ- z2ymljb&{2-tgWC(7u1$A_R^o3w>5aM0G{*Et=;*ZUcPm$MD{hKyV`~kiL6;lA%oL8 zO*{$fF)F~`!pD(Iw?VJG@&nA0;ihp;p1Gr?rB06{eo-`B zB4>w7$$Y4w#VmAv7ba3(tX^E}w1?^Ncvv@TK-%BC-nCe0`i{KC#vkXdn{?Ql(MCnU zT9&@qJl(YE!Qy~iB@9@mxgrQc@Mb4*>|okC4{I5&Wye4K{ct6`Q3@g0T!LV#U|Cn% zfj((U(bDzt)k5+KoxxMd?#PDcuMmGQ_Yede6)n&tcHDMQxo@xjXKk_S64gWdja#*K z1tlHL)k-}F)S%(b3`bV@Kte=k76WP^wlD z>K9=?U9@Ezbp5SFxkQ^&ZC0y1`JW2$Md;J0ru*g$AqoNl0wOLVBU~w{=lg#E{1*Sb literal 0 HcmV?d00001 diff --git a/tools/Texture_Conversion_Table.csv b/tools/Texture_Conversion_Table.csv index 836004a0f..29cb3ce66 100644 --- a/tools/Texture_Conversion_Table.csv +++ b/tools/Texture_Conversion_Table.csv @@ -845,3 +845,4 @@ Source path,Source file,Target path,Target file,xs,ys,xl,yl,xt,yt /assets/minecraft/textures/items,banner_overlay.png,/mods/ITEMS/mcl_banners/textures,mcl_banners_item_overlay.png,,,,,, /assets/minecraft/textures/blocks,portal.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_portal.png,,,,,, /assets/minecraft/textures/entity,end_portal.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_end_portal.png,,,,,, +/assets/minecraft/textures/environment,end_sky.png,/mods/PLAYER/mcl_playerplus/textures,mcl_playerplus_end_sky.png,,,,,, From 95f62236f73c61a3d863eee1113dc6576109bd2a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 16:40:36 +0200 Subject: [PATCH 61/75] Fix Nether sky color --- mods/PLAYER/mcl_playerplus/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index a4f7473d8..02bd7b5cc 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -164,7 +164,7 @@ minetest.register_globalstep(function(dtime) local t = "mcl_playerplus_end_sky.png" player:set_sky("#000000", "skybox", {t,t,t,t,t,t}, false) elseif dim == "nether" then - player:set_sky("#300810", "plain", nil, false) + player:set_sky("#300808", "plain", nil, false) end if void_deadly then -- Player is deep into the void, deal void damage From 022682a75ed29633224a26c1399ecbbe8266a5c6 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 21:25:29 +0200 Subject: [PATCH 62/75] Refactor: Drop legacy get_mapgen_params --- mods/ITEMS/mcl_core/functions.lua | 2 +- mods/MISC/mcl_commands/init.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index 5a181069b..ba27b4c15 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -642,7 +642,7 @@ end -local grass_spread_randomizer = PseudoRandom(minetest.get_mapgen_params().seed) +local grass_spread_randomizer = PseudoRandom(minetest.get_mapgen_setting("seed")) ------------------------------ -- Spread grass blocks and mycelium on neighbor dirt diff --git a/mods/MISC/mcl_commands/init.lua b/mods/MISC/mcl_commands/init.lua index 6c0b0b798..b3041ad06 100644 --- a/mods/MISC/mcl_commands/init.lua +++ b/mods/MISC/mcl_commands/init.lua @@ -138,7 +138,7 @@ minetest.register_chatcommand("seed", { params = "", privs = {}, func = function(name) - minetest.chat_send_player(name, string.format("%d", minetest.get_mapgen_params().seed)) + minetest.chat_send_player(name, string.format("%d", minetest.get_mapgen_setting("seed"))) end }) From cfd1456dab08ab2e0dbd39548c058a143144e197 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 18 Aug 2017 21:29:25 +0200 Subject: [PATCH 63/75] Mapgen: Call update_liquids less often --- mods/MAPGEN/mcl_mapgen_core/init.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 6bb4fac06..bc448cbf2 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -901,8 +901,7 @@ end -- Apply mapgen-specific mapgen code if mg_name == "v6" then register_mgv6_decorations() -end -if mg_name == "flat" then +elseif mg_name == "flat" then local classic = minetest.get_mapgen_setting("mcl_superflat_classic") if classic == nil then classic = minetest.settings:get_bool("mcl_superflat_classic") @@ -1209,6 +1208,7 @@ minetest.register_on_generated(function(minp, maxp) local data = vm:get_data(lvm_buffer) local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) local lvm_used = false + local liquids_used = false -- Generate bedrock and lava layers if minp.y <= GEN_MAX then @@ -1287,15 +1287,18 @@ minetest.register_on_generated(function(minp, maxp) if y <= mcl_vars.mg_lava_overworld_max and y >= mcl_vars.mg_overworld_min then data[p_pos] = c_lava lvm_used = true + liquids_used = true elseif y <= mcl_vars.mg_lava_nether_max and y >= mcl_vars.mg_nether_min then data[p_pos] = c_nether_lava lvm_used = true + liquids_used = true end -- Water in the Nether or End? No way! elseif data[p_pos] == c_water then if y <= mcl_vars.mg_nether_max and y >= mcl_vars.mg_nether_min then data[p_pos] = c_nether_lava lvm_used = true + liquids_used = true elseif y <= mcl_vars.mg_end_min + 104 and y >= mcl_vars.mg_end_min + 40 then data[p_pos] = c_end_stone lvm_used = true @@ -1355,7 +1358,9 @@ minetest.register_on_generated(function(minp, maxp) if lvm_used then vm:set_data(data) vm:calc_lighting() - vm:update_liquids() + if liquids_used then + vm:update_liquids() + end vm:write_to_map() end From c9f277f7e03ba8de5a4f1c0a9915ef44b64ea61d Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Sat, 19 Aug 2017 11:17:38 +0200 Subject: [PATCH 64/75] Update sky color more often --- mods/PLAYER/mcl_playerplus/depends.txt | 1 + mods/PLAYER/mcl_playerplus/init.lua | 2 ++ 2 files changed, 3 insertions(+) diff --git a/mods/PLAYER/mcl_playerplus/depends.txt b/mods/PLAYER/mcl_playerplus/depends.txt index 45b93f966..467d9b138 100644 --- a/mods/PLAYER/mcl_playerplus/depends.txt +++ b/mods/PLAYER/mcl_playerplus/depends.txt @@ -6,3 +6,4 @@ mcl_hunger mcl_death_messages mcl_playerinfo 3d_armor? +weather_pack diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 02bd7b5cc..1d4debbf5 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -165,6 +165,8 @@ minetest.register_globalstep(function(dtime) player:set_sky("#000000", "skybox", {t,t,t,t,t,t}, false) elseif dim == "nether" then player:set_sky("#300808", "plain", nil, false) + else + skycolor.update_sky_color({player}) end if void_deadly then -- Player is deep into the void, deal void damage From dd5730a33da5086c1997c07cbeb53c28b3323047 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Sun, 20 Aug 2017 22:18:26 +0200 Subject: [PATCH 65/75] Fix water in the End --- mods/MAPGEN/mcl_mapgen_core/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index bc448cbf2..77b28decd 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1222,6 +1222,7 @@ minetest.register_on_generated(function(minp, maxp) local c_soul_sand = minetest.get_content_id("mcl_nether:soul_sand") local c_netherrack = minetest.get_content_id("mcl_nether:netherrack") local c_nether_lava = minetest.get_content_id("mcl_nether:nether_lava_source") + local c_end_stone = minetest.get_content_id("mcl_end:end_stone") local c_realm_barrier = minetest.get_content_id("mcl_core:realm_barrier") local c_air = minetest.get_content_id("air") From b34c4ad4970f475a977113fd81dda21d84c2ca0f Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 21 Aug 2017 02:25:22 +0200 Subject: [PATCH 66/75] Add important decorations for v7, v5, etc. --- mods/MAPGEN/mcl_biomes/depends.txt | 3 +- mods/MAPGEN/mcl_biomes/init.lua | 449 ++++++++++++++++++--------- mods/MAPGEN/mcl_mapgen_core/init.lua | 162 +--------- 3 files changed, 311 insertions(+), 303 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/depends.txt b/mods/MAPGEN/mcl_biomes/depends.txt index 442501faa..39cd4d88a 100644 --- a/mods/MAPGEN/mcl_biomes/depends.txt +++ b/mods/MAPGEN/mcl_biomes/depends.txt @@ -1,3 +1,4 @@ +mcl_init mcl_core mcl_farming -mcl_flowers +mcl_flowers \ No newline at end of file diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 898c082bf..055bf4e2c 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1,3 +1,4 @@ +local mg_name = minetest.get_mapgen_setting("mg_name") -- -- Register biomes @@ -48,7 +49,7 @@ local function register_biomes() minetest.register_biome({ name = "icesheet_ocean", node_dust = "mcl_core:snowblock", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, node_filler = "mcl_core:stone", depth_filler = 3, @@ -89,11 +90,11 @@ local function register_biomes() minetest.register_biome({ name = "tundra_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, node_filler = "mcl_core:stone", depth_filler = 3, - node_riverbed = "mcl_core:gravel", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = -4, @@ -118,11 +119,11 @@ local function register_biomes() minetest.register_biome({ name = "taiga_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, node_filler = "mcl_core:stone", depth_filler = 3, - node_riverbed = "mcl_core:stone", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = 1, @@ -131,7 +132,6 @@ local function register_biomes() }) -- Snowy grassland - minetest.register_biome({ name = "snowy_grassland", node_dust = "mcl_core:snow", @@ -162,7 +162,6 @@ local function register_biomes() }) -- Grassland - minetest.register_biome({ name = "grassland", node_top = "mcl_core:dirt_with_grass", @@ -207,7 +206,6 @@ local function register_biomes() }) -- Coniferous forest - minetest.register_biome({ name = "coniferous_forest", node_top = "mcl_core:dirt_with_grass", @@ -251,8 +249,6 @@ local function register_biomes() }) -- Deciduous forest - - minetest.register_biome({ name = "deciduous_forest", node_top = "mcl_core:dirt_with_grass", @@ -296,7 +292,6 @@ local function register_biomes() }) -- Desert - minetest.register_biome({ name = "desert", node_top = "mcl_core:redsand", @@ -328,7 +323,6 @@ local function register_biomes() }) -- Sandstone desert - minetest.register_biome({ name = "sandstone_desert", node_top = "mcl_core:sand", @@ -360,7 +354,6 @@ local function register_biomes() }) -- Cold desert - minetest.register_biome({ name = "cold_desert", --node_dust = "", @@ -408,11 +401,11 @@ local function register_biomes() -- Savanna minetest.register_biome({ name = "savanna", - node_top = "mcl_core:dirt_with_grass", + node_top = "mcl_core:coarse_dirt", depth_top = 1, - node_filler = "mcl_core:dirt", + node_filler = "mcl_core:coarse_dirt", depth_filler = 1, - node_riverbed = "mcl_core:sand", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = 1, y_max = upper_limit, @@ -449,7 +442,6 @@ local function register_biomes() }) -- Rainforest - minetest.register_biome({ name = "rainforest", node_top = "mcl_core:podzol", @@ -597,7 +589,7 @@ local function register_biomelike_ores() clust_scarcity = 16 * 16 * 16, clust_size = 3, y_min = 25, - y_max = 31000, + y_max = mcl_vars.mg_overworld_max, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -814,17 +806,6 @@ local function register_biomelike_ores() noise_threshold = 0.0, noise_params = {offset=0, scale=1, spread={x=3100, y=3100, z=3100}, seed=23, octaves=3, persist=0.70} , }) - minetest.register_ore({ - ore_type = "sheet", - ore = "mcl_core:obsidian", - wherein = {"mcl_colorblocks:hardened_clay_orange"}, - - clust_size = 8, - y_min = 161, - y_max = 170, - noise_threshold = 0.0, - noise_params = {offset=0, scale=1, spread= {x=3100, y=3100, z=3100}, seed=23, octaves=3, persist=0.70} , - }) end -- Non-Overworld ores @@ -1046,23 +1027,182 @@ end -- All mapgens except mgv6 local function register_grass_decoration(offset, scale) + local noise_grass = { + offset = offset, + scale = scale, + spread = {x = 200, y = 200, z = 200}, + seed = 329, + octaves = 3, + persist = 0.6 + } minetest.register_decoration({ deco_type = "simple", - place_on = {"mcl_core:dirt_with_grass"}, + place_on = {"mcl_core:dirt_with_grass", "mcl_core:dirt_with_grass_snow"}, + sidelen = 16, + noise_params = noise_grass, + biomes = {"grassland", "snowy_grassland", "coniferous_forest", "deciduous_forest", "savanna"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_flowers:tallgrass", + }) + + local noise_fern = table.copy(noise_grass) + noise_fern.seed = 923, + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt_with_grass", "mcl_core:dirt_with_grass_snow", "mcl_core:podzol", "mcl_core:podzol_snow"}, + sidelen = 16, + noise_params = noise_fern, + biomes = { "rainforest", "taiga", "cold_taiga", "mega_taiga" }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_flowers:fern", + }) +end + +-- Decorations which can be used by all mapgens, including v6, but not flat +local function register_shared_decorations() + + -- Doubletall grass + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_flowers:double_grass", param1=255, }, + { name = "mcl_flowers:double_grass_top", param1=255, }, + }, + }, + replacements = { + ["mcl_flowers:tallgrass"] = "mcl_flowers:double_grass" + }, + place_on = {"mcl_core:dirt_with_grass", "mcl_core:dirt_with_grass_snow"}, sidelen = 16, noise_params = { - offset = offset, - scale = scale, - spread = {x = 200, y = 200, z = 200}, - seed = 329, + offset = 55,---0.01, + scale = 0.03, + spread = {x = 500, y = 500, z = 500}, + seed = 420, + octaves = 2, + persist = 0.6, + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + flags = "", + biomes = {"grassland", "snowy_grassland", "coniferous_forest", "deciduous_forest", "savanna"}, + }) + + -- v6 hack: This makes sure large ferns only appear in jungles + local spawn_by, num_spawn_by + if mg_name == "v6" then + spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" } + num_spawn_by = 1 + end + -- Large ferns + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_flowers:double_fern", param1=255, }, + { name = "mcl_flowers:double_fern_top", param1=255, }, + }, + }, + replacements = { + ["mcl_flowers:fern"] = "mcl_flowers:double_fern" + }, + spawn_by = spawn_by, + num_spawn_by = num_spawn_by, + place_on = {"mcl_core:dirt_with_grass", "mcl_core:podzol"}, + + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.01, + spread = {x = 250, y = 250, z = 250}, + seed = 333, + octaves = 2, + persist = 0.66, + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + flags = "", + biomes = { "rainforest", "taiga", "cold_taiga", "mega_taiga" }, + }) + + -- Cacti + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand"}, + sidelen = 16, + noise_params = { + offset = -0.012, + scale = 0.024, + spread = {x = 100, y = 100, z = 100}, + seed = 257, octaves = 3, persist = 0.6 }, - biomes = {"grassland", "coniferous_forest", "deciduous_forest", "savanna"}, - y_min = 1, - y_max = 31000, - decoration = "mcl_flowers:tallgrass", + y_min = 4, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:cactus", + biomes = {"desert","sandstone_desert","grassland_dunes", "coniferous_forest_dunes"}, + height = 1, + height_max = 3, }) + + -- Sugar canes + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_core:dirt", "mcl_core:dirt_with_grass", "group:sand", "mcl_core:podzol"}, + sidelen = 16, + noise_params = { + offset = -0.3, + scale = 0.7, + spread = {x = 100, y = 100, z = 100}, + seed = 2, + octaves = 3, + persist = 0.7 + }, + biomes = {"grassland", "snowy_grassland", "beach", "desert", "sandstone_desert", "swamp"}, + y_min = 1, + y_max = 1, + decoration = "mcl_core:reeds", + height = 1, + height_max = 3, + spawn_by = { "mcl_core:water_source", "group:frosted_ice" }, + num_spawn_by = 1, + }) + + -- Pumpkin + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=2, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_farming:pumpkin_face", param1=255, }, + }, + }, + place_on = {"mcl_core:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = -0.008, + scale = 0.00666, + spread = {x = 250, y = 250, z = 250}, + seed = 666, + octaves = 6, + persist = 0.666 + }, + biomes = {"grassland"}, + y_min = 3, + y_max = 29, + rotation = "random", + }) + end local function register_decorations() @@ -1349,58 +1489,6 @@ local function register_decorations() --TODO MAKE SCHEMATICS - - --Red Mushroom - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_core:mycelium"}, - sidelen = 80, - fill_ratio = 0.004, - biomes = {"mushroom"}, - y_min = -6000, - y_max = 31000, - decoration = "mcl_mushrooms:mushroom_red", - }) - --Brown Mushroom - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_core:mycelium"}, - sidelen = 80, - fill_ratio = 0.003, - biomes = {"mushroom"}, - y_min = -6000, - y_max = 31000, - decoration = "mcl_mushrooms:mushroom_brown", - }) - - --Red Mushroom - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_core:mycelium", "mcl_core:mycelium_snow"}, - sidelen = 80, - fill_ratio = 0.0002, - biomes = {"mushroom", "mushroom_cold"}, - y_min = -6000, - y_max = 31000, - decoration = "mcl_mushrooms:mushroom_red", - }) - - --Huge Mushroom - minetest.register_decoration({ - deco_type = "schematic", - place_on = {"mcl_core:mycelium", "mcl_core:mycelium_snow"}, - sidelen = 80, - fill_ratio = 0.0004, - biomes = {"mushroom", "mushroom_cold"}, - y_min = -6000, - y_max = 31000, - schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_huge_brown.mts", - flags = "place_center_x", - rotation = "random", - }) - - - --Huge Brown Mushroom minetest.register_decoration({ deco_type = "schematic", @@ -1429,6 +1517,60 @@ local function register_decorations() rotation = "random", }) + -- Large flowers + local register_large_flower = function(name, biomes, seed, offset) + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_flowers:"..name, param1=255, }, + { name = "mcl_flowers:"..name.."_top", param1=255, }, + }, + }, + place_on = {"mcl_core:dirt_with_grass"}, + + sidelen = 16, + noise_params = { + offset = offset, + scale = 0.01, + spread = {x = 300, y = 300, z = 300}, + seed = seed, + octaves = 5, + persist = 0.62, + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + flags = "", + biomes = biomes, + }) + end + + register_large_flower("rose_bush", {"deciduous_forest", "coniferous_forest", "flower_forest"}, 9350, -0.008) + register_large_flower("peony", {"deciduous_forest", "coniferous_forest", "flower_forest"}, 10450, -0.008) + register_large_flower("lilac", {"deciduous_forest", "coniferous_forest", "flower_forest"}, 10600, -0.007) + -- TODO: Make exclusive to sunflower plains + register_large_flower("sunflower", {"grassland", "sunflower_plains"}, 2940, -0.005) + + -- Melon + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt_with_grass", "mcl_core:podzol"}, + sidelen = 16, + noise_params = { + offset = 0.003, + scale = 0.006, + spread = {x = 250, y = 250, z = 250}, + seed = 333, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_farming:melon", + biomes = { "rainforest" }, + }) -- Simple 1×1×1 moss stone minetest.register_decoration({ @@ -1441,52 +1583,8 @@ local function register_decorations() y_max = 31000, decoration = "mcl_core:mossycobble", }) - -- Cactus - - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_core:sand", "mcl_core:redsand"}, - sidelen = 16, - noise_params = { - offset = -0.0003, - scale = 0.0009, - spread = {x = 200, y = 200, z = 200}, - seed = 230, - octaves = 3, - persist = 0.6 - }, - biomes = {"desert"}, - y_min = 5, - y_max = 31000, - decoration = "mcl_core:cactus", - biomes = {"desert","sandstone_desert","grassland_dunes", "coniferous_forest_dunes"}, - height = 1, - height_max = 3, - }) - - -- Sugar canes - minetest.register_decoration({ - deco_type = "schematic", - place_on = {"mcl_core:dirt", "mcl_core:dirt_with_grass"}, - sidelen = 16, - noise_params = { - offset = -0.3, - scale = 0.7, - spread = {x = 200, y = 200, z = 200}, - seed = 354, - octaves = 3, - persist = 0.7 - }, - biomes = {"grassland", "savanna", "beach", "desert", "savanna_swamp"}, - y_min = 0, - y_max = 0, - decoration = "mcl_core:reeds", - height = 1, - height_max = 3, - }) -- Grasses - register_grass_decoration(-0.03, 0.09) register_grass_decoration(-0.015, 0.075) register_grass_decoration(0, 0.06) @@ -1498,27 +1596,88 @@ local function register_decorations() register_grass_decoration(0.07, -0.01) register_grass_decoration(0.09, -0.03) - -- Dead bushes - + --Red Mushroom minetest.register_decoration({ deco_type = "simple", - place_on = {"mcl_core:sand", "mcl_core:redsand"}, + place_on = {"mcl_core:mycelium"}, + sidelen = 80, + fill_ratio = 0.003, + biomes = {"mushroom"}, + y_min = -6000, + y_max = 31000, + decoration = "mcl_mushrooms:mushroom_red", + }) + + --Brown Mushroom + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:mycelium"}, + sidelen = 80, + fill_ratio = 0.003, + biomes = {"mushroom"}, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_mushrooms:mushroom_brown", + }) + + -- Dead bushes + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand", "mcl_core:podzol", "mcl_core:podzol_snow", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"}, sidelen = 16, noise_params = { offset = 0, - scale = 0.02, - spread = {x = 200, y = 200, z = 200}, - seed = 329, + scale = 0.035, + spread = {x = 100, y = 100, z = 100}, + seed = 1972, octaves = 3, persist = 0.6 }, - biomes = {"desert"}, - y_min = 2, - y_max = 31000, + y_min = 4, + y_max = mcl_vars.mg_overworld_max, + biomes = {"desert", "sandstone_desert", "mesa", "taiga", "mega_taiga"}, decoration = "mcl_core:deadbush", height = 1, }) + local function register_flower(name, biomes, seed) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt_with_grass", "mcl_core:podzol"}, + sidelen = 16, + noise_params = { + offset = 0.0, + scale = 0.006, + spread = {x = 100, y = 100, z = 100}, + seed = seed, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + biomes = biomes, + decoration = "mcl_flowers:"..name, + }) + end + + local flower_biomes1 = {"grassland", "snowy_grassland", "sunflower_plains", "flower_forest", "deciduous_forest", "coniferous_forest", "taiga"} + + register_flower("dandelion", flower_biomes1, 8) + register_flower("poppy", flower_biomes1, 9439) + + local flower_biomes2 = {"grassland", "snowy_grassland", "sunflower_plains", "flower_forest"} + register_flower("tulip_red", flower_biomes2, 436) + register_flower("tulip_orange", flower_biomes2, 536) + register_flower("tulip_pink", flower_biomes2, 636) + register_flower("tulip_white", flower_biomes2, 736) + register_flower("azure_bluet", flower_biomes2, 800) + register_flower("oxeye_daisy", flower_biomes2, 3490) + + -- TODO: Make exclusive to flower forest + register_flower("allium", {"deciduous_forest", "flower_forest"}, 0) + -- TODO: Make exclusive to swamp + register_flower("blue_orchid", {"coniferous_forest", "swamp"}, 64500) + end @@ -1576,7 +1735,9 @@ end -- -- Detect mapgen to select functions -- -local mg_name = minetest.get_mapgen_setting("mg_name") +if mg_name ~= "flat" then + register_shared_decorations() +end if mg_name ~= "v6" and mg_name ~= "flat" then minetest.clear_registered_biomes() minetest.clear_registered_decorations() diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 77b28decd..c7e133140 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -602,112 +602,6 @@ minetest.register_ore({ local function register_mgv6_decorations() - -- Sugar canes - - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_core:dirt_with_grass"}, - sidelen = 16, - noise_params = { - offset = -0.3, - scale = 0.7, - spread = {x = 100, y = 100, z = 100}, - seed = 2, - octaves = 3, - persist = 0.7 - }, - y_min = 1, - y_max = 1, - decoration = "mcl_core:reeds", - height = 2, - height_max = 4, - spawn_by = "mcl_core:water_source", - num_spawn_by = 1, - }) - - -- Cacti - - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:sand"}, - sidelen = 16, - noise_params = { - offset = -0.012, - scale = 0.024, - spread = {x = 100, y = 100, z = 100}, - seed = 257, - octaves = 3, - persist = 0.6 - }, - y_min = 4, - y_max = 30, - decoration = "mcl_core:cactus", - height = 1, - height_max = 3, - }) - - -- Doubletall grass - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:double_grass", param1=255, }, - { name = "mcl_flowers:double_grass_top", param1=255, }, - }, - }, - replacements = { - ["mcl_flowers:tallgrass"] = "mcl_flowers:double_grass" - }, - place_on = {"mcl_core:dirt_with_grass"}, - sidelen = 8, - noise_params = { - offset = -0.01, - scale = 0.03, - spread = {x = 500, y = 500, z = 500}, - seed = 420, - octaves = 2, - persist = 0.6, - }, - y_min = 1, - y_max = 40, - flags = "", - }) - - -- Large ferns - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:double_fern", param1=255, }, - { name = "mcl_flowers:double_fern_top", param1=255, }, - }, - }, - replacements = { - ["mcl_flowers:fern"] = "mcl_flowers:double_fern" - }, - -- This makes sure large ferns only appear in jungles - spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, - num_spawn_by = 1, - place_on = {"mcl_core:dirt_with_grass"}, - - sidelen = 16, - noise_params = { - offset = 0, - scale = 0.01, - spread = {x = 250, y = 250, z = 250}, - seed = 333, - octaves = 2, - persist = 0.66, - }, - y_min = 1, - y_max = 30, - flags = "", - }) - -- Large flowers local register_large_flower = function(name, seed, offset) minetest.register_decoration({ @@ -796,10 +690,9 @@ local function register_mgv6_decorations() end -- Dead bushes - minetest.register_decoration({ deco_type = "simple", - place_on = {"group:sand", "mcl_core:podzol", "mcl_core:coarse_dirt", "mcl_colorblocks:hardened_clay"}, + place_on = {"group:sand", "mcl_core:podzol", "mcl_core:podzol_snow", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"}, sidelen = 16, noise_params = { offset = 0, @@ -849,53 +742,6 @@ local function register_mgv6_decorations() register_mgv6_flower("oxeye_daisy", 3490) register_mgv6_flower("poppy", 9439) - -- Pumpkin - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=2, z=1 }, - data = { - { name = "air", prob = 0 }, - { name = "mcl_farming:pumpkin_face", param1=255, }, - }, - }, - place_on = {"mcl_core:dirt_with_grass"}, - sidelen = 16, - noise_params = { - offset = -0.008, - scale = 0.00666, - spread = {x = 250, y = 250, z = 250}, - seed = 666, - octaves = 6, - persist = 0.666 - }, - y_min = 3, - y_max = 29, - rotation = "random", - }) - - -- Melon - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_core:dirt_with_grass"}, - sidelen = 16, - noise_params = { - offset = 0.003, - scale = 0.006, - spread = {x = 250, y = 250, z = 250}, - seed = 333, - octaves = 3, - persist = 0.6 - }, - -- Small trick to make sure melon spawn in jungles - spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, - num_spawn_by = 1, - y_min = 1, - y_max = 40, - decoration = "mcl_farming:melon", - }) - - end -- Apply mapgen-specific mapgen code @@ -952,7 +798,7 @@ minetest.register_on_generated(function(minp, maxp, seed) num_water_around = num_water_around + 1 end if num_water_around >= 2 then is_shallow = false - end + end if is_shallow then for x1=-divlen,divlen do for z1=-divlen,divlen do @@ -993,7 +839,7 @@ minetest.register_on_generated(function(minp, maxp, seed) break end end - + if ground_y then local p = {x=x,y=ground_y+1,z=z} local nn = minetest.get_node(p).name @@ -1040,7 +886,7 @@ minetest.register_on_generated(function(minp, maxp, seed) end end end - + end end end From 1f40c867547caaec9fc73c6b59f73a91c4b0b19f Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 21 Aug 2017 02:28:15 +0200 Subject: [PATCH 67/75] Generate vines and cocoas in v5, v7, etc., too --- mods/MAPGEN/mcl_mapgen_core/init.lua | 193 +++++++++++++-------------- 1 file changed, 95 insertions(+), 98 deletions(-) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index c7e133140..939769cff 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -903,121 +903,118 @@ local lvm_buffer = {} -- Generate cocoas and vines at jungle trees within the bounding box local function generate_jungle_tree_decorations(minp, maxp) - if mg_name == "v6" then + if maxp.y < 0 then + return + end + + local pos, treepos, dir + local jungletree = minetest.find_nodes_in_area(minp, maxp, "mcl_core:jungletree") + local jungleleaves = minetest.find_nodes_in_area(minp, maxp, "mcl_core:jungleleaves") + + -- Pass 1: Generate cocoas + for n = 1, #jungletree do + + pos = jungletree[n] + treepos = table.copy(pos) + + if minetest.find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then + + dir = math.random(1, 40) + + if dir == 1 then + pos.z = pos.z + 1 + elseif dir == 2 then + pos.z = pos.z - 1 + elseif dir == 3 then + pos.x = pos.x + 1 + elseif dir == 4 then + pos.x = pos.x -1 + end + + local nn = minetest.get_node(pos).name + + if dir < 5 + and nn == "air" + and minetest.get_node_light(pos) > 12 then + minetest.swap_node(pos, { + name = "mcl_cocoas:cocoa_" .. tostring(math.random(1, 3)), + param2 = minetest.dir_to_facedir(vector.subtract(treepos, pos)) + }) + end - if maxp.y < 0 then - return end + end - local pos, treepos, dir - local jungletree = minetest.find_nodes_in_area(minp, maxp, "mcl_core:jungletree") - local jungleleaves = minetest.find_nodes_in_area(minp, maxp, "mcl_core:jungleleaves") + -- Pass 2: Generate vines at jungle wood and jungle leaves + perlin_vines = perlin_vines or minetest.get_perlin(555, 4, 0.6, 500) + perlin_vines_fine = perlin_vines_fine or minetest.get_perlin(43000, 3, 0.6, 1) + perlin_vines_length = perlin_vines_length or minetest.get_perlin(435, 4, 0.6, 75) + perlin_vines_upwards = perlin_vines_upwards or minetest.get_perlin(436, 3, 0.6, 10) + perlin_vines_density = perlin_vines_density or minetest.get_perlin(436, 3, 0.6, 500) + local junglething + for i=1, 2 do + if i==1 then junglething = jungletree + else junglething = jungleleaves end - -- Pass 1: Generate cocoas - for n = 1, #jungletree do + for n = 1, #junglething do + pos = junglething[n] - pos = jungletree[n] treepos = table.copy(pos) - if minetest.find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then + local dirs = { + {x=1,y=0,z=0}, + {x=-1,y=0,z=0}, + {x=0,y=0,z=1}, + {x=0,y=0,z=-1}, + } - dir = math.random(1, 40) + for d = 1, #dirs do + local pos = vector.add(pos, dirs[d]) - if dir == 1 then - pos.z = pos.z + 1 - elseif dir == 2 then - pos.z = pos.z - 1 - elseif dir == 3 then - pos.x = pos.x + 1 - elseif dir == 4 then - pos.x = pos.x -1 - end + local nn = minetest.get_node(pos).name - local nn = minetest.get_node(pos).name + if perlin_vines:get2d(pos) > 0.1 and perlin_vines_fine:get3d(pos) > math.max(0.3333, perlin_vines_density:get2d(pos)) and nn == "air" then - if dir < 5 - and nn == "air" - and minetest.get_node_light(pos) > 12 then - minetest.swap_node(pos, { - name = "mcl_cocoas:cocoa_" .. tostring(math.random(1, 3)), - param2 = minetest.dir_to_facedir(vector.subtract(treepos, pos)) - }) - end - - end - end - - -- Pass 2: Generate vines at jungle wood and jungle leaves - perlin_vines = perlin_vines or minetest.get_perlin(555, 4, 0.6, 500) - perlin_vines_fine = perlin_vines_fine or minetest.get_perlin(43000, 3, 0.6, 1) - perlin_vines_length = perlin_vines_length or minetest.get_perlin(435, 4, 0.6, 75) - perlin_vines_upwards = perlin_vines_upwards or minetest.get_perlin(436, 3, 0.6, 10) - perlin_vines_density = perlin_vines_density or minetest.get_perlin(436, 3, 0.6, 500) - local junglething - for i=1, 2 do - if i==1 then junglething = jungletree - else junglething = jungleleaves end - - for n = 1, #junglething do - pos = junglething[n] - - treepos = table.copy(pos) - - local dirs = { - {x=1,y=0,z=0}, - {x=-1,y=0,z=0}, - {x=0,y=0,z=1}, - {x=0,y=0,z=-1}, + local newnode = { + name = "mcl_core:vine", + param2 = minetest.dir_to_wallmounted(vector.subtract(treepos, pos)) } - for d = 1, #dirs do - local pos = vector.add(pos, dirs[d]) - - local nn = minetest.get_node(pos).name - - if perlin_vines:get2d(pos) > 0.1 and perlin_vines_fine:get3d(pos) > math.max(0.3333, perlin_vines_density:get2d(pos)) and nn == "air" then - - local newnode = { - name = "mcl_core:vine", - param2 = minetest.dir_to_wallmounted(vector.subtract(treepos, pos)) - } - - -- Determine growth direction - local grow_upwards = false - -- Only possible on the wood, not on the leaves - if i == 1 then - grow_upwards = perlin_vines_upwards:get3d(pos) > 0.8 + -- Determine growth direction + local grow_upwards = false + -- Only possible on the wood, not on the leaves + if i == 1 then + grow_upwards = perlin_vines_upwards:get3d(pos) > 0.8 + end + if grow_upwards then + -- Grow vines up 1-4 nodes, even through jungleleaves. + -- This may give climbing access all the way to the top of the tree :-) + -- But this will be fairly rare. + local length = math.ceil(math.abs(perlin_vines_length:get3d(pos)) * 4) + for l=0, length-1 do + local tnn = minetest.get_node(treepos).name + local nn = minetest.get_node(pos).name + if (nn == "air" or nn == "mcl_core:jungleleaves") and mcl_core.supports_vines(tnn) then + minetest.set_node(pos, newnode) + else + break + end + pos.y = pos.y + 1 + treepos.y = treepos.y + 1 end - if grow_upwards then - -- Grow vines up 1-4 nodes, even through jungleleaves. - -- This may give climbing access all the way to the top of the tree :-) - -- But this will be fairly rare. - local length = math.ceil(math.abs(perlin_vines_length:get3d(pos)) * 4) - for l=0, length-1 do - local tnn = minetest.get_node(treepos).name - local nn = minetest.get_node(pos).name - if (nn == "air" or nn == "mcl_core:jungleleaves") and mcl_core.supports_vines(tnn) then - minetest.set_node(pos, newnode) - else - break - end - pos.y = pos.y + 1 - treepos.y = treepos.y + 1 - end - else - -- Grow vines down 1-7 nodes - local length = math.ceil(math.abs(perlin_vines_length:get3d(pos)) * 7) - for l=0, length-1 do - if minetest.get_node(pos).name == "air" then - minetest.set_node(pos, newnode) - else - break - end - pos.y = pos.y - 1 + else + -- Grow vines down 1-7 nodes + local length = math.ceil(math.abs(perlin_vines_length:get3d(pos)) * 7) + for l=0, length-1 do + if minetest.get_node(pos).name == "air" then + minetest.set_node(pos, newnode) + else + break end + pos.y = pos.y - 1 end end - end + end end end end From a69ab5ec3491266a4e2acd5d1c28a4235ca0e885 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 21 Aug 2017 02:31:10 +0200 Subject: [PATCH 68/75] Remove fallen log schematics and mushrooms on logs --- mods/ITEMS/mcl_core/schematics/acacia_log.mts | Bin 65 -> 0 bytes mods/ITEMS/mcl_core/schematics/apple_log.mts | Bin 90 -> 0 bytes mods/ITEMS/mcl_core/schematics/aspen_log.mts | Bin 118 -> 0 bytes mods/ITEMS/mcl_core/schematics/jungle_log.mts | Bin 96 -> 0 bytes mods/ITEMS/mcl_core/schematics/pine_log.mts | Bin 93 -> 0 bytes mods/MAPGEN/mcl_biomes/init.lua | 10 +++++----- 6 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 mods/ITEMS/mcl_core/schematics/acacia_log.mts delete mode 100644 mods/ITEMS/mcl_core/schematics/apple_log.mts delete mode 100644 mods/ITEMS/mcl_core/schematics/aspen_log.mts delete mode 100644 mods/ITEMS/mcl_core/schematics/jungle_log.mts delete mode 100644 mods/ITEMS/mcl_core/schematics/pine_log.mts diff --git a/mods/ITEMS/mcl_core/schematics/acacia_log.mts b/mods/ITEMS/mcl_core/schematics/acacia_log.mts deleted file mode 100644 index 037bca8c32152f0927ff027811e918e713872b91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65 zcmeYb3HD`RVPIxpVqmPVXJBGrPRuM~5Kc)=ODxSPu}Vx%OwLSi!+My r^K;{qit@|zD&{07Ffh9rq$DITeSY-%t>hC&9yvKV1x^N`IL0&pk~SOx diff --git a/mods/ITEMS/mcl_core/schematics/aspen_log.mts b/mods/ITEMS/mcl_core/schematics/aspen_log.mts deleted file mode 100644 index 180e6fd1be8b31d1578f057edd7e3fb3f321c5ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 118 zcmeYb3HD`RVPIxpW?-zZuLm&`Gm996Qc}|rOLI!B5{nB`^Wsa2Qd1d3(sJ_4Q;UkN za!ZRdit_VwfConL(8Kfj7uzh~@`t8%Fjy!U5atfRbqF)(T F004eZD475N diff --git a/mods/ITEMS/mcl_core/schematics/jungle_log.mts b/mods/ITEMS/mcl_core/schematics/jungle_log.mts deleted file mode 100644 index 54fa16d175a053f47c4ee55d678b33dbf507f314..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 zcmeYb3HD`RVPIxpW?-zZuLm&_Gm996Qc}|rOLI!BvP$#Pb5cu+Qd1ek(sJ_4Q;UkN xa!ZRdit_Vwe)RgS Date: Mon, 21 Aug 2017 02:35:31 +0200 Subject: [PATCH 69/75] Move mushroom gen to mcl_biomes --- mods/MAPGEN/mcl_biomes/init.lua | 24 ++++++++++++++++++++++++ mods/MAPGEN/mcl_mapgen_core/init.lua | 24 ------------------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 74f7be235..8759d2895 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1203,6 +1203,30 @@ local function register_shared_decorations() rotation = "random", }) + local mushrooms = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"} + local mseeds = { 7133, 8244 } + for m=1, #mushrooms do + -- Mushrooms next to trees + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt_with_grass", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:mycelium", "mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.04, + spread = {x = 100, y = 100, z = 100}, + seed = mseeds[m], + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = mushrooms[m], + spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", "mcl_core:jungletree", "mcl_core:acaciatree" }, + num_spawn_by = 1, + }) + end + end local function register_decorations() diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 939769cff..2ef5654e2 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -665,30 +665,6 @@ local function register_mgv6_decorations() decoration = "mcl_flowers:tallgrass", }) - local mushrooms = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"} - local mseeds = { 7133, 8244 } - for m=1, #mushrooms do - -- Mushrooms next to trees - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_core:dirt_with_grass", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:mycelium", "mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite"}, - sidelen = 16, - noise_params = { - offset = 0, - scale = 0.04, - spread = {x = 100, y = 100, z = 100}, - seed = mseeds[m], - octaves = 3, - persist = 0.6 - }, - y_min = 1, - y_max = 128, - decoration = mushrooms[m], - spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", "mcl_core:jungletree", "mcl_core:acaciatree" }, - num_spawn_by = 1, - }) - end - -- Dead bushes minetest.register_decoration({ deco_type = "simple", From 5f6bc471856e8d93a437b1164af00a2d7d62c84a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 21 Aug 2017 02:37:29 +0200 Subject: [PATCH 70/75] Fix savannah cover --- mods/MAPGEN/mcl_biomes/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 8759d2895..4c20fa473 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -401,11 +401,11 @@ local function register_biomes() -- Savanna minetest.register_biome({ name = "savanna", - node_top = "mcl_core:coarse_dirt", + node_top = "mcl_core:dirt_with_grass", depth_top = 1, node_filler = "mcl_core:coarse_dirt", - depth_filler = 1, - node_riverbed = "mcl_core:dirt", + depth_filler = 2, + node_riverbed = "mcl_core:coarse_dirt", depth_riverbed = 2, y_min = 1, y_max = upper_limit, From 4a66e390de8e0a157a5edb055440ef1ed038307a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 21 Aug 2017 02:52:38 +0200 Subject: [PATCH 71/75] Fix missing large plants in v7 etc. --- mods/MAPGEN/mcl_biomes/init.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 4c20fa473..58578396e 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1081,9 +1081,9 @@ local function register_shared_decorations() place_on = {"mcl_core:dirt_with_grass", "mcl_core:dirt_with_grass_snow"}, sidelen = 16, noise_params = { - offset = 55,---0.01, + offset = -0.01, scale = 0.03, - spread = {x = 500, y = 500, z = 500}, + spread = {x = 300, y = 300, z = 300}, seed = 420, octaves = 2, persist = 0.6, @@ -1759,13 +1759,13 @@ end -- -- Detect mapgen to select functions -- +minetest.clear_registered_biomes() +minetest.clear_registered_decorations() +minetest.clear_registered_schematics() if mg_name ~= "flat" then register_shared_decorations() end if mg_name ~= "v6" and mg_name ~= "flat" then - minetest.clear_registered_biomes() - minetest.clear_registered_decorations() - minetest.clear_registered_schematics() register_biomes() register_biomelike_ores() register_decorations() From 0ac05ee84744bbddd48d9a24bdb4d86db05a03d2 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 21 Aug 2017 03:19:06 +0200 Subject: [PATCH 72/75] Fix fern/tallgrass confusion bugs --- mods/MAPGEN/mcl_biomes/init.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 58578396e..996cfb567 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1047,7 +1047,7 @@ local function register_grass_decoration(offset, scale) }) local noise_fern = table.copy(noise_grass) - noise_fern.seed = 923, + noise_fern.seed = 923 minetest.register_decoration({ deco_type = "simple", @@ -1090,7 +1090,6 @@ local function register_shared_decorations() }, y_min = 1, y_max = mcl_vars.mg_overworld_max, - flags = "", biomes = {"grassland", "snowy_grassland", "coniferous_forest", "deciduous_forest", "savanna"}, }) @@ -1116,7 +1115,7 @@ local function register_shared_decorations() }, spawn_by = spawn_by, num_spawn_by = num_spawn_by, - place_on = {"mcl_core:dirt_with_grass", "mcl_core:podzol"}, + place_on = {"mcl_core:podzol", "mcl_core:podzol_snow"}, sidelen = 16, noise_params = { @@ -1127,10 +1126,9 @@ local function register_shared_decorations() octaves = 2, persist = 0.66, }, + biomes = { "rainforest", "taiga", "cold_taiga", "mega_taiga" }, y_min = 1, y_max = mcl_vars.mg_overworld_max, - flags = "", - biomes = { "rainforest", "taiga", "cold_taiga", "mega_taiga" }, }) -- Cacti From 0aebd9955a4ce08b5b8f0702cadc046640720dab Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 21 Aug 2017 03:23:59 +0200 Subject: [PATCH 73/75] Use dirt and sand for ocean floor --- mods/MAPGEN/mcl_biomes/init.lua | 69 ++++++++++++++++----------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 996cfb567..7e725b5a4 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -51,7 +51,7 @@ local function register_biomes() node_dust = "mcl_core:snowblock", node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:dirt", depth_filler = 3, node_water_top = "mcl_core:ice", depth_water_top = 10, @@ -92,7 +92,7 @@ local function register_biomes() name = "tundra_ocean", node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:dirt", depth_filler = 3, node_riverbed = "mcl_core:dirt", depth_riverbed = 2, @@ -121,7 +121,7 @@ local function register_biomes() name = "taiga_ocean", node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:dirt", depth_filler = 3, node_riverbed = "mcl_core:dirt", depth_riverbed = 2, @@ -149,11 +149,11 @@ local function register_biomes() minetest.register_biome({ name = "snowy_grassland_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:dirt", depth_filler = 3, - node_riverbed = "mcl_core:stone", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = 4, @@ -193,11 +193,11 @@ local function register_biomes() minetest.register_biome({ name = "grassland_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:dirt", depth_filler = 3, - node_riverbed = "mcl_core:stone", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = 0, @@ -236,11 +236,11 @@ local function register_biomes() minetest.register_biome({ name = "coniferous_forest_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:dirt", depth_filler = 3, - node_riverbed = "mcl_core:stone", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = 0, @@ -279,11 +279,11 @@ local function register_biomes() minetest.register_biome({ name = "deciduous_forest_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:dirt", depth_filler = 3, - node_riverbed = "mcl_core:stone", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = -2, @@ -309,12 +309,11 @@ local function register_biomes() minetest.register_biome({ name = "desert_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:redsand", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:redsand", depth_filler = 3, - node_stone = "mcl_core:stone", - node_riverbed = "mcl_core:stone", + node_riverbed = "mcl_core:redsand", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = 0, @@ -325,12 +324,11 @@ local function register_biomes() -- Sandstone desert minetest.register_biome({ name = "sandstone_desert", - node_top = "mcl_core:sand", + node_top = "mcl_core:redsand", depth_top = 1, - node_filler = "mcl_core:sand", + node_filler = "mcl_core:redsand", depth_filler = 1, - node_stone = "mcl_core:sandstone", - node_riverbed = "mcl_core:sand", + node_riverbed = "mcl_core:redsand", depth_riverbed = 2, y_min = 0, y_max = upper_limit, @@ -340,12 +338,11 @@ local function register_biomes() minetest.register_biome({ name = "sandstone_desert_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:sand", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:sand", depth_filler = 3, - node_stone = "mcl_core:stone", - node_riverbed = "mcl_core:stone", + node_riverbed = "mcl_core:sand", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = 4, @@ -429,11 +426,11 @@ local function register_biomes() minetest.register_biome({ name = "savanna_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:coarse_dirt", depth_filler = 3, - node_riverbed = "mcl_core:stone", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = -2, @@ -472,11 +469,11 @@ local function register_biomes() minetest.register_biome({ name = "rainforest_ocean", - node_top = "mcl_core:sand", + node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:sand", + node_filler = "mcl_core:dirt", depth_filler = 3, - node_riverbed = "mcl_core:sand", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = -2, @@ -501,11 +498,11 @@ local function register_biomes() minetest.register_biome({ name = "mushroom_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:gravel", + node_filler = "mcl_core:dirt", depth_filler = 3, - node_riverbed = "mcl_core:coarse_dirt", + node_riverbed = "mcl_core:dirt", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, y_max = 0, From 584434cf87341f5a629b0f80fa575d38b797f86b Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 21 Aug 2017 03:27:26 +0200 Subject: [PATCH 74/75] Change cold desert floor cover --- mods/MAPGEN/mcl_biomes/init.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 7e725b5a4..19fea240f 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -350,13 +350,14 @@ local function register_biomes() humidity_point = 0, --was 0 }) + -- TODO: Remove cold desert -- Cold desert minetest.register_biome({ name = "cold_desert", --node_dust = "", - node_top = "mcl_core:stone", + node_top = "mcl_core:coarse_dirt", depth_top = 1, - node_filler = "mcl_core:stone", + node_filler = "mcl_core:coarse_dirt", depth_filler = 1, node_riverbed = "mcl_core:stone", depth_riverbed = 2, @@ -368,10 +369,10 @@ local function register_biomes() minetest.register_biome({ name = "cold_desert_ocean", - node_top = "mcl_core:stone", + node_top = "mcl_core:dirt", depth_top = 1, - node_filler = "mcl_core:stone", - depth_filler = 3, + node_filler = "mcl_core:dirt", + depth_filler = 1, node_riverbed = "mcl_core:stone", depth_riverbed = 2, y_min = mcl_vars.mg_overworld_min, @@ -1654,7 +1655,8 @@ local function register_decorations() }, y_min = 4, y_max = mcl_vars.mg_overworld_max, - biomes = {"desert", "sandstone_desert", "mesa", "taiga", "mega_taiga"}, + -- TODO: Remove cold desert + biomes = {"desert", "sandstone_desert", "mesa", "taiga", "mega_taiga", "cold_desert"}, decoration = "mcl_core:deadbush", height = 1, }) From dfbc29810a03396861ad6e46e265004afdd23bcc Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 21 Aug 2017 03:35:46 +0200 Subject: [PATCH 75/75] Generate less plants in snowy grassland --- mods/MAPGEN/mcl_biomes/init.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 19fea240f..fc3fc07f0 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1038,7 +1038,7 @@ local function register_grass_decoration(offset, scale) place_on = {"mcl_core:dirt_with_grass", "mcl_core:dirt_with_grass_snow"}, sidelen = 16, noise_params = noise_grass, - biomes = {"grassland", "snowy_grassland", "coniferous_forest", "deciduous_forest", "savanna"}, + biomes = {"grassland", "coniferous_forest", "deciduous_forest", "savanna"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, decoration = "mcl_flowers:tallgrass", @@ -1088,7 +1088,7 @@ local function register_shared_decorations() }, y_min = 1, y_max = mcl_vars.mg_overworld_max, - biomes = {"grassland", "snowy_grassland", "coniferous_forest", "deciduous_forest", "savanna"}, + biomes = {"grassland", "coniferous_forest", "deciduous_forest", "savanna"}, }) -- v6 hack: This makes sure large ferns only appear in jungles @@ -1163,7 +1163,7 @@ local function register_shared_decorations() octaves = 3, persist = 0.7 }, - biomes = {"grassland", "snowy_grassland", "beach", "desert", "sandstone_desert", "swamp"}, + biomes = {"grassland", "beach", "desert", "sandstone_desert", "swamp"}, y_min = 1, y_max = 1, decoration = "mcl_core:reeds", @@ -1681,12 +1681,12 @@ local function register_decorations() }) end - local flower_biomes1 = {"grassland", "snowy_grassland", "sunflower_plains", "flower_forest", "deciduous_forest", "coniferous_forest", "taiga"} + local flower_biomes1 = {"grassland", "sunflower_plains", "flower_forest", "deciduous_forest", "coniferous_forest", "taiga"} register_flower("dandelion", flower_biomes1, 8) register_flower("poppy", flower_biomes1, 9439) - local flower_biomes2 = {"grassland", "snowy_grassland", "sunflower_plains", "flower_forest"} + local flower_biomes2 = {"grassland", "sunflower_plains", "flower_forest"} register_flower("tulip_red", flower_biomes2, 436) register_flower("tulip_orange", flower_biomes2, 536) register_flower("tulip_pink", flower_biomes2, 636)