Compare commits

...

9 Commits

Author SHA1 Message Date
Noodlemire 2b20d972e6 Updated readme 2020-07-15 21:44:41 -05:00
Noodlemire 1245c9e207 united_inventory support added 2020-07-15 21:40:51 -05:00
Noodlemire 9b4cdc1996 Merge branch 'louisroyer-translation' and 'louisroyer-fix_paging' 2020-07-15 18:56:06 -05:00
Noodlemire dce9ec9604 Merge branch 'louisroyer-fix_paging'
fix buggy duplication menu pages when nothing is researched
2020-07-15 18:52:22 -05:00
Noodlemire d91523434b Fixed allow_player_inventory_action bug 2020-07-15 18:50:45 -05:00
Noodlemire 16c7f0653c Fixed allow_player_inventory_action bug 2020-07-15 18:47:08 -05:00
Noodlemire a7037eed81 Merge branch 'translation' of https://github.com/louisroyer/minetest-rnd into louisroyer-translation
Added french translation
2020-07-15 18:26:00 -05:00
Noodlemire d02b430e4c Fixed allow_player_inventory_action bug 2020-07-15 18:25:55 -05:00
Louis Royer 6d3cb211c3 Add french translation 2020-07-13 13:37:40 +02:00
11 changed files with 182 additions and 101 deletions

View File

@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@ -158,7 +158,7 @@ Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
@ -267,7 +267,7 @@ Library will still fall under Section 6.)
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
@ -456,49 +456,3 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random
Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -11,7 +11,7 @@ This mod is inspired directly by the main feature of Terraria's "Journey Mode".
-------------------------------------------------------------------------------------------------------------
Dependencies and Support
-------------------------------------------------------------------------------------------------------------
No hard dependencies are necessary. There is support for sfinv, though, which lets the research and duplication menus appear as tabs in the regular survival inventory. Without it, those menus are accessed through the /research and /duplicate commands.
No hard dependencies are necessary. There is support for sfinv and unified_inventory, though, which lets the research and duplication menus appear as tabs in the regular survival inventory. Without either, those menus are accessed through the /research and /duplicate commands.
-------------------------------------------------------------------------------------------------------------
License

15
changelog.txt Normal file
View File

@ -0,0 +1,15 @@
v1.1.0:
unified_inventory:
+Added support for unified_inventory.
Now, in survival mode, research and duplication pages are available.
Look for the gear icon for the research page, and the 3 blocks icon for the duplication page.
translations:
+Added support for translations
+Added French translation
(Both courtesy of louisroyer)
fixed:
-Duplication menu's paging not working correctly if nothing has been researched (courtesy of louisroyer)
-compatability issue where other mods wouldn't be able to use minetest.register_allow_player_inventory_action
-removed "init trash" message when a player first joins

View File

