Guidebook!

This commit is contained in:
Evert Prants 2019-11-08 20:39:07 +02:00
parent 80b8364527
commit d8350bd491
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
16 changed files with 292 additions and 30 deletions

View File

@ -79,6 +79,10 @@ function magicalities.available_to_player(player_name, unlocked, researchable)
return all
end
local function no_newline(str)
return str:gsub("\n(.*)", "")
end
-- Learn a recipe or an ability
function magicalities.player_learn(player_name, item, recipe, silent)
if not magicalities.data[player_name] then
@ -91,7 +95,7 @@ function magicalities.player_learn(player_name, item, recipe, silent)
if recipe and not magicalities.player_has_recipe(player_name, item) then
local recipe_n = recipes[item]
if recipe_n then
recipe_n = recipe_n.description
recipe_n = no_newline(recipe_n.description)
table.insert(magicalities.data[player_name].recipes, item)
success = true
msgname = msgname .. recipe_n
@ -99,7 +103,7 @@ function magicalities.player_learn(player_name, item, recipe, silent)
elseif not recipe and not magicalities.player_has_ability(player_name, item) then
local ability_n = abilities[item]
if ability_n then
ability_n = ability_n.description
ability_n = no_newline(ability_n.description)
table.insert(magicalities.data[player_name].abilities, item)
success = true
msgname = "to " .. ability_n

141
book.lua
View File

@ -1,18 +1,135 @@
local function book_formspec(user)
local page_cache = {}
local function book_formspec(user, page, scrollindex)
if page then
return "size[8,8]"..
"button[0,0;2,1;back;Back to index]"..
"hypertext[0.1,0.5;7.9,7.5;text;"..page_cache[page].."]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots
end
local avail_list = magicalities.available_to_player(user, true)
return "size[5,6]"..
return "size[6,5.7]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots
default.gui_slots..
magicalities.researching.generate_formspec_list(avail_list, 0, 0, 5, 5.25, scrollindex, false, true)
end
local function book_read(itemstack, user, pointed_thing)
local uname = user:get_player_name()
minetest.show_formspec(uname, "magicalities:book", book_formspec(uname))
return itemstack
local function first_key(list)
local ekey
for key,_ in pairs(list) do
ekey = key
break
end
return ekey
end
local function book_read_page(book, user, page, ptype)
local uname = user:get_player_name()
local check = magicalities.player_has_ability
if ptype == 2 then
check = magicalities.player_has_recipe
end
if not check(uname, page) then return book end
local chapter = "#"..ptype..""..page
if not page_cache[chapter] then
return
end
minetest.show_formspec(uname, "magicalities:book", book_formspec(uname, chapter, 0))
end
local function book_read(book, user, pointed_thing)
local uname = user:get_player_name()
local meta = book:get_meta()
minetest.show_formspec(uname, "magicalities:book", book_formspec(uname, nil, meta:get_int("scrolli")))
return book
end
local function cache_book_pages()
local file = io.open(minetest.get_modpath("magicalities").."/book.txt")
local all = {}
local previous = ""
local since = 0
for line in file:lines() do
if line:sub(0,1) == "#" then
all[line] = ""
previous = line
since = 0
elseif previous ~= "" then
if since > 0 then
line = '\n'..line
end
all[previous] = all[previous] .. line
since = since + 1
end
end
page_cache = all
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "magicalities:book" then return false end
local book = player:get_wielded_item()
if book:get_name() ~= "magicalities:book" then return true end
local bmeta = book:get_meta()
local scrolled = false
local findex = bmeta:get_int("scrolli")
local page
local page_type
local fkey = first_key(fields)
if fields["text"] and fields["text"]:sub(0,6) == "action" then
local pact = fields["text"]:sub(8):gsub("\"", "")
if pact then
fkey = pact
end
end
if fields["dn"] then
scrolled = true
findex = findex + 1
elseif fields["up"] then
scrolled = true
findex = findex - 1
if findex < 0 then
findex = 0
end
elseif fkey and fkey:sub(0,1) == "#" then
page_type = tonumber(fkey:sub(2,2))
page = fkey:sub(3)
elseif fields["back"] then
book_read(book, player)
return true
end
if scrolled then
bmeta:set_int("scrolli", findex)
player:set_wielded_item(book)
book_read(book, player)
return true
end
if not page or not page_type then return true end
-- Handle page
--print("Open page on topic " .. page .. ", which is of type " .. page_type)
book_read_page(book, player, page, page_type)
return true
end)
minetest.register_craftitem("magicalities:book", {
description = "Magicalities' Guide for Witches and Wizards",
inventory_image = "magicalities_book.png",
@ -24,3 +141,13 @@ minetest.register_craftitem("magicalities:book", {
end,
stack_max = 1
})
minetest.register_chatcommand("mgcbookcache", {
privs = {basic_privs = 1},
func = function ()
cache_book_pages()
return true, "Reloaded book cache successfully."
end
})
cache_book_pages()

46
book.txt Normal file
View File

@ -0,0 +1,46 @@
#1magicalities:crystal
<b>Crystals</b> are nodes that you can find in underground - they grow on the ceilings and the floors of caves.
<b>Crystal Tapping</b> is an action in which by <b>right-clicking</b> a crystal with your wand, you can extract elements from it.
#1magicalities:crystal_preserve
The <b>Crystal Preservation</b> ability helps you collect elements from crystals without completely draining them. You learned that when you drain a crystal of it's elements completely, it will not regenerate anything.
#1magicalities:crystal_draining
The <b>Efficient Crystal Draining</b> ability helps you collect elements from crystals 5x faster than normal.
#1magicalities:pickup_jarred
The <b>Crystal Jarring</b> procedure will enable you to collect crystals without removing all of their contents.
When using this method, the crystal will not break into shards, instead it will drop itself.
<big><b>Procedure</b></big>
Surround a crystal in a 3x3 thing of glass, except for the top layer, which has to be wood slabs.
When the structure is complete, hit any node of glass with the <action name="#2magicalities:wand_steel">wand</action>.
<center><item name="stairs:slab_wood" width=64 height=64><item name="stairs:slab_wood" width=64 height=64><item name="stairs:slab_wood" width=64 height=64></center>
<center><item name="default:glass" width=64 height=64><item name="magicalities:crystal_cluster_air" width=64 height=64><item name="default:glass" width=64 height=64></center>
<center><item name="default:glass" width=64 height=64><item name="default:glass" width=64 height=64><item name="default:glass" width=64 height=64></center>
#2magicalities:table
The <b>Research Table</b> is used to do research about various topics in the world of magic.
In order to do research, you need to find knowledge around the world. You can find bookshelves in various structures that will give you the knowledge you need to do your research. If you find a bookshelf that is generated in the world, you can extract knowledge from it by right-clicking.
The Research Table will need three items to operate: Your <b>Guide Book</b> (you're reading it right now!), an <b>Ink and Quill</b> and a piece of paper.
Provided you have acquired sufficient knowledge from exploring the world, you can then dwell deeper into topics you have heard about but don't know all the details of.
#2magicalities:arcane_table
<b>Arcane Table</b> is used for magical crafting. You can create an Arcane Table by <i>using</i> your wand on a Table. Make sure that the table is empty first, though!
<center><item name="magicalities:table" width=64 height=64><img name=magicalities_book_plus.png width=64 height=64><item name="magicalities:wand_steel" width=64 height=64></center>
The Arcane Table will also tell you what elements you need inside of your wand to finish crafting your item.
#2magicalities:cauldron
<b>Cauldron</b> is used for magical crafting. It requires a <b>fire source</b> under it and <b>water</b> to accept items.
Right-Click on the Cauldron with a <b>Bucket of Water</b> in order to fill it with water.
#2magicalities:wand_steel
<b>Wands</b> are used to cast spells. The first wand you know of is called the <b>Steel-Capped Wand</b>, which can contain up to 25 of any element.
#2magicalities:wand_gold
The <b>Gold-Capped Wand</b> is an improved version of the Steel-Capped Wand. It can contain up to 50 of each element instead of the Steel Wand's 25.
#2magicalities:transterra
The <b>Transterra</b> is a stone that can be used to <b>create or remove nodes from the world</b>. It is made in the Cauldron.
<center><item name="default:stone" width=64 height=64><img name=magicalities_book_plus.png width=64 height=64><item name="default:dirt" width=64 height=64><img name=magicalities_book_plus.png width=64 height=64><item name="magicalities:crystal_fire" width=64 height=64></center>
<center><img name=gui_furnace_arrow_bg.png^\[transformFY width=64 height=64></center>
<center><item name="magicalities:cauldron_with_water" width=64 height=64><img name=magicalities_book_plus.png width=64 height=64><item name="magicalities:wand_steel" width=64 height=64></center>
#2magicalities:tellium
<b>Tellium</b> is a metal that can be used to <b>create magical tools</b>. It is made in the Cauldron.
<center><item name="default:steel_ingot" width=64 height=64><img name=magicalities_book_plus.png width=64 height=64><item name="default:obsidian" width=64 height=64></center>
<center><img name=gui_furnace_arrow_bg.png^\[transformFY width=64 height=64></center>
<center><item name="magicalities:cauldron_with_water" width=64 height=64><img name=magicalities_book_plus.png width=64 height=64><item name="magicalities:wand_steel" width=64 height=64></center>
#2magicalities:element_ring
The <b>Elemental Ring</b> can show you what elements a crystal contains and their quantities.
#2magicalities:focus_blank
The <b>Blank Wand Focus</b> is your gateway to the world of <b>Wand Focuses</b>.

View File

@ -86,7 +86,8 @@ local function update_contents(pos, contents)
end
local function crystal_rightclick(pos, node, clicker, itemstack, pointed_thing)
local meta = minetest.get_meta(pos)
local player = clicker:get_player_name()
local meta = minetest.get_meta(pos)
-- Add contents to the crystal
local contents = minetest.deserialize(meta:get_string("contents"))
@ -100,13 +101,19 @@ local function crystal_rightclick(pos, node, clicker, itemstack, pointed_thing)
return itemstack
end
-- Check if the player knows anything about the Element Ring, if not, surprise them!
local element_ring = magicalities.player_has_recipe(player, "magicalities:element_ring")
if not element_ring then
magicalities.player_learn(player, "magicalities:element_ring", true)
end
-- Check if player can preserve this crystal
local preserve = magicalities.player_has_ability(clicker:get_player_name(), "magicalities:crystal_preserve")
local preserve = magicalities.player_has_ability(player, "magicalities:crystal_preserve")
local mincheck = 0
if preserve then mincheck = 1 end
-- Check if we can take more than one
local draining = magicalities.player_has_ability(clicker:get_player_name(), "magicalities:crystal_draining")
local draining = magicalities.player_has_ability(player, "magicalities:crystal_draining")
local maxtake = 1
if draining then maxtake = 5 end
@ -124,13 +131,17 @@ local function crystal_rightclick(pos, node, clicker, itemstack, pointed_thing)
end
end
local done_did = 0
local can_put = magicalities.wands.wand_insertable_contents(itemstack, one_of_each)
for name, count in pairs(can_put) do
if count > 0 then
done_did = done_did + count
contents[name][1] = contents[name][1] - count
end
end
if done_did == 0 then return itemstack end
-- Take - Particles
local cpls = clicker:get_pos()
cpls.y = cpls.y + 1

View File

@ -1,5 +1,7 @@
-- Wand Focuses
local particles = minetest.settings:get_bool("mgc_particles", true)
-- Constants
-- TODO: make settings
magicalities.magic_spray_count = 16
@ -299,6 +301,7 @@ local special_fn = {}
-- Particles
local randparticles = PcgRandom(os.clock())
local function shoot_particles (user, velocity, color)
if not particles then return end
if not color then
color = ""
else

View File

@ -50,5 +50,8 @@ dofile(modpath.."/cauldron.lua")
-- Book
dofile(modpath.."/book.lua")
-- Map generation
dofile(modpath.."/mapgen.lua")
-- Register
dofile(modpath.."/register.lua")

16
mapgen.lua Normal file
View File

@ -0,0 +1,16 @@
local nostructures = minetest.settings:get_bool("mgc_skip_structures", false)
if not nostructures then
minetest.register_decoration({
deco_type = "schematic",
place_on = "default:dirt_with_grass",
y_min = 0,
y_max = 31000,
flags = "force_placement, all_floors",
schematic = "schems/magicalities_booktower.mts",
rotation = "random",
place_offset_y = 0,
-- what noise_params should i use instead of this?
fill_ratio = 0.00000001,
})
end

View File

@ -1,4 +1,4 @@
name = magicalities
description = Magic mod.
depends = default
optional_depends = craftguide,fluid_lib,creative,mobs,mobs_animal,dye
optional_depends = craftguide,fluid_lib,creative,mobs,mobs_animal,dye,treasurer

View File

@ -11,6 +11,11 @@ minetest.register_node("magicalities:tree_enchanted", {
on_place = minetest.rotate_node
})
-- circumvent a weird issue
local function add_fix(inv, item)
inv:add_item("main", item)
end
-- Researchable bookshelf
-- Supposed to be a generated node that gives Research Notes
minetest.register_node("magicalities:bookshelf", {
@ -48,8 +53,7 @@ minetest.register_node("magicalities:bookshelf", {
local inv = clicker:get_inventory()
if inv:room_for_item("main", item) then
-- idk
inv:add_item("main", item)
minetest.after(0.1, add_fix, inv, item)
else
minetest.item_drop(item, clicker, clicker:get_pos())
end

View File

@ -45,7 +45,8 @@ local recipes = {
["fire"] = 15,
["dark"] = 15,
["air"] = 15,
}
},
learnable = true
},
{
input = {
@ -358,7 +359,47 @@ if minetest.get_modpath("craftguide") ~= nil then
end
end
-- Abilities
-- Treasurer mod, add Research Notes as a form of treasure.
if minetest.get_modpath("treasurer") then
treasurer.register_treasure("magicalities:note", 0.35, 5, {1,3}, nil, "tool")
end
---------------
-- Abilities --
---------------
-- Default abilities
magicalities.register_recipe_learnable({
name = "magicalities:wand_steel",
description = "Wands",
default = true,
})
magicalities.register_ability_learnable({
name = "magicalities:crystal",
description = "Crystal Tapping\nExtract elements from crystals",
icon = "magicalities_crystal_gui.png",
default = true,
})
magicalities.register_recipe_learnable({
name = "magicalities:table",
description = "Research Table\nDo research about the magic world",
default = true,
})
magicalities.register_recipe_learnable({
name = "magicalities:arcane_table",
description = "Arcane Table\nCraft magical items",
default = true,
})
magicalities.register_recipe_learnable({
name = "magicalities:cauldron",
description = "Cauldron",
default = true
})
magicalities.register_ability_learnable({
name = "magicalities:crystal_preserve",
@ -379,9 +420,3 @@ magicalities.register_ability_learnable({
depends = {"magicalities:crystal_preserve"},
icon = "magicalities_jarred.png"
})
magicalities.register_recipe_learnable({
name = "magicalities:cauldron",
description = "Cauldron",
default = true
})

View File

@ -1,7 +1,7 @@
magicalities.researching = {}
local function genlist(list, x, y, w, h, index, canlearn)
function magicalities.researching.generate_formspec_list(list, x, y, w, h, index, canlearn, canopen)
local i = ""
if #list == 0 then return "" end
local ty = 0
@ -9,7 +9,7 @@ local function genlist(list, x, y, w, h, index, canlearn)
local visualtotal = math.ceil(y + h)
local reallist = {}
for i = index * visualtotal, visualtotal do
for i = index * visualtotal, (index * visualtotal) + visualtotal do
if list[i + 1] then
table.insert(reallist, list[i + 1])
end
@ -18,6 +18,12 @@ local function genlist(list, x, y, w, h, index, canlearn)
for _,v in pairs(reallist) do
if ty + 1 > visualtotal then break end
local icon = ""
local t = 1
if v.type == "recipe" then t = 2 end
if canopen then
i = i .. "button["..x..","..(y+ty)..";"..w..",1;#"..t..""..v.name..";]"
end
if v.icon ~= nil then
icon = "image["..x..","..(y+ty)..";1,1;"..v.icon.."]"
@ -27,8 +33,6 @@ local function genlist(list, x, y, w, h, index, canlearn)
i = i .. icon .. "label["..(x + 1)..","..(y+ty)..";"..v.description.."]"
if canlearn then
local t = 1
if v.type == "recipe" then t = 2 end
i = i .. "button["..(x+w-1)..","..(y+ty)..";1,1;@"..t..""..v.name..";Learn]"
end
ty = ty + 1
@ -37,7 +41,7 @@ local function genlist(list, x, y, w, h, index, canlearn)
if index > 0 then
i = i .. "button["..(x+w)..","..y..";1,1;up;Up]"
elseif total > visualtotal then
i = i .. "button["..(x+w)..","..(y+h)..";1,1;dn;Down]"
i = i .. "button["..(x+w)..","..(y+h-0.25)..";1,1;dn;Down]"
end
return i
@ -60,7 +64,7 @@ local function table_formspec(player, research, index, canlearn)
"list[context;tools;0.5,1.5;1,1;]"..
"image[0.5,2.5;1,1;magicalities_gui_paper_slot.png]"..
"list[context;paper;0.5,2.5;3,3;]"..
genlist(list, 1.5, 0.5, 5.5, 2, index, canlearn)..
magicalities.researching.generate_formspec_list(list, 1.5, 0.5, 5.5, 2, index, canlearn)..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
"listring[current_player;main]"..
@ -254,6 +258,7 @@ end
-- Base Table Override
minetest.override_item("magicalities:table", {
description = "Research Table",
on_construct = function (pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()

Binary file not shown.

6
settingtypes.txt Normal file
View File

@ -0,0 +1,6 @@
# Setting this to true will prevent Magicalities' structures from being placed in the world
mgc_skip_structures (Skip generating Magicalities structures) bool false
# Enable Magicalities' particle effects
mgc_particles (Magicalities particle effects) bool true

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -236,8 +236,10 @@ function magicalities.wands.wand_insertable_contents(stack, to_put)
for name, count in pairs(to_put) do
if data_table[name] then
if data_table[name] + count < cap + 1 then
if data_table[name] + count <= cap then
insertable[name] = count
elseif cap - data_table[name] > 0 then
insertable[name] = cap - data_table[name]
end
end
end