diff --git a/crafting.lua b/crafting.lua new file mode 100644 index 0000000..64b2a3e --- /dev/null +++ b/crafting.lua @@ -0,0 +1,253 @@ +minetest.register_craft({ + output = "hell:fim", + recipe = { + {"hell:shroom_head"}, + {"hell:fruit_no_leaf"}, + {"hell:shroom_head"}, + } +}) + +minetest.register_craft({ + output = "hell:fruit_leaves", + recipe = { + {"hell:fruit_leaf", "hell:fruit_leaf", "hell:fruit_leaf"}, + {"hell:fruit_leaf", "hell:fruit_leaf", "hell:fruit_leaf"}, + {"hell:fruit_leaf", "hell:fruit_leaf", "hell:fruit_leaf"}, + } +}) + +minetest.register_craft({ + output = "hell:pick_mushroom", + recipe = { + {"hell:shroom_head", "hell:shroom_head", "hell:shroom_head"}, + {"", "hell:shroom_stem", ""}, + {"", "hell:shroom_stem", ""}, + } +}) + +minetest.register_craft({ + output = "hell:pick_wood", + recipe = { + {"hell:wood_cooked", "hell:wood_cooked", "hell:wood_cooked"}, + {"", "group:stick", ""}, + {"", "group:stick", ""}, + } +}) + +for _,m in pairs({"hellrack", "hellrack_blue", "white"}) do + local input = "hell:"..m + + minetest.register_craft({ + output = "hell:pick_"..m, + recipe = { + {input, input, input}, + {"", "group:stick", ""}, + {"", "group:stick", ""}, + } + }) + + minetest.register_craft({ + output = "hell:axe_"..m, + recipe = { + {input, input}, + {input, "group:stick"}, + {"", "group:stick"}, + } + }) + + minetest.register_craft({ + output = "hell:sword_"..m, + recipe = { + {input}, + {input}, + {"group:stick"}, + } + }) + + minetest.register_craft({ + output = "hell:shovel_"..m, + recipe = { + {input}, + {"group:stick"}, + {"group:stick"}, + } + }) +end + +minetest.register_craft({ + output = "hell:hellrack_brick 4", + recipe = { + {"hell:hellrack", "hell:hellrack"}, + {"hell:hellrack", "hell:hellrack"}, + } +}) + +minetest.register_craft({ + output = "hell:hellrack_brick_black 4", + recipe = { + {"hell:hellrack_black", "hell:hellrack_black"}, + {"hell:hellrack_black", "hell:hellrack_black"}, + } +}) + +minetest.register_craft({ + output = "hell:hellrack_brick_blue 4", + recipe = { + {"hell:hellrack_blue", "hell:hellrack_blue"}, + {"hell:hellrack_blue", "hell:hellrack_blue"}, + } +}) + +minetest.register_craft({ + output = "default:furnace", + recipe = { + {"hell:hellrack_brick", "hell:hellrack_brick", "hell:hellrack_brick"}, + {"hell:hellrack_brick", "", "hell:hellrack_brick"}, + {"hell:hellrack_brick", "hell:hellrack_brick", "hell:hellrack_brick"}, + } +}) + +minetest.register_craft({ + output = "hell:extractor", + recipe = { + {"hell:hellrack_brick", "hell:blood_top_cooked", "hell:hellrack_brick"}, + {"hell:blood_cooked", "hell:shroom_stem", "hell:blood_cooked"}, + {"hell:hellrack_brick", "hell:blood_stem_cooked", "hell:hellrack_brick"}, + } +}) + +minetest.register_craft({ + output = "hell:wood 4", + recipe = { + {"hell:blood_stem"}, + } +}) + +minetest.register_craft({ + output = "hell:wood_empty 4", + recipe = { + {"hell:blood_stem_empty"}, + } +}) + +minetest.register_craft({ + output = "hell:stick 4", + recipe = { + {"hell:wood_empty"}, + } +}) + +minetest.register_craft({ + output = "hell:torch", + recipe = { + {"hell:bark"}, + {"group:stick"}, + } +}) + +minetest.register_craft({ + output = "hell:forest_wood", + recipe = { + {"hell:forest_planks", "hell:forest_planks", "hell:forest_planks"}, + {"hell:forest_planks", "", "hell:forest_planks"}, + {"hell:forest_planks", "hell:forest_planks", "hell:forest_planks"}, + } +}) + +minetest.register_craft({ + output = "hell:forest_planks 8", + recipe = { + {"hell:forest_wood"}, + } +}) + +minetest.register_craft({ + output = "hell:forest_planks 7", + recipe = { + {"hell:tree"}, + }, +}) + +local sound_allowed = true +minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) + if itemstack:get_name() ~= "hell:forest_planks" + or itemstack:get_count() ~= 7 then + return + end + local tree + for i = 1,9 do + if old_craft_grid[i]:get_name() == "hell:tree" then + tree = i + break + end + end + if not tree then -- do nth if theres no tree + return + end + local rdif = math.random(-1,1) -- add a bit randomness + local barkstack = ItemStack("hell:bark "..4-rdif) + local inv = player:get_inventory() + if not inv:room_for_item("main", barkstack) then -- disallow crafting if there's not enough free space + craft_inv:set_list("craft", old_craft_grid) + itemstack:set_name("") + return + end + itemstack:set_count(7+rdif) + inv:add_item("main", barkstack) + if not sound_allowed then -- avoid playing the sound multiple times, e.g. when middle mouse click + return + end + minetest.sound_play("default_wood_footstep", {pos=player:getpos(), gain=0.25}) + sound_allowed = false + minetest.after(0, function() + sound_allowed = true + end) +end) + +minetest.register_craft({ + output = "default:paper", + recipe = { + {"hell:grass_dried", "hell:grass_dried", "hell:grass_dried"}, + } +}) + + +minetest.register_craft({ + type = "cooking", + output = "default:coal_lump", + recipe = "hell:tree", +}) + +minetest.register_craft({ + type = "cooking", + output = "hell:grass_dried", + recipe = "hell:grass", +}) + +minetest.register_craft({ + type = "cooking", + output = "hell:pearl", + recipe = "hell:fim", +}) + +minetest.register_craft({ + type = "cooking", + output = "hell:hotbed", + recipe = "hell:blood_extracted", +}) + +for _,i in ipairs({"hell:blood", "hell:blood_top", "hell:blood_stem", "hell:wood"}) do + local cooked = i.."_cooked" + + minetest.register_craft({ + type = "cooking", + output = cooked, + recipe = i, + }) + + minetest.register_craft({ + type = "fuel", + recipe = cooked, + burntime = 30, + }) +end diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..9b7915e --- /dev/null +++ b/depends.txt @@ -0,0 +1,13 @@ +default +nether +creative? +glow +riesenpilz +stairs +moreblocks? +vector_extras +fence_registration? +function_delayer? +watershed? +darkage +witchcraft diff --git a/guide.lua b/guide.lua new file mode 100644 index 0000000..02478a8 --- /dev/null +++ b/guide.lua @@ -0,0 +1,397 @@ +local cube = minetest.inventorycube + +-- the content of the guide +local guide_infos = { + { + description = "Mushrooms", + {"text", "Hell mushrooms can be found on the hell's ground and\n".. + "on hellrack soil, it can be dug by hand."}, + {"image", {1, 1, "riesenpilz_nether_shroom_side.png"}}, + {"y", 0.2}, + {"text", "If you drop it without holding the fast key, you can split it into its stem and head:"}, + {"image", {1, 1, "hell_shroom_top.png", 1}}, + {"image", {1, 1, "hell_shroom_stem.png"}}, + {"y", 0.1}, + {"text", "You can get more mushrooms by using a hellrack soil:\n".. + "1. search a dark place and, if necessary, place hellrack with air about it\n".. + "2. right click with cooked blood onto the hellrack to make it soiled\n".. + "3. right click onto the hellrack soil with a hell mushroom head to add some spores\n".. + "4. dig the mushroom which grew after some time to make place for another one"}, + {"image", {1, 1, "riesenpilz_nether_shroom_side.png", 6, 0.12}}, + {"y", 1}, + {"image", {1, 1, "hell_hellrack.png^hell_hellrack_soil.png", 1.8}}, + {"image", {1, 1, "hell_hotbed.png", 1.3, -0.4}}, + {"image", {1, 1, "hell_hellrack.png^hell_hellrack_soil.png", 3.6}}, + {"image", {1, 1, "hell_shroom_top.png", 3.1, -0.5}}, + {"image", {1, 1, "hell_hellrack.png^hell_hellrack_soil.png", 6}}, + {"image", {1, 1, "hell_hellrack.png"}}, + }, + { + description = "Tools", + {"text", "You can craft 5 kinds of tools in the hell,\n".. + "which (except the mushroom pick) require sticks to be crafted:"}, + {"image", {1, 1, "hell_pick_mushroom.png"}}, + {"y", 0.1}, + {"text", "strength : 1\n".. + "The mushroom pick needs mushroom stems and heads to be crafted."}, + {"image", {1, 1, "hell_pick_wood.png"}}, + {"y", 0.1}, + {"text", "strength : 2\n".. + "The hell wood pick can be crafted with cooked hell blood wood."}, + {"image", {1, 1, "hell_axe_hellrack.png", 1.5}}, + {"image", {1, 1, "hell_shovel_hellrack.png", 3}}, + {"image", {1, 1, "hell_sword_hellrack.png", 4.5}}, + {"image", {1, 1, "hell_pick_hellrack.png"}}, + {"y", 0.1}, + {"text", "strength : 3\n".. + "The red hellrack tools can be crafted with usual hellrack."}, + {"image", {1, 1, "hell_axe_hellrack_blue.png", 1.5}}, + {"image", {1, 1, "hell_shovel_hellrack_blue.png", 3}}, + {"image", {1, 1, "hell_sword_hellrack_blue.png", 4.5}}, + {"image", {1, 1, "hell_pick_hellrack_blue.png"}}, + {"y", 0.1}, + {"text", "strength : 3\n".. + "The blue hellrack tools can be crafted with blue hellrack."}, + {"image", {1, 1, "hell_axe_white.png", 1.5}}, + {"image", {1, 1, "hell_shovel_white.png", 3}}, + {"image", {1, 1, "hell_sword_white.png", 4.5}}, + {"image", {1, 1, "hell_pick_white.png"}}, + {"y", 0.1}, + {"text", "strength : 3\n".. + "The siwtonic tools can be crafted with the siwtonic ore."}, + }, + { + description = "Blood structures", + {"text", "You can find blood structures on the ground and\n".. + "dig their nodes even with the bare hand."}, + {"y", 0.5}, + {"text", "One contains 4 kinds of blocks :"}, + {"image", {1, 1, cube("hell_blood.png"), 1}}, + {"image", {1, 1, + cube("hell_blood_top.png", "hell_blood.png^hell_blood_side.png", "hell_blood.png^hell_blood_side.png"), + 2}}, + {"image", {1, 1, "hell_fruit.png", 3}}, + {"image", {1, 1, cube("hell_blood_stem_top.png", "hell_blood_stem.png", "hell_blood_stem.png")}}, + {"y", 0.1}, + {"text", "Blood stem, blood, blood head and hell fruit"}, + {"y", 0.1}, + {"text", "You can craft 4 blood wood with the stem :"}, + {"image", {1, 1, cube("hell_wood.png")}}, + {"y", 0.1}, + {"text", "The 4 blood nodes can be cooked and, except\n".. + "blood wood, their blood can be extracted."}, + }, + { + description = "Fruits", + {"text", "You can find the hell fruits on blood structures\n".. + "and dig them even with the bare hand."}, + {"image", {1, 1, "hell_fruit.png"}}, + {"text", "Eating it will make you lose life but\n".. + "it might feed you and give you blood :"}, + {"image", {1, 1, "hell_blood_extracted.png"}}, + {"y", 0.2}, + {"text", "If you eat it at the right place inside a portal,\n".. + "you will teleport instead of getting blood."}, + {"y", 0.2}, + {"text", "If you drop it without holding the fast key,\n".. + "you can split it into its fruit and leaf:"}, + {"image", {1, 1, "hell_fruit_leaf.png", 1}}, + {"image", {1, 1, "hell_fruit_no_leaf.png"}}, + {"y", 0.2}, + {"text", "Craft a fruit leave block out of 9 fruit leaves\n".. + "The fruit can be used to craft a hell pearl."}, + {"image", {1, 1, cube("hell_fruit_leaves.png")}}, + {"y", 0.2}, + {"text", "A fruit leaves block"}, + }, + { + description = "Cooking", + {"text", "To get a furnace you need to dig at least 8 hellrack bricks.\n".. + "They can be found at pyramid like constructions and require at least\n".. + "a strength 1 hell pick to be dug.\n".. + "To craft the furnace, use the hellrack bricks like cobble:"}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png"), 0.5}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png"), 1}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png")}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png"), 1}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png")}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png"), 0.5}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png"), 1}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png")}}, + {"y", 0.2}, + {"text", "To begin cooking stuff, you can use a mushroom or fruit.\n".. + "After that it's recommended to use cooked blood nodes."}, + {"y", 0.1}, + {"text", "Some hell items can be cooked:"}, + {"image", {1, 1, cube("hell_blood_stem_top_cooked.png", "hell_blood_stem_cooked.png", "hell_blood_stem_cooked.png"), 0.35}}, + {"image", {1, 1, cube("hell_blood_cooked.png"), 1.6}}, + {"image", {1, 1, + cube("hell_blood_top_cooked.png", "hell_blood_cooked.png^hell_blood_side_cooked.png", "hell_blood_cooked.png^hell_blood_side_cooked.png"), + 2.9}}, + {"image", {1, 1, cube("hell_wood_cooked.png"), 4.3}}, + {"y", 1.2}, + {"text", "Some cooked blood stem, cooked blood,\n".. + "cooked blood head and cooked blood wood,"}, + {"image", {1, 1, "hell_hotbed.png", 0.3}}, + {"image", {1, 1, "hell_pearl.png", 2}}, + {"y", 1.2}, + {"text", "Some cooked extracted blood and a hell pearl"}, + }, + { + description = "Extractors", + {"text", "Here you can find out information about the hell extractor."}, + {"y", 0.2}, + {"text", "Here you can see its craft recipe:"}, + {"image", {0.5, 0.5, cube("hell_blood_top_cooked.png", "hell_blood_cooked.png^hell_blood_side_cooked.png", "hell_blood_cooked.png^hell_blood_side_cooked.png"), 0.5}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png"), 1}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png")}}, + {"image", {0.5, 0.5, cube("hell_blood_extractor.png"), 2.5}}, + {"image", {0.5, 0.5, "hell_shroom_stem.png", 0.5}}, + {"image", {0.5, 0.5, cube("hell_blood_cooked.png"), 1}}, + {"image", {0.5, 0.5, cube("hell_blood_cooked.png")}}, + {"image", {0.5, 0.5, cube("hell_blood_stem_top_cooked.png", "hell_blood_stem_cooked.png", "hell_blood_stem_cooked.png"), 0.5}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png"), 1}}, + {"image", {0.5, 0.5, cube("hell_hellrack_brick.png")}}, + {"y", 0.2}, + {"text", "Extract blood from the blood nodes you get from the blood structures.\n".. + "You can also get blood with a hell fruit."}, + {"y", 0.2}, + {"text", "So you can use it:\n".. + "1. place it somewhere\n".. + "2. place blood blocks next to it (4 or less)\n".. + "3. right click with extracted blood onto it to power it\n".. + "4. take the new extracted blood and dig the extracted nodes"}, + {"y", 0.2}, + {"text", "Example (view from the top):"}, + {"y", 0.88}, + {"image", {1, 1, "hell_blood_stem_top.png", 0.82, -0.88}}, + {"image", {1, 1, "hell_blood.png", 1.63}}, + {"image", {1, 1, "hell_blood_extractor.png", 0.82}}, + {"image", {1, 1, "hell_blood_stem_top_empty.png", 3.82, -0.88}}, + {"image", {1, 1, "hell_blood_empty.png", 4.63}}, + {"image", {1, 1, "hell_blood_empty.png", 3.001}}, + {"image", {1, 1, "hell_blood_extractor.png", 3.82}}, + {"image", {1, 1, "hell_blood.png"}}, + {"image", {1, 1, "hell_blood.png", 0.82, -0.12}}, + {"image", {1, 1, "hell_blood_empty.png", 3.82, -0.12}}, + {"y", 1.2}, + {"text", "The empty blood stem can be crafted into empty hell wood,\n".. + "which can be crafted into hell sticks."}, + }, + { + description = "Ores", + {"text", "You can find 5 types of ores:"}, + {"image", {1, 1, cube("hell_hellrack_black.png"), 4}}, + {"image", {1, 1, cube("hell_hellrack.png")}}, + {"y", 0.2}, + {"text", "The red hellrack is generated like stone.\n".. + "The black hellrack is generated like gravel.\n".. + "Both require at least a strength 2 hell pick to be dug."}, + {"image", {1, 1, cube("hell_white.png"), 4}}, + {"image", {1, 1, cube("hell_hellrack_blue.png")}}, + {"y", 0.2}, + {"text", "The blue hellrack is generated like diamond ore.\n".. + "The siwtonic ore is generated like mese blocks.\n".. + "Both require at least a strength 3 hell pick to be dug."}, + {"image", {1, 1, cube("hell_hellrack_tiled.png"), 4}}, + {"image", {1, 1, cube("glow_stone.png")}}, + {"y", 0.2}, + {"text", "Glow stone can be used for lighting.\n".. + "Tiled hellrack is generated like coal ore.\n".. + "Glow stone requires at least a strength 1 pick to be dug.\n".. + "Dig tiled hellrack with at least a level 2 pickaxe."}, + }, + { + description = "Vines", + {"text", "Feed hell vines with blood.\n".. + "Dig them with anything."}, + {"image", {1, 1, "hell_vine.png"}}, + {"y", 0.2}, + {"text", "Grow hell child by placing\n".. + "placing it to a dark place onto a\n".. + "blood structure head node."}, + {"image", {1, 1, "hell_sapling.png"}}, + {"y", -0.10}, + {"image", {1, 1, "hell_blood.png^hell_blood_side.png"}}, + }, + { + description = "Pearls", + {"text", "The hell pearl can be used to teleport by throwing it.\n".. + "Here is how to get one :"}, + {"y", 0.2}, + {"text", "First of all craft 2 mushroom heads and 1 hell fruit\n".. + "without leaf together :"}, + {"image", {1, 1, "hell_shroom_top.png"}}, + {"image", {1, 1, "hell_fim.png", 3}}, + {"image", {1, 1, "hell_fruit_no_leaf.png"}}, + {"image", {1, 1, "hell_shroom_top.png"}}, + {"y", 0.2}, + {"text", "Put the result into the furnace\n".. + "to cook it into a hell pearl :"}, + {"image", {1, 1, "hell_pearl.png"}}, + }, + { + description = "Bricks", + {"text", "Craft bricks out of red,\n".. + "black and blue hellrack."}, + {"image", {1, 1, cube("hell_hellrack_brick_black.png"), 1}}, + {"image", {1, 1, cube("hell_hellrack_brick_blue.png"), 2}}, + {"image", {1, 1, cube("hell_hellrack_brick.png")}}, + {"y", 0.4}, + {"text", "Dig them with at least a level 1 pickaxe."}, + {"y", 0.2}, + }, + { + description = "Portals", + {"text", "Here you can find out how to built the hell portal."}, + {"y", 0.3}, + {"text", "A hell portal requires following nodes:"}, + {"y", 0.05}, + {"text", "25 empty hell wooden planks\n".. + "16 black hellrack\n".. + "12 blue hellrack bricks\n".. + "8 red hellrack\n".. + "8 cooked hell blood\n".. + "4 hell fruits\n".. + "2 siwtonic blocks"}, + {"y", 0.2}, + {"text", "It should look approximately like this one:"}, + {"image", {5.625, 6, "hell_teleporter.png", 0, -1.5}}, + {"y", 5.5}, + {"text", "Activate it by standing in the middle,\n".. + "on the siwtonic block and eating a hell fruit.\n".. + "Take enough stuff with you to build a portal when you'll come back."}, + }, + { + description = "Forests", + {"text", "The hell forest is generated in caves,\n".. + "above the usual hell."}, + {"y", 0.2}, + {"text", "There you can find some plants:"}, + {"image", {1, 1, "hell_grass_middle.png", 1}}, + {"image", {1, 1, "hell_grass_big.png", 2}}, + {"image", {1, 1, "hell_grass_small.png"}}, + {"y", 0.2}, + {"text", "Use the hell forest grass to get paper.\n".. + "Craft paper out of the dried grass."}, + {"image", {1, 1, cube("hell_tree_top.png", "hell_tree.png", "hell_tree.png")}}, + {"y", 0.2}, + {"text", "Hell trunks can be found at hell trees.\n".. + "Craft hell wood out of hell trunk."}, + {"image", {1, 1, "hell_glowflower.png"}}, + {"y", 0.2}, + {"text", "Use it for lighting and decoration."}, + }, +} + +-- the size of guide pages +local guide_size = {x=40, y=10, cx=0.2, cy=0.2} + +-- informations about settings and ... +local formspec_offset = {x=0.25, y=0.50} +local font_size +if minetest.is_singleplayer() then + font_size = tonumber(minetest.settings:get("font_size")) or 13 +else + font_size = 13 +end +guide_size.fx = math.floor((40*(guide_size.cx+formspec_offset.x))*font_size) +guide_size.fy = font_size/40 + +-- the default guide formspecs +local guide_forms = { + contents = "size[3.6,"..(#guide_infos)-2 ..";]label["..guide_size.cx+0.7 ..","..guide_size.cy+0.2 ..";Contents:]", +} + +-- change the infos to formspecs +for n,data in ipairs(guide_infos) do + local form = "" + local y = 0 + local x = guide_size.cx + for _,i in ipairs(data) do + local typ, content = unpack(i) + if typ == "y" then + y = y+content + elseif typ == "x" then + x = math.max(x, content) + elseif typ == "text" then + local tab = minetest.wrap_text(content, guide_size.fx, true) + local l = guide_size.cx + for _,str in ipairs(tab) do + form = form.."label["..guide_size.cx ..","..guide_size.cy+y..";"..str.."]" + y = y+guide_size.fy + l = math.max(l, #str) + end + x = math.max(x, l/font_size) + elseif typ == "image" then + local w, h, texture_name, px, py = unpack(content) + if not px then + form = form.."image["..guide_size.cx..","..guide_size.cy+y+h*0.3 ..";"..w..","..h..";"..texture_name.."]" + y = y+h + else + px = guide_size.cx+px + py = py or 0 + form = form.."image["..px..",".. + guide_size.cy+y+h*0.3+py ..";"..w..","..h..";"..texture_name.."]" + x = math.max(x, px+w) + end + end + end + form = "size["..x*1.8 ..","..y+1 ..";]"..form.."button["..x/2-0.5 ..","..y ..";1,2;quit;Back]" + guide_forms[n] = {data.description, form} +end + +local desc_tab = {} +for n,i in ipairs(guide_forms) do + desc_tab[i[1]] = n +end + +-- creates contents formspec +local y = 0 +for y,i in ipairs(guide_forms) do + local desc, form = unpack(i) + local s = #desc*1.3/font_size+1.5 + guide_forms.contents = guide_forms.contents.."button["..guide_size.cx*12/s-0.5 ..","..guide_size.cy+y/1.3 ..";"..s..",1;name;"..desc.."]" +end + +-- shows the contents of the formspec +local function show_guide(pname) + minetest.show_formspec(pname, "hell_guide_contents", guide_forms["contents"]) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname == "hell_guide_contents" then + local fname = fields.name + local pname = player:get_player_name() + if fname + and pname then + minetest.show_formspec(pname, "hell_guide", guide_forms[desc_tab[fname]][2]) + end + elseif formname == "hell_guide" then + local fname = fields.quit + local pname = player:get_player_name() + if fname + and pname then + minetest.show_formspec(pname, "hell_guide_contents", guide_forms["contents"]) + end + end +end) + +minetest.register_chatcommand("hell_help", { + params = "", + description = "Shows a hell guide", + func = function(name) + local player = minetest.get_player_by_name(name) + if not player then + minetest.chat_send_player(name, "Something went wrong.") + return false + end + if player:getpos().y > hell.start then + minetest.chat_send_player(name, "Usually you don't neet this guide here. You can view it in the hell.") + return false + end + minetest.chat_send_player(name, "Showing guide...") + show_guide(name) + return true + end +}) diff --git a/hell.lua b/hell.lua new file mode 100644 index 0000000..e4fd8b4 --- /dev/null +++ b/hell.lua @@ -0,0 +1,1044 @@ +-- Hell Mod (based on Nyanland by Jeija, Catapult by XYZ, and Livehouse by neko259) +-- lkjoel (main developer, code, ideas, textures) +-- == CONTRIBUTERS == +-- jordan4ibanez (code, ideas, textures) +-- Gilli (code, ideas, textures, mainly for the Glowstone) +-- Death Dealer (code, ideas, textures) +-- LolManKuba (ideas, textures) +-- IPushButton2653 (ideas, textures) +-- Menche (textures) +-- sdzen (ideas) +-- godkiller447 (ideas) +-- If I didn't list you, please let me know! + +local load_time_start = minetest.get_us_time() + +if not rawget(_G, "hell") then + hell = {} +end + +--== EDITABLE OPTIONS ==-- + +--says some information. +hell.info = true + +-- tell everyone about the generation +hell.inform_all = minetest.is_singleplayer() + +--1: 2: 3: +hell.max_spam = 2 + +-- Depth of the hell +local hell_middle = hell.DEPTH-360 + +-- forest bottom perlin multiplication +local f_bottom_scale = 4 + +-- forest bottom height +local f_h_min = hell_middle+10 + +-- forest top height +local f_h_max = f_h_min+250 + +-- Frequency of trees in the hell forest (higher is less frequent) +local tree_rarity = 200 + +-- Frequency of glowflowers in the hell forest (higher is less frequent) +local glowflower_rarity = 120 + +-- Frequency of hell grass in the hell forest (higher is less frequent) +local grass_rarity = 2 + +-- Frequency of hell mushrooms in the hell forest (higher is less frequent) +local mushroom_rarity = 80 + +local abm_tree_interval = 864 +local abm_tree_chance = 100 + +-- height of the hell generation's end +hell.start = f_h_max+100 + +-- Height of the hell (bottom of the hell is hell_middle - HELL_HEIGHT) +local HELL_HEIGHT = 30 +local HELL_BOTTOM = (hell_middle - HELL_HEIGHT) +hell.buildings = HELL_BOTTOM+12 + +-- Maximum amount of randomness in the map generation +HELL_RANDOM = 2 + +-- Frequency of Glowstone on the "roof" of the Hell (higher is less frequent) +local GLOWSTONE_FREQ_ROOF = 500 + +-- Frequency of lava (higher is less frequent) +local LAVA_FREQ = 100 + +local hell_structure_freq = 350 +local HELL_SHROOM_FREQ = 100 + +-- Maximum height of lava +--LAVA_HEIGHT = 2 +-- Frequency of Glowstone on lava (higher is less frequent) +--GLOWSTONE_FREQ_LAVA = 2 +-- Height of hell structures +--HELL_TREESIZE = 2 +-- Frequency of apples in a hell structure (higher is less frequent) +--HELL_APPLE_FREQ = 5 +-- Frequency of healing apples in a hell structure (higher is less frequent) +--HELL_HEAL_APPLE_FREQ = 10 +-- Start position for the Throne of Hades (y is relative to the bottom of the +-- hell) +--HADES_THRONE_STARTPOS = {x=0, y=1, z=0} +-- Spawn pos for when the hell hasn't been loaded yet (i.e. no portal in the +-- hell) (y is relative to the bottom of the hell) +--HELL_SPAWNPOS = {x=0, y=5, z=0} +-- Structure of the hell portal (all is relative to the hell portal creator +-- block) + +--== END OF EDITABLE OPTIONS ==-- + +if hell.info then + function hell:inform(msg, spam, t) + if spam <= self.max_spam then + local info + if t then + info = "[hell] " .. msg .. (" after ca. %.3g s"):format( + (minetest.get_us_time() - t) / 1000000) + else + info = "[hell] " .. msg + end + print(info) + if self.inform_all then + minetest.chat_send_all(info) + end + end + end +else + function hell.inform() + end +end + + +local path = minetest.get_modpath("hell") +dofile(path.."/weird_mapgen_noise.lua") +dofile(path.."/items.lua") +dofile(path.."/portal.lua") +--dofile(path.."/furnace.lua") +dofile(path.."/pearl.lua") + +-- Weierstrass function stuff from https://github.com/slemonide/gen +local SIZE = 1000 +local ssize = math.ceil(math.abs(SIZE)) +local function do_ws_func(depth, a, x) + local n = math.pi * x / (16 * SIZE) + local y = 0 + for k=1,depth do + y = y + math.sin(k^a * n) / k^a + end + return SIZE * y / math.pi +end + +local chunksize = minetest.settings:get("chunksize") or 5 +local ws_lists = {} +local function get_ws_list(a,x) + ws_lists[a] = ws_lists[a] or {} + local v = ws_lists[a][x] + if v then + return v + end + v = {} + for x=x,x + (chunksize*16 - 1) do + local y = do_ws_func(ssize, a, x) + v[x] = y + end + ws_lists[a][x] = v + return v +end + + +local function dif(z1, z2) + return math.abs(z1-z2) +end + +local function pymg(x1, x2, z1, z2) + return math.max(dif(x1, x2), dif(z1, z2)) +end + +local function r_area(manip, width, height, pos) + local emerged_pos1, emerged_pos2 = manip:read_from_map( + {x=pos.x-width, y=pos.y, z=pos.z-width}, + {x=pos.x+width, y=pos.y+height, z=pos.z+width} + ) + return VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2}) +end + +local function set_vm_data(manip, nodes, pos, t1, name, generated) + manip:set_data(nodes) + manip:write_to_map(not generated) + hell:inform(name.." grew at " .. minetest.pos_to_string(pos), + generated and 3 or 2, t1) +end + +-- Generated variables +--~ local HELL_ROOF_ABS = (hell_middle - HELL_RANDOM) +local f_yscale_top = (f_h_max-f_h_min)/2 +local f_yscale_bottom = f_yscale_top/2 +--HADES_THRONE_STARTPOS_ABS = {x=HADES_THRONE_STARTPOS.x, y=(HELL_BOTTOM + +--HADES_THRONE_STARTPOS.y), z=HADES_THRONE_STARTPOS.z} +--LAVA_Y = (HELL_BOTTOM + LAVA_HEIGHT) +--HADES_THRONE_ABS = {} +--HADES_THRONE_ENDPOS_ABS = {} +--HADES_THRONE_GENERATED = minetest.get_worldpath() .. "/hellhadesthrone.txt" +--HELL_SPAWNPOS_ABS = {x=HELL_SPAWNPOS.x, y=(HELL_BOTTOM + +--HELL_SPAWNPOS.y), z=HELL_SPAWNPOS.z} +--[[for i,v in ipairs(HADES_THRONE) do + v.pos.x = v.pos.x + HADES_THRONE_STARTPOS_ABS.x + v.pos.y = v.pos.y + HADES_THRONE_STARTPOS_ABS.y + v.pos.z = v.pos.z + HADES_THRONE_STARTPOS_ABS.z + HADES_THRONE_ABS[i] = v +end +local htx = 0 +local hty = 0 +local htz = 0 +for i,v in ipairs(HADES_THRONE_ABS) do + if v.pos.x > htx then + htx = v.pos.x + end + if v.pos.y > hty then + hty = v.pos.y + end + if v.pos.z > htz then + htz = v.pos.z + end +end +HADES_THRONE_ENDPOS_ABS = {x=htx, y=hty, z=htz}]] + +local c, hell_tree_nodes +local function define_contents() + c = { + ignore = minetest.get_content_id("ignore"), + air = minetest.get_content_id("air"), + lava = minetest.get_content_id("default:lava_source"), + gravel = minetest.get_content_id("default:gravel"), + coal = minetest.get_content_id("default:stone_with_coal"), + diamond = minetest.get_content_id("default:stone_with_diamond"), + mese = minetest.get_content_id("default:mese"), + + --https://github.com/Zeg9/minetest-glow + glowstone = minetest.get_content_id("glow:stone"), + + hell_shroom = minetest.get_content_id("riesenpilz:nether_shroom"), + + hellrack = minetest.get_content_id("hell:hellrack"), + hellrack_tiled = minetest.get_content_id("hell:hellrack_tiled"), + hellrack_black = minetest.get_content_id("hell:hellrack_black"), + hellrack_blue = minetest.get_content_id("hell:hellrack_blue"), + hellrack_brick = minetest.get_content_id("hell:hellrack_brick"), + white = minetest.get_content_id("hell:white"), + + hell_vine = minetest.get_content_id("hell:vine"), + blood = minetest.get_content_id("hell:blood"), + blood_top = minetest.get_content_id("hell:blood_top"), + blood_stem = minetest.get_content_id("hell:blood_stem"), + hell_apple = minetest.get_content_id("hell:apple"), + + hell_tree = minetest.get_content_id("hell:tree"), + hell_tree_corner = minetest.get_content_id("hell:tree_corner"), + hell_leaves = minetest.get_content_id("hell:leaves"), + hell_grass = { + minetest.get_content_id("hell:grass_small"), + minetest.get_content_id("hell:grass_middle"), + minetest.get_content_id("hell:grass_big") + }, + glowflower = minetest.get_content_id("hell:glowflower"), + hell_dirt = minetest.get_content_id("hell:dirt"), + hell_dirt_top = minetest.get_content_id("hell:dirt_top"), + hell_dirt_bottom = minetest.get_content_id("hell:dirt_bottom"), + } + local trn = {c.hell_tree, c.hell_tree_corner, c.hell_leaves, + c.hell_fruit} + hell_tree_nodes = {} + for i = 1,#trn do + hell_tree_nodes[trn[i]] = true + end +end + +local pr, contents_defined + +local function return_hell_ore(id, glowstone) + if glowstone + and pr:next(0,GLOWSTONE_FREQ_ROOF) == 1 then + return c.glowstone + end + if id == c.coal then + return c.hellrack_tiled + end + if id == c.gravel then + return c.hellrack_black + end + if id == c.diamond then + return c.hellrack_blue + end + if id == c.mese then + return c.white + end + return c.hellrack +end + +local f_perlins = {} + +-- abs(v) < 1-(persistance^octaves))/(1-persistance) = amp +--local perlin1 = minetest.get_perlin(13,3, 0.5, 50) --Get map specific perlin +-- local perlin2 = minetest.get_perlin(133,3, 0.5, 10) +-- local perlin3 = minetest.get_perlin(112,3, 0.5, 5) +local tmp = f_yscale_top*4 +local tmp2 = tmp/f_bottom_scale +local perlins = { + { -- amp 1.75 + seed = 13, + octaves = 3, + persist = 0.5, + spread = {x=50, y=50, z=50}, + scale = 1, + offset = 0, + }, + {-- amp 1.75 + seed = 133, + octaves = 3, + persist = 0.5, + spread = {x=10, y=10, z=10}, + scale = 1, + offset = 0, + }, + {-- amp 1.75 + seed = 112, + octaves = 3, + persist = 0.5, + spread = {x=5, y=5, z=5}, + scale = 1, + offset = 0, + }, + --[[forest_bottom = { + seed = 11, + octaves = 3, + persist = 0.8, + spread = {x=tmp2, y=tmp2, z=tmp2}, + scale = 1, + offset = 0, + },]] + forest_top = {-- amp 2.44 + seed = 21, + octaves = 3, + persist = 0.8, + spread = {x=tmp, y=tmp, z=tmp}, + scale = 1, + offset = 0, + }, +} + +-- buffers, see https://forum.minetest.net/viewtopic.php?f=18&t=16043 +local pelin_maps +local pmap1 = {} +local pmap2 = {} +local pmap3 = {} +local pmap_f_top = {} +local data = {} + +local structures_enabled = true +local vine_maxlength = math.floor(HELL_HEIGHT/4+0.5) + +local function grow_hellstructure(pos, generated) + local t1 = minetest.get_us_time() + + if not contents_defined then + define_contents() + contents_defined = true + end + + if not pos.x then print(dump(pos)) + hell:inform("Error: "..dump(pos), 1) + return + end + + local height = 6 + local manip = minetest.get_voxel_manip() + local rarea = r_area(manip, 2, height, pos) + local nodes = manip:get_data() + + local vi = rarea:indexp(pos) + for _ = 0, height-1 do + nodes[vi] = c.blood_stem + vi = vi + rarea.ystride + end + + for i = -1,1 do + for j = -1,1 do + nodes[rarea:index(pos.x+i, pos.y+height, pos.z+j)] = c.blood_top + end + end + + for k = -1, 1, 2 do + for l = -2+1, 2 do + local p1 = {pos.x+2*k, pos.y+height, pos.z-l*k} + local p2 = {pos.x+l*k, pos.y+height, pos.z+2*k} + local udat = c.blood_top + if math.random(2) == 1 then + nodes[rarea:index(p1[1], p1[2], p1[3])] = c.blood_top + nodes[rarea:index(p2[1], p2[2], p2[3])] = c.blood_top + udat = c.blood + end + nodes[rarea:index(p1[1], p1[2]-1, p1[3])] = udat + nodes[rarea:index(p2[1], p2[2]-1, p2[3])] = udat + end + for l = 0, 1 do + for _,p in ipairs({ + {pos.x+k, pos.y+height-1, pos.z-l*k}, + {pos.x+l*k, pos.y+height-1, pos.z+k}, + }) do + if math.random(2) == 1 then + nodes[rarea:index(p[1], p[2], p[3])] = c.hell_apple + --elseif math.random(10) == 1 then + -- nodes[rarea:index(p[1], p[2], p[3])] = c.apple + end + end + end + end + set_vm_data(manip, nodes, pos, t1, "blood", generated) +end + +local poshash = minetest.hash_node_position +local pos_from_hash = minetest.get_position_from_hash + +local function soft_node(id) + return id == c.air or id == c.ignore +end + +local function update_minmax(min, max, p) + min.x = math.min(min.x, p.x) + max.x = math.max(max.x, p.x) + min.z = math.min(min.z, p.z) + max.z = math.max(max.z, p.z) +end + +local fruit_chances = {} +for y = -2,1 do --like a hyperbola + fruit_chances[y] = math.floor(-4/(y-2)+0.5) +end + +local dirs = { + {-1, 0, 12, 19}, + {1, 0, 12, 13}, + {0, 1, 4}, + {0, -1, 4, 10}, +} + +local h_max = 26 +local h_stem_min = 3 +local h_stem_max = 7 +local h_arm_min = 2 +local h_arm_max = 6 +local r_arm_min = 1 +local r_arm_max = 5 +local fruit_rarity = 25 --a bigger number results in less fruits +local leaf_thickness = 3 --a bigger number results in more blank trees + +local h_trunk_max = h_max-h_arm_max + +local function grow_tree(pos, generated) + local t1 = minetest.get_us_time() + + if not contents_defined then + define_contents() + contents_defined = true + end + + local min = vector.new(pos) + local max = vector.new(pos) + min.y = min.y-1 + max.y = max.y+h_max + + local trunks = {} + local trunk_corners = {} + local h_stem = math.random(h_stem_min, h_stem_max) + local todo,n = {{x=pos.x, y=pos.y+h_stem, z=pos.z}},1 + while n do + local p = todo[n] + todo[n] = nil + n = next(todo) + + local used_dirs,u = {},1 + for _,dir in pairs(dirs) do + if math.random(1,2) == 1 then + used_dirs[u] = dir + u = u+1 + end + end + if not used_dirs[1] then + local dir1 = math.random(4) + local dir2 = math.random(3) + if dir1 <= dir2 then + dir2 = dir2+1 + end + used_dirs[1] = dirs[dir1] + used_dirs[2] = dirs[dir2] + end + for _,dir in pairs(used_dirs) do + local p = vector.new(p) + local r = math.random(r_arm_min, r_arm_max) + for j = 1,r do + local x = p.x+j*dir[1] + local z = p.z+j*dir[2] + trunks[poshash{x=x, y=p.y, z=z}] = dir[3] + end + r = r+1 + p.x = p.x+r*dir[1] + p.z = p.z+r*dir[2] + trunk_corners[poshash(p)] = dir[4] or dir[3] + local h = math.random(h_arm_min, h_arm_max) + for i = 1,h do + p.y = p.y + i + trunks[poshash(p)] = true + p.y = p.y - i + end + p.y = p.y+h + --n = #todo+1 -- caused small trees + todo[#todo+1] = p + end + if p.y > pos.y+h_trunk_max then + break + end + + n = n or next(todo) + end + local leaves = {} + local fruits = {} + local trunk_ps = {} + local count = 0 + + local ps = {} + local trunk_count = 0 + for i,par2 in pairs(trunks) do + local pos = pos_from_hash(i) + update_minmax(min, max, pos) + local z,y,x = pos.z, pos.y, pos.x + trunk_count = trunk_count+1 + ps[trunk_count] = {z,y,x, par2} + end + + for _,d in pairs(ps) do + if d[4] == true then + d[4] = nil + end + trunk_ps[#trunk_ps+1] = d + local pz, py, px = unpack(d) + count = count+1 + if count > leaf_thickness then + count = 0 + for y = -2,2 do + local fruit_chance = fruit_chances[y] + for z = -2,2 do + for x = -2,2 do + local distq = x*x+y*y+z*z + if distq ~= 0 + and math.random(1, math.sqrt(distq)) == 1 then + local x = x+px + local y = y+py + local z = z+pz + local vi = poshash{x=x, y=y, z=z} + if not trunks[vi] then + if fruit_chance + and math.random(1, fruit_rarity) == 1 + and math.random(1, fruit_chance) == 1 then + fruits[vi] = true + else + leaves[vi] = true + end + update_minmax(min, max, {x=x, z=z}) + end + end + end + end + end + end + end + + --ps = nil + --collectgarbage() + + for i = -1,h_stem+1 do + -- param2 explicitly set 0 due to possibly previous leaves node + trunk_ps[#trunk_ps+1] = {pos.z, pos.y+i, pos.x, 0} + end + + local manip = minetest.get_voxel_manip() + local emerged_pos1, emerged_pos2 = manip:read_from_map(min, max) + local varea = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2}) + local nodes = manip:get_data() + local param2s = manip:get_param2_data() + + for i in pairs(leaves) do + local p = varea:indexp(pos_from_hash(i)) + if soft_node(nodes[p]) then + nodes[p] = c.hell_leaves + param2s[p] = math.random(0,179) + --param2s[p] = math.random(0,44) + end + end + + for i in pairs(fruits) do + local p = varea:indexp(pos_from_hash(i)) + if soft_node(nodes[p]) then + nodes[p] = c.hell_apple + end + end + + for i = 1,#trunk_ps do + local p = trunk_ps[i] + local par = p[4] + p = varea:index(p[3], p[2], p[1]) + if par then + param2s[p] = par + end + nodes[p] = c.hell_tree + end + + for i,par2 in pairs(trunk_corners) do + local vi = varea:indexp(pos_from_hash(i)) + nodes[vi] = c.hell_tree_corner + param2s[vi] = par2 + end + + manip:set_data(nodes) + manip:set_param2_data(param2s) + manip:write_to_map(not generated) + hell:inform("a hell tree with " .. trunk_count .. + " branch trunk nodes grew at " .. minetest.pos_to_string(pos), + generated and 3 or 2, t1) +end + +-- Create the Hell +minetest.register_on_generated(function(minp, maxp, seed) + --avoid big map generation + if not (maxp.y >= HELL_BOTTOM-100 and minp.y <= hell.start) then + return + end + + local t1 = minetest.get_us_time() + hell:inform("generates at: x=["..minp.x.."; "..maxp.x.."]; y=[" .. + minp.y.."; "..maxp.y.."]; z=["..minp.z.."; "..maxp.z.."]", 2) + + if not contents_defined then + define_contents() + contents_defined = true + end + + local buildings = 0 + if maxp.y <= HELL_BOTTOM then + buildings = 1 + elseif minp.y <= hell.buildings then + buildings = 2 + end + + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + vm:get_data(data) + local varea = VoxelArea:new{MinEdge=emin, MaxEdge=emax} + + pr = PseudoRandom(seed+33) + local tab,num = {},1 + local trees,num_trees = {},1 + + --local perlin1 = minetest.get_perlin(13,3, 0.5, 50) + --local perlin2 = minetest.get_perlin(133,3, 0.5, 10) + --local perlin3 = minetest.get_perlin(112,3, 0.5, 5) + + local side_length = maxp.x - minp.x + 1 + local map_lengths_xyz = {x=side_length, y=side_length, z=side_length} + + if not pelin_maps then + pelin_maps = { + a = minetest.get_perlin_map(perlins[1], map_lengths_xyz), + b = minetest.get_perlin_map(perlins[2], map_lengths_xyz), + c = minetest.get_perlin_map(perlins[3], map_lengths_xyz), + forest_top = minetest.get_perlin_map(perlins.forest_top, + map_lengths_xyz), + } + end + pelin_maps.a:get2dMap_flat({x=minp.x, y=minp.z}, pmap1) + pelin_maps.b:get2dMap_flat({x=minp.x, y=minp.z}, pmap2) + pelin_maps.c:get2dMap_flat({x=minp.x, y=minp.z}, pmap3) + + local forest_possible = maxp.y > f_h_min and minp.y < f_h_max + + --local pmap_f_bottom = minetest.get_perlin_map(perlins.forest_bottom, + -- map_lengths_xyz):get2dMap_flat({x=minp.x, y=minp.z}) + local perlin_f_bottom, strassx, strassz + if forest_possible then + perlin_f_bottom = minetest.get_perlin(11, 3, 0.8, tmp2) + pelin_maps.forest_top:get2dMap_flat({x=minp.x, y=minp.z}, pmap_f_top) + strassx = get_ws_list(2, minp.x) + strassz = get_ws_list(2, minp.z) + end + + local num2, tab2 + if buildings >= 1 then + num2 = 1 + tab2 = hell_weird_noise({x=minp.x, y=hell.buildings-79, z=minp.z}, + pymg, 200, 8, 10, side_length-1) + end + + local count = 0 + for z=minp.z, maxp.z do + for x=minp.x, maxp.x do + + count = count+1 + + local test = pmap1[count]+1 + local test2 = pmap2[count] + local test3 = math.abs(pmap3[count]) + + local t = math.floor(test*3+0.5) + + local h + if test2 < 0 then + h = math.floor(test2*3+0.5)-1 + else + h = 3+t+pr:next(0,HELL_RANDOM) + end + + local generate_vine = false + if test3 >= 0.72+pr:next(0,HELL_RANDOM)/10 + and pr:next(0,HELL_RANDOM) == 1 then + generate_vine = true + end + + local bottom = HELL_BOTTOM+h + local top = hell_middle-pr:next(0,HELL_RANDOM)+t + + local py_h = 0 + local difn, noisp, py_h_g + if buildings >= 1 then + py_h = tab2[num2].y + num2 = num2+1 + + difn = hell.buildings-py_h + if difn == 5 then + noisp = 1 + elseif difn < 5 then + noisp = 2 + end + py_h_g = hell.buildings-7 + end + + local vi = varea:index(x, minp.y, z) + if buildings == 1 + and noisp then + if noisp == 1 then + for _ = 1,side_length do + data[vi] = c.hellrack_brick + vi = vi + varea.ystride + end + else + for _ = 1,side_length do + data[vi] = c.lava + vi = vi + varea.ystride + end + end + else + + local r_structure = pr:next(1,hell_structure_freq) + local r_shroom = pr:next(1,HELL_SHROOM_FREQ) + local r_glowstone = pr:next(0,GLOWSTONE_FREQ_ROOF) + local r_vine_length = pr:next(1,vine_maxlength) + + local f_bottom, f_top, is_forest, f_h_dirt + if forest_possible then + local p = {x=math.floor(x/f_bottom_scale), + z=math.floor(z/f_bottom_scale)} + local pstr = p.x.." "..p.z + if not f_perlins[pstr] then + f_perlins[pstr] = math.floor(f_h_min + (math.abs( + perlin_f_bottom:get2d{x=p.x, y=p.z} + 1)) + * f_yscale_bottom + 0.5) + end + local top_noise = pmap_f_top[count]+1 + if top_noise < 0 then + top_noise = -top_noise/10 + --hell:inform("ERROR: (perlin noise) ".. + -- pmap_f_top[count].." is not inside [-1; 1]", 1) + end + f_top = math.floor(f_h_max - top_noise*f_yscale_top + 0.5) + f_bottom = f_perlins[pstr]+pr:next(0,f_bottom_scale-1) + is_forest = f_bottom < f_top + f_h_dirt = f_bottom-pr:next(0,1) + end + + for y=minp.y, maxp.y do + local d_p_addp = data[vi] + --if py_h >= maxp.y-4 then + if y <= py_h + and noisp then + if noisp == 1 then + data[vi] = c.hellrack_brick + elseif noisp == 2 then + if y == py_h then + data[vi] = c.hellrack_brick + elseif y == py_h_g + and pr:next(1,3) <= 2 then + data[vi] = c.hellrack + elseif y <= py_h_g then + data[vi] = c.lava + else + data[vi] = c.air + end + end + elseif d_p_addp ~= c.air then + + if is_forest + and y == f_bottom then + data[vi] = c.hell_dirt_top + elseif is_forest + and y < f_bottom + and y >= f_h_dirt then + data[vi] = c.hell_dirt + elseif is_forest + and y == f_h_dirt-1 then + data[vi] = c.hell_dirt_bottom + elseif is_forest + and y == f_h_dirt+1 then + if pr:next(1,tree_rarity) == 1 then + trees[num_trees] = {x=x, y=y, z=z} + num_trees = num_trees+1 + elseif pr:next(1,mushroom_rarity) == 1 then + data[vi] = c.hell_shroom + elseif pr:next(1,glowflower_rarity) == 1 then + data[vi] = c.glowflower + elseif pr:next(1,grass_rarity) == 1 then + data[vi] = c.hell_grass[pr:next(1,3)] + else + data[vi] = c.air + end + elseif is_forest + and y > f_bottom + and y < f_top then + if not hell_tree_nodes[d_p_addp] then + data[vi] = c.air + end + elseif is_forest + and y == f_top then + local sel = math.floor(strassx[x]+strassz[z]+0.5)%10 + if sel <= 5 then + data[vi] = return_hell_ore(d_p_addp, true) + elseif sel == 6 then + data[vi] = c.hellrack_black + elseif sel == 7 then + data[vi] = c.glowstone + else + data[vi] = c.air + end + + elseif y <= HELL_BOTTOM then + if y <= bottom then + data[vi] = return_hell_ore(d_p_addp, true) + else + data[vi] = c.lava + end + elseif r_structure == 1 + and y == bottom then + tab[num] = {x=x, y=y-1, z=z} + num = num+1 + elseif y <= bottom then + if pr:next(1,LAVA_FREQ) == 1 then + data[vi] = c.lava + else + data[vi] = return_hell_ore(d_p_addp, false) + end + elseif r_shroom == 1 + and r_structure ~= 1 + and y == bottom+1 then + data[vi] = c.hell_shroom + elseif (y == top and r_glowstone == 1) then + data[vi] = c.glowstone + elseif y >= top then + data[vi] = return_hell_ore(d_p_addp, true) + elseif y <= top-1 + and generate_vine + and y >= top-r_vine_length then + data[vi] = c.hell_vine + else + data[vi] = c.air + end + end + vi = vi + varea.ystride + end + end + end + end + vm:set_data(data) +-- vm:set_lighting(12) +-- vm:calc_lighting() +-- vm:update_liquids() + vm:write_to_map(true) + + hell:inform("nodes set", 2, t1) + + local t2 = minetest.get_us_time() + local tr_bl_cnt = 0 + + if structures_enabled then -- Blood hellstructures + tr_bl_cnt = #tab + for i = 1,tr_bl_cnt do + grow_hellstructure(tab[i], true) + end + end + + if forest_possible then -- Forest trees + tr_bl_cnt = tr_bl_cnt + #trees + for i = 1,#trees do + grow_tree(trees[i], true) + end + end + + if tr_bl_cnt > 0 then + hell:inform(tr_bl_cnt .. " trees and blood structures set", 2, t2) + end + + t2 = minetest.get_us_time() + minetest.fix_light(minp, maxp) + + hell:inform("light fixed", 2, t2) + + hell:inform("done", 1, t1) +end) + +--abms + +minetest.register_abm({ + nodenames = {"hell:sapling"}, + neighbors = {"hell:blood_top"}, + interval = 20, + chance = 8, + action = function(pos) + local under = {x=pos.x, y=pos.y-1, z=pos.z} + if minetest.get_node_light(pos) < 4 + and minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name == "air" + and minetest.get_node(under).name == "hell:blood_top" then + grow_hellstructure(under) + end + end +}) + +minetest.register_abm({ + nodenames = {"hell:tree_sapling"}, + neighbors = {"group:hell_dirt"}, + interval = abm_tree_interval, + chance = abm_tree_chance, + action = function(pos) + if minetest.get_node({x=pos.x, y=pos.y+2, z=pos.z}).name == "air" + and minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name == "air" then + local udata = minetest.registered_nodes[ + minetest.get_node{x=pos.x, y=pos.y-1, z=pos.z}.name] + if udata + and udata.groups + and udata.groups.hell_dirt then + grow_tree(pos) + end + end + end +}) + +minetest.register_abm({ + nodenames = {"hell:hellrack_soil"}, + neighbors = {"air"}, + interval = 20, + chance = 20, + action = function(pos, node) + local par2 = node.param2 + if par2 == 0 then + return + end + pos.y = pos.y+1 + --mushrooms grow at dark places + if (minetest.get_node_light(pos) or 16) > 7 then + return + end + if minetest.get_node(pos).name == "air" then + minetest.set_node(pos, {name="riesenpilz:nether_shroom"}) + pos.y = pos.y-1 + minetest.set_node(pos, + {name="hell:hellrack_soil", param2=par2-1}) + end + end +}) + +local function grass_allowed(pos) + local nd = minetest.get_node(pos).name + if nd == "air" then + return true + end + if nd == "ignore" then + return 0 + end + local data = minetest.registered_nodes[nd] + if not data then + -- unknown node + return false + end + local drawtype = data.drawtype + if drawtype + and drawtype ~= "normal" + and drawtype ~= "liquid" + and drawtype ~= "flowingliquid" then + return true + end + local light = data.light_source + if light + and light > 0 then + return true + end + return false +end + +minetest.register_abm({ + nodenames = {"hell:dirt"}, + interval = 20, + chance = 9, + action = function(pos) + local allowed = grass_allowed({x=pos.x, y=pos.y+1, z=pos.z}) + if allowed == 0 then + return + end + if allowed then + minetest.set_node(pos, {name="hell:dirt_top"}) + end + end +}) + +minetest.register_abm({ + nodenames = {"hell:dirt_top"}, + interval = 30, + chance = 9, + action = function(pos) + local allowed = grass_allowed({x=pos.x, y=pos.y+1, z=pos.z}) + if allowed == 0 then + return + end + if not allowed then + minetest.set_node(pos, {name="hell:dirt"}) + end + end +}) + + +minetest.register_privilege("hell", + "Allows sending players to hell and extracting them") + +dofile(path.."/crafting.lua") +dofile(path.."/guide.lua") + + +local time = (minetest.get_us_time() - load_time_start) / 1000000 +local msg = ("[hell] loaded after ca. %g seconds."):format(time) +if time > 0.01 then + print(msg) +else + minetest.log("action", msg) +end diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..ca75437 --- /dev/null +++ b/init.lua @@ -0,0 +1,35 @@ +local S +if minetest.get_translator ~= nil then + S = minetest.get_translator("hell") +else + -- mock the translator function for MT 0.4 + S = function(str, ...) + local args={...} + return str:gsub( + "@%d+", + function(match) return args[tonumber(match:sub(2))] end + ) + end +end + +-- Global Hell namespace +hell = {} +hell.modname = minetest.get_current_modname() +hell.path = minetest.get_modpath(hell.modname) +hell.get_translator = S + +-- Settings +hell.DEPTH = -20000 -- The y location of the Hell +hell.FASTTRAVEL_FACTOR = 10 -- 10 could be better value for Minetest, since there's no sprint, but ex-Minecraft players will be mathing for 8 +hell.HELL_REALM_ENABLED = true -- Setting to false disables the Hell and Hell portal + + +-- Override default settings with values from the .conf file, if any are present. +hell.FASTTRAVEL_FACTOR = tonumber(minetest.settings:get("hell_fasttravel_factor") or hell.FASTTRAVEL_FACTOR) +hell.HELL_REALM_ENABLED = minetest.settings:get_bool("hell_realm_enabled", hell.HELL_REALM_ENABLED) or hell.HELL_REALM_ENABLED + + +-- Load files +if hell.HELL_REALM_ENABLED then + dofile(hell.path .. "/hell.lua") +end diff --git a/items.lua b/items.lua new file mode 100644 index 0000000..09fd98c --- /dev/null +++ b/items.lua @@ -0,0 +1,1016 @@ +local hell_sound = default.node_sound_stone_defaults({ + dig = {name="hell_dig", gain=0.7}, + dug = {name="hell_dug", gain=1}, + footstep = {name="hell_footstep", gain=0.4} +}) + +local add_fence = minetest.register_fence +local function add_more_nodes(name) + local nd = "hell:"..name + if not string.find(name, "hell") then + name = "hell_"..name + end + local data = minetest.registered_nodes[nd] + if stairsplus then + stairsplus:register_all( + "hell", + name, + nd, + data + ) + minetest.register_alias("stairs:stair_"..name, "hell"..":stair_"..name) + minetest.register_alias("stairs:slab_"..name, "hell"..":slab_"..name) + else + stairs.register_stair_and_slab( + name, nd, + data.groups, + data.tiles, + data.description.." Stair", + data.description.." Slab", + data.sounds + ) + end + if add_fence then + add_fence({fence_of = nd}) + end +end + +--[[ +local function add_fence(name) + local def = minetest.registered_nodes[name] + local fencedef = {} + for _,i in pairs({"walkable", "sunlike_propagates"}) do + if def[i] ~= nil then + fencedef[i] = def[i] + end + end +end +--]] + +local creative_installed = minetest.global_exists("creative") + +local function digging_allowed(player, v) + if not player then + return false + end + if creative_installed and creative.is_enabled_for(player:get_player_name()) then + return true + end + local tool = player:get_wielded_item():get_name() + tool = minetest.registered_tools[tool] or tool == "" and minetest.registered_items[tool] + if not tool + or not tool.tool_capabilities then + return false + end + local groups = tool.tool_capabilities.groupcaps + if not groups then + return false + end + if groups.hell + and groups.hell.times[v] then + return true + end + return false +end + +-- Hellrack +minetest.register_node("hell:hellrack", { + description = "Hellrack", + tiles = {"hell_hellrack.png"}, + groups = {hell=2}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 2) + end, +}) +add_more_nodes("hellrack") + +minetest.register_node("hell:hellrack_tiled", { + description = "Tiled Hellrack", + tiles = {"hell_hellrack_tiled.png"}, + groups = {hell=2}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 2) + end, +}) +add_more_nodes("hellrack_tiled") + +minetest.register_node("hell:hellrack_soil", { + description = "Dirty Hellrack", + tiles = {"hell_hellrack.png^hell_hellrack_soil.png"}, + groups = {hell=2}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 2) + end, +}) + +minetest.register_node("hell:hellrack_black", { + description = "Black Hellrack", + tiles = {"hell_hellrack_black.png"}, + groups = {hell=2}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 2) + end, +}) +add_more_nodes("hellrack_black") + +minetest.register_node("hell:hellrack_blue", { + description = "Blue Hellrack", + tiles = {"hell_hellrack_blue.png"}, + groups = {hell=1}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 1) + end, +}) +add_more_nodes("hellrack_blue") + +-- Hellbrick +minetest.register_node("hell:hellrack_brick", { + description = "Hellrack Brick", + tiles = {"hell_hellrack_brick.png"}, + groups = {hell=3}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 3) + end, +}) +add_more_nodes("hellrack_brick") + +minetest.register_node("hell:hellrack_brick_blue", { + description = "Blue Hellrack Brick", + tiles = {"hell_hellrack_brick_blue.png"}, + groups = {hell=3}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 3) + end, +}) +add_more_nodes("hellrack_brick_blue") + +minetest.register_node("hell:hellrack_brick_black", { + description = "Black Hellrack Brick", + tiles = {"hell_hellrack_brick_black.png"}, + groups = {hell=3}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 3) + end, +}) +add_more_nodes("hellrack_brick_black") + +minetest.register_node("hell:white", { + description = "Siwtonic block", + tiles = {"hell_white.png"}, + groups = {hell=1}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 1) + end, +}) +add_more_nodes("white") + + +-- Hell blood +minetest.register_node("hell:sapling", { + description = "Hell Blood Child", + drawtype = "plantlike", + tiles = {"hell_sapling.png"}, + inventory_image = "hell_sapling.png", + wield_image = "hell_sapling.png", + paramtype = "light", + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + }, + groups = {snappy=2, oddly_breakable_by_hand=2, attached_node=1}, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("hell:blood", { + description = "Hell Blood", + tiles = {"hell_blood.png"}, + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=1}, + sounds = default.node_sound_wood_defaults(), +}) +add_more_nodes("blood") + +minetest.register_node("hell:blood_cooked", { + description = "Cooked Hell Blood", + tiles = {"hell_blood_cooked.png"}, + groups = {hell=3}, + sounds = hell_sound, + furnace_burntime = 10, + can_dig = function(_, player) + return digging_allowed(player, 3) + end, +}) +add_more_nodes("blood_cooked") + +minetest.register_node("hell:blood_empty", { + description = "Hell Blood Extracted", + tiles = {"hell_blood_empty.png"}, + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=1}, + sounds = default.node_sound_wood_defaults(), +}) +add_more_nodes("blood_empty") + + +minetest.register_node("hell:blood_top", { + description = "Hell Blood Head", + tiles = {"hell_blood_top.png", "hell_blood.png", "hell_blood.png^hell_blood_side.png"}, + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=1}, + sounds = default.node_sound_wood_defaults(), +}) +add_more_nodes("blood_top") + +minetest.register_node("hell:blood_top_cooked", { + description = "Cooked Hell Blood Head", + tiles = {"hell_blood_top_cooked.png", "hell_blood_cooked.png", "hell_blood_cooked.png^hell_blood_side_cooked.png"}, + groups = {hell=3}, + sounds = hell_sound, + furnace_burntime = 10, + can_dig = function(_, player) + return digging_allowed(player, 3) + end, +}) +add_more_nodes("blood_top_cooked") + +minetest.register_node("hell:blood_top_empty", { + description = "Hell Blood Head Extracted", + tiles = {"hell_blood_top_empty.png", "hell_blood_empty.png", "hell_blood_empty.png^hell_blood_side_empty.png"}, + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=1}, + sounds = default.node_sound_wood_defaults(), +}) +add_more_nodes("blood_top_empty") + + +minetest.register_node("hell:blood_stem", { + description = "Hell Blood Stem", + tiles = {"hell_blood_stem_top.png", "hell_blood_stem_top.png", "hell_blood_stem.png"}, + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=1}, + sounds = default.node_sound_wood_defaults(), +}) +add_more_nodes("blood_stem") + +minetest.register_node("hell:blood_stem_cooked", { + description = "Cooked Hell Blood Stem", + tiles = {"hell_blood_stem_top_cooked.png", "hell_blood_stem_top_cooked.png", "hell_blood_stem_cooked.png"}, + groups = {hell=3}, + sounds = hell_sound, + furnace_burntime = 30, + can_dig = function(_, player) + return digging_allowed(player, 3) + end, +}) +add_more_nodes("blood_stem_cooked") + +minetest.register_node("hell:blood_stem_empty", { + description = "Hell Blood Stem Extracted", + tiles = {"hell_blood_stem_top_empty.png", "hell_blood_stem_top_empty.png", "hell_blood_stem_empty.png"}, + groups = {tree=1, choppy=2, oddly_breakable_by_hand=1}, + sounds = default.node_sound_wood_defaults(), +}) +add_more_nodes("blood_stem_empty") + + +minetest.register_node("hell:wood", { + description = "Hell Blood Wood", + tiles = {"hell_wood.png"}, + groups = {choppy=2, oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), +}) +add_more_nodes("wood") + +minetest.register_node("hell:wood_cooked", { + description = "Cooked Hell Blood Wood", + tiles = {"hell_wood_cooked.png"}, + groups = {hell=3}, + sounds = hell_sound, + furnace_burntime = 8, + can_dig = function(_, player) + return digging_allowed(player, 3) + end, +}) +add_more_nodes("wood_cooked") + +minetest.register_node("hell:wood_empty", { + description = "Hell Wood", + tiles = {"hell_wood_empty.png"}, + groups = {choppy=2, oddly_breakable_by_hand=2, wood=1}, + sounds = default.node_sound_wood_defaults(), +}) +add_more_nodes("wood_empty") + +minetest.register_node("hell:extractor", { + description = "Hell Blood Extractor", + tiles = {"hell_blood_extractor.png"}, + groups = {hell=3}, + sounds = hell_sound, + can_dig = function(_, player) + return digging_allowed(player, 3) + end, +}) + +-- Hell fruit +minetest.register_node("hell:fruit_leaves", { + description = "Hell Fruit Leaves", + tiles = {"hell_fruit_leaves.png"}, + groups = {fleshy=3, dig_immediate=2}, + sounds = default.node_sound_defaults(), + furnace_burntime = 18, +}) +add_more_nodes("fruit_leaves") + +local function room_for_items(inv) + local free_slots = 0 + for _,i in ipairs(inv:get_list("main")) do + if i:get_count() == 0 then + free_slots = free_slots+1 + end + end + if free_slots < 2 then + return false + end + return true +end + +local drop_mushroom = minetest.registered_nodes["riesenpilz:nether_shroom"].on_drop +minetest.override_item("riesenpilz:nether_shroom", { + on_drop = function(itemstack, dropper, pos) + if dropper:get_player_control().aux1 then + return drop_mushroom(itemstack, dropper, pos) + end + local inv = dropper:get_inventory() + if not inv then + return + end + if not room_for_items(inv) then + return + end + minetest.sound_play("hell_remove_leaf", {pos = pos, gain = 0.25}) + itemstack:take_item() + inv:add_item("main", "hell:shroom_head") + inv:add_item("main", "hell:shroom_stem") + return itemstack + end, +}) + +minetest.register_node("hell:apple", { + description = "Hell Fruit", + drawtype = "nodebox", + tiles = {"hell_fruit_top.png", "hell_fruit_bottom.png", "hell_fruit.png", "hell_fruit.png^[transformFX", "hell_fruit.png^[transformFX", "hell_fruit.png"}, + node_box = { + type = "fixed", + fixed = { + {-1/6, -1/4, -1/6, 1/6, -1/6, 1/6}, + + {-1/6, -1/6, -1/4, 1/6, 1/6, 1/4}, + {-1/4, -1/6, -1/6, 1/4, 1/6, 1/6}, + + {-1/4, 1/6, -1/12, 1/4, 1/4, 1/12}, + {-1/12, 1/6, -1/4, 1/12, 1/4, 1/4}, + + {-1/6, 1/6, -1/6, 1/6, 1/3, 1/6}, + + {-1/12, 1/3, -1/12, 0, 5/12, 0}, + + {-1/12, 5/12, -1/6, 0, 0.5, 1/12}, + {-1/6, 5/12, -1/12, 1/12, 0.5, 0}, + } + }, + paramtype = "light", + groups = {fleshy=3, dig_immediate=3}, + sounds = default.node_sound_defaults(), + furnace_burntime = 6, + on_use = minetest.item_eat(-5, "hell:blood_extracted 2"), +}) + +local drop_fruit = minetest.registered_nodes["hell:apple"].on_drop +minetest.override_item("hell:apple", { + on_drop = function(itemstack, dropper, pos) + if dropper:get_player_control().aux1 then + return drop_fruit(itemstack, dropper, pos) + end + local inv = dropper:get_inventory() + if not inv then + return + end + if not room_for_items(inv) then + return + end + minetest.sound_play("hell_remove_leaf", {pos = pos, gain = 0.25}) + itemstack:take_item() + inv:add_item("main", "hell:fruit_leaf") + inv:add_item("main", "hell:fruit_no_leaf") + return itemstack + end, +}) + +-- Hell vine +minetest.register_node("hell:vine", { + description = "Hell vine", + walkable = false, + drop = "hell:sapling", + sunlight_propagates = true, + paramtype = "light", + tiles = { "hell_vine.png" }, + drawtype = "plantlike", + inventory_image = "hell_vine.png", + groups = { snappy = 3,flammable=2 }, + sounds = default.node_sound_leaves_defaults(), + after_dig_node = function(pos, _, _, digger) + if digger then + local p = {x=pos.x, y=pos.y-1, z=pos.z} + local nn = minetest.get_node(p) + if nn.name == "hell:vine" then + minetest.node_dig(p, nn, digger) + end + end + end +}) + + +-- forest stuff + +for n,i in pairs({"small", "middle", "big"}) do + minetest.register_node("hell:grass_"..i, { + description = "Hell Grass", + drawtype = "plantlike", + waving = 1, + tiles = {"hell_grass_"..i..".png"}, + inventory_image = "hell_grass_"..i..".png", + wield_image = "hell_grass_"..i..".png", + paramtype = "light", + walkable = false, + buildable_to = true, + drop = "hell:grass "..n, + groups = {snappy=3,flora=1,attached_node=1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + }, + }) +end + +minetest.register_node("hell:glowflower", { + description = "Glowing Flower", + drawtype = "plantlike", + tiles = {"hell_glowflower.png"}, + inventory_image = "hell_glowflower.png", + wield_image = "hell_glowflower.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + buildable_to = true, + light_source = 10, + groups = {snappy=3,flammable=2,flower=1,flora=1,attached_node=1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -0.15, -0.5, -0.15, 0.15, 0.2, 0.15 }, + }, +}) + +minetest.register_node("hell:tree_sapling", { + description = "Hell Tree Sapling", + drawtype = "plantlike", + tiles = {"hell_tree_sapling.png"}, + inventory_image = "hell_tree_sapling.png", + wield_image = "hell_tree_sapling.png", + paramtype = "light", + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + }, + groups = {snappy=2, oddly_breakable_by_hand=2, attached_node=1}, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("hell:tree", { + description = "Hell Trunk", + tiles = {"hell_tree_top.png", "hell_tree_top.png", "hell_tree.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree=1,choppy=2,oddly_breakable_by_hand=1}, + sounds = default.node_sound_wood_defaults(), + on_place = minetest.rotate_node +}) + +minetest.register_node("hell:tree_corner", { + description = "Hell Trunk Corner", + tiles = {"hell_tree.png^[transformR180", "hell_tree_top.png", "hell_tree_corner.png^[transformFY", + "hell_tree_corner.png^[transformR180", "hell_tree.png", "hell_tree_top.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,not_in_creative_inventory=1}, + drop = "hell:tree", + sounds = default.node_sound_wood_defaults(), + on_place = minetest.rotate_node +}) + +minetest.register_node("hell:forest_wood", { + description = "Hell Wood Block", + tiles = {"hell_forest_wood.png"}, + groups = {choppy=2,oddly_breakable_by_hand=2,wood=1}, + sounds = default.node_sound_wood_defaults(), +}) +add_more_nodes("forest_wood") + +minetest.register_node("hell:leaves", { + description = "Hell Leaves", + drawtype = "plantlike", + waving = 1, + visual_scale = math.sqrt(2) + 0.01, + tiles = {"hell_leaves.png"}, + inventory_image = "hell_leaves.png", + wield_image = "hell_leaves.png", + paramtype = "light", + paramtype2 = "degrotate", + is_ground_content = false, + groups = {snappy=3, leafdecay=3, leaves=1}, + drop = { + max_items = 1, + items = { + { + items = {"hell:tree_sapling"}, + rarity = 30, + }, + { + items = {"hell:leaves"}, + } + } + }, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("hell:dirt", { + description = "Hell Dirt", + tiles = {"hell_dirt.png"}, + groups = {crumbly=3,soil=1,hell_dirt=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_node("hell:dirt_top", { + description = "Hell Dirt Top", + tiles = {"hell_dirt_top.png", "hell_dirt.png", + {name="hell_dirt.png^hell_dirt_top_side.png", tileable_vertical = false} + }, + groups = {crumbly=3,soil=1,hell_dirt=1}, + drop = "hell:dirt", + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) + +minetest.register_node("hell:dirt_bottom", { + description = "Hellrack Dirt Transition", + tiles = {"hell_dirt.png", "hell_hellrack.png", + {name="hell_hellrack.png^hell_dirt_transition.png", tileable_vertical = false} + }, + groups = {hell=2}, + drop = "hell:hellrack", + sounds = default.node_sound_dirt_defaults({ + dig = {name="hell_dig", gain=0.7}, + dug = {name="hell_dug", gain=1}, + }), + can_dig = function(_, player) + return digging_allowed(player, 2) + end, +}) + + +-- Hell torch +minetest.register_node("hell:torch", { + description = "Hell Torch", + drawtype = "torchlike", + tiles = {"hell_torch_on_floor.png", "hell_torch_on_ceiling.png", + { + name = "hell_torch.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + inventory_image = "hell_torch_on_floor.png", + wield_image = "hell_torch_on_floor.png", + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + light_source = 13, + selection_box = { + type = "wallmounted", + wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1}, + wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1}, + wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1}, + }, + groups = {choppy=2, dig_immediate=3, attached_node=1, hot=3, igniter=1}, + legacy_wallmounted = true, + sounds = default.node_sound_defaults(), +}) + +local invisible = "hell_transparent.png" +minetest.register_node("hell:portal", { + description = "Hell Portal Essence", + tiles = {invisible, invisible, invisible, invisible, "hell_portal_stuff.png"}, + inventory_image = "hell_portal_stuff.png", + wield_image = "hell_portal_stuff.png", + light_source = 12, + paramtype = "light", + sunlight_propagates = true, + use_texture_alpha = true, + walkable = false, + pointable = false, + buildable_to = false, + drop = "", + diggable = false, + groups = {not_in_creative_inventory=1}, + post_effect_color = {a=200, r=50, g=0, b=60},--{a=180, r=128, g=0, b=128} + drawtype = "nodebox", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.1, 0.5, 0.5, 0.1}, + }, + }, +}) + + +minetest.register_craftitem("hell:grass", { + description = "Hell Grass", + inventory_image = "hell_grass.png", +}) + +minetest.register_craftitem("hell:grass_dried", { + description = "Dried Hell Grass", + inventory_image = "hell_grass_dried.png", + furnace_burntime = 1, +}) + +minetest.register_craftitem("hell:forest_planks", { + description = "Hell Wooden Planks", + inventory_image = "hell_forest_planks.png", + stack_max = 990, +}) + +minetest.register_craftitem("hell:bark", { + description = "Hell Trunk Bark", + inventory_image = "hell_bark.png", + furnace_burntime = 5, +}) + +-- Hell Pearl +minetest.register_craftitem("hell:pearl", { + description = "Hell Pearl", + inventory_image = "hell_pearl.png", +}) + +minetest.register_craftitem("hell:stick", { + description = "Hell Stick", + inventory_image = "hell_stick.png", + groups = {stick=1}, +}) + +local tmp = {} +minetest.register_craftitem("hell:shroom_head", { + description = "Hell Mushroom Head", + inventory_image = "hell_shroom_top.png", + furnace_burntime = 3, + on_place = function(itemstack, _, pointed_thing) + if not pointed_thing then + return + end + + if pointed_thing.type ~= "node" then + return + end + + local pos = minetest.get_pointed_thing_position(pointed_thing) + local node = minetest.get_node(pos) + local pstr = pos.x.." "..pos.y.." "..pos.z + + if node.name == "hell:hellrack_soil" + and not tmp[pstr] then + minetest.sound_play("default_grass_footstep", {pos=pos}) + minetest.set_node(pos, {name="hell:hellrack_soil", param2=math.max(node.param2, math.random(3, 10))}) + tmp[pstr] = true + minetest.after(3, function() tmp[pos.x.." "..pos.y.." "..pos.z] = nil end) + end + end +}) + +minetest.register_craftitem("hell:shroom_stem", { + description = "Hell Mushroom Stem", + inventory_image = "hell_shroom_stem.png", + furnace_burntime = 3, +}) + +minetest.register_craftitem("hell:fruit_leaf", { + description = "Hell Fruit Leaf", + inventory_image = "hell_fruit_leaf.png", + furnace_burntime = 2, +}) + +minetest.register_craftitem("hell:fruit_no_leaf", { + description = "Hell Fruit Without Leaf", + inventory_image = "hell_fruit_no_leaf.png", + furnace_burntime = 4, +}) + +minetest.register_craftitem("hell:fim", { + description = "Hell FIM", --fruit in mushroom + inventory_image = "hell_fim.png", + furnace_burntime = 10, +}) + +local blood_exno = {} +for _,i in ipairs({"hell:blood", "hell:blood_top", "hell:blood_stem"}) do + blood_exno[i] = i.."_empty" +end + +minetest.register_craftitem("hell:blood_extracted", { + description = "Blood", + inventory_image = "hell_blood_extracted.png", + on_place = function(itemstack, _, pointed_thing) + if not pointed_thing then + return + end + + if pointed_thing.type ~= "node" then + return + end + + local pos = minetest.get_pointed_thing_position(pointed_thing) + local node = minetest.get_node_or_nil(pos) + + if not node then + return + end + + if node.name == "hell:vine" then + pos = {x=pos.x, y=pos.y-1, z=pos.z} + if minetest.get_node(pos).name == "air" then + minetest.set_node(pos, {name = "hell:vine"}) + end + itemstack:take_item() + return itemstack + end + + if node.name ~= "hell:extractor" then + return + end + itemstack:take_item() + minetest.after(1, function(pos) + for i = -1,1,2 do + for _,p in ipairs({ + {x=pos.x+i, y=pos.y, z=pos.z}, + {x=pos.x, y=pos.y, z=pos.z+i}, + }) do + local nodename = blood_exno[minetest.get_node(p).name] + if nodename then + minetest.set_node(p, {name=nodename}) + p = vector.add(p, {x=math.random()-0.5, y=math.random()+0.5, z=math.random()-0.5}) + minetest.sound_play("hell_extract_blood", {pos = p, gain = 1}) + minetest.add_item(p, "hell:blood_extracted") + end + end + end + end, pos) + + return itemstack + end +}) + +minetest.register_craftitem("hell:hotbed", { + description = "Cooked Blood", + inventory_image = "hell_hotbed.png", + on_place = function(itemstack, _, pointed_thing) + if not pointed_thing then + return + end + if pointed_thing.type ~= "node" then + return + end + local pos = minetest.get_pointed_thing_position(pointed_thing) + local node = minetest.get_node(pos) + + if node.name ~= "hell:hellrack" then + return + end + + minetest.sound_play("default_place_node", {pos=pos}) + minetest.set_node(pos, {name = "hell:hellrack_soil"}) + + itemstack:take_item() + return itemstack + end +}) + + +minetest.register_tool("hell:pick_mushroom", { + description = "Hell Mushroom Pickaxe", + inventory_image = "hell_pick_mushroom.png", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + cracky = {times={[3]=3}, uses=1, maxlevel=1}, + hell = {times={[3]=3}, uses=1, maxlevel=1}, + }, + }, +}) + +minetest.register_tool("hell:pick_wood", { + description = "Hell Wood Pickaxe", + inventory_image = "hell_pick_wood.png", + tool_capabilities = { + full_punch_interval = 1.2, + max_drop_level=0, + groupcaps={ + cracky = {times={[3]=1.6}, uses=10, maxlevel=1}, + hell = {times={[2]=6, [3]=1.6}, uses=10, maxlevel=1}, + }, + damage_groups = {fleshy=2}, + }, +}) + +minetest.register_tool("hell:pick_hellrack", { + description = "Hellrack Pickaxe", + inventory_image = "hell_pick_hellrack.png", + tool_capabilities = { + full_punch_interval = 1.3, + max_drop_level=0, + groupcaps={ + cracky = {times={[2]=2.0, [3]=1.20}, uses=20, maxlevel=1}, + hell = {times={[1]=16, [2]=2, [3]=1.20}, uses=20, maxlevel=1}, + }, + damage_groups = {fleshy=3}, + }, +}) + +minetest.register_tool("hell:pick_hellrack_blue", { + description = "Blue Hellrack Pickaxe", + inventory_image = "hell_pick_hellrack_blue.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + groupcaps={ + cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=30, maxlevel=2}, + hell = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=30, maxlevel=2}, + }, + damage_groups = {fleshy=4}, + }, +}) + +minetest.register_tool("hell:pick_white", { + description = "Siwtonic Pickaxe", + inventory_image = "hell_pick_white.png", + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level=3, + groupcaps={ + cracky = {times={[1]=1, [2]=0.8, [3]=0.3}, uses=180, maxlevel=3}, + hell = {times={[1]=1, [2]=0.5, [3]=0.3}, uses=180, maxlevel=3}, + }, + damage_groups = {fleshy=5}, + }, +}) + +minetest.register_tool("hell:axe_hellrack", { + description = "Hellrack Axe", + inventory_image = "hell_axe_hellrack.png", + tool_capabilities = { + full_punch_interval = 1.3, + max_drop_level=0, + groupcaps={ + choppy={times={[1]=2.9, [2]=1.9, [3]=1.4}, uses=20, maxlevel=1}, + }, + damage_groups = {fleshy=4}, + }, +}) + +minetest.register_tool("hell:axe_hellrack_blue", { + description = "Blue Hellrack Axe", + inventory_image = "hell_axe_hellrack_blue.png", + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level=1, + groupcaps={ + choppy={times={[1]=2.5, [2]=1.5, [3]=1}, uses=30, maxlevel=2}, + }, + damage_groups = {fleshy=6}, + }, +}) + +minetest.register_tool("hell:axe_white", { + description = "Siwtonic Axe", + inventory_image = "hell_axe_white.png", + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level=1, + groupcaps={ + choppy={times={[1]=1.2, [2]=0.5, [3]=0.3}, uses=180, maxlevel=2}, + }, + damage_groups = {fleshy=8}, + }, +}) + +minetest.register_tool("hell:shovel_hellrack", { + description = "Hellrack Shovel", + inventory_image = "hell_shovel_hellrack.png", + wield_image = "hell_shovel_hellrack.png^[transformR90", + tool_capabilities = { + full_punch_interval = 1.4, + max_drop_level=0, + groupcaps={ + crumbly = {times={[1]=1.7, [2]=1.1, [3]=0.45}, uses=22, maxlevel=2}, + }, + damage_groups = {fleshy=2}, + }, +}) + +minetest.register_tool("hell:shovel_hellrack_blue", { + description = "Blue Hellrack Shovel", + inventory_image = "hell_shovel_hellrack_blue.png", + wield_image = "hell_shovel_hellrack_blue.png^[transformR90", + tool_capabilities = { + full_punch_interval = 1.1, + max_drop_level=1, + groupcaps={ + crumbly = {times={[1]=1.4, [2]=0.8, [3]=0.35}, uses=50, maxlevel=2}, + }, + damage_groups = {fleshy=3}, + }, +}) + +minetest.register_tool("hell:shovel_white", { + description = "Siwtonic Shovel", + inventory_image = "hell_shovel_white.png", + wield_image = "hell_shovel_white.png^[transformR90", + tool_capabilities = { + full_punch_interval = 1, + max_drop_level=1, + groupcaps={ + crumbly = {times={[1]=0.95, [2]=0.45, [3]=0.1}, uses=151, maxlevel=3}, + }, + damage_groups = {fleshy=4}, + }, +}) + +minetest.register_tool("hell:sword_hellrack", { + description = "Hellrack Sword", + inventory_image = "hell_sword_hellrack.png", + tool_capabilities = { + full_punch_interval = 1, + max_drop_level=0, + groupcaps={ + snappy={times={[2]=1.3, [3]=0.38}, uses=40, maxlevel=1}, + }, + damage_groups = {fleshy=5}, + }, +}) + +minetest.register_tool("hell:sword_hellrack_blue", { + description = "Blue Hellrack Sword", + inventory_image = "hell_sword_hellrack_blue.png", + tool_capabilities = { + full_punch_interval = 0.8, + max_drop_level=1, + groupcaps={ + snappy={times={[1]=2.5, [2]=1.1, [3]=0.33}, uses=40, maxlevel=2}, + }, + damage_groups = {fleshy=7}, + }, +}) + +minetest.register_tool("hell:sword_white", { + description = "Siwtonic Sword", + inventory_image = "hell_sword_white.png", + wield_image = "hell_sword_white.png^[transformR90", + tool_capabilities = { + full_punch_interval = 0.7, + max_drop_level=1, + groupcaps={ + snappy={times={[1]=1.7, [2]=0.8, [3]=0.2}, uses=100, maxlevel=3}, + }, + damage_groups = {fleshy=11}, + }, +}) + + +-- override creative hand +if minetest.settings:get_bool("creative_mode") then + local capas = minetest.registered_items[""].tool_capabilities + capas.groupcaps.hell = capas.groupcaps.cracky + minetest.override_item("", {tool_capabilities = capas}) +end diff --git a/locale/hell.fr.tr b/locale/hell.fr.tr new file mode 100644 index 0000000..96679df --- /dev/null +++ b/locale/hell.fr.tr @@ -0,0 +1,8 @@ +# textdomain: hell +For any reason you arrived here. Type /hell_help to find out things like craft recipes.=Peu importe la raison, vous vous retrouvez ici. Entrez /hell_help pour trouver quoi faire comme des recettes de craft. +Hell Gate=Porte de l'Enfer +Construction requires 16 blocks of ??. The finished frame must be in the shape of a circle and laid vertically, like a door.=La construction requiert 16 blocks de ??. Le cadre fini doit être en forme de cercle et posé verticalement, comme une porte. +However, I never knew what material to use for building this door despite my many attempts.=Par contre je n'ai jamais su quels matériaux utiliser pour construire cette porte malgré mes multiples essaies. +One day, however, I met an old lady who frankly looked like a witch. In the course of our discussion we came to talk about the Hell Gate. This old lady confessed to me that in her family there was a legend that one of her ancestors had managed to activate the portal. But that the poor man was instantly killed as he passed through it. The gate was destroyed and several years passed. But since a certain night, the poor widow of the deceased began to rave that her Husband had come back from the dead to take her also to hell because he said that he had made this world a wonderful place and that after several years, he would have found a way to come back and return to it as he wished without causing death. A few days later, the widow disappeared without a trace. Since then the house was destroyed in a fire with all the secrets it could hold. Only an old cauldron remained amidst the ashes.=Un jour cependant, je fis la rencontre d'une vielle dame qui franchement avait l'allure d'une sorcière. Au cours de notre discussion nous en vîmes à parler de la Porte de l'Enfer. Cette vieille dame me confessa que dans sa famille se perpétuait une légende selon laquelle un de ses ancêtres serait parvenu à activer le portail. Mais que le pauvre homme fût instantanément tué en le traversant. Le portail fût détruit et plusieurs années ont passées. Mais depuis une certaine nuit, la pauvre veuve du défunt se mit à délirer en affirmant que son Mari était revenue d'entre les morts pour l'emmener elle aussi en enfer car il disait qu'il avait fait de ce monde un endroit merveilleux et qu'après plusieurs années, il aurait découvert un moyen d'en revenir et d'y retourner à sa guise sans provoquer la mort. Quelques jours après, la veuve disparu sans laisser de traces. Depuis la maison fût détruite dans un incendie avec tous les secrets qu'elle pouvait renfermer. Il ne resta qu'un vieux chaudron au milieux des cendres. +When I wanted to ask the old lady with what material the gate was made, she stared at me with eyes so black that I had the impression that the Nether wanted to take over me, and I did not insist any further.=En voulant questionner la vielle dame de quelle matière le portail était fait, elle me fixa du regard avec des yeux si noirs que j'avais l'impression que les Bas-Fonds voulaient s'emparer de moi et je n'insista pas plus. +You shall not pass!=Vous ne passerez pas ! diff --git a/locale/template.txt b/locale/template.txt new file mode 100644 index 0000000..f141f4b --- /dev/null +++ b/locale/template.txt @@ -0,0 +1,8 @@ +# textdomain: hell +For any reason you arrived here. Type /hell_help to find out things like craft recipes.= +Hell Gate= +Construction requires 16 blocks of ??. The finished frame must be in the shape of a circle and laid vertically, like a door.= +However, I never knew what material to use for building this door despite my many attempts.= +One day, however, I met an old lady who frankly looked like a witch. In the course of our discussion we came to talk about the Hell Gate. This old lady confessed to me that in her family there was a legend that one of her ancestors had managed to activate the portal. But that the poor man was instantly killed as he passed through it. The gate was destroyed and several years passed. But since a certain night, the poor widow of the deceased began to rave that her Husband had come back from the dead to take her also to hell because he said that he had made this world a wonderful place and that after several years, he would have found a way to come back and return to it as he wished without causing death. A few days later, the widow disappeared without a trace. Since then the house was destroyed in a fire with all the secrets it could hold. Only an old cauldron remained amidst the ashes.= +When I wanted to ask the old lady with what material the gate was made, she stared at me with eyes so black that I had the impression that the Nether wanted to take over me, and I did not insist any further.= +You shall not pass!= diff --git a/pearl.lua b/pearl.lua new file mode 100644 index 0000000..a01da20 --- /dev/null +++ b/pearl.lua @@ -0,0 +1,198 @@ +local function table_contains(t, v) + for _,i in pairs(t) do + if v == i then + return true + end + end + return false +end + +local creative = minetest.settings:get_bool("creative_mode") +local function throw_pearl(item, player) + local playerpos = player:getpos() + playerpos.y = playerpos.y+1.625 + local obj = minetest.add_entity(playerpos, "hell:pearl_entity") + local dir = player:get_look_dir() + obj:setvelocity(vector.multiply(dir, 30)) + obj:setacceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3}) + obj:get_luaentity().player = player:get_player_name() + if not creative then + item:take_item() + return item + end +end + +local function get_node(pos) + local name = minetest.get_node(pos).name + if name ~= "ignore" then + return name + end + minetest.get_voxel_manip():read_from_map(pos, pos) + name = minetest.get_node_or_nil(pos) + if not name then + return + end + return name.name +end + +local softs = {} +local function is_soft(pos) + local name = get_node(pos) + if not name then + return false + end + local is_soft = softs[name] + if is_soft ~= nil then + return is_soft + end + if not minetest.registered_nodes[name] then + softs[name] = false + return false + end + is_soft = minetest.registered_nodes[name].walkable == false + softs[name] = is_soft + return is_soft +end + +-- teleports the player there if there's free space +local function teleport_player(pos, player) + if not is_soft(pos) then + return false + end + if not is_soft({x=pos.x, y=pos.y+1, z=pos.z}) + and not is_soft({x=pos.x, y=pos.y-1, z=pos.z}) then + return false + end + pos.y = pos.y+0.05 + player:moveto(pos) + return true +end + +--[[ +local dg_ps = {} +local function forceload(pos) + dg_ps[#dg_ps+1] = pos + minetest.forceload_block(pos) + minetest.after(5, function(pos) + minetest.forceload_free_block(pos) + for i,p in pairs(dg_ps) do + if vector.equals(p, pos) then + dg_ps[i] = nil + return + end + end + end, pos) +end +minetest.register_on_shutdown(function() + for _,p in pairs(dg_ps) do + minetest.forceload_free_block(p) + end +end)--]] + +minetest.register_entity("hell:pearl_entity", { + collisionbox = {0,0,0,0,0,0}, --not pointable + visual_size = {x=0.1, y=0.1}, + physical = false, -- Collides with things + textures = {"hell_pearl.png"}, + on_activate = function(self, staticdata) + if not staticdata + or staticdata == "" then + return + end + local tmp = minetest.deserialize(staticdata) + if not tmp then + minetest.log("error", "[hell] pearl: invalid staticdata ") + return + end + self.player = tmp.player + end, + get_staticdata = function(self) + --forceload(vector.round(self.object:getpos())) + return minetest.serialize({ + player = self.player, + }) + end, + timer = 0, + on_step = function(self, dtime) + self.timer = self.timer+dtime + + --[[ + local delay = self.delay + if delay < 0.1 then + self.delay = delay+dtime + return + end + self.delay = 0--]] + + if self.timer > 20 then + self.object:remove() + return + end + + local pos = self.object:getpos() + local rpos = vector.round(pos) + local lastpos = self.lastpos + if not lastpos then + self.lastpos = vector.new(rpos) + return + end + if lastpos.x + and vector.equals(vector.round(lastpos), rpos) then + return + end + + local player = self.player + if not player then + minetest.log("error", "[hell] pearl: missing playername") + self.object:remove() + return + end + player = minetest.get_player_by_name(player) + if not player then + minetest.log("error", "[hell] pearl: missing player") + self.object:remove() + return + end + + if not get_node(rpos) then + minetest.log("error", "[hell] pearl: missing node") + self.object:remove() + return + end + + self.lastpos = vector.new(pos) + + local free, p = minetest.line_of_sight(lastpos, pos) + if free then + return + end + if is_soft(p) then + return + end + self.object:remove() + minetest.after(0, function(p) --minetest.after is used that the sound is played after the teleportation + minetest.sound_play("hell_pearl", {pos=p, max_hear_distance=10}) + end, p) + p.y = p.y+1 + if teleport_player(vector.new(p), player) then + return + end + p.y = p.y-2 + for i = -1,1,2 do + for _,j in pairs({{i, 0}, {0, i}}) do + if teleport_player({x=p.x+j[1], y=p.y, z=p.z+j[2]}, player) then + return + end + end + end + for i = -1,1,2 do + for j = -1,1,2 do + if teleport_player({x=p.x+j, y=p.y, z=p.z+i}, player) then + return + end + end + end + end +}) + +minetest.override_item("hell:pearl", {on_use = throw_pearl}) diff --git a/portal.lua b/portal.lua new file mode 100644 index 0000000..75ad1ce --- /dev/null +++ b/portal.lua @@ -0,0 +1,561 @@ +--code copied from Pilzadam's nether mod and edited +local S = hell.get_translator +-- kills the player if he uses PilzAdam portal +local portal_target = hell.buildings+1 +local hell_prisons = minetest.settings:get_bool("enable_damage") +local obsidian_portal_kills = hell_prisons and true +local mclike_portal = false +local save_path = minetest.get_worldpath() .. "/hell_players" +local players_in_hell = {} +-- only get info from file if hell prisons +if hell_prisons then + local file = io.open(save_path, "r") + if file then + local contents = file:read("*all") + io.close(file) + if contents then + local playernames = string.split(contents, " ") + for i = 1,#playernames do + players_in_hell[playernames[i]] = true + end + end + end +end + +local function save_hell_players() + local playernames,n = {},1 + for name in pairs(players_in_hell) do + playernames[n] = name + n = n+1 + end + local f = io.open(save_path, "w") + assert(f, "Could not open hell_players file for writing.") + f:write(table.concat(playernames, " ")) + io.close(f) +end + +local update_background +if hell_prisons then + function update_background(player, down) + if down then + player:set_sky({r=15, g=0, b=0}, "plain") + else + player:set_sky(nil, "regular") + end + end +else + function update_background() end +end + +-- returns nodename if area is generated, else calls generation function +local function generated_or_generate(pos) + local node = minetest.get_node_or_nil(pos) + if node then + return node.name + end + minetest.get_voxel_manip():read_from_map(pos, pos) + node = minetest.get_node_or_nil(pos) + if not node then + minetest.emerge_area(vector.subtract(pos, 80), vector.add(pos, 80)) + return false + end + return node.name +end + +-- where the player appears after dying +local function get_player_died_target(player) + local target = vector.add(player:get_pos(), + {x=math.random(-100,100), y=0, z=math.random(-100,100)}) + target.y = portal_target + math.random(4) + return target +end + +-- used for obsidian portal +local function obsidian_teleport(player, pname, target) + minetest.chat_send_player(pname, S("For any reason you arrived here. Type /hell_help to find out things like craft recipes.")) + players_in_hell[pname] = true + save_hell_players() + update_background(player, true) + if target then + player:set_pos(target) + else + player:set_hp(0) + end +end + +-- teleports players to hell or helps it +local function player_to_hell(player, pos) + local pname = player:get_player_name() + if players_in_hell[pname] then + return + end + players_in_hell[pname] = true + save_hell_players() + update_background(player, true) + if pos then + player:set_pos(pos) + return + end + minetest.chat_send_player(pname, S("For any reason you arrived here. Type /hell_help to find out things like craft recipes.")) + player:set_hp(0) + if hell_prisons then + player:set_pos(get_player_died_target(player)) + end +end + +local function player_from_hell(player, pos) + local pname = player:get_player_name() + if players_in_hell[pname] then + players_in_hell[pname] = nil + save_hell_players() + end + update_background(player) + player:set_pos(pos) +end + +local function is_player_connected(name) + for _,player in pairs(minetest.get_connected_players()) do + if player:get_player_name() == name then + return true + end + end + return false +end + +-- Chatcommands (edited) written by sss +minetest.register_chatcommand("to_hell", { + params = "[player_name]", + description = "Send someone to hell", + func = function(name, pname) + if not minetest.check_player_privs(name, {hell=true}) then + return false, + "You need the hell privilege to execute this chatcommand." + end + if not is_player_connected(pname) then + pname = name + end + local player = minetest.get_player_by_name(pname) + if not player then + return false, "Something went wrong." + end + minetest.chat_send_player(pname, "Go to hell !!!") + player_to_hell(player) + return true, pname.." is now in the hell." + end +}) + +minetest.register_chatcommand("from_hell", { + params = "[player_name]", + description = "Extract from hell", + func = function(name, pname) + if not minetest.check_player_privs(name, {hell=true}) then + return false, + "You need the hell priv to execute this chatcommand." + end + if not is_player_connected(pname) then + pname = name + end + local player = minetest.get_player_by_name(pname) + if not player then + return false, "Something went wrong." + end + minetest.chat_send_player(pname, "You are free now") + local pos = player:getpos() + player_from_hell(player, {x=pos.x, y=100, z=pos.z}) + return true, pname.." is now out of the hell." + end +}) + + +if hell_prisons then + -- randomly set player position when he/she dies in hell + minetest.register_on_respawnplayer(function(player) + local pname = player:get_player_name() + if not players_in_hell[pname] then + return + end + local target = get_player_died_target(player) + player:set_pos(target) + minetest.after(0, function(pname, target) + -- fixes respawn bug + local player = minetest.get_player_by_name(pname) + if player then + player:moveto(target) + end + end, pname, target) + return true + end) + + -- override set_pos etc. to disallow player teleportion by e.g. travelnet + local function can_teleport(player, pos) + if not player:is_player() then + -- the same metatable is used for entities + return true + end + local pname = player:get_player_name() + local in_hell = players_in_hell[pname] + + -- test if the target is valid + if pos.y < hell.start and pos.y > hell.DEPTH-510 then + if in_hell then + return true + end + elseif not in_hell then + return true + end + + -- test if the current position is valid + local current_pos = player:get_pos() + local now_in_hell = current_pos.y < hell.start and current_pos.y > hell.DEPTH-510 + if now_in_hell ~= in_hell then + if in_hell then + minetest.log("action", "Player \"" .. pname .. + "\" has to be in the hell, teleporting it!") + update_background(player, true) + current_pos.y = portal_target + player:set_pos(current_pos) + else + minetest.log("action", "Player \"" .. pname .. + "\" must not be in the hell, teleporting it!") + update_background(player) + current_pos.y = 20 + player:set_pos(current_pos) + end + return false + end + + minetest.chat_send_player(pname, + "You can not simply teleport to or from the hell!") + minetest.log("action", "Player \"" .. pname .. + "\" attempted to teleport from or to the hell, ignoring.") + return false + end + local methods = {"set_pos", "move_to", "setpos", "moveto"} + local metatable_overridden + minetest.register_on_joinplayer(function(player) + -- set the background when the player joins + local y = player:get_pos().y + if y < hell.start and y > hell.DEPTH-510 then + update_background(player, true) + end + + -- overide set_pos etc. if not yet done + if metatable_overridden then + return + end + metatable_overridden = true + local mt = getmetatable(player) + for i = 1,#methods do + local methodname = methods[i] + local origfunc = mt[methodname] + mt[methodname] = function(...) + if can_teleport(...) then + origfunc(...) + end + end + end + end) +else + -- test if player is in hell when he/she joins + minetest.register_on_joinplayer(function(player) + local y = player:get_pos().y + players_in_hell[player:get_player_name()] = + y < hell.start and y > hell.DEPTH-510 or nil + end) +end + +-- teleports player to hell (obsidian portal) +local function obsi_teleport_player(player, pos, target) + local pname = player:get_player_name() + if players_in_hell[pname] then + return + end + + local objpos = player:get_pos() + objpos.y = objpos.y+0.1 -- Fix some glitches at -8000 + if minetest.get_node(vector.round(objpos)).name ~= "hell:portal" then + return + end + + local has_teleported + if obsidian_portal_kills then + obsidian_teleport(player, pname) + has_teleported = true + elseif not mclike_portal then + local target = vector.round(get_player_died_target(player)) + if generated_or_generate(target) then + obsidian_teleport(player, pname, target) + has_teleported = true + end + end + + if not has_teleported then + -- e.g. ungenerated area + return + end + + minetest.sound_play("hell_portal_usual", {to_player=pname, gain=1}) +end + +-- a not filled square +vector.square = vector.square or +function(r) + local tab, n = {}, 1 + for i = -r+1, r do + for j = -1, 1, 2 do + local a, b = r*j, i*j + tab[n] = {a, b} + tab[n+1] = {b, a} + n=n+2 + end + end + return tab +end + +local function is_hellportal(pos) + local x, y, z = pos.x, pos.y, pos.z + for _,i in pairs({-1, 3}) do + if minetest.get_node({x=x, y=y+i, z=z}).name ~= "hell:white" then + return + end + end + for _,sn in pairs(vector.square(1)) do + if minetest.get_node({x=x+sn[1], y=y-1, z=z+sn[2]}).name ~= "hell:hellrack" + or minetest.get_node({x=x+sn[1], y=y+3, z=z+sn[2]}).name ~= "hell:blood_cooked" then + return + end + end + for _,sn in pairs(vector.square(2)) do + if minetest.get_node({x=x+sn[1], y=y-1, z=z+sn[2]}).name ~= "hell:hellrack_black" + or minetest.get_node({x=x+sn[1], y=y+3, z=z+sn[2]}).name ~= "hell:wood_empty" then + return + end + end + for i = -1,1,2 do + for j = -1,1,2 do + if minetest.get_node({x=x+i, y=y+2, z=z+j}).name ~= "hell:apple" then + return + end + end + end + for i = -2,2,4 do + for j = 0,2 do + for k = -2,2,4 do + if minetest.get_node({x=x+i, y=y+j, z=z+k}).name ~= "hell:hellrack_brick_blue" then + return + end + end + end + end + for i = -1,1 do + for j = -1,1 do + if minetest.get_node({x=x+i, y=y+4, z=z+j}).name ~= "hell:wood_empty" then + return + end + end + end + return true +end + +-- cache known portals +local known_portals_d = {} +local known_portals_u = {} +local function get_portal(t, z,x) + return t[z] and t[z][x] +end +local function set_portal(t, z,x, y) + t[z] = t[z] or {} + t[z][x] = y +end + +-- used when a player eats hell:apple in a portal +local function hell_port(player, pos) + if not player + or not pos + or not pos.x then + minetest.log("error", "[hell] hell_port: something failed.") + return + end + if not is_hellportal(pos) then + return + end + minetest.sound_play("hell_teleporter", {pos=pos}) + local meta = minetest.get_meta({x=pos.x, y=pos.y-1, z=pos.z}) + if pos.y < hell.start then + set_portal(known_portals_d, pos.z,pos.x, pos.y) + + local my = tonumber(meta:get_string("y")) + local y = get_portal(known_portals_u, pos.z,pos.x) + if y then + if y ~= my then + meta:set_string("y", y) + end + else + y = my or 100 + end + pos.y = y - 0.3 + + player_from_hell(player, pos) + else + set_portal(known_portals_u, pos.z,pos.x, pos.y) + + local my = tonumber(meta:get_string("y")) + local y = get_portal(known_portals_d, pos.z,pos.x) + if y then + if y ~= my then + meta:set_string("y", y) + end + else + y = my or portal_target+math.random(4) + end + pos.y = y - 0.3 + + player_to_hell(player, pos) + end + minetest.sound_play("hell_teleporter", {pos=pos}) + return true +end + +minetest.register_on_item_eat(function(_, _, itemstack, user, _) + if not user or itemstack:is_empty() then + return + end + + local inv = user:get_inventory() + if not inv then + return + end + if itemstack:get_name() == "hell:apple" then + itemstack:take_item() + if hell_port(user, vector.round(user:get_pos())) then + return itemstack + end + end +end) + +if hell.HELL_REALM_ENABLED then + -- Use the Portal API to add a portal type which goes to the Hell + -- See portal_api.txt for documentation + nether.register_portal("hell_gate", { + shape = nether.PortalShape_Circular, + frame_node_name = "nether:brick", + wormhole_node_color = 5, -- 5 is red + title = S("Hell Gate"), + particle_texture = { + name = "nether_particle_anim2.png", + animation = { + type = "vertical_frames", + aspect_w = 7, + aspect_h = 7, + length = 1, + }, + scale = 1.5 + }, + book_of_portals_pagetext = S("Construction requires 16 blocks of ??. The finished frame must be in the shape of a circle and laid vertically, like a door.").."\n\n"..S("However, I never knew what material to use for building this door despite my many attempts.").."\n\n"..S("One day, however, I met an old lady who frankly looked like a witch. In the course of our discussion we came to talk about the Hell Gate. This old lady confessed to me that in her family there was a legend that one of her ancestors had managed to activate the portal. But that the poor man was instantly killed as he passed through it. The gate was destroyed and several years passed. But since a certain night, the poor widow of the deceased began to rave that her Husband had come back from the dead to take her also to hell because he said that he had made this world a wonderful place and that after several years, he would have found a way to come back and return to it as he wished without causing death. A few days later, the widow disappeared without a trace. Since then the house was destroyed in a fire with all the secrets it could hold. Only an old cauldron remained amidst the ashes.").."\n\n"..S("When I wanted to ask the old lady with what material the gate was made, she stared at me with eyes so black that I had the impression that the Nether wanted to take over me, and I did not insist any further."), + + is_within_realm = function(pos) -- return true if pos is inside the Hell + return pos.y < hell.DEPTH and pos.y > hell.DEPTH-510 + end, + + find_realm_anchorPos = function(surface_anchorPos) + -- divide x and z by a factor of 8 to implement Hell fast-travel + local destination_pos = vector.divide(surface_anchorPos, hell.FASTTRAVEL_FACTOR) + destination_pos.x = math.floor(0.5 + destination_pos.x) -- round to int + destination_pos.z = math.floor(0.5 + destination_pos.z) -- round to int + destination_pos.y = hell.DEPTH-390 -- temp value so find_nearest_working_portal() returns hell portals + + -- a y_factor of 0 makes the search ignore the altitude of the portals (as long as they are in the Hell) + local existing_portal_location, existing_portal_orientation = + nether.find_nearest_working_portal("hell_gate", destination_pos, 8, 0) + + if existing_portal_location ~= nil then + return existing_portal_location, existing_portal_orientation + else + destination_pos.y = hell.DEPTH-390 + math.random(0, 30) + return destination_pos + end + end, + + find_surface_anchorPos = function(realm_anchorPos) + -- A portal definition doesn't normally need to provide a find_surface_anchorPos() function, + -- since find_surface_target_y() will be used by default, but Hell portals also scale position + -- to create fast-travel. + -- Defining a custom function also means we can look for existing nearby portals. + + -- Multiply x and z by a factor of 8 to implement Hell fast-travel + local destination_pos = vector.multiply(realm_anchorPos, hell.FASTTRAVEL_FACTOR) + destination_pos.x = math.min(30900, math.max(-30900, destination_pos.x)) -- clip to world boundary + destination_pos.z = math.min(30900, math.max(-30900, destination_pos.z)) -- clip to world boundary + destination_pos.y = 0 -- temp value so find_nearest_working_portal() doesn't return hell portals + + -- a y_factor of 0 makes the search ignore the altitude of the portals (as long as they are outside the Hell) + local existing_portal_location, existing_portal_orientation = + nether.find_nearest_working_portal("hell_gate", destination_pos, 8 * hell.FASTTRAVEL_FACTOR, 0) + + if existing_portal_location ~= nil then + return existing_portal_location, existing_portal_orientation + else + destination_pos.y = nether.find_surface_target_y(destination_pos.x, destination_pos.z, "hell_gate") + return destination_pos + end + end, + + on_ignite = function(portalDef, anchorPos, orientation) + + -- make some sparks fly + local p1, p2 = portalDef.shape:get_p1_and_p2_from_anchorPos(anchorPos, orientation) + local pos = vector.divide(vector.add(p1, p2), 2) + + local textureName = portalDef.particle_texture + if type(textureName) == "table" then textureName = textureName.name end + + minetest.add_particlespawner({ + amount = 110, + time = 0.1, + minpos = {x = pos.x - 0.5, y = pos.y - 1.2, z = pos.z - 0.5}, + maxpos = {x = pos.x + 0.5, y = pos.y + 1.2, z = pos.z + 0.5}, + minvel = {x = -5, y = -1, z = -5}, + maxvel = {x = 5, y = 1, z = 5}, + minacc = {x = 0, y = 0, z = 0}, + maxacc = {x = 0, y = 0, z = 0}, + minexptime = 0.1, + maxexptime = 0.5, + minsize = 0.2 * portalDef.particle_texture_scale, + maxsize = 0.8 * portalDef.particle_texture_scale, + collisiondetection = false, + texture = textureName .. "^[colorize:#F00:alpha", + animation = portalDef.particle_texture_animation, + glow = 8 + }) + + end, + + on_player_teleported = function(portal_definition, player, playerPos, new_playerPos) + local pname = player:get_player_name() + if players_in_hell[pname] then + return + end + + obsidian_teleport(player, pname) + end, + }) +end + +-- Pour éviter de pouvoir aller en enfer depuis le nether avec un portail du nether construit depuis l'enfer +if nether.NETHER_REALM_ENABLED then + nether.registered_portals["nether_portal"].on_player_teleported = + function(portal_definition, player, playerPos, new_playerPos) + local new_y = new_playerPos.y + if new_y > hell.DEPTH-510 and new_y < hell.DEPTH then + minetest.after( + 0,function(player, target) + -- fixes respawn bug + if player then + player:moveto(target) + end + end, player, playerPos) + minetest.chat_send_player(player:get_player_name(), + S("You shall not pass!")) + end + end +end diff --git a/sounds/hell_dig.1.ogg b/sounds/hell_dig.1.ogg new file mode 100644 index 0000000..4c49832 Binary files /dev/null and b/sounds/hell_dig.1.ogg differ diff --git a/sounds/hell_dig.2.ogg b/sounds/hell_dig.2.ogg new file mode 100644 index 0000000..c69b45e Binary files /dev/null and b/sounds/hell_dig.2.ogg differ diff --git a/sounds/hell_dug.1.ogg b/sounds/hell_dug.1.ogg new file mode 100644 index 0000000..a6dfa9e Binary files /dev/null and b/sounds/hell_dug.1.ogg differ diff --git a/sounds/hell_dug.2.ogg b/sounds/hell_dug.2.ogg new file mode 100644 index 0000000..cc7666b Binary files /dev/null and b/sounds/hell_dug.2.ogg differ diff --git a/sounds/hell_extract_blood.1.ogg b/sounds/hell_extract_blood.1.ogg new file mode 100644 index 0000000..c69d486 Binary files /dev/null and b/sounds/hell_extract_blood.1.ogg differ diff --git a/sounds/hell_extract_blood.2.ogg b/sounds/hell_extract_blood.2.ogg new file mode 100644 index 0000000..bf41821 Binary files /dev/null and b/sounds/hell_extract_blood.2.ogg differ diff --git a/sounds/hell_extract_blood.3.ogg b/sounds/hell_extract_blood.3.ogg new file mode 100644 index 0000000..db3a39c Binary files /dev/null and b/sounds/hell_extract_blood.3.ogg differ diff --git a/sounds/hell_extract_blood.4.ogg b/sounds/hell_extract_blood.4.ogg new file mode 100644 index 0000000..2ac3495 Binary files /dev/null and b/sounds/hell_extract_blood.4.ogg differ diff --git a/sounds/hell_extract_blood.5.ogg b/sounds/hell_extract_blood.5.ogg new file mode 100644 index 0000000..5d628d9 Binary files /dev/null and b/sounds/hell_extract_blood.5.ogg differ diff --git a/sounds/hell_extract_blood.6.ogg b/sounds/hell_extract_blood.6.ogg new file mode 100644 index 0000000..618d6d6 Binary files /dev/null and b/sounds/hell_extract_blood.6.ogg differ diff --git a/sounds/hell_extract_blood.7.ogg b/sounds/hell_extract_blood.7.ogg new file mode 100644 index 0000000..fd0a7fe Binary files /dev/null and b/sounds/hell_extract_blood.7.ogg differ diff --git a/sounds/hell_footstep.1.ogg b/sounds/hell_footstep.1.ogg new file mode 100644 index 0000000..15f31a0 Binary files /dev/null and b/sounds/hell_footstep.1.ogg differ diff --git a/sounds/hell_footstep.2.ogg b/sounds/hell_footstep.2.ogg new file mode 100644 index 0000000..fbc200a Binary files /dev/null and b/sounds/hell_footstep.2.ogg differ diff --git a/sounds/hell_footstep.3.ogg b/sounds/hell_footstep.3.ogg new file mode 100644 index 0000000..1648043 Binary files /dev/null and b/sounds/hell_footstep.3.ogg differ diff --git a/sounds/hell_pearl.ogg b/sounds/hell_pearl.ogg new file mode 100644 index 0000000..90dde6a Binary files /dev/null and b/sounds/hell_pearl.ogg differ diff --git a/sounds/hell_portal_usual.ogg b/sounds/hell_portal_usual.ogg new file mode 100644 index 0000000..cf1f84a Binary files /dev/null and b/sounds/hell_portal_usual.ogg differ diff --git a/sounds/hell_remove_leaf.1.ogg b/sounds/hell_remove_leaf.1.ogg new file mode 100644 index 0000000..224b424 Binary files /dev/null and b/sounds/hell_remove_leaf.1.ogg differ diff --git a/sounds/hell_remove_leaf.2.ogg b/sounds/hell_remove_leaf.2.ogg new file mode 100644 index 0000000..c02ef1c Binary files /dev/null and b/sounds/hell_remove_leaf.2.ogg differ diff --git a/sounds/hell_remove_leaf.3.ogg b/sounds/hell_remove_leaf.3.ogg new file mode 100644 index 0000000..c5b79ba Binary files /dev/null and b/sounds/hell_remove_leaf.3.ogg differ diff --git a/sounds/hell_teleporter.1.ogg b/sounds/hell_teleporter.1.ogg new file mode 100644 index 0000000..65e4803 Binary files /dev/null and b/sounds/hell_teleporter.1.ogg differ diff --git a/sounds/hell_teleporter.2.ogg b/sounds/hell_teleporter.2.ogg new file mode 100644 index 0000000..eaafec9 Binary files /dev/null and b/sounds/hell_teleporter.2.ogg differ diff --git a/sounds/hell_teleporter.3.ogg b/sounds/hell_teleporter.3.ogg new file mode 100644 index 0000000..949dd93 Binary files /dev/null and b/sounds/hell_teleporter.3.ogg differ diff --git a/textures/hell_axe_hellrack.png b/textures/hell_axe_hellrack.png new file mode 100644 index 0000000..5f9076c Binary files /dev/null and b/textures/hell_axe_hellrack.png differ diff --git a/textures/hell_axe_hellrack_blue.png b/textures/hell_axe_hellrack_blue.png new file mode 100644 index 0000000..cfd9e6f Binary files /dev/null and b/textures/hell_axe_hellrack_blue.png differ diff --git a/textures/hell_axe_white.png b/textures/hell_axe_white.png new file mode 100644 index 0000000..44f3de0 Binary files /dev/null and b/textures/hell_axe_white.png differ diff --git a/textures/hell_bark.png b/textures/hell_bark.png new file mode 100644 index 0000000..69e079a Binary files /dev/null and b/textures/hell_bark.png differ diff --git a/textures/hell_blood.png b/textures/hell_blood.png new file mode 100644 index 0000000..067285b Binary files /dev/null and b/textures/hell_blood.png differ diff --git a/textures/hell_blood_cooked.png b/textures/hell_blood_cooked.png new file mode 100644 index 0000000..ac72a3d Binary files /dev/null and b/textures/hell_blood_cooked.png differ diff --git a/textures/hell_blood_empty.png b/textures/hell_blood_empty.png new file mode 100644 index 0000000..d1d8dda Binary files /dev/null and b/textures/hell_blood_empty.png differ diff --git a/textures/hell_blood_extracted.png b/textures/hell_blood_extracted.png new file mode 100644 index 0000000..9f2ca0f Binary files /dev/null and b/textures/hell_blood_extracted.png differ diff --git a/textures/hell_blood_extractor.png b/textures/hell_blood_extractor.png new file mode 100644 index 0000000..49897f6 Binary files /dev/null and b/textures/hell_blood_extractor.png differ diff --git a/textures/hell_blood_side.png b/textures/hell_blood_side.png new file mode 100644 index 0000000..086b645 Binary files /dev/null and b/textures/hell_blood_side.png differ diff --git a/textures/hell_blood_side_cooked.png b/textures/hell_blood_side_cooked.png new file mode 100644 index 0000000..60f86ba Binary files /dev/null and b/textures/hell_blood_side_cooked.png differ diff --git a/textures/hell_blood_side_empty.png b/textures/hell_blood_side_empty.png new file mode 100644 index 0000000..9df720b Binary files /dev/null and b/textures/hell_blood_side_empty.png differ diff --git a/textures/hell_blood_stem.png b/textures/hell_blood_stem.png new file mode 100644 index 0000000..21ac5cc Binary files /dev/null and b/textures/hell_blood_stem.png differ diff --git a/textures/hell_blood_stem_cooked.png b/textures/hell_blood_stem_cooked.png new file mode 100644 index 0000000..e1c200b Binary files /dev/null and b/textures/hell_blood_stem_cooked.png differ diff --git a/textures/hell_blood_stem_empty.png b/textures/hell_blood_stem_empty.png new file mode 100644 index 0000000..008d49d Binary files /dev/null and b/textures/hell_blood_stem_empty.png differ diff --git a/textures/hell_blood_stem_top.png b/textures/hell_blood_stem_top.png new file mode 100644 index 0000000..2191e37 Binary files /dev/null and b/textures/hell_blood_stem_top.png differ diff --git a/textures/hell_blood_stem_top_cooked.png b/textures/hell_blood_stem_top_cooked.png new file mode 100644 index 0000000..4ed2403 Binary files /dev/null and b/textures/hell_blood_stem_top_cooked.png differ diff --git a/textures/hell_blood_stem_top_empty.png b/textures/hell_blood_stem_top_empty.png new file mode 100644 index 0000000..16223a5 Binary files /dev/null and b/textures/hell_blood_stem_top_empty.png differ diff --git a/textures/hell_blood_top.png b/textures/hell_blood_top.png new file mode 100644 index 0000000..622fbcc Binary files /dev/null and b/textures/hell_blood_top.png differ diff --git a/textures/hell_blood_top_cooked.png b/textures/hell_blood_top_cooked.png new file mode 100644 index 0000000..7385db1 Binary files /dev/null and b/textures/hell_blood_top_cooked.png differ diff --git a/textures/hell_blood_top_empty.png b/textures/hell_blood_top_empty.png new file mode 100644 index 0000000..815d998 Binary files /dev/null and b/textures/hell_blood_top_empty.png differ diff --git a/textures/hell_dirt.png b/textures/hell_dirt.png new file mode 100644 index 0000000..8eea86e Binary files /dev/null and b/textures/hell_dirt.png differ diff --git a/textures/hell_dirt_normal.png b/textures/hell_dirt_normal.png new file mode 100644 index 0000000..5e117c1 Binary files /dev/null and b/textures/hell_dirt_normal.png differ diff --git a/textures/hell_dirt_top.png b/textures/hell_dirt_top.png new file mode 100644 index 0000000..1bb0fba Binary files /dev/null and b/textures/hell_dirt_top.png differ diff --git a/textures/hell_dirt_top_normal.png b/textures/hell_dirt_top_normal.png new file mode 100644 index 0000000..885f03d Binary files /dev/null and b/textures/hell_dirt_top_normal.png differ diff --git a/textures/hell_dirt_top_side.png b/textures/hell_dirt_top_side.png new file mode 100644 index 0000000..577367a Binary files /dev/null and b/textures/hell_dirt_top_side.png differ diff --git a/textures/hell_dirt_top_side_normal.png b/textures/hell_dirt_top_side_normal.png new file mode 100644 index 0000000..9aa7c9a Binary files /dev/null and b/textures/hell_dirt_top_side_normal.png differ diff --git a/textures/hell_dirt_transition.png b/textures/hell_dirt_transition.png new file mode 100644 index 0000000..9937ff3 Binary files /dev/null and b/textures/hell_dirt_transition.png differ diff --git a/textures/hell_dirt_transition_normal.png b/textures/hell_dirt_transition_normal.png new file mode 100644 index 0000000..137e2e8 Binary files /dev/null and b/textures/hell_dirt_transition_normal.png differ diff --git a/textures/hell_fim.png b/textures/hell_fim.png new file mode 100644 index 0000000..eaa319c Binary files /dev/null and b/textures/hell_fim.png differ diff --git a/textures/hell_forest_planks.png b/textures/hell_forest_planks.png new file mode 100644 index 0000000..2001002 Binary files /dev/null and b/textures/hell_forest_planks.png differ diff --git a/textures/hell_forest_wood.png b/textures/hell_forest_wood.png new file mode 100644 index 0000000..69f8d1e Binary files /dev/null and b/textures/hell_forest_wood.png differ diff --git a/textures/hell_forest_wood_normal.png b/textures/hell_forest_wood_normal.png new file mode 100644 index 0000000..5212894 Binary files /dev/null and b/textures/hell_forest_wood_normal.png differ diff --git a/textures/hell_fruit.png b/textures/hell_fruit.png new file mode 100644 index 0000000..8fb46af Binary files /dev/null and b/textures/hell_fruit.png differ diff --git a/textures/hell_fruit_bottom.png b/textures/hell_fruit_bottom.png new file mode 100644 index 0000000..f6436cb Binary files /dev/null and b/textures/hell_fruit_bottom.png differ diff --git a/textures/hell_fruit_leaf.png b/textures/hell_fruit_leaf.png new file mode 100644 index 0000000..784c2f7 Binary files /dev/null and b/textures/hell_fruit_leaf.png differ diff --git a/textures/hell_fruit_leaves.png b/textures/hell_fruit_leaves.png new file mode 100644 index 0000000..4f41ff3 Binary files /dev/null and b/textures/hell_fruit_leaves.png differ diff --git a/textures/hell_fruit_no_leaf.png b/textures/hell_fruit_no_leaf.png new file mode 100644 index 0000000..19d6c99 Binary files /dev/null and b/textures/hell_fruit_no_leaf.png differ diff --git a/textures/hell_fruit_top.png b/textures/hell_fruit_top.png new file mode 100644 index 0000000..3945e17 Binary files /dev/null and b/textures/hell_fruit_top.png differ diff --git a/textures/hell_glowflower.png b/textures/hell_glowflower.png new file mode 100644 index 0000000..5784ce5 Binary files /dev/null and b/textures/hell_glowflower.png differ diff --git a/textures/hell_grass.png b/textures/hell_grass.png new file mode 100644 index 0000000..2e11a1f Binary files /dev/null and b/textures/hell_grass.png differ diff --git a/textures/hell_grass_big.png b/textures/hell_grass_big.png new file mode 100644 index 0000000..53ed795 Binary files /dev/null and b/textures/hell_grass_big.png differ diff --git a/textures/hell_grass_dried.png b/textures/hell_grass_dried.png new file mode 100644 index 0000000..8f2af2b Binary files /dev/null and b/textures/hell_grass_dried.png differ diff --git a/textures/hell_grass_middle.png b/textures/hell_grass_middle.png new file mode 100644 index 0000000..b5c82fa Binary files /dev/null and b/textures/hell_grass_middle.png differ diff --git a/textures/hell_grass_small.png b/textures/hell_grass_small.png new file mode 100644 index 0000000..b540c49 Binary files /dev/null and b/textures/hell_grass_small.png differ diff --git a/textures/hell_hellrack.png b/textures/hell_hellrack.png new file mode 100644 index 0000000..e30280c Binary files /dev/null and b/textures/hell_hellrack.png differ diff --git a/textures/hell_hellrack_black.png b/textures/hell_hellrack_black.png new file mode 100644 index 0000000..8b130d5 Binary files /dev/null and b/textures/hell_hellrack_black.png differ diff --git a/textures/hell_hellrack_black_normal.png b/textures/hell_hellrack_black_normal.png new file mode 100644 index 0000000..aebf5fe Binary files /dev/null and b/textures/hell_hellrack_black_normal.png differ diff --git a/textures/hell_hellrack_blue.png b/textures/hell_hellrack_blue.png new file mode 100644 index 0000000..03f4bf5 Binary files /dev/null and b/textures/hell_hellrack_blue.png differ diff --git a/textures/hell_hellrack_blue_normal.png b/textures/hell_hellrack_blue_normal.png new file mode 100644 index 0000000..ff6a573 Binary files /dev/null and b/textures/hell_hellrack_blue_normal.png differ diff --git a/textures/hell_hellrack_brick.png b/textures/hell_hellrack_brick.png new file mode 100644 index 0000000..b9199b7 Binary files /dev/null and b/textures/hell_hellrack_brick.png differ diff --git a/textures/hell_hellrack_brick_black.png b/textures/hell_hellrack_brick_black.png new file mode 100644 index 0000000..7efb179 Binary files /dev/null and b/textures/hell_hellrack_brick_black.png differ diff --git a/textures/hell_hellrack_brick_blue.png b/textures/hell_hellrack_brick_blue.png new file mode 100644 index 0000000..9db6250 Binary files /dev/null and b/textures/hell_hellrack_brick_blue.png differ diff --git a/textures/hell_hellrack_normal.png b/textures/hell_hellrack_normal.png new file mode 100644 index 0000000..5e2eafd Binary files /dev/null and b/textures/hell_hellrack_normal.png differ diff --git a/textures/hell_hellrack_soil.png b/textures/hell_hellrack_soil.png new file mode 100644 index 0000000..dedab0e Binary files /dev/null and b/textures/hell_hellrack_soil.png differ diff --git a/textures/hell_hellrack_soil_normal.png b/textures/hell_hellrack_soil_normal.png new file mode 100644 index 0000000..b939572 Binary files /dev/null and b/textures/hell_hellrack_soil_normal.png differ diff --git a/textures/hell_hellrack_tiled.png b/textures/hell_hellrack_tiled.png new file mode 100644 index 0000000..dcaa06a Binary files /dev/null and b/textures/hell_hellrack_tiled.png differ diff --git a/textures/hell_hellrack_tiled_normal.png b/textures/hell_hellrack_tiled_normal.png new file mode 100644 index 0000000..ca51e52 Binary files /dev/null and b/textures/hell_hellrack_tiled_normal.png differ diff --git a/textures/hell_hotbed.png b/textures/hell_hotbed.png new file mode 100644 index 0000000..96b9063 Binary files /dev/null and b/textures/hell_hotbed.png differ diff --git a/textures/hell_leaves.png b/textures/hell_leaves.png new file mode 100644 index 0000000..a5ef808 Binary files /dev/null and b/textures/hell_leaves.png differ diff --git a/textures/hell_pearl.png b/textures/hell_pearl.png new file mode 100644 index 0000000..e3a1b70 Binary files /dev/null and b/textures/hell_pearl.png differ diff --git a/textures/hell_pick_hellrack.png b/textures/hell_pick_hellrack.png new file mode 100644 index 0000000..922a097 Binary files /dev/null and b/textures/hell_pick_hellrack.png differ diff --git a/textures/hell_pick_hellrack_blue.png b/textures/hell_pick_hellrack_blue.png new file mode 100644 index 0000000..e8757fb Binary files /dev/null and b/textures/hell_pick_hellrack_blue.png differ diff --git a/textures/hell_pick_mushroom.png b/textures/hell_pick_mushroom.png new file mode 100644 index 0000000..a0e3029 Binary files /dev/null and b/textures/hell_pick_mushroom.png differ diff --git a/textures/hell_pick_white.png b/textures/hell_pick_white.png new file mode 100644 index 0000000..8bd46cb Binary files /dev/null and b/textures/hell_pick_white.png differ diff --git a/textures/hell_pick_wood.png b/textures/hell_pick_wood.png new file mode 100644 index 0000000..0973dfe Binary files /dev/null and b/textures/hell_pick_wood.png differ diff --git a/textures/hell_portal_particle.png b/textures/hell_portal_particle.png new file mode 100644 index 0000000..e619dc8 Binary files /dev/null and b/textures/hell_portal_particle.png differ diff --git a/textures/hell_portal_stuff.png b/textures/hell_portal_stuff.png new file mode 100644 index 0000000..9a91adb Binary files /dev/null and b/textures/hell_portal_stuff.png differ diff --git a/textures/hell_portal_stuff_normal.png b/textures/hell_portal_stuff_normal.png new file mode 100644 index 0000000..0e013bf Binary files /dev/null and b/textures/hell_portal_stuff_normal.png differ diff --git a/textures/hell_sapling.png b/textures/hell_sapling.png new file mode 100644 index 0000000..f0aea81 Binary files /dev/null and b/textures/hell_sapling.png differ diff --git a/textures/hell_shovel_hellrack.png b/textures/hell_shovel_hellrack.png new file mode 100644 index 0000000..3cb91b6 Binary files /dev/null and b/textures/hell_shovel_hellrack.png differ diff --git a/textures/hell_shovel_hellrack_blue.png b/textures/hell_shovel_hellrack_blue.png new file mode 100644 index 0000000..03caa1c Binary files /dev/null and b/textures/hell_shovel_hellrack_blue.png differ diff --git a/textures/hell_shovel_white.png b/textures/hell_shovel_white.png new file mode 100644 index 0000000..989e29e Binary files /dev/null and b/textures/hell_shovel_white.png differ diff --git a/textures/hell_shroom_stem.png b/textures/hell_shroom_stem.png new file mode 100644 index 0000000..d4ab203 Binary files /dev/null and b/textures/hell_shroom_stem.png differ diff --git a/textures/hell_shroom_top.png b/textures/hell_shroom_top.png new file mode 100644 index 0000000..6dd58c7 Binary files /dev/null and b/textures/hell_shroom_top.png differ diff --git a/textures/hell_stick.png b/textures/hell_stick.png new file mode 100644 index 0000000..c287e16 Binary files /dev/null and b/textures/hell_stick.png differ diff --git a/textures/hell_sword_hellrack.png b/textures/hell_sword_hellrack.png new file mode 100644 index 0000000..d0824e3 Binary files /dev/null and b/textures/hell_sword_hellrack.png differ diff --git a/textures/hell_sword_hellrack_blue.png b/textures/hell_sword_hellrack_blue.png new file mode 100644 index 0000000..90a26ee Binary files /dev/null and b/textures/hell_sword_hellrack_blue.png differ diff --git a/textures/hell_sword_white.png b/textures/hell_sword_white.png new file mode 100644 index 0000000..73f41f7 Binary files /dev/null and b/textures/hell_sword_white.png differ diff --git a/textures/hell_teleporter.png b/textures/hell_teleporter.png new file mode 100644 index 0000000..eaac926 Binary files /dev/null and b/textures/hell_teleporter.png differ diff --git a/textures/hell_torch.png b/textures/hell_torch.png new file mode 100644 index 0000000..317c880 Binary files /dev/null and b/textures/hell_torch.png differ diff --git a/textures/hell_torch_on_ceiling.png b/textures/hell_torch_on_ceiling.png new file mode 100644 index 0000000..43cb69a Binary files /dev/null and b/textures/hell_torch_on_ceiling.png differ diff --git a/textures/hell_torch_on_floor.png b/textures/hell_torch_on_floor.png new file mode 100644 index 0000000..c5d5da0 Binary files /dev/null and b/textures/hell_torch_on_floor.png differ diff --git a/textures/hell_transparent.png b/textures/hell_transparent.png new file mode 100644 index 0000000..d0ff224 Binary files /dev/null and b/textures/hell_transparent.png differ diff --git a/textures/hell_tree.png b/textures/hell_tree.png new file mode 100644 index 0000000..99101b3 Binary files /dev/null and b/textures/hell_tree.png differ diff --git a/textures/hell_tree_corner.png b/textures/hell_tree_corner.png new file mode 100644 index 0000000..4b79eb5 Binary files /dev/null and b/textures/hell_tree_corner.png differ diff --git a/textures/hell_tree_sapling.png b/textures/hell_tree_sapling.png new file mode 100644 index 0000000..14686be Binary files /dev/null and b/textures/hell_tree_sapling.png differ diff --git a/textures/hell_tree_top.png b/textures/hell_tree_top.png new file mode 100644 index 0000000..f58589e Binary files /dev/null and b/textures/hell_tree_top.png differ diff --git a/textures/hell_vine.png b/textures/hell_vine.png new file mode 100644 index 0000000..a8a6632 Binary files /dev/null and b/textures/hell_vine.png differ diff --git a/textures/hell_vine_normal.png b/textures/hell_vine_normal.png new file mode 100644 index 0000000..8c3c777 Binary files /dev/null and b/textures/hell_vine_normal.png differ diff --git a/textures/hell_white.png b/textures/hell_white.png new file mode 100644 index 0000000..47d412c Binary files /dev/null and b/textures/hell_white.png differ diff --git a/textures/hell_wood.png b/textures/hell_wood.png new file mode 100644 index 0000000..8604e02 Binary files /dev/null and b/textures/hell_wood.png differ diff --git a/textures/hell_wood_cooked.png b/textures/hell_wood_cooked.png new file mode 100644 index 0000000..761f1d6 Binary files /dev/null and b/textures/hell_wood_cooked.png differ diff --git a/textures/hell_wood_empty.png b/textures/hell_wood_empty.png new file mode 100644 index 0000000..6c848d6 Binary files /dev/null and b/textures/hell_wood_empty.png differ diff --git a/textures/hell_wood_empty_normal.png b/textures/hell_wood_empty_normal.png new file mode 100644 index 0000000..43628f5 Binary files /dev/null and b/textures/hell_wood_empty_normal.png differ diff --git a/weird_mapgen_noise.lua b/weird_mapgen_noise.lua new file mode 100644 index 0000000..6a05079 --- /dev/null +++ b/weird_mapgen_noise.lua @@ -0,0 +1,88 @@ +--V2 +local function get_random(a, b, seed) + return PseudoRandom(math.abs(a+b*5)+seed) +end + +local r_chs = {} + +function hell_weird_noise(minp, fct, s, seed, range, scale) + if not r_chs[s] then + r_chs[s] = math.floor(s/3+0.5) + end + scale = scale or 15 + local r_ch = r_chs[s] + local maxp = vector.add(minp, scale) + + local tab,n = {},1 + local sm = range or (s+r_ch)*2 + for z = -sm, scale+sm do + local pz = z+minp.z + if pz%s == 0 then + for x = -sm, scale+sm do + local px = x+minp.x + if px%s == 0 then + local pr = get_random(px, pz, seed) + tab[n] = {x=px+pr:next(-r_ch, r_ch), y=0, z=pz+pr:next(-r_ch, r_ch)} + n = n+1 + end + end + end + end + + local tab2,n = {},1 + for z = minp.z, maxp.z do + for x = minp.x, maxp.x do + local h = sm + for _,i in ipairs(tab) do + h = math.min(h, fct(x, i.x, z, i.z)) + end + tab2[n] = {x=x, y=maxp.y-h, z=z} + n = n+1 + end + end + return tab2 +end + +--[[ +local function dif(z1, z2) + return math.abs(z1-z2) +end + +local function pymg(x1, x2, z1, z2) + return math.max(dif(x1, x2), dif(z1, z2)) +end + +local function romg(x1, x2, z1, z2) + return math.hypot(dif(x1, x2), dif(z1, z2)) +end + +local function py2mg(x1, x2, z1, z2) + return dif(x1, x2) + dif(z1, z2) +end + +minetest.register_node("ac:wmg", { + description = "wmg", + tiles = {"ac_block.png"}, + groups = {snappy=1,bendy=2,cracky=1}, + sounds = default.node_sound_stone_defaults(), + on_construct = function(pos) + local minp = vector.chunkcorner(pos) + for _,p in ipairs(weird_noise(minp, pymg, 20, 8, 4)) do + local p2 = {x=p.x, y=p.y+1, z=p.z} + if p.y <= minp.y+7 then + local p2 = {x=p.x, y=minp.y+6, z=p.z} + local p3 = {x=p.x, y=p2.y+1, z=p.z} + if minetest.get_node(p2).name ~= "default:desert_stone" then + minetest.set_node(p2, {name="default:desert_stone"}) + end + if minetest.get_node(p3).name ~= "default:desert_sand" then + minetest.set_node(p3, {name="default:desert_sand"}) + end + else + if minetest.get_node(p).name ~= "default:desert_stone" then + minetest.set_node(p, {name="default:desert_stone"}) + end + end + end + end, +})]]