@ -23,13 +23,15 @@ rnd.duplication = {}
--Stores each player's current selected duplication page, which is important only so that page selection works at all.
rnd.duplication.currentPage = {}
-- Translation support
local S = minetest.get_translator("rnd")
local F = minetest.formspec_escape
--Create both the player's duplication inventory, and a hidden trash inventory so that items in the survival inventory can be shift-click-dumped.
function rnd.duplication.init(player)
player:get_inventory():set_size("duplication", 32)
player:get_inventory():set_size("trash", 1)
minetest.log("init trash")
end
@ -52,8 +54,8 @@ local function spairs(t)
--Collect the keys
local keys = {}
for k in pairs(t) do
keys[#keys + 1] = k
for k in pairs(t) do
keys[#keys + 1] = k
end
--Sort them
@ -72,7 +74,7 @@ local function spairs(t)
end
--This function creates the duplication menu.
local function duplication_formspec(player, page)
local function duplication_formspec(player, page, unified)
local pname = player:get_player_name()
--Get the player's inventory to look through later.
@ -117,30 +119,36 @@ local function duplication_formspec(player, page)
----The page number label's text is stored here because it is used more than once.
local pageString = tostring(rnd.duplication.currentPage[pname]).."/"..tostring(math.max(math.ceil(countComplete(pname) / 32), 1))
--Show a different inventory layout based on if the unified_inventory is open or not
local base_inv = rnd.base_inv_formspec
local btn_height = 4.05
if unified then
base_inv = rnd.base_unified_formspec
btn_height = 3.7
end
--With all of the above information, the formspec can be formed here.
--Note that every time information changes, the menu is reformed.
--Also, note the extra listring to trash, which enables deletion of items in the survival inventory via shift-clicking.
return rnd.base_inv_formspec..
"button[1.5,4;1,1;frst;<<]"..
"button[2.5,4;1,1;prev;<]"..
"button[4.5,4;1,1;next;>]"..
"button[5.5,4;1,1;last;>>]"..
"label[3.7,4;Page]"..
"label["..tostring(3.9 - 0.05 * pageString:len())..",4.25;"..pageString.."]"..
"list[current_player;duplication;0,0;8,4;]"..
return base_inv..
"button[1.5,"..btn_height..";1,1;frst;<<]"..
"button[2.5,"..btn_height..";1,1;prev;<]"..
"button[4.5,"..btn_height..";1,1;next;>]"..
"button[5.5,"..btn_height..";1,1;last;>>]"..
"label[3.7,"..(btn_height+0.05)..";"..F(S("Page")).."]"..
"label["..tostring(3.9 - 0.05 * pageString:len())..","..(btn_height+0.3)..";"..pageString.."]"..
"list[current_player;duplication;0,-0.1;8,4;]"..
"listring[current_player;duplication]"..
"listring[current_player;main]"..
"listring[current_player;trash]"
end
--This function prevents players from placing anything inside the duplication inventory.
function rnd.duplication.allow_player_inventory_action(player, action, inventory, inventory_info)
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
if (action == "put" and inventory_info.listname == "duplication") or (action == "move" and inventory_info.to_list == "duplication") then
return 0
end
return inventory_info.count or inventory_info.stack:get_count()
end
end)
--This function refills the duplication inventory whenever something is removed, and empties the trash slot whenever it is filled.
minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info)
@ -164,7 +172,7 @@ end)
--This function is defined like this because it is used in two different places, one for sfinv and one that is used for /duplicate.
local function on_player_receive_fields_duplication(player, formname, fields, context)
--If one of the four buttons were pressed...
if formname == "duplication" and (fields["frst"] or fields["prev"] or fields["next"] or fields["last"]) then
if ((unified_inventory and formname == "") or formname == "duplication") and (fields["frst"] or fields["prev"] or fields["next"] or fields["last"]) then
local pname = player:get_player_name()
local page = rnd.duplication.currentPage[pname]
@ -184,7 +192,10 @@ local function on_player_receive_fields_duplication(player, formname, fields, co
--When a page changes, the duplication menu has to be reformed.
--A different method must be used if the sfinv inventory is open, so the tabs still work after the reformation.
if sfinv and context then
if unified_inventory and formname == "" then
rnd.duplication.currentPage[pname] = page
unified_inventory.set_inventory_formspec(player, "duplication")
elseif sfinv and context then
rnd.duplication.currentPage[pname] = page
sfinv.set_player_inventory_formspec(player)
else
@ -198,23 +209,44 @@ minetest.register_on_player_receive_fields(on_player_receive_fields_duplication)
--For use when sfinv isn't active.
minetest.register_chatcommand("duplicate", {
params = "",
description = "Open the duplication menu.",
description = S("Open the duplication menu."),
privs = {},
func = function(name, param)
--Block creative players from using it.
if minetest.settings:get_bool("creative_mode") or (creative and creative.is_enabled_for(name)) then
minetest.chat_send_player(name, "Creative Mode players can't use this.")
minetest.chat_send_player(name, S("Creative Mode players can't use this."))
else
minetest.show_formspec(name, "duplication", duplication_formspec(minetest.get_player_by_name(name)))
end
end,
})
--When unified_inventory is active, the duplication tab is defined here, using several previously defined functions.
if unified_inventory then
unified_inventory.register_page("duplication", {
get_formspec = function(player)
return {
formspec = duplication_formspec(player, rnd.duplication.currentPage[player:get_player_name()], true),
draw_inventory = false,
}
end
})
unified_inventory.register_button("duplication", {
type = "image",
image = "rnd_button_duplication_page.png",
tooltip = S("Duplicate"),
condition = function(player)
return not unified_inventory.is_creative(player)
end
})
--When sfinv is active, the duplication tab is defined here, using several previously defined functions.
if sfinv then
elseif sfinv then
sfinv.register_page("duplication", {
title = "Duplicate",
title = S("Duplicate"),
get = function(self, player, context)
return sfinv.make_formspec(player, context, duplication_formspec(player, rnd.duplication.currentPage[player:get_player_name()]))

View File

@ -38,6 +38,11 @@ rnd.base_inv_formspec = "size[8,9.1]"..
"list[current_player;main;0,6.35;8,3;8]"..
hotbar_bg
if unified_inventory then
rnd.base_unified_formspec =
"list[current_player;main;0,4.5;8,4;]"
end
--A custom API file that I find a little more convenient than the usual mod storage API.

21
locale/rnd.fr.tr Normal file
View File

@ -0,0 +1,21 @@
# textdomain: rnd
### duplication.lua ###
Duplicate=Dupliquer
Open the duplication menu.=Ouvre le menu de duplication
Page=Page
### duplication.lua ###
### research.lua ###
Creative Mode players can't use this.=Les joueurs en mode créatif ne peuvent pas utiliser ceci.
### research.lua ###
Open the research menu.=Ouvre le menu de recherche.
Research=Rechercher
Warning: You are in creative mode. Research and Duplication is disabled in favor of the default creative inventory.=Attention : Vous êtes en mode créatif. La recherche et la duplication sont désactivées au profit de linventaire par défaut du mode créatif.

21
locale/template.txt Normal file
View File

@ -0,0 +1,21 @@
# textdomain: rnd
### duplication.lua ###
Duplicate=
Open the duplication menu.=
Page=
### duplication.lua ###
### research.lua ###
Creative Mode players can't use this.=
### research.lua ###
Open the research menu.=
Research=
Warning: You are in creative mode. Research and Duplication is disabled in favor of the default creative inventory.=

View File

@ -1,3 +1,4 @@
name = rnd
description = Research N' Duplicate: Obtain and research enough of a specific item to unlock the ability to infinitely duplicate it. In other words, it's an "earned" creative mode.
optional_depends = creative, default, sfinv
optional_depends = creative, default, sfinv, unified_inventory
min_minetest_version = 5.2.0

View File

@ -20,14 +20,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--file-specific global storage
rnd.research = {}
--Every researchable item has a specific amount needed to be researched in order to unlock duplication.
--Every researchable item has a specific amount needed to be researched in order to unlock duplication.
--This table stores the research requirement of each, indexed by item name.
rnd.research.goals = {}
--Tracks research progress of each item of each player
rnd.research.progs = {}
--This variable is needed to prevent buggy behavior when players grab an item from the sfinv research tab,
-- Translation support
local S = minetest.get_translator("rnd")
local F = minetest.formspec_escape
--This variable is needed to prevent buggy behavior when players grab an item from the sfinv research tab,
--switch to a different tab, and place the item somewhere.
--Without it, the game erroneously displays the /research menu in this scenario.
local normal_research_menu_active = {}
@ -36,7 +40,7 @@ local normal_research_menu_active = {}
--In research.txt, research requirements of entire groups can be defined.
--In case an item fits into numberous groups, the smallest research requirement takes precedent over larger research requirements.
--Note that if a multi-group item is named specifically in research.txt or fits into group:rnd_goal,
--Note that if a multi-group item is named specifically in research.txt or fits into group:rnd_goal,
--that research requirement is used no matter how many group requirements are defined.
--The point of returning rnd.research.goals[item] is to confirm that anything was found at all for an if statement.
local function find_research_groups(item, research_specs)
@ -95,17 +99,17 @@ end)
minetest.register_on_joinplayer(function(player)
local pname = player:get_player_name()
--If the current game/world doesn't use the sfinv mod, commands are used to view menus.
--If the current game/world doesn't use the sfinv mod, commands are used to view menus.
--This might not be intuitive, so players are reminded each time they join.
--When sfinv is used, this isn't necessary, as those menus are integrated to the survival inventory.
if not sfinv then
--Research mode is redundant if the player already has creative mode.
--This also saves on a bit of memory, since a progs table won't be created for creative players.
if minetest.settings:get_bool("creative_mode") or (creative and creative.is_enabled_for(pname)) then
minetest.chat_send_player(pname, "Warning: You are in creative mode. Research and Duplication is disabled in favor of the default creative inventory.")
minetest.chat_send_player(pname, S("Warning: You are in creative mode. Research and Duplication is disabled in favor of the default creative inventory."))
return
else
minetest.chat_send_player(pname, "Research and Duplication is active. You can use /research and /duplicate to bring up their respective menus.")
minetest.chat_send_player(pname, S)("Research and Duplication is active. You can use /research and /duplicate to bring up their respective menus.")
end
end
@ -174,7 +178,7 @@ end
--This function creates the research menu.
local function research_formspec(player)
local function research_formspec(player, unified)
--Get the player's inventory to look through later.
local inv = player:get_inventory()
@ -202,13 +206,19 @@ local function research_formspec(player)
--The progress label's text is stored here because it is used more than once.
local progString = "("..item.count.."/"..item.goal..")"
--Show a different inventory layout based on if the unified_inventory is open or not
local base_inv = rnd.base_inv_formspec
if unified then
base_inv = rnd.base_unified_formspec
end
--With all of the above information, the formspec can be formed here.
--Note that every time information changes, the menu is reformed.
return rnd.base_inv_formspec..
"label["..tostring(4 - 0.05 * item.name:len())..",1.75;"..item.name.."]"..
"label["..tostring(3.9 - 0.05 * progString:len())..",2;"..progString.."]"..
"button[3,2.5;2,1;research;Research]"..
"list[current_player;research;0,3.5;8,1;]"..
return base_inv..
"label["..tostring(4 - 0.05 * item.name:len())..",0.75;"..item.name.."]"..
"label["..tostring(3.9 - 0.05 * progString:len())..",1;"..progString.."]"..
"button[3,1.5;2,1;research;"..F(S("Research")).."]"..
"list[current_player;research;0,2.5;8,1;]"..
"listring[]"
end
@ -236,11 +246,7 @@ minetest.register_allow_player_inventory_action(function(player, action, invento
end
--If we got this far, we can let the itemstack into the research inventory.
return inventory_info.count
end
--For sorting purposes, the next part of the function is in duplication.lua.
return rnd.duplication.allow_player_inventory_action(player, action, inventory, inventory_info)
end)
--Whenever something is successfully moved to the research menu, reform it to adjust the research progress labels.
@ -249,7 +255,9 @@ minetest.register_on_player_inventory_action(function(player, action, inventory,
local pname = player:get_player_name()
--A different method must be used if the sfinv inventory is open, so the tabs still work after the reformation.
if sfinv and sfinv.get_or_create_context(player).page == "research" then
if (unified_inventory and not normal_research_menu_active[pname]) then
unified_inventory.set_inventory_formspec(player, "research")
elseif sfinv and sfinv.get_or_create_context(player).page == "research" then
sfinv.set_player_inventory_formspec(player)
--Check first that the /research menu is open. If it is, update it.
elseif normal_research_menu_active[pname] then
@ -263,7 +271,7 @@ end)
local function on_player_receive_fields_research(player, formname, fields, context)
local pname = player:get_player_name()
if formname == "research" and fields["research"] then
if fields["research"] and ((unified_inventory and formname == "") or (formname == "research")) then
--Get the player's inventory to look through later.
local inv = player:get_inventory()
@ -293,7 +301,10 @@ local function on_player_receive_fields_research(player, formname, fields, conte
--Its placement here, before the research inventory is cleared, is important.
--This makes the research label "lag", so if all of the items are removed by research,
--The player will still see the total research progress for that item, rather than the usual (0/X)
if sfinv and context then
--However, unified_inventory is too aggressive for this trick to work. Sorry.
if unified_inventory and formname == "" then
unified_inventory.set_inventory_formspec(player, "research")
elseif sfinv and context then
sfinv.set_player_inventory_formspec(player)
else
minetest.show_formspec(pname, "research", research_formspec(player))
@ -334,13 +345,13 @@ minetest.register_on_player_receive_fields(on_player_receive_fields_research)
--For use when sfinv isn't active.
minetest.register_chatcommand("research", {
params = "",
description = "Open the research menu.",
description = S("Open the research menu."),
privs = {},
func = function(name, param)
--Block creative players from using it.
if minetest.settings:get_bool("creative_mode") or (creative and creative.is_enabled_for(name)) then
minetest.chat_send_player(name, "Creative Mode players can't use this.")
minetest.chat_send_player(name, S("Creative Mode players can't use this."))
else
--Remember that the /research menu is being used right now.
normal_research_menu_active[name] = true
@ -350,10 +361,31 @@ minetest.register_chatcommand("research", {
end,
})
--When unified_inventory is active, the research tab is defined here, using several previously defined functions.
if unified_inventory then
unified_inventory.register_page("research", {
get_formspec = function(player)
return {
formspec = research_formspec(player, true),
draw_inventory = false,
}
end
})
unified_inventory.register_button("research", {
type = "image",
image = "rnd_button_research_page.png",
tooltip = S("Research"),
condition = function(player)
return not unified_inventory.is_creative(player)
end
})
--When sfinv is active, the research tab is defined here, using several previously defined functions.
if sfinv then
elseif sfinv then
sfinv.register_page("research", {
title = "Research",
title = S("Research"),
get = function(self, player, context)
return sfinv.make_formspec(player, context, research_formspec(player))

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B