2019-07-20 08:56:32 +02:00
--[[
2017-12-20 06:03:58 +01:00
Nether mod for minetest
Copyright ( C ) 2013 PilzAdam
Permission to use , copy , modify , and / or distribute this software for
any purpose with or without fee is hereby granted , provided that the
above copyright notice and this permission notice appear in all copies .
THE SOFTWARE IS PROVIDED " AS IS " AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS . IN NO EVENT SHALL THE AUTHOR
BE LIABLE FOR ANY SPECIAL , DIRECT , INDIRECT , OR CONSEQUENTIAL DAMAGES
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE , DATA OR PROFITS ,
WHETHER IN AN ACTION OF CONTRACT , NEGLIGENCE OR OTHER TORTIOUS ACTION ,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE .
] ] --
2019-07-13 06:09:23 +02:00
local S = minetest.get_translator ( " nether " )
2019-07-05 15:22:22 +02:00
-- Global Nether namespace
2019-07-22 14:55:13 +02:00
nether = { }
nether.modname = minetest.get_current_modname ( )
nether.path = minetest.get_modpath ( nether.modname )
2019-07-13 06:09:23 +02:00
nether.get_translator = S
2017-12-20 06:03:58 +01:00
2019-07-05 15:22:22 +02:00
-- Settings
2019-07-13 06:09:23 +02:00
nether.DEPTH = - 5000
nether.FASTTRAVEL_FACTOR = 8 -- 10 could be better value for Minetest, since there's no sprint, but ex-Minecraft players will be mathing for 8
nether.PORTAL_BOOK_LOOT_WEIGHTING = 0.9 -- Likelyhood of finding the Book of Portals (guide) in dungeon chests. Set to 0 to disable.
2020-01-02 13:42:20 +01:00
nether.ENABLE_EXAMPLE_PORTALS = false -- Enables extra portal types - examples of how to create your own portal types using the Nether's portal API. Once enabled, their shapes will be shown in the book of portals.
2016-05-30 21:55:04 +02:00
2019-07-05 15:22:22 +02:00
-- Load files
dofile ( nether.path .. " /portal_api.lua " )
dofile ( nether.path .. " /nodes.lua " )
dofile ( nether.path .. " /mapgen.lua " )
2016-05-30 21:55:04 +02:00
2020-01-02 13:42:20 +01:00
if nether.ENABLE_EXAMPLE_PORTALS then
dofile ( nether.path .. " /portal_examples.lua " )
end
2016-05-30 21:55:04 +02:00
2019-07-05 15:22:22 +02:00
-- Portals are ignited by right-clicking with a mese crystal fragment
2019-07-27 11:50:59 +02:00
nether.register_portal_ignition_item (
" default:mese_crystal_fragment " ,
{ name = " nether_portal_ignition_failure " , gain = 0.3 }
)
2016-05-30 21:55:04 +02:00
2019-07-05 15:22:22 +02:00
-- Use the Portal API to add a portal type which goes to the Nether
-- See portal_api.txt for documentation
nether.register_portal ( " nether_portal " , {
shape = nether.PortalShape_Traditional ,
frame_node_name = " default:obsidian " ,
2019-07-13 06:09:23 +02:00
wormhole_node_color = 0 , -- 0 is magenta
2019-07-21 05:06:04 +02:00
2019-07-16 13:39:16 +02:00
-- Warning: "Four per Em" spaces have been used to align the diagram in this text, rather
2019-07-13 06:09:23 +02:00
-- than ASCII spaces. If Minetest changes font this may need to be updated.
book_of_portals_pagetext = S ( [ [ ─ ─ ═ ═ ♦ ♦ ♦ ◊ The Nether ◊ ♦ ♦ ♦ ═ ═ ─ ─
Requiring 14 blocks of obsidian , which we found deep underground where water had solidified molten rock . The frame must be constructed in the following fashion :
┌ ═ ╤ ═ ╤ ═ ╤ ═ ╗
├ ─ ╥ ─ ┴ ─ ┼ ─ ╢
├ ─ ╢ ├ ─ ╢
├ ─ ╢ ├ ─ ╢ four blocks wide
├ ─ ╚ ═ ╤ ═ ╡ ─ ╢ five blocks high
└ ─ ┴ ─ ┴ ─ ┴ ─ ┘ Standing vertically , like a doorway
This opens to a truly hellish place , though for small mercies the air there is still breathable . There is an intriguing dimensional mismatch happening between this realm and ours , as after opening the second portal into it we observed that 10 strides taken in the Nether appear to be an equivalent of @ 1 in the natural world .
The expedition parties have found no diamonds or gold , and after an experienced search party failed to return from the trail of a missing expedition party , I must conclude this is a dangerous place .
] ] , 10 * nether.FASTTRAVEL_FACTOR ) ,
2016-05-30 21:55:04 +02:00
2019-07-28 05:15:51 +02:00
is_within_realm = function ( pos ) -- return true if pos is inside the Nether
2019-07-05 15:22:22 +02:00
return pos.y < nether.DEPTH
2019-06-30 05:38:56 +02:00
end ,
2019-07-13 09:22:17 +02:00
find_realm_anchorPos = function ( surface_anchorPos )
2019-07-05 15:22:22 +02:00
-- divide x and z by a factor of 8 to implement Nether fast-travel
2019-07-13 09:22:17 +02:00
local destination_pos = vector.divide ( surface_anchorPos , nether.FASTTRAVEL_FACTOR )
2019-07-05 15:22:22 +02:00
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
2019-07-13 09:22:17 +02:00
destination_pos.y = nether.DEPTH - 1000 -- temp value so find_nearest_working_portal() returns nether portals
-- a y_factor of 0 makes the search ignore the altitude of the portals (as long as they are in the Nether)
local existing_portal_location , existing_portal_orientation = nether.find_nearest_working_portal ( " nether_portal " , destination_pos , 8 , 0 )
if existing_portal_location ~= nil then
return existing_portal_location , existing_portal_orientation
else
local start_y = nether.DEPTH - math.random ( 500 , 1500 ) -- Search starting altitude
destination_pos.y = nether.find_nether_ground_y ( destination_pos.x , destination_pos.z , start_y )
return destination_pos
end
2019-06-29 05:18:18 +02:00
end ,
2019-07-13 09:22:17 +02:00
find_surface_anchorPos = function ( realm_anchorPos )
2019-07-05 15:22:22 +02:00
-- 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 Nether portals also scale position
2019-07-16 13:39:16 +02:00
-- to create fast-travel. Defining a custom function also means we can look for existing nearby portals:
2016-05-25 08:59:47 +02:00
2019-07-05 15:22:22 +02:00
-- Multiply x and z by a factor of 8 to implement Nether fast-travel
2019-07-13 09:22:17 +02:00
local destination_pos = vector.multiply ( realm_anchorPos , nether.FASTTRAVEL_FACTOR )
2019-07-05 15:22:22 +02:00
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
2019-07-13 09:22:17 +02:00
destination_pos.y = 0 -- temp value so find_nearest_working_portal() doesn't return nether portals
-- a y_factor of 0 makes the search ignore the altitude of the portals (as long as they are outside the Nether)
local existing_portal_location , existing_portal_orientation = nether.find_nearest_working_portal ( " nether_portal " , destination_pos , 8 * nether.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 , " nether_portal " )
return destination_pos
end
2019-07-22 14:55:13 +02:00
end ,
2019-07-27 11:50:59 +02:00
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:#F4F:alpha " ,
animation = portalDef.particle_texture_animation ,
glow = 8
} )
2019-07-22 14:55:13 +02:00
2019-06-30 05:38:56 +02:00
end
2019-07-22 14:55:13 +02:00
2019-07-21 05:06:04 +02:00
} )