]> git.lizzy.rs Git - Crafter.git/blobdiff - mods/nether/init.lua
remove server debug
[Crafter.git] / mods / nether / init.lua
index 395e27b502f5125b560400fe446fd5207ae7d132..ab15282176c56b43447f5d4cb8b2d12d8b8c9edb 100644 (file)
-minetest.register_biome({
-       name = "Nether",
-       node_top = "air",
-       depth_top = 0,
-       node_filler = "air",
-       depth_filler = 0,
-       node_riverbed = "air",
-       depth_riverbed= 0,
-       node_stone = "air",
-       node_water = "air",
-       node_dungeon = "air",
-       node_dungeon_alt = "air",
-       node_dungeon_stair = "air",
-       vertical_blend = 0,
-       y_max = -10000,
-       y_min = -20000,
-       heat_point = -100,
-       humidity_point = -100,
-})
-
-minetest.register_node("nether:bedrock", {
-    description = "Bedrock",
-    tiles = {"bedrock.png"},
-    groups = {unbreakable = 1, pathable = 1},
-    sounds = main.stoneSound(),
-    is_ground_content = false,
-    --light_source = 14, --debugging
-})
-
-
-minetest.register_node("nether:netherrack", {
-    description = "Netherrack",
-    tiles = {"netherrack.png"},
-    groups = {stone = 1, pathable = 1},
-    sounds = main.stoneSound(),
-    is_ground_content = false,
-    light_source = 7,
-})
-
-
-minetest.register_node("nether:obsidian", {
-    description = "Obsidian",
-    tiles = {"obsidian.png"},
-    groups = {stone = 5, pathable = 1},
-    sounds = main.stoneSound(),
-    is_ground_content = false,
-    --light_source = 7,
-})
-
---this is from https://github.com/paramat/lvm_example/blob/master/init.lua
---hi paramat :D
-
--- Set the 3D noise parameters for the terrain.
-local perlin= minetest.get_mapgen_params()
-local np_terrain = {
-       offset = 0,
-       scale = 1,
-       spread = {x = 384, y = 192, z = 384},
-       seed = 5900033, --perlin.seed
-       octaves = 5,
-       persist = 0.63,
-       lacunarity = 2.0,
-       --flags = ""
-}
-
-
--- Set singlenode mapgen (air nodes only).
--- Disable the engine lighting calculation since that will be done for a
--- mapchunk of air nodes and will be incorrect after we place nodes.
-
---minetest.set_mapgen_params({mgname = "singlenode", flags = "nolight"})
-
-
--- Get the content IDs for the nodes used.
-
-local c_sandstone = minetest.get_content_id("nether:netherrack")
-local c_bedrock = minetest.get_content_id("nether:bedrock")
-local c_air = minetest.get_content_id("air")
-local c_lava = minetest.get_content_id("main:lava")
-
-
--- Initialize noise object to nil. It will be created once only during the
--- generation of the first mapchunk, to minimise memory use.
-
-local nobj_terrain = nil
-
-
--- Localise noise buffer table outside the loop, to be re-used for all
--- mapchunks, therefore minimising memory use.
-
-local nvals_terrain = {}
-
-
--- Localise data buffer table outside the loop, to be re-used for all
--- mapchunks, therefore minimising memory use.
+local nether_channels = {}
 
-local data = {}
-
-
--- On generated function.
-
--- 'minp' and 'maxp' are the minimum and maximum positions of the mapchunk that
--- define the 3D volume.
-minetest.register_on_generated(function(minp, maxp, seed)
-       --nether starts at -10033 y
-       if maxp.y > -10033 then
-               return
-       end
-       -- Start time of mapchunk generation.
-       --local t0 = os.clock()
-       
-       -- Noise stuff.
-
-       -- Side length of mapchunk.
-       local sidelen = maxp.x - minp.x + 1
-       -- Required dimensions of the 3D noise perlin map.
-       local permapdims3d = {x = sidelen, y = sidelen, z = sidelen}
-       -- Create the perlin map noise object once only, during the generation of
-       -- the first mapchunk when 'nobj_terrain' is 'nil'.
-       nobj_terrain = minetest.get_perlin_map(np_terrain, permapdims3d) --nobj_terrain or 
-       -- Create a flat array of noise values from the perlin map, with the
-       -- minimum point being 'minp'.
-       -- Set the buffer parameter to use and reuse 'nvals_terrain' for this.
-       nobj_terrain:get3dMap_flat(minp, nvals_terrain)
-
-       -- Voxelmanip stuff.
-
-       -- Load the voxelmanip with the result of engine mapgen. Since 'singlenode'
-       -- mapgen is used this will be a mapchunk of air nodes.
-       local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
-       -- 'area' is used later to get the voxelmanip indexes for positions.
-       local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
-       -- Get the content ID data from the voxelmanip in the form of a flat array.
-       -- Set the buffer parameter to use and reuse 'data' for this.
-       vm:get_data(data)
-
-       -- Generation loop.
-
-       -- Noise index for the flat array of noise values.
-       local ni = 1
-       -- Process the content IDs in 'data'.
-       -- The most useful order is a ZYX loop because:
-       -- 1. This matches the order of the 3D noise flat array.
-       -- 2. This allows a simple +1 incrementing of the voxelmanip index along x
-       -- rows.
-       -- rows.
-       for z = minp.z, maxp.z do
-       for y = minp.y, maxp.y do
-               -- Voxelmanip index for the flat array of content IDs.
-               -- Initialise to first node in this x row.
-               local vi = area:index(minp.x, y, z)
-               for x = minp.x, maxp.x do
-                       -- Consider a 'solidness' value for each node,
-                       -- let's call it 'density', where
-                       -- density = density noise + density gradient.
-                       local density_noise = nvals_terrain[ni]
-                       -- Density gradient is a value that is 0 at water level (y = 1)
-                       -- and falls in value with increasing y. This is necessary to
-                       -- create a 'world surface' with only solid nodes deep underground
-                       -- and only air high above water level.
-                       -- Here '128' determines the typical maximum height of the terrain.
-                       local density_gradient = (1 - y) / 128
-                       
-                       --print(density_noise, density_gradient)
-                       -- Place solid nodes when 'density' > 0.
-                       --if density_noise + density_gradient > 0 then
-                       if density_noise > 0  and y ~= -10033 then
-                               data[vi] = c_sandstone
-                       -- Otherwise if at or below water level place water.
-                       elseif y == -10033 then
-                               data[vi] = c_bedrock
-                       --elseif y <= 1 then
-                       --      data[vi] = c_water
-                       elseif y > -15000 then
-                               data[vi] = c_air
-                       else
-                               data[vi] = c_lava
-                       end
-
-                       -- Increment noise index.
-                       ni = ni + 1
-                       -- Increment voxelmanip index along x row.
-                       -- The voxelmanip index increases by 1 when
-                       -- moving by 1 node in the +x direction.
-                       vi = vi + 1
-               end
-       end
-       end
-
-       -- After processing, write content ID data back to the voxelmanip.
-       vm:set_data(data)
-       -- Calculate lighting for what has been created.
-       --vm:calc_lighting()
-       
-       vm:set_lighting({day=7,night=7}, minp, maxp)
-       
-       -- Write what has been created to the world.
-       vm:write_to_map()
-       -- Liquid nodes were placed so set them flowing.
-       --vm:update_liquids()
-
-       -- Print generation time of this mapchunk.
-       --local chugent = math.ceil((os.clock() - t0) * 1000)
-       --print ("[lvm_example] Mapchunk generation time " .. chugent .. " ms")
+minetest.register_on_joinplayer(function(player)
+       local name = player:get_player_name()
+       nether_channels[name] = minetest.mod_channel_join(name..":nether_teleporters")
 end)
 
+local path = minetest.get_modpath("nether")
+dofile(path.."/schem.lua")
+dofile(path.."/nodes.lua")
+dofile(path.."/biomes.lua")
+dofile(path.."/craft_recipes.lua")
+dofile(path.."/ore.lua")
+dofile(path.."/items.lua")
+
 
 minetest.register_node("nether:portal", {
        description = "Nether Portal",
@@ -211,6 +20,7 @@ minetest.register_node("nether:portal", {
        tiles = {
                {
                        name = "nether_portal.png",
+                       backface_culling = true,
                        animation = {
                                type = "vertical_frames",
                                aspect_w = 16,
@@ -220,6 +30,7 @@ minetest.register_node("nether:portal", {
                },
                {
                        name = "nether_portal.png",
+                       backface_culling = true,
                        animation = {
                                type = "vertical_frames",
                                aspect_w = 16,
@@ -241,18 +52,376 @@ minetest.register_node("nether:portal", {
        drop = "",
        light_source = 7,
        --post_effect_color = {a = 180, r = 51, g = 7, b = 89},
-       --alpha = 192,
+       alpha = 140,
        node_box = {
        type = "connected",
                -- connect_top =
                -- connect_bottom =
-               connect_front = {-1/16,  -1/2, -1/2,   1/16,  1/2, 0 },
-               connect_left =  {-1/2,   -1/2, -1/16, 0,   1/2,  1/16},
-               connect_back =  {-1/16,  -1/2,  0,   1/16,  1/2,  1/2 },
-               connect_right = { 0,   -1/2, -1/16,  1/2,   1/2,  1/16},
+               connect_front = {0,  -1/2, -1/2,   0,  1/2, 0 },
+               connect_left =  {-1/2,   -1/2, 0, 0,   1/2,  0},
+               connect_back =  {0,  -1/2,  0,   0,  1/2,  1/2 },
+               connect_right = { 0,   -1/2, 0,  1/2,   1/2,  0},
        },
        connects_to = {"nether:portal","nether:obsidian"},
        groups = {unbreakable=1},
        --on_destruct = destroy_portal,
 })
 
+--branch out from center
+local n_index = {}
+local portal_failure = false
+local x_failed = false
+
+--this can be used globally to create nether portals from obsidian
+function create_nether_portal(pos,origin,axis)
+       --create the origin node for stored memory
+       if not origin then
+               origin = pos
+               portal_failure = false
+       end
+       if not axis then
+               axis = "x"
+       end
+               
+       --2d virtual memory map creation (x axis)
+       if axis == "x" then
+               for x = -1,1 do
+               for y = -1,1 do
+                       --index only direct neighbors
+                       if x_failed == false and (math.abs(x)+math.abs(y) == 1) then
+                               local i = vector.add(pos,vector.new(x,y,0))
+                               
+                               local execute_collection = true
+                               
+                               if n_index[i.x] and n_index[i.x][i.y] then
+                                       if n_index[i.x][i.y][i.z] then
+                                               execute_collection = false
+                                       end
+                               end     
+                               
+                               if execute_collection == true then
+                                       --print(minetest.get_node(i).name)
+                                       --index air
+                                       if minetest.get_node(i).name == "air" then
+                                               
+                                               if vector.distance(i,origin) < 50 then
+                                                       --add data to both maps
+                                                       if not n_index[i.x] then n_index[i.x] = {} end
+                                                       if not n_index[i.x][i.y] then n_index[i.x][i.y] = {} end
+                                                       n_index[i.x][i.y][i.z] = {nether_portal=1} --get_group(i,"redstone_power")}             
+                                                       --the data to the 3d array must be written to memory before this is executed
+                                                       --or a stack overflow occurs!!!
+                                                       --pass down info for activators
+                                                       create_nether_portal(i,origin,"x")
+                                               else
+                                                       --print("try z")
+                                                       x_failed = true
+                                                       n_index = {}
+                                                       create_nether_portal(origin,origin,"z")
+                                               end
+                                       elseif minetest.get_node(i).name ~= "nether:obsidian" then
+                                               x_failed = true
+                                               n_index = {}
+                                               create_nether_portal(origin,origin,"z")
+                                       end
+                               end
+                       end
+               end
+               end
+       --2d virtual memory map creation (z axis)
+       elseif axis == "z" then
+               for z = -1,1 do
+               for y = -1,1 do
+                       --index only direct neighbors
+                       if x_failed == true and portal_failure == false and (math.abs(z)+math.abs(y) == 1) then
+                               local i = vector.add(pos,vector.new(0,y,z))
+                               
+                               local execute_collection = true
+                               
+                               if n_index[i.x] and n_index[i.x][i.y] then
+                                       if n_index[i.x][i.y][i.z] then
+                                               execute_collection = false
+                                       end
+                               end     
+                               
+                               if execute_collection == true then
+                                       --print(minetest.get_node(i).name)
+                                       --index air
+                                       if minetest.get_node(i).name == "air" then
+                                               if vector.distance(i,origin) < 50 then
+                                                       --add data to both maps
+                                                       if not n_index[i.x] then n_index[i.x] = {} end
+                                                       if not n_index[i.x][i.y] then n_index[i.x][i.y] = {} end
+                                                       n_index[i.x][i.y][i.z] = {nether_portal=1} --get_group(i,"redstone_power")}                             
+                                                       --the data to the 3d array must be written to memory before this is executed
+                                                       --or a stack overflow occurs!!!
+                                                       --pass down info for activators
+                                                       create_nether_portal(i,origin,"z")
+                                               else
+                                                       --print("portal failed")
+                                                       portal_failure = true
+                                                       n_index = {}
+                                                       --print("try z")
+                                               end
+                                       elseif minetest.get_node(i).name ~= "nether:obsidian" then
+                                               --print("portal failed")
+                                               portal_failure = true
+                                               n_index = {}
+                                       end
+                               end
+                       end
+               end
+               end
+       end
+end
+
+--creates a nether portal in the nether
+--this essentially makes it so you have to move 30 away from one portal to another otherwise it will travel to an existing portal
+local nether_origin_pos = nil
+local function spawn_portal_into_nether_callback(blockpos, action, calls_remaining, param)
+       if calls_remaining == 0 then
+               local portal_exists = minetest.find_node_near(nether_origin_pos, 30, {"nether:portal"})
+                               
+               if not portal_exists then
+                       local min = vector.subtract(nether_origin_pos,30)
+                       local max = vector.add(nether_origin_pos,30)
+                       local platform = minetest.find_nodes_in_area_under_air(min, max, {"nether:netherrack","main:lava"})
+                       
+                       if platform and next(platform) then
+                               --print("setting the platform")
+                               local platform_location = platform[math.random(1,table.getn(platform))]
+                               
+                               minetest.place_schematic(platform_location, portalSchematic,"0",nil,true,"place_center_x, place_center_z")
+                       else
+                               --print("generate a portal within netherrack")
+                               minetest.place_schematic(nether_origin_pos, portalSchematic,"0",nil,true,"place_center_x, place_center_z")
+                       end
+               else
+                       --print("portal exists, utilizing")
+               end
+               nether_origin_pos = nil
+       end
+end
+--creates nether portals in the overworld
+local function spawn_portal_into_overworld_callback(blockpos, action, calls_remaining, param)
+       if calls_remaining == 0 then
+               local portal_exists = minetest.find_node_near(nether_origin_pos, 30, {"nether:portal"})
+                               
+               if not portal_exists then
+                       local min = vector.subtract(nether_origin_pos,30)
+                       local max = vector.add(nether_origin_pos,30)
+                       local platform = minetest.find_nodes_in_area_under_air(min, max, {"main:stone","main:water","main:grass","main:sand","main:dirt"})
+                       
+                       if platform and next(platform) then
+                               --print("setting the platform")
+                               local platform_location = platform[math.random(1,table.getn(platform))]
+                               
+                               minetest.place_schematic(platform_location, portalSchematic,"0",nil,true,"place_center_x, place_center_z")
+                       else
+                               --print("generate a portal within overworld stone")
+                               minetest.place_schematic(nether_origin_pos, portalSchematic,"0",nil,true,"place_center_x, place_center_z")
+                       end
+               else
+                       --print("portal exists, utilizing")
+               end
+               nether_origin_pos = nil
+       end
+end
+
+
+local function generate_nether_portal_in_nether(pos)
+       if pos.y > -10033 then
+               --center the location to the lava height
+               pos.y = -15000--+math.random(-30,30)    
+               nether_origin_pos = pos
+               
+               local min = vector.subtract(nether_origin_pos,30)
+               local max = vector.add(nether_origin_pos,30)
+               
+               --force load the area
+               minetest.emerge_area(min, max, spawn_portal_into_nether_callback)
+       else
+               --center the location to the water height
+               pos.y = 0--+math.random(-30,30) 
+               nether_origin_pos = pos
+               --prefer height for mountains
+               local min = vector.subtract(nether_origin_pos,vector.new(30,30,30))
+               local max = vector.add(nether_origin_pos,vector.new(30,120,30))
+               
+               --force load the area
+               minetest.emerge_area(min, max, spawn_portal_into_overworld_callback)
+       end
+end
+
+
+--modify the map with the collected data
+local function portal_modify_map(n_copy)
+       local sorted_table = {}
+       local created_portal = false
+       for x,datax in pairs(n_copy) do
+               for y,datay in pairs(datax) do
+                       for z,index in pairs(datay) do
+                               --try to create a return side nether portal
+                               if created_portal == false then
+                                       created_portal = true
+                                       generate_nether_portal_in_nether(vector.new(x,y,z))
+                               end
+                               table.insert(sorted_table, vector.new(x,y,z))
+                       end
+               end
+       end
+       minetest.bulk_set_node(sorted_table, {name="nether:portal"})
+end
+
+-------------------------------------------------------------------------------------------
+--the teleporter parts - stored here for now so I can read from other functions
+local teleporting_player = nil
+local function teleport_to_overworld(blockpos, action, calls_remaining, param)
+       if calls_remaining == 0 then
+               local portal_exists = minetest.find_node_near(nether_origin_pos, 30, {"nether:portal"})
+               if portal_exists then
+                       --print(teleporting_player)
+                       if teleporting_player then
+                               teleporting_player:set_pos(vector.new(portal_exists.x,portal_exists.y-0.5,portal_exists.z))
+                       end
+               end
+               teleporting_player = nil
+       end
+end
+local function teleport_to_nether(blockpos, action, calls_remaining, param)
+       if calls_remaining == 0 then
+               local portal_exists = minetest.find_node_near(nether_origin_pos, 30, {"nether:portal"})
+               if portal_exists then
+                       --print(teleporting_player)
+                       if teleporting_player then
+                               teleporting_player:set_pos(vector.new(portal_exists.x,portal_exists.y-0.5,portal_exists.z))
+                       end
+               end
+               teleporting_player = nil
+       end
+end
+
+--this initializes all teleporter commands from the client
+minetest.register_on_modchannel_message(function(channel_name, sender, message)
+       local channel_decyphered = channel_name:gsub(sender,"")
+       if channel_decyphered == ":nether_teleporters" then
+               local player = minetest.get_player_by_name(sender)
+               local pos = player:get_pos()
+               
+               if pos.y > -10033 then
+                       --center the location to the lava height
+                       pos.y = -15000--+math.random(-30,30)    
+                       nether_origin_pos = pos
+                       
+                       local min = vector.subtract(nether_origin_pos,30)
+                       local max = vector.add(nether_origin_pos,30)
+                       
+                       --force load the area
+                       teleporting_player = player
+                       minetest.emerge_area(min, max, teleport_to_nether)
+               else
+                       --center the location to the water height
+                       pos.y = 0--+math.random(-30,30) 
+                       nether_origin_pos = pos
+                       --prefer height for mountains
+                       local min = vector.subtract(nether_origin_pos,vector.new(30,30,30))
+                       local max = vector.add(nether_origin_pos,vector.new(30,120,30))
+                       
+                       --force load the area
+                       teleporting_player = player
+                       minetest.emerge_area(min, max, teleport_to_overworld)
+               end
+       end
+end)
+-------------------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+
+local destroy_n_index = {}
+local destroy_portal_failure = false
+local destroy_x_failed = false
+
+--this can be used globally to create nether portals from obsidian
+function destroy_nether_portal(pos,origin,axis)
+       --create the origin node for stored memory
+       if not origin then
+               origin = pos
+       end             
+       --3d virtual memory map creation (x axis)
+       for x = -1,1 do
+       for z = -1,1 do
+       for y = -1,1 do
+               --index only direct neighbors
+               if (math.abs(x)+math.abs(z)+math.abs(y) == 1) then
+                       local i = vector.add(pos,vector.new(x,y,z))
+                       
+                       local execute_collection = true
+                       
+                       if destroy_n_index[i.x] and destroy_n_index[i.x][i.y] then
+                               if destroy_n_index[i.x][i.y][i.z] then
+                                       execute_collection = false
+                               end
+                       end     
+                       
+                       if execute_collection == true then
+                               --print(minetest.get_node(i).name)
+                               --index air
+                               if minetest.get_node(i).name == "nether:portal" then
+                                       if vector.distance(i,origin) < 50 then
+                                               --add data to both maps
+                                               if not destroy_n_index[i.x] then destroy_n_index[i.x] = {} end
+                                               if not destroy_n_index[i.x][i.y] then destroy_n_index[i.x][i.y] = {} end
+                                               destroy_n_index[i.x][i.y][i.z] = {nether_portal=1} --get_group(i,"redstone_power")}                             
+                                               --the data to the 3d array must be written to memory before this is executed
+                                               --or a stack overflow occurs!!!
+                                               --pass down info for activators
+                                               destroy_nether_portal(i,origin,"z")
+                                       end
+                               end
+                       end
+               end
+       end
+       end
+       end
+end
+
+--modify the map with the collected data
+local function destroy_portal_modify_map(destroy_n_copy)
+       local destroy_sorted_table = {}
+       for x,datax in pairs(destroy_n_copy) do
+               for y,datay in pairs(datax) do
+                       for z,index in pairs(datay) do
+                               table.insert(destroy_sorted_table, vector.new(x,y,z))
+                       end
+               end
+       end
+       minetest.bulk_set_node(destroy_sorted_table, {name="air"})
+end
+
+minetest.register_globalstep(function(dtime)
+       --if indexes exist then calculate redstone
+       if n_index and next(n_index) and portal_failure == false then
+               --create the old version to help with deactivation calculation
+               local n_copy = table.copy(n_index)
+               portal_modify_map(n_copy)
+               portal_failure = false
+       end
+       if x_failed == true then
+               x_failed = false
+       end
+       if portal_failure == true then
+               portal_failure = false
+       end
+       --clear the index to avoid cpu looping wasting processing power
+       n_index = {}
+       
+       
+       --if indexes exist then calculate redstone
+       if destroy_n_index and next(destroy_n_index) and destroy_portal_failure == false then
+               --create the old version to help with deactivation calculation
+               local destroy_n_copy = table.copy(destroy_n_index)
+               destroy_portal_modify_map(destroy_n_copy)
+       end
+       --clear the index to avoid cpu looping wasting processing power
+       destroy_n_index = {}
+end)