From 43b37e96b2dfc916817aa5defcf62f31ddb5b91b Mon Sep 17 00:00:00 2001 From: Treer Date: Sat, 13 Jul 2019 14:09:23 +1000 Subject: [PATCH] Add Book of Portals Squashed commit of the following: commit e80030750df91f75745c7d52729a0d4942eb32f8 Author: Treer Date: Sat Jul 13 13:52:02 2019 +1000 Finish book of portals commit 82ad3d6af683b6bb4cc107e8c76f44c0b791a28d Author: Treer Date: Thu Jul 11 22:43:02 2019 +1000 Book of Portals art commit fac6ff1da89a1b06b78deb0b5b4e3bebe4166860 Author: Treer Date: Thu Jul 11 00:39:50 2019 +1000 starting book of portals --- README.md | 1 + depends.txt | 2 + init.lua | 33 ++++-- portal_api.lua | 160 ++++++++++++++++++++++++---- sounds/nether_book_open.ogg | Bin 0 -> 15883 bytes textures/nether_book_background.png | Bin 0 -> 6274 bytes textures/nether_book_close.png | Bin 0 -> 1750 bytes textures/nether_book_of_portals.png | Bin 0 -> 542 bytes 8 files changed, 168 insertions(+), 28 deletions(-) create mode 100644 sounds/nether_book_open.ogg create mode 100644 textures/nether_book_background.png create mode 100644 textures/nether_book_close.png create mode 100644 textures/nether_book_of_portals.png diff --git a/README.md b/README.md index 2e1d7d8..b1263f1 100644 --- a/README.md +++ b/README.md @@ -29,3 +29,4 @@ Copyright (C) 2013 PilzAdam - nether_rack.png: Zeg9 - nether_glowstone.png: BlockMen + - nether_book_*: Treer diff --git a/depends.txt b/depends.txt index 73b5fd5..036393d 100644 --- a/depends.txt +++ b/depends.txt @@ -2,3 +2,5 @@ stairs default moreblocks? mesecons? +loot? +dungeon_loot? \ No newline at end of file diff --git a/init.lua b/init.lua index 93ac9ec..d61526f 100644 --- a/init.lua +++ b/init.lua @@ -1,4 +1,4 @@ ---[[ +--[[ Nether mod for minetest @@ -19,13 +19,17 @@ ]]-- +local S = minetest.get_translator("nether") + -- Global Nether namespace nether = {} nether.path = minetest.get_modpath("nether") +nether.get_translator = S -- Settings -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.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. -- Load files @@ -44,7 +48,24 @@ nether.register_portal("nether_portal", { shape = nether.PortalShape_Traditional, frame_node_name = "default:obsidian", wormhole_node_name = "nether:portal", - wormhole_node_color = 0, + wormhole_node_color = 0, -- 0 is magenta + -- Warning: "Four per Em" spaces have been used to align the diagram in this text, rather + -- 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), sound_ambient = "nether_portal_hum", sound_ignite = "", sound_extinguish = "", @@ -79,7 +100,3 @@ nether.register_portal("nether_portal", { return destination_pos end }) - - - - diff --git a/portal_api.lua b/portal_api.lua index 5ff01fd..dc49c5a 100644 --- a/portal_api.lua +++ b/portal_api.lua @@ -214,6 +214,8 @@ nether.PortalShape_Traditional = { -- list of node names that are used as frame nodes by registered portals local is_frame_node = {} +local S = nether.get_translator +local ignition_item_name -- this is a function that will be assigned to further down, allowing functions to use it -- that are defined before it is. @@ -862,29 +864,89 @@ function run_wormhole(pos, time_elapsed) end -minetest.register_lbm({ - label = "Start portal timer", - name = "nether:start_portal_timer", - nodenames = {"nether:portal"}, - run_at_every_load = false, - action = function(pos, node) - local p1, p2 - local meta = minetest.get_meta(pos) - if meta ~= nil then - p1 = minetest.string_to_pos(meta:get_string("p1")) - p2 = minetest.string_to_pos(meta:get_string("p1")) - end - if p1 ~= nil and p2 ~= nil then - local timerPos = get_timerPos_from_p1_and_p2(p1, p2) - local timer = minetest.get_node_timer(timerPos) - if timer ~= nil then - timer:start(1) - elseif DEBUG then - minetest.chat_send_all("get_node_timer" .. minetest.pos_to_string(timerPos) .. " returned null") +local function create_book(item_name, inventory_description, inventory_image, title, author, page1_text, page2_text) + + local display_book = function(itemstack, user, pointed_thing) + local player_name = user:get_player_name() + + minetest.sound_play("nether_book_open", {to_player = player_name, gain = 0.25}) + + local formspec = + "size[18,12.122]" .. + + "label[3.1,0.5;" .. minetest.formspec_escape(title) .. "]" .. + "label[3.6,0.9;" .. author .. "]" .. + + "textarea[ 0.9,1.7;7.9,12.0;;" .. minetest.formspec_escape(page1_text) .. ";]" .. + "textarea[10.1,0.8;7.9,12.9;;" .. minetest.formspec_escape(page2_text) .. ";]" .. + + "background[0,0;18,11;nether_book_background.png;true]".. + "image_button_exit[17.3,0;0.8,0.8;nether_book_close.png;;]" + + minetest.show_formspec(player_name, item_name, formspec) + end + + minetest.register_craftitem(item_name, { + description = inventory_description, + inventory_image = inventory_image, + groups = {book = 1}, + on_use = display_book + }) +end + +-- Updates nether.book_of_portals +-- A book the player can read to lean how to build the different portals +local function create_book_of_portals() + + local page1_text + local page2_text = "" + + -- tell the player how many portal types there are + local portalCount = 0 + for _ in pairs(nether.registered_portals) do portalCount = portalCount + 1 end + if portalCount == 1 then + page1_text = S("In all my travels, and time spent in the Great Libraries, I have encountered no shortage of legends surrounding preternatural doorways said to open into other worlds, yet only one can I confirm as being more than merely a story.") + else + page1_text = S("In all my travels, and time spent in the Great Libraries, I have encountered no shortage of legends surrounding preternatural doorways said to open into other worlds, yet only @1 can I confirm as being more than merely stories.", portalCount) + end + + -- tell the player how to ignite portals + local ignition_item_description = "" + if ignition_item_name ~= nil and minetest.registered_items[ignition_item_name] ~= nil then + ignition_item_description = minetest.registered_items[ignition_item_name].description + end + page1_text = page1_text .. + S("\n\nThe key to opening such a doorway is to strike the frame with a @1, at which point the very air inside begins to crackle and glow.\n\n\n", string.lower(ignition_item_description)) + + -- Describe how to create each type of portal, or perhaps just give clues or flavor text, + -- but ensure the Nether is always listed first on the first page so other definitions can + -- refer to it (pairs() returns order based on a random hash). + local i = 1 + if nether.registered_portals["nether_portal"] then + page1_text = page1_text .. nether.registered_portals["nether_portal"].book_of_portals_pagetext .. "\n\n\n" + i = i + 1 + end + for portalName, portalDef in pairs(nether.registered_portals) do + if portalName ~= "nether_portal" then + if i <= portalCount / 2 then + page1_text = page1_text .. portalDef.book_of_portals_pagetext .. "\n\n\n" + else + page2_text = page2_text .. portalDef.book_of_portals_pagetext .. "\n\n\n" end + i = i + 1 end end -}) + + create_book( + "nether:book_of_portals", + S("Book of Portals"), + "nether_book_of_portals.png", + S("A treatise on Rifts and Portals"), + "Riccard F. Burton", -- perhaps a Richard F. Burton of an alternate universe + page1_text, + page2_text + ) +end function register_frame_node(frame_node_name) @@ -969,6 +1031,61 @@ function test_portaldef_is_valid(portal_definition) end +minetest.register_lbm({ + label = "Start portal timer", + name = "nether:start_portal_timer", + nodenames = {"nether:portal"}, + run_at_every_load = false, + action = function(pos, node) + local p1, p2 + local meta = minetest.get_meta(pos) + if meta ~= nil then + p1 = minetest.string_to_pos(meta:get_string("p1")) + p2 = minetest.string_to_pos(meta:get_string("p1")) + end + if p1 ~= nil and p2 ~= nil then + local timerPos = get_timerPos_from_p1_and_p2(p1, p2) + local timer = minetest.get_node_timer(timerPos) + if timer ~= nil then + timer:start(1) + elseif DEBUG then + minetest.chat_send_all("get_node_timer" .. minetest.pos_to_string(timerPos) .. " returned null") + end + end + end +}) + +minetest.register_on_mods_loaded(function() + + -- Make the Book of Portals available as treasure/loot + if nether.PORTAL_BOOK_LOOT_WEIGHTING > 0 and minetest.registered_items["nether:book_of_portals"] ~= nil then + + -- All portals should be registered now. + -- If the Nether is the only registered portal then lower the amount of these books + -- found as treasure, since many players already know the shape of a Nether portal + -- and what to build one out of, so would probably prefer other treasures. + local portalCount = 0 + for _ in pairs(nether.registered_portals) do portalCount = portalCount + 1 end + local weight_adjust = 1 + if portalCount <= 1 then weight_adjust = 0.5 end + + if minetest.get_modpath("loot") then + loot.register_loot({ + weights = { generic = nether.PORTAL_BOOK_LOOT_WEIGHTING * 1000 * weight_adjust, + books = 100 }, + payload = { stack = "nether:book_of_portals" } + }) + end + + if minetest.get_modpath("dungeon_loot") then + dungeon_loot.register({name = "nether:book_of_portals", chance = nether.PORTAL_BOOK_LOOT_WEIGHTING * weight_adjust}) + end + + -- todo: add to Treasurer mod TRMP https://github.com/poikilos/trmp_minetest_game + end +end) + + -- Portal API functions -- -- ==================== -- @@ -1021,11 +1138,13 @@ function nether.register_portal(name, portaldef) if test_portaldef_is_valid(portaldef) then nether.registered_portals[portaldef.name] = portaldef + create_book_of_portals() if not is_frame_node[portaldef.frame_node_name] then register_frame_node(portaldef.frame_node_name) is_frame_node[portaldef.frame_node_name] = true end + return true end end @@ -1066,4 +1185,5 @@ function nether.register_portal_ignition_item(item_name) end, }) + ignition_item_name = item_name end \ No newline at end of file diff --git a/sounds/nether_book_open.ogg b/sounds/nether_book_open.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ebd5bfc7699c53239117b0059a5c4822fe2f20cd GIT binary patch literal 15883 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 Ik;t6C0E;pJmjD0& literal 0 HcmV?d00001 diff --git a/textures/nether_book_of_portals.png b/textures/nether_book_of_portals.png new file mode 100644 index 0000000000000000000000000000000000000000..4ad3a2050ea5a5fb7f1be7224a4d020b1b785ca1 GIT binary patch literal 542 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlYxANWRD)EoNDpN=x}xar@!9(qWzK7Gy|KpvsGjxeKMkOErjj5( zpcBd_pS1w;7?Zr+T^Kr8Wj%l#&H|6fVg?3oVGw3ym^DWND9B#o>Fdh=n4McpjC<7) zZJ-E4iKmNWh{Wa4{y?F_3LLDOc1kR_?)=}z+B37Peom~LOlMxjg~QsC4IcBXISNX4 zIsdxCnNZOFrDZDP>J59i&fVj`+HBpqeD>8f<{j;Vhg=PoXZ^hGp|mIHy!{DjxtRv* ziYupjeXQ8K>(V!tsdalMZM