From c02e496a15871b335e819522bfc670e7fbe8e3d8 Mon Sep 17 00:00:00 2001 From: v-rob <31123645+v-rob@users.noreply.github.com> Date: Sun, 17 Jun 2018 17:21:04 -0700 Subject: [PATCH] Initial commit --- LICENSE | 63 + crafting.lua | 331 +++++ depends.txt | 2 + init.lua | 1422 +++++++++++++++++++ textures/default_book.png | Bin 0 -> 583 bytes textures/default_book_written.png | Bin 0 -> 628 bytes textures/library_antique_bookshelf_1.png | Bin 0 -> 1515 bytes textures/library_antique_bookshelf_2.png | Bin 0 -> 1445 bytes textures/library_antique_bookshelf_3.png | Bin 0 -> 1544 bytes textures/library_antique_bookshelf_4.png | Bin 0 -> 1467 bytes textures/library_book_Black.png | Bin 0 -> 483 bytes textures/library_book_Black_written.png | Bin 0 -> 561 bytes textures/library_book_Brown.png | Bin 0 -> 399 bytes textures/library_book_Brown_written.png | Bin 0 -> 417 bytes textures/library_book_Cyan.png | Bin 0 -> 593 bytes textures/library_book_Cyan_written.png | Bin 0 -> 3154 bytes textures/library_book_Green.png | Bin 0 -> 643 bytes textures/library_book_Green_written.png | Bin 0 -> 716 bytes textures/library_book_Orange.png | Bin 0 -> 580 bytes textures/library_book_Orange_written.png | Bin 0 -> 579 bytes textures/library_book_Purple.png | Bin 0 -> 528 bytes textures/library_book_Purple_written.png | Bin 0 -> 3153 bytes textures/library_book_Red.png | Bin 0 -> 3100 bytes textures/library_book_Red_written.png | Bin 0 -> 3146 bytes textures/library_bookshelf_1.png | Bin 0 -> 1619 bytes textures/library_bookshelf_2.png | Bin 0 -> 1532 bytes textures/library_bookshelf_3.png | Bin 0 -> 1475 bytes textures/library_bookshelf_4.png | Bin 0 -> 1525 bytes textures/library_card_catalogue.png | Bin 0 -> 1216 bytes textures/library_card_catalogue_top.png | Bin 0 -> 574 bytes textures/library_empty_bookshelf_1.png | Bin 0 -> 1083 bytes textures/library_empty_bookshelf_2.png | Bin 0 -> 1173 bytes textures/library_empty_bookshelf_3.png | Bin 0 -> 1439 bytes textures/library_empty_bookshelf_4.png | Bin 0 -> 601 bytes textures/library_empty_bookshelf_5.png | Bin 0 -> 601 bytes textures/library_empty_bookshelf_6.png | Bin 0 -> 601 bytes textures/library_empty_shelf_1.png | Bin 0 -> 599 bytes textures/library_empty_shelf_2.png | Bin 0 -> 612 bytes textures/library_nonfiction_bookshelf_1.png | Bin 0 -> 962 bytes textures/library_nonfiction_bookshelf_2.png | Bin 0 -> 733 bytes textures/library_nonfiction_bookshelf_3.png | Bin 0 -> 1084 bytes textures/library_wood_pulp.png | Bin 0 -> 435 bytes 42 files changed, 1818 insertions(+) create mode 100644 LICENSE create mode 100644 crafting.lua create mode 100644 depends.txt create mode 100644 init.lua create mode 100644 textures/default_book.png create mode 100644 textures/default_book_written.png create mode 100644 textures/library_antique_bookshelf_1.png create mode 100644 textures/library_antique_bookshelf_2.png create mode 100644 textures/library_antique_bookshelf_3.png create mode 100644 textures/library_antique_bookshelf_4.png create mode 100644 textures/library_book_Black.png create mode 100644 textures/library_book_Black_written.png create mode 100644 textures/library_book_Brown.png create mode 100644 textures/library_book_Brown_written.png create mode 100644 textures/library_book_Cyan.png create mode 100644 textures/library_book_Cyan_written.png create mode 100644 textures/library_book_Green.png create mode 100644 textures/library_book_Green_written.png create mode 100644 textures/library_book_Orange.png create mode 100644 textures/library_book_Orange_written.png create mode 100644 textures/library_book_Purple.png create mode 100644 textures/library_book_Purple_written.png create mode 100644 textures/library_book_Red.png create mode 100644 textures/library_book_Red_written.png create mode 100644 textures/library_bookshelf_1.png create mode 100644 textures/library_bookshelf_2.png create mode 100644 textures/library_bookshelf_3.png create mode 100644 textures/library_bookshelf_4.png create mode 100644 textures/library_card_catalogue.png create mode 100644 textures/library_card_catalogue_top.png create mode 100644 textures/library_empty_bookshelf_1.png create mode 100644 textures/library_empty_bookshelf_2.png create mode 100644 textures/library_empty_bookshelf_3.png create mode 100644 textures/library_empty_bookshelf_4.png create mode 100644 textures/library_empty_bookshelf_5.png create mode 100644 textures/library_empty_bookshelf_6.png create mode 100644 textures/library_empty_shelf_1.png create mode 100644 textures/library_empty_shelf_2.png create mode 100644 textures/library_nonfiction_bookshelf_1.png create mode 100644 textures/library_nonfiction_bookshelf_2.png create mode 100644 textures/library_nonfiction_bookshelf_3.png create mode 100644 textures/library_wood_pulp.png diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..64a2fed --- /dev/null +++ b/LICENSE @@ -0,0 +1,63 @@ +LICENSE FOR CODE: +================= + + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + + +LICENSE FOR MEDIA: +================== + + +Licenses of media (textures, models and sounds) +----------------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ \ No newline at end of file diff --git a/crafting.lua b/crafting.lua new file mode 100644 index 0000000..0a5955c --- /dev/null +++ b/crafting.lua @@ -0,0 +1,331 @@ +minetest.register_craft({ + output = 'library:corner 8', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', 'group:wood', ''}, + {'group:wood', '', ''}, + } +}) + +minetest.register_craft({ + output = 'library:corner 8', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'', 'group:wood', 'group:wood'}, + {'', '', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'library:inside_corner 12', + recipe = { + {'group:wood', 'group:wood'}, + {'', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'library:inside_corner 12', + recipe = { + {'group:wood', 'group:wood'}, + {'group:wood', ''}, + } +}) + +minetest.register_craft({ + output = 'library:card_catalogue', + recipe = { + {'group:wood', 'group:stick', 'group:wood'}, + {'default:paper', 'default:paper', 'default:paper'}, + {'group:wood', 'group:stick', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'library:bookshelf_1 2', + recipe = { + {'group:wood', 'group:stick', 'group:wood'}, + {'', 'group:book', ''}, + {'group:wood', 'group:stick', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'library:bookshelf_1 2', + recipe = { + {'default:bookshelf'}, + } +}) + +minetest.register_craft({ + output = 'library:nonfiction_bookshelf_1 2', + recipe = { + {'group:wood', 'group:stick', 'group:wood'}, + {'group:book', 'group:book', 'group:book'}, + {'group:wood', 'group:stick', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'library:empty_bookshelf 2', + recipe = { + {'group:wood', 'group:stick', 'group:wood'}, + {'', '', ''}, + {'group:wood', 'group:stick', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'library:empty_bookshelf_1 2', + recipe = { + {'group:wood', 'group:stick', 'group:wood'}, + {'', 'farming:string', ''}, + {'group:wood', 'group:stick', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'library:shelf_1 2', + recipe = { + {'group:wood', 'group:stick', 'group:wood'}, + {'group:stick', '', 'group:stick'}, + {'group:wood', 'group:stick', 'group:wood'}, + } +}) + +minetest.register_craft({ + type = "shapeless", + output = 'library:shelf_2 2', + recipe = {'library:shelf_1', 'library:shelf_1'}, +}) + +minetest.register_craft({ + type = "shapeless", + output = 'library:shelf_1 2', + recipe = {'library:shelf_2', 'library:shelf_2'}, +}) + +minetest.register_craft({ + output = 'library:antique_bookshelf_1', + recipe = { + {'', 'group:stick', ''}, + {'group:wood', 'group:book', 'group:wood'}, + {'group:wood', 'farming:string', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'library:antique_bookshelf_3', + recipe = { + {'group:wood', 'group:stick', 'group:wood'}, + {'', 'group:book', ''}, + {'group:wood', 'farming:string', 'group:wood'}, + } +}) + +minetest.register_craft({ + type = "shapeless", + output = 'library:book_Green', + recipe = {'group:book', 'dye:dark_green'}, +}) + +minetest.register_craft({ + type = "shapeless", + output = 'library:book_Cyan', + recipe = {'group:book', 'dye:cyan'}, +}) + +minetest.register_craft({ + type = "shapeless", + output = 'library:book_Red', + recipe = {'group:book', 'dye:red'}, +}) + +minetest.register_craft({ + type = "shapeless", + output = 'library:book_Purple', + recipe = {'group:book', 'dye:violet'}, +}) + +minetest.register_craft({ + type = "shapeless", + output = 'library:book_Brown', + recipe = {'group:book', 'dye:brown'}, +}) + +minetest.register_craft({ + type = "shapeless", + output = 'library:book_Orange', + recipe = {'group:book', 'dye:orange'}, +}) + +minetest.register_craft({ + type = "shapeless", + output = 'library:book_Black', + recipe = {'group:book', 'dye:black'}, +}) + +minetest.register_craft({ + type = "shapeless", + output = 'default:book', + recipe = {'group:book'}, +}) + +minetest.register_craft({ + output = 'default:paper', + recipe = { + {'farming:string', 'farming:string', 'farming:string'}, + } +}) + +minetest.register_craft({ + output = 'default:paper', + recipe = { + {'library:wood_pulp', 'library:wood_pulp', 'library:wood_pulp'}, + } +}) + +minetest.register_craft({ + type = "cooking", + output = 'library:wood_pulp', + recipe = 'group:stick', + cooktime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:wood_pulp", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:bookshelf_1", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:antique_bookshelf_1", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:antique_bookshelf_3", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:nonfiction_bookshelf_1", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:shelf_1", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:shelf_2", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:empty_bookshelf_1", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:empty_bookshelf", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:book_Green", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Red", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Cyan", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Purple", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Black", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Orange", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Brown", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "library:book_Green_written", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Red_written", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Cyan_written", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Purple_written", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Black_written", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Orange_written", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_Brown_written", + burntime = 3, +}) \ No newline at end of file diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..2ced593 --- /dev/null +++ b/depends.txt @@ -0,0 +1,2 @@ +default +farming \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..5bc7f3c --- /dev/null +++ b/init.lua @@ -0,0 +1,1422 @@ +local bookshelf_formspec = + "size[8,7;]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[context;books;0,0.3;8,2;]" .. + "list[current_player;main;0,2.85;8,1;]" .. + "list[current_player;main;0,4.08;8,3;8]" .. + "listring[context;books]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,2.85) + +local function get_bookshelf_formspec(inv) + local formspec = bookshelf_formspec + local invlist = inv and inv:get_list("books") + -- Inventory slots overlay + local bx, by = 0, 0.3 + for i = 1, 16 do + if i == 9 then + bx = 0 + by = by + 1 + end + if not invlist or invlist[i]:is_empty() then + formspec = formspec .. + "image[" .. bx .. "," .. by .. ";1,1;default_bookshelf_slot.png]" + end + bx = bx + 1 + end + return formspec +end + +minetest.register_node("library:bookshelf_1", { + description = "Bookshelf", + drawtype = "nodebox", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_bookshelf_1.png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:bookshelf_1" + minetest.remove_node(pos) + return drops + end, + on_place = function(itemstack, placer, pointed_thing) + local stack = ItemStack("library:bookshelf_" .. math.random(1,4)) + local ret = minetest.item_place(stack, placer, pointed_thing) + return ItemStack("library:bookshelf_1 " .. + itemstack:get_count() - (1 - ret:get_count())) + end, +}) + +for i = 2, 4 do +minetest.register_node("library:bookshelf_"..i, { + description = "Bookshelf", + drawtype = "nodebox", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_bookshelf_"..i..".png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, not_in_creative_inventory = 1}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:bookshelf_1" + minetest.remove_node(pos) + return drops + end, + drop = "library:bookshelf_1", +}) +end + +minetest.register_node("library:nonfiction_bookshelf_1", { + description = "Nonfiction Bookshelf", + drawtype = "nodebox", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_nonfiction_bookshelf_1.png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:bookshelf_1" + minetest.remove_node(pos) + return drops + end, + on_place = function(itemstack, placer, pointed_thing) + local stack = ItemStack("library:nonfiction_bookshelf_" .. math.random(1,3)) + local ret = minetest.item_place(stack, placer, pointed_thing) + return ItemStack("library:nonfiction_bookshelf_1 " .. + itemstack:get_count() - (1 - ret:get_count())) + end, +}) + +for i = 2, 3 do +minetest.register_node("library:nonfiction_bookshelf_"..i, { + description = "Nonfiction Bookshelf", + drawtype = "nodebox", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_nonfiction_bookshelf_"..i..".png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, not_in_creative_inventory = 1}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:nonfiction_bookshelf_1" + minetest.remove_node(pos) + return drops + end, + drop = "library:nonfiction_bookshelf_1", +}) +end + +minetest.register_node("library:empty_bookshelf_1", { + description = "Old Bookshelf", + drawtype = "nodebox", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_empty_bookshelf_1.png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:empty_bookshelf_1" + minetest.remove_node(pos) + return drops + end, + on_place = function(itemstack, placer, pointed_thing) + local stack = ItemStack("library:empty_bookshelf_" .. math.random(1,6)) + local ret = minetest.item_place(stack, placer, pointed_thing) + return ItemStack("library:empty_bookshelf_1 " .. + itemstack:get_count() - (1 - ret:get_count())) + end, +}) + +for i = 2, 6 do +minetest.register_node("library:empty_bookshelf_"..i, { + description = "Old Bookshelf", + drawtype = "nodebox", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_empty_bookshelf_"..i..".png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, not_in_creative_inventory = 1}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:empty_bookshelf_1" + minetest.remove_node(pos) + return drops + end, + drop = "library:empty_bookshelf_1", +}) +end + +minetest.register_node("library:empty_bookshelf", { + description = "Empty Bookshelf", + drawtype = "nodebox", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_empty_bookshelf_4.png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:empty_bookshelf" + minetest.remove_node(pos) + return drops + end, +}) + +minetest.register_node("library:empty_shelf", { + description = "Empty Shelf", + drawtype = "nodebox", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_empty_shelf_1.png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:empty_shelf" + minetest.remove_node(pos) + return drops + end, +}) + +minetest.register_node("library:empty_shelf_2", { + description = "Empty Shelf", + drawtype = "nodebox", + tiles = {"default_wood.png", + "default_wood.png", + "library_empty_shelf_1.png", + "library_empty_shelf_1.png", + "default_wood.png", + "library_empty_shelf_2.png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:empty_shelf_2" + minetest.remove_node(pos) + return drops + end, +}) + +minetest.register_node("library:antique_bookshelf_1", { + description = "Antique Bookshelf Top", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_antique_bookshelf_1.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:antique_bookshelf_1" + minetest.remove_node(pos) + return drops + end, + on_place = function(itemstack, placer, pointed_thing) + local stack = ItemStack("library:antique_bookshelf_" .. math.random(1,2)) + local ret = minetest.item_place(stack, placer, pointed_thing) + return ItemStack("library:antique_bookshelf_1 " .. + itemstack:get_count() - (1 - ret:get_count())) + end, +}) + +minetest.register_node("library:antique_bookshelf_2", { + description = "Antique Bookshelf", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_antique_bookshelf_2.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, not_in_creative_inventory = 1}, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:antique_bookshelf_1" + minetest.remove_node(pos) + return drops + end, + drop = "library:antique_bookshelf_1", +}) + +minetest.register_node("library:antique_bookshelf_3", { + description = "Antique Bookshelf", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_antique_bookshelf_3.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:antique_bookshelf_3" + minetest.remove_node(pos) + return drops + end, + on_place = function(itemstack, placer, pointed_thing) + local stack = ItemStack("library:antique_bookshelf_" .. math.random(3,4)) + local ret = minetest.item_place(stack, placer, pointed_thing) + return ItemStack("library:antique_bookshelf_3 " .. + itemstack:get_count() - (1 - ret:get_count())) + end, +}) + +minetest.register_node("library:antique_bookshelf_4", { + description = "Antique Bookshelf", + tiles = {"default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "library_antique_bookshelf_4.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, not_in_creative_inventory = 1}, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "library:antique_bookshelf_3" + minetest.remove_node(pos) + return drops + end, + drop = "library:antique_bookshelf_3", +}) + +minetest.register_node("library:corner", { + description = "Corner", + drawtype = "nodebox", + tiles = {"default_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, 0, 0.5, 0.5}, + } + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, +}) + +minetest.register_node("library:inside_corner", { + description = "Inside Corner", + drawtype = "nodebox", + tiles = {"default_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0, 0, 0.5, 0.5}, + } + }, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, +}) + +local CATALOGUE_FORMNAME = "library:catalogue_form" + +local player_catalogue = {} + +minetest.register_node("library:card_catalogue", { + description = "Card Catalogue", + tiles = {"library_card_catalogue_top.png", + "library_card_catalogue_top.png", + "library_card_catalogue_top.png", + "library_card_catalogue_top.png", + "library_card_catalogue_top.png", + "library_card_catalogue.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + local player_name = clicker:get_player_name() + local title = meta:get_string("title") or "" + local text1 = meta:get_string("text1") or "" + local text2 = meta:get_string("text2") or "" + local text3 = meta:get_string("text3") or "" + local text4 = meta:get_string("text4") or "" + local text5 = meta:get_string("text5") or "" + local text6 = meta:get_string("text6") or "" + local text7 = meta:get_string("text7") or "" + local text8 = meta:get_string("text8") or "" + local text9 = meta:get_string("text9") or "" + local text10 = meta:get_string("text10") or "" + local text11 = meta:get_string("text11") or "" + local text12 = meta:get_string("text12") or "" + local text13 = meta:get_string("text13") or "" + local text14 = meta:get_string("text14") or "" + local text15 = meta:get_string("text15") or "" + local text16 = meta:get_string("text16") or "" + local text17 = meta:get_string("text17") or "" + local text18 = meta:get_string("text18") or "" + local text19 = meta:get_string("text19") or "" + local text20 = meta:get_string("text20") or "" + local text21 = meta:get_string("text21") or "" + local text22 = meta:get_string("text22") or "" + local text23 = meta:get_string("text23") or "" + local text24 = meta:get_string("text24") or "" + local text25 = meta:get_string("text25") or "" + local text26 = meta:get_string("text26") or "" + local text27 = meta:get_string("text27") or "" + local text28 = meta:get_string("text28") or "" + local text29 = meta:get_string("text29") or "" + local text30 = meta:get_string("text30") or "" + local text31 = meta:get_string("text31") or "" + local text32 = meta:get_string("text32") or "" + local text33 = meta:get_string("text33") or "" + local text34 = meta:get_string("text34") or "" + local text35 = meta:get_string("text35") or "" + local text36 = meta:get_string("text36") or "" + local text37 = meta:get_string("text37") or "" + local text38 = meta:get_string("text38") or "" + local text39 = meta:get_string("text39") or "" + local text40 = meta:get_string("text40") or "" + local text41 = meta:get_string("text41") or "" + local text42 = meta:get_string("text42") or "" + local text43 = meta:get_string("text43") or "" + local text44 = meta:get_string("text44") or "" + local text45 = meta:get_string("text45") or "" + local text46 = meta:get_string("text46") or "" + local text47 = meta:get_string("text47") or "" + local owner = meta:get_string("owner") or "" + local formspec + if owner == "" or owner == player_name then + formspec = "size[16,8]"..default.gui_bg..default.gui_bg_img.. + "field[0.5,1;4.5,0;title;Description;".. + minetest.formspec_escape(title).."]".. + "field[7,1;1,0;text1;Col.;".. + minetest.formspec_escape(text1).."]".. + "field[6,1;1,0;text2;Row.;".. + minetest.formspec_escape(text2).."]".. + "field[5,1;1,0;text3;Sec.;".. + minetest.formspec_escape(text3).."]".. + + "field[0.5,2;4.5,0;text4;;".. + minetest.formspec_escape(text4).."]".. + "field[7,2;1,0;text5;;".. + minetest.formspec_escape(text5).."]".. + "field[6,2;1,0;text6;;".. + minetest.formspec_escape(text6).."]".. + "field[5,2;1,0;text7;;".. + minetest.formspec_escape(text7).."]".. + + "field[0.5,3;4.5,0;text8;;".. + minetest.formspec_escape(text8).."]".. + "field[7,3;1,0;text9;;".. + minetest.formspec_escape(text9).."]".. + "field[6,3;1,0;text10;;".. + minetest.formspec_escape(text10).."]".. + "field[5,3;1,0;text11;;".. + minetest.formspec_escape(text11).."]".. + + "field[0.5,4;4.5,0;text12;;".. + minetest.formspec_escape(text12).."]".. + "field[7,4;1,0;text13;;".. + minetest.formspec_escape(text13).."]".. + "field[6,4;1,0;text14;;".. + minetest.formspec_escape(text14).."]".. + "field[5,4;1,0;text15;;".. + minetest.formspec_escape(text15).."]".. + + "field[0.5,5;4.5,0;text16;;".. + minetest.formspec_escape(text16).."]".. + "field[7,5;1,0;text17;;".. + minetest.formspec_escape(text17).."]".. + "field[6,5;1,0;text18;;".. + minetest.formspec_escape(text18).."]".. + "field[5,5;1,0;text19;;".. + minetest.formspec_escape(text19).."]".. + + "field[0.5,6;4.5,0;text20;;".. + minetest.formspec_escape(text20).."]".. + "field[7,6;1,0;text21;;".. + minetest.formspec_escape(text21).."]".. + "field[6,6;1,0;text22;;".. + minetest.formspec_escape(text22).."]".. + "field[5,6;1,0;text23;;".. + minetest.formspec_escape(text23).."]".. + + "field[8.5,1;4.5,0;text24;Description;".. + minetest.formspec_escape(text24).."]".. + "field[15,1;1,0;text25;Sec.;".. + minetest.formspec_escape(text25).."]".. + "field[14,1;1,0;text26;Row.;".. + minetest.formspec_escape(text26).."]".. + "field[13,1;1,0;text27;Col.;".. + minetest.formspec_escape(text27).."]".. + + "field[8.5,2;4.5,0;text28;;".. + minetest.formspec_escape(text28).."]".. + "field[15,2;1,0;text29;;".. + minetest.formspec_escape(text29).."]".. + "field[14,2;1,0;text30;;".. + minetest.formspec_escape(text30).."]".. + "field[13,2;1,0;text31;;".. + minetest.formspec_escape(text31).."]".. + + "field[8.5,3;4.5,0;text32;;".. + minetest.formspec_escape(text32).."]".. + "field[15,3;1,0;text33;;".. + minetest.formspec_escape(text33).."]".. + "field[14,3;1,0;text34;;".. + minetest.formspec_escape(text34).."]".. + "field[13,3;1,0;text35;;".. + minetest.formspec_escape(text35).."]".. + + "field[8.5,4;4.5,0;text36;;".. + minetest.formspec_escape(text36).."]".. + "field[15,4;1,0;text37;;".. + minetest.formspec_escape(text37).."]".. + "field[14,4;1,0;text38;;".. + minetest.formspec_escape(text38).."]".. + "field[13,4;1,0;text39;;".. + minetest.formspec_escape(text39).."]".. + + "field[8.5,5;4.5,0;text40;;".. + minetest.formspec_escape(text40).."]".. + "field[15,5;1,0;text41;;".. + minetest.formspec_escape(text41).."]".. + "field[14,5;1,0;text42;;".. + minetest.formspec_escape(text42).."]".. + "field[13,5;1,0;text43;;".. + minetest.formspec_escape(text43).."]".. + + "field[8.5,6;4.5,0;text44;;".. + minetest.formspec_escape(text44).."]".. + "field[15,6;1,0;text45;;".. + minetest.formspec_escape(text45).."]".. + "field[14,6;1,0;text46;;".. + minetest.formspec_escape(text46).."]".. + "field[13,6;1,0;text47;;".. + minetest.formspec_escape(text47).."]".. + ------------------------------------------------------ + + "button_exit[6.5,7;3,1;save;Save]" + else + formspec = "size[16,8]"..default.gui_bg..default.gui_bg_img.. + "button_exit[6.5,7;3,1;close;Exit]".. + "field[0.5,1;4.5,0;title;Description;".. + minetest.formspec_escape(title).."]".. + "field[7,1;1,0;text1;Col.;".. + minetest.formspec_escape(text1).."]".. + "field[6,1;1,0;text2;Row.;".. + minetest.formspec_escape(text2).."]".. + "field[5,1;1,0;text3;Sec.;".. + minetest.formspec_escape(text3).."]".. + + "field[0.5,2;4.5,0;text4;;".. + minetest.formspec_escape(text4).."]".. + "field[7,2;1,0;text5;;".. + minetest.formspec_escape(text5).."]".. + "field[6,2;1,0;text6;;".. + minetest.formspec_escape(text6).."]".. + "field[5,2;1,0;text7;;".. + minetest.formspec_escape(text7).."]".. + + "field[0.5,3;4.5,0;text8;;".. + minetest.formspec_escape(text8).."]".. + "field[7,3;1,0;text9;;".. + minetest.formspec_escape(text9).."]".. + "field[6,3;1,0;text10;;".. + minetest.formspec_escape(text10).."]".. + "field[5,3;1,0;text11;;".. + minetest.formspec_escape(text11).."]".. + + "field[0.5,4;4.5,0;text12;;".. + minetest.formspec_escape(text12).."]".. + "field[7,4;1,0;text13;;".. + minetest.formspec_escape(text13).."]".. + "field[6,4;1,0;text14;;".. + minetest.formspec_escape(text14).."]".. + "field[5,4;1,0;text15;;".. + minetest.formspec_escape(text15).."]".. + + "field[0.5,5;4.5,0;text16;;".. + minetest.formspec_escape(text16).."]".. + "field[7,5;1,0;text17;;".. + minetest.formspec_escape(text17).."]".. + "field[6,5;1,0;text18;;".. + minetest.formspec_escape(text18).."]".. + "field[5,5;1,0;text19;;".. + minetest.formspec_escape(text19).."]".. + + "field[0.5,6;4.5,0;text20;;".. + minetest.formspec_escape(text20).."]".. + "field[7,6;1,0;text21;;".. + minetest.formspec_escape(text21).."]".. + "field[6,6;1,0;text22;;".. + minetest.formspec_escape(text22).."]".. + "field[5,6;1,0;text23;;".. + minetest.formspec_escape(text23).."]".. + + "field[8.5,1;4.5,0;text24;Description;".. + minetest.formspec_escape(text24).."]".. + "field[15,1;1,0;text25;Sec.;".. + minetest.formspec_escape(text25).."]".. + "field[14,1;1,0;text26;Row.;".. + minetest.formspec_escape(text26).."]".. + "field[13,1;1,0;text27;Col.;".. + minetest.formspec_escape(text27).."]".. + + "field[8.5,2;4.5,0;text28;;".. + minetest.formspec_escape(text28).."]".. + "field[15,2;1,0;text29;;".. + minetest.formspec_escape(text29).."]".. + "field[14,2;1,0;text30;;".. + minetest.formspec_escape(text30).."]".. + "field[13,2;1,0;text31;;".. + minetest.formspec_escape(text31).."]".. + + "field[8.5,3;4.5,0;text32;;".. + minetest.formspec_escape(text32).."]".. + "field[15,3;1,0;text33;;".. + minetest.formspec_escape(text33).."]".. + "field[14,3;1,0;text34;;".. + minetest.formspec_escape(text34).."]".. + "field[13,3;1,0;text35;;".. + minetest.formspec_escape(text35).."]".. + + "field[8.5,4;4.5,0;text36;;".. + minetest.formspec_escape(text36).."]".. + "field[15,4;1,0;text37;;".. + minetest.formspec_escape(text37).."]".. + "field[14,4;1,0;text38;;".. + minetest.formspec_escape(text38).."]".. + "field[13,4;1,0;text39;;".. + minetest.formspec_escape(text39).."]".. + + "field[8.5,5;4.5,0;text40;;".. + minetest.formspec_escape(text40).."]".. + "field[15,5;1,0;text41;;".. + minetest.formspec_escape(text41).."]".. + "field[14,5;1,0;text42;;".. + minetest.formspec_escape(text42).."]".. + "field[13,5;1,0;text43;;".. + minetest.formspec_escape(text43).."]".. + + "field[8.5,6;4.5,0;text44;;".. + minetest.formspec_escape(text44).."]".. + "field[15,6;1,0;text45;;".. + minetest.formspec_escape(text45).."]".. + "field[14,6;1,0;text46;;".. + minetest.formspec_escape(text46).."]".. + "field[13,6;1,0;text47;;".. + minetest.formspec_escape(text47).."]" + end + player_catalogue[player_name] = pos + minetest.show_formspec(player_name, CATALOGUE_FORMNAME, formspec) + return itemstack + end, +}) + +minetest.register_on_player_receive_fields(function(player, form_name, fields) + if form_name ~= CATALOGUE_FORMNAME or not fields.save then + return + end + local player_name = player:get_player_name() + local pos = player_catalogue[player_name] + if not pos then return end + local meta = minetest.get_meta(pos) + meta:set_string("title", fields.title or "") + meta:set_string("text1", fields.text1 or "") + meta:set_string("text2", fields.text2 or "") + meta:set_string("text3", fields.text3 or "") + meta:set_string("text4", fields.text4 or "") + meta:set_string("text5", fields.text5 or "") + meta:set_string("text6", fields.text6 or "") + meta:set_string("text7", fields.text7 or "") + meta:set_string("text8", fields.text8 or "") + meta:set_string("text9", fields.text9 or "") + meta:set_string("text10", fields.text10 or "") + meta:set_string("text11", fields.text11 or "") + meta:set_string("text12", fields.text12 or "") + meta:set_string("text13", fields.text13 or "") + meta:set_string("text14", fields.text14 or "") + meta:set_string("text15", fields.text15 or "") + meta:set_string("text16", fields.text16 or "") + meta:set_string("text17", fields.text17 or "") + meta:set_string("text18", fields.text18 or "") + meta:set_string("text19", fields.text19 or "") + meta:set_string("text20", fields.text20 or "") + meta:set_string("text21", fields.text21 or "") + meta:set_string("text22", fields.text22 or "") + meta:set_string("text23", fields.text23 or "") + meta:set_string("text24", fields.text24 or "") + meta:set_string("text25", fields.text25 or "") + meta:set_string("text26", fields.text26 or "") + meta:set_string("text27", fields.text27 or "") + meta:set_string("text28", fields.text28 or "") + meta:set_string("text29", fields.text29 or "") + meta:set_string("text30", fields.text30 or "") + meta:set_string("text31", fields.text31 or "") + meta:set_string("text32", fields.text32 or "") + meta:set_string("text33", fields.text33 or "") + meta:set_string("text34", fields.text34 or "") + meta:set_string("text35", fields.text35 or "") + meta:set_string("text36", fields.text36 or "") + meta:set_string("text37", fields.text37 or "") + meta:set_string("text38", fields.text38 or "") + meta:set_string("text39", fields.text39 or "") + meta:set_string("text40", fields.text40 or "") + meta:set_string("text41", fields.text41 or "") + meta:set_string("text42", fields.text42 or "") + meta:set_string("text43", fields.text43 or "") + meta:set_string("text44", fields.text44 or "") + meta:set_string("text45", fields.text45 or "") + meta:set_string("text46", fields.text46 or "") + meta:set_string("text47", fields.text47 or "") + meta:set_string("owner", player_name) + minetest.log("action", "@1 has written in a card catalogue (title: \"@2\"): \"@3\" at location @4", + player:get_player_name(), fields.title, fields.text1, fields.text2, fields.text3, fields.text4, fields.text5, fields.text6, fields.text7, fields.text8, fields.text9, + fields.text10, fields.text11, fields.text12, fields.text13, fields.text14, fields.text15, fields.text16, fields.text17, fields.text18, fields.text19, + fields.text20, fields.text21, fields.text22, fields.text23, fields.text24, fields.text25, fields.text26, fields.text27, fields.text28, fields.text29, + fields.text30, fields.text31, fields.text32, fields.text33, fields.text34, fields.text35, fields.text36, fields.text37, fields.text38, fields.text39, + fields.text40, fields.text41, fields.text42, fields.text43, fields.text44, fields.text45, fields.text46, fields.text47, + minetest.pos_to_string(player:getpos())) +end) + +local color = { + "Red", + "Green", + "Cyan", + "Purple", + "Black", + "Orange", + "Brown" +} + +for c in ipairs(color) do + local color = color[c] + +local lpp = 14 -- Lines per book's page +local function book_on_use(itemstack, user) + local player_name = user:get_player_name() + local meta = itemstack:get_meta() + local title, text, owner = "", "", player_name + local page, page_max, lines, string = 1, 1, {}, "" + + -- Backwards compatibility + local old_data = minetest.deserialize(itemstack:get_metadata()) + if old_data then + meta:from_table({ fields = old_data }) + end + + local data = meta:to_table().fields + + if data.owner then + title = data.title + text = data.text + owner = data.owner + + for str in (text .. "\n"):gmatch("([^\n]*)[\n]") do + lines[#lines+1] = str + end + + if data.page then + page = data.page + page_max = data.page_max + + for i = ((lpp * page) - lpp) + 1, lpp * page do + if not lines[i] then break end + string = string .. lines[i] .. "\n" + end + end + end + + local formspec + if owner == player_name then + formspec = "size[8,8]" .. default.gui_bg .. + default.gui_bg_img .. + "field[0.5,1;7.5,0;title;Title:;" .. + minetest.formspec_escape(title) .. "]" .. + "textarea[0.5,1.5;7.5,7;text;Contents:;" .. + minetest.formspec_escape(text) .. "]" .. + "button_exit[2.5,7.5;3,1;save;Save]" + else + formspec = "size[8,8]" .. default.gui_bg .. + default.gui_bg_img .. + "label[0.5,0.5;by " .. owner .. "]" .. + "tablecolumns[color;text]" .. + "tableoptions[background=#00000000;highlight=#00000000;border=false]" .. + "table[0.4,0;7,0.5;title;#FFFF00," .. minetest.formspec_escape(title) .. "]" .. + "textarea[0.5,1.5;7.5,7;;" .. + minetest.formspec_escape(string ~= "" and string or text) .. ";]" .. + "button[2.4,7.6;0.8,0.8;book_prev;<]" .. + "label[3.2,7.7;Page " .. page .. " of " .. page_max .. "]" .. + "button[4.9,7.6;0.8,0.8;book_next;>]" + end + + minetest.show_formspec(player_name, "library:book_"..color, formspec) + return itemstack +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "library:book_"..color then return end + local inv = player:get_inventory() + local stack = player:get_wielded_item() + + if fields.save and fields.title ~= "" and fields.text ~= "" then + local new_stack, data + if stack:get_name() ~= "library:book_"..color.."_written" then + local count = stack:get_count() + if count == 1 then + stack:set_name("library:book_"..color.."_written") + else + stack:set_count(count - 1) + new_stack = ItemStack("library:book_"..color.."_written") + end + else + data = stack:get_meta():to_table().fields + end + + if data and data.owner and data.owner ~= player:get_player_name() then + return + end + + if not data then data = {} end + data.title = fields.title + data.owner = player:get_player_name() + data.description = "\""..fields.title.."\" by "..data.owner + data.text = fields.text + data.text_len = #data.text + data.page = 1 + data.page_max = math.ceil((#data.text:gsub("[^\n]", "") + 1) / lpp) + + if new_stack then + new_stack:get_meta():from_table({ fields = data }) + if inv:room_for_item("main", new_stack) then + inv:add_item("main", new_stack) + else + minetest.add_item(player:getpos(), new_stack) + end + else + stack:get_meta():from_table({ fields = data }) + end + + elseif fields.book_next or fields.book_prev then + local data = stack:get_meta():to_table().fields + if not data or not data.page then + return + end + + data.page = tonumber(data.page) + data.page_max = tonumber(data.page_max) + + if fields.book_next then + data.page = data.page + 1 + if data.page > data.page_max then + data.page = 1 + end + else + data.page = data.page - 1 + if data.page == 0 then + data.page = data.page_max + end + end + + stack:get_meta():from_table({fields = data}) + stack = book_on_use(stack, player) + end + + -- Update stack + player:set_wielded_item(stack) +end) + +minetest.register_craftitem("library:book_"..color, { + description = color.." Book", + inventory_image = "library_book_"..color..".png", + groups = {book = 1, flammable = 3}, + on_use = book_on_use, +}) + +minetest.register_craftitem("library:book_"..color.."_written", { + description = color.." Book With Text", + inventory_image = "library_book_"..color.."_written.png", + groups = {book = 1, not_in_creative_inventory = 1, flammable = 3}, + stack_max = 1, + on_use = book_on_use, +}) + +minetest.register_craftitem("library:wood_pulp", { + description = "Wood Pulp", + inventory_image = "library_wood_pulp.png", + groups = {flammable = 3}, +}) + +end + +dofile(minetest.get_modpath("library").."/crafting.lua") \ No newline at end of file diff --git a/textures/default_book.png b/textures/default_book.png new file mode 100644 index 0000000000000000000000000000000000000000..5be244077cac17c75e8ad859060312ac62c5b17c GIT binary patch literal 583 zcmV-N0=WH&P)hA()=s0$ptJ znYZMZ=NKCpWTT=}ab0fRyT-heRTbG5_s6FIa8`C+q1xl0knCKB&CTzWN^5*xSR|3? z2nchl`+VgpWccnZFJ3;PTyc3i^#rNG$NX+#-Cd|coIGrM!5jZ-nQXJ>*AxCX`wdR7 VqZ;vL0*3$q002ovPDHLkV1kZS`tJY$ literal 0 HcmV?d00001 diff --git a/textures/default_book_written.png b/textures/default_book_written.png new file mode 100644 index 0000000000000000000000000000000000000000..3f6acd8927e699dc30533281b36b7a53ce541a90 GIT binary patch literal 628 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 literal 0 HcmV?d00001 diff --git a/textures/library_book_Brown.png b/textures/library_book_Brown.png new file mode 100644 index 0000000000000000000000000000000000000000..9965268bf6c8bec084126145d96cd51a5cb5b440 GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=DjSL74G){)!Z!AbW|YuPggQ4rviK_R_5f0vQ+>WjtLRLo7}wCrGgN++aD}llsrt zz`$V7&u`Nkfxxk)duHO*o9aCkyaku0{Lw#j^vr>SCtI&BlfS<|(X_?zOvJPO^O__M zf9AjcplN>nzr$H4CU2iF`7O4-FNx#w?EHGkb#{M`Oqh9yTl`6CdeVc`^g{*?ZZoDI z^bG!F-^KWQoqhVB-@n-pw|3`C-mCrFyohnO mn)bAzTi?F0y-?yAE5nq9S?bcV41U0%WAJqKb6Mw<&;$VcjH<{0 literal 0 HcmV?d00001 diff --git a/textures/library_book_Brown_written.png b/textures/library_book_Brown_written.png new file mode 100644 index 0000000000000000000000000000000000000000..2ca092522c91e4a44fd53c1ee37908cf66093309 GIT binary patch literal 417 zcmV;S0bc%zP)VGd000McNliru;RqWP1OVCRH*f#|0WL{I zK~y-)?US)e!%!54zniqSP07**p%BDDhb$`e4f+I5-Q2o#(@h+F04EVdp>7U>IP?j! zDu|E_C4-%$C5Wx0)}|GWaq?v#&{LVf9fB(a|@PEWCSS_0|Krf5{Ff^6RyN;ME zP_as}p{ZnZ+Dxa(IGiaWs%0}?TVBKuLJ8|N9mnmnv0mihcp!PFKg9O@gox4$BU;@T z>NQ=$ld~Z}q8Y#}>Qt;!oDi@*UqtT{9JkN&=tCB+Zx_%r3VKGFD>5|$HJzo9Pfg8W z`1Z+U{1dYmM%bP&5_u|CDL&daXgLn$Ajoanlxm@GpD;utajnnwBoC00000 LNkvXXu0mjfJN2&N literal 0 HcmV?d00001 diff --git a/textures/library_book_Cyan.png b/textures/library_book_Cyan.png new file mode 100644 index 0000000000000000000000000000000000000000..af0c9899b62140f2e1cef085f8f8bfecffa57300 GIT binary patch literal 593 zcmV-X0@2HM@dak$cnsV0005FNkl%H=YEH&@KstWMnL?9Ztf8XP`P5CmTY0aPl@Qfyi) zr9@Ty2H;93_@atgn~jHaE z+@w+}u{IMYm&?&;G}t~q^1&_FD5b=8U23%&$@mjo*Cmt5P_Nf{efYHn_IfbT6BFCV zN6c)lA*Do0iQ_mZr7#SmE$mA$&=V5?_m=0i848h@dVmmu#Fvk4;lP*JEPnoWS651< fj&R4%bXolcInTdC6=`(100000NkvXXu0mjfdMg5x literal 0 HcmV?d00001 diff --git a/textures/library_book_Cyan_written.png b/textures/library_book_Cyan_written.png new file mode 100644 index 0000000000000000000000000000000000000000..8d59cfaf4f8a1d72836e663e089d92ab5b1f5a7f GIT binary patch literal 3154 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 literal 0 HcmV?d00001 diff --git a/textures/library_book_Green.png b/textures/library_book_Green.png new file mode 100644 index 0000000000000000000000000000000000000000..c5482814612f4a98e6be34eb30b23b0e79a9142d GIT binary patch literal 643 zcmV-}0(||6P);V?2%_!|our_a7Q{tbs@RAnO|QeHR@0`rd`?EvP%7vmcLem9K+M-nWQ5UqkTd-3RqRAFQ5y^Hpg{BL(#X%%HPI!F!5vx-O#u*aGC|r zC#aQ(MN^dgBF`U>AiZf{?C5G!%aui(ScYf!Z*j7(pVe}epi<+}?LOv<^DKR@kVqvF zLSckVhK5HPH_^>y)xFCD7$KYd*Kr`ATrN=!45SRGu2zv!aQ*HJ0A|MKMAIs}xvUyI z(~D`^OisS0vKr9Znxe&wa`onL1Gw%jxVfx4f7B&vZ?1zv7kqhB5PyA4ZZ4}9K9^8| dYI^a%*DndRz?rw8s>T2S002ovPDHLkV1m*O7dHR^ literal 0 HcmV?d00001 diff --git a/textures/library_book_Green_written.png b/textures/library_book_Green_written.png new file mode 100644 index 0000000000000000000000000000000000000000..11588f2a15f5f02f80287baf2cca52e12b7b6c9f GIT binary patch literal 716 zcmV;-0yF)IP)@2HM@dak$cnsV0006rNklKxq(qXP+qg0yAo!e>#ZH9z8tFt)Y@4z|V2me{pMgxJMu(G`|k;raUCw~ZBhbpSlN3xMrSrFjsgkWdc^lp-55?-S@D0l>=ADuHT|2T>Zz zU``d*u9MY#H)$To>B0;E7tSgPhElg`k1rjDt1 zaU7~0n<8_ns+r)9daiV}GCPu_@oX)F(NEYMGF>+>($^Q0q(D$uzH*hT&4;iIHkAS*Jya+TPV(cDdDN0M}0iy$jMG1IGzjm0Gy!0C0cf8S|dKDtYP*9c_|8d{Z) z^e+>D#CR(AB{Q>#+r0^Z7d^em#zaag_7$s^op!);EPeTYC?BNRSv$p_VuSn2NRBTd3{yB#W6ghF#4;_`ZYvZn>0cte7V;aNA;{v4C^8TL0000@2HM@dak$cnsV00052Nkl|*qnHVa% zDs>&*>Ra%y%k9L6HxKN^S;2JTY1Akap&b+eH7E<=;^TLhW~cW6vJ=O-a5DC+>d4R; z0OMS!gHfcy5R4?v?9P?XFMGa>_)gf|3{%sh|c?4d)!{*bhhqrW4P%%Nj8_ z8hM6bRGo71bV4^6PCTQ;?FWd1Dk!hc$E@nD)luf~spF5j*paHJ0mvr$!3MYl9kFahcLo}un&(%g5WsY#$pU-a)JCK4JynO!! zFP^4pz$G{$F-G#DVCZ|)>~M^qzb@RmduK%^RE-kV?yj>NjA1a!u@Kexzv>U>v)j>t SjRt7|0000@2HM@dak$cnsV00051Nkl0v@6o#Ms zF$wX~K*gea7YY?xK@hPL+t7kaqgNuh_aC@-<*yK2b*m(_LUGepDHVzv|9~R6Dxra< z$xUYNojERI(%e?To#0u$GxN^FIqwYo>+&WSU%%|gNMD{`{Hrs6BtCC9buoopZhUW(a*$rxw>aJZv*n z3Qjrz$g+&gS~fSD2*Sho3D#Pybv#&&5fO|rD5Y}n93bf>R9Eh!3JR??#-vzh(OUC< z^W89Y4{qJQdlt}35_UgsQCV661QjYwY6yIvfiWyC-vbdG!tqfj511+iI43MrsyJuK zti_m=UN@moRD9a|fH(mW?kp~&wV_<{PXOhTk8=*AQ}%YZ@O>X^EmvmeNd_Ks*KeXi zh2ZE9256(1j!uPm-09HuyIh@}quQFIRL-1q~H0SB!%KlWee z5Pi3r literal 0 HcmV?d00001 diff --git a/textures/library_book_Purple.png b/textures/library_book_Purple.png new file mode 100644 index 0000000000000000000000000000000000000000..ad7ab74df0989d7cf0897571f6d8aa51ff855fe3 GIT binary patch literal 528 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 literal 0 HcmV?d00001 diff --git a/textures/library_book_Red.png b/textures/library_book_Red.png new file mode 100644 index 0000000000000000000000000000000000000000..c8d6b68f8ee6329009871d67f55d346f66c2c5a4 GIT binary patch literal 3100 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 bB2E7Xt#Zn|a6MFv00000NkvXXu0mjf5Kr3b literal 0 HcmV?d00001 diff --git a/textures/library_card_catalogue.png b/textures/library_card_catalogue.png new file mode 100644 index 0000000000000000000000000000000000000000..2c677715c220a00318ecc829e553be1e71ac1fb5 GIT binary patch literal 1216 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 literal 0 HcmV?d00001 diff --git a/textures/library_empty_bookshelf_3.png b/textures/library_empty_bookshelf_3.png new file mode 100644 index 0000000000000000000000000000000000000000..a050e9584f8552210b6588ce77767654ededa9de GIT binary patch literal 1439 zcmV;Q1z`G#P)Ao$;;IFJr6jKx*VDk0XH#$3^QQB2BG!$& zkAd)-o!N9(?T&^_>RfDBLpGg~@>w+2kjr!dLIBi7>w#P*6{~N|Wm7<1q#lqC=~R~x zBG{>f20pAV0xTaVo9^1R?{Hi5sgDmF?rdv0di=!G;i1m6Et|JTu3gM++7S(fDw1bT z14oaaIQ8RqyAK{29vaG|IsxDG>qLBgYy)5~-i5QT z9j(Ae+afnEWn+8eK>BP8;CULbEET}yJq>uC0b=Xs6>5-6CL&GonaCp}L%_yuk#u{) z*Z9^m?TO3_&0E#Lc1nQ81A8u|3iEKwA+7!zxNQZaa*kC zQs!M)))b!~s%-t~dtk}RHJxqEo3=-@$wb5c!|C>xV#f}S`9A7te+lYg z5P)S#VA-Piul9lOcyv!3cyOl|xY3;hMuvypxewIRaQV|Q_q}y>fB$v=gPOWjd-J{9 zz3Xcuk0164A&fQ~wnndA%o>AI(ty^!_W*kOkMMIKr4T|$DW>wC)@EXSyl-H1I)Yo5 zvpaXkd%Cl)qzr_V6+Klq}Do^ z@RkxU8X2t%ktrzvODSMpi7G@8t|$vIS5&Ft{#$c(AE@f8`9sh0ml%|vq?d+Fkk z|K0a+7+6{5hv@v?KlP3^SX5C2bl({P#wShFmaxCzBl$4Enra95^NBGt=B1P(sEvOg zj87H5tE=V}ZnQv>R|dc|ZCNxc%<@X%4~9Pmy|;~EY(fK$B?JDto=IML=zFny^P&J| zCeo^f3b^+~1IkiBKJNii0!-yypxD;4MDU7qULOP+YZlHL&`O`yL;6h-EUqjA?me0W zT%Q&KKq>)9;lm67jWvbxc%BRN4~_yWDtscyy92IJ67bCw7nl5d1T&?pXAm$@zdi(n zL#5$RDRBMvBY(r{um#*1c&R+%^QQNKM^6nfQO);qW8FS&l7te-}g0JUqU@owB5d?|u&zNi7N-J1wl>`hNi4-nJ0l?;4$ z-5D7W1e#-w%V$1Vd+$G4v7~%1-=-(i4^E~Z_|}27D=Me6hj4&Rs~lir%6;Y7^YKZ* teW`4-XSK9g0{xGl2b$3QqW|M{{STRQG+gHk)$ITP002ovPDHLkV1myvrTzc_ literal 0 HcmV?d00001 diff --git a/textures/library_empty_bookshelf_4.png b/textures/library_empty_bookshelf_4.png new file mode 100644 index 0000000000000000000000000000000000000000..92ebfd87f58a4fb8388111ae3e94eddaebf2069d GIT binary patch literal 601 zcmV-f0;c_mP)HCLH@=P! z;yb!=p%D@n8ij}f<-(mgr_06Npw_CZmS6Mjn^%iv0+`0zgT1YA!@bm&m%qmQOT0h( z@$uWT$s|bEk|I1aCApad0joOe?b*DG)I6yqXa2Q%LK?;6Mz|OZ7Bizd39qipYF|iFV3!57{bk+?#z~9D8at?(3RpWVaNMJ zd^x{<@n{&Q3IMoo`j_vj{=RLow^_C~H&*<$<%iFgyIX^M;J=LHMASI_x;TAzH6^mC zww9?8#OkL-anHh-{)HpQ~DJccmtmon016$nXRI3>T zmCntXPy%DESbawV6pk)zC}{_~>){^mMvlu$(CC?IBndN^6GY8yO~WwrqlatfSJlm& z6aaugH~~qJD6td|w=j;&J9~1tHtXFDWD;_NK}wZ~F5C_7a$|8DI)DCnH^A=o$u@wg nPK&$zhcX=Nvwn3CT>$t4lnCxhp-sT)00000NkvXXu0mjf%e@S- literal 0 HcmV?d00001 diff --git a/textures/library_empty_bookshelf_5.png b/textures/library_empty_bookshelf_5.png new file mode 100644 index 0000000000000000000000000000000000000000..781db83333efd7f60c4d8d8417db460d11c59542 GIT binary patch literal 601 zcmV-f0;c_mP)HCLH@=P! z;yb!=p%D@n8ij}f<-(mgr_06Npw_CZmS6Mjn^%iv0+`0zgT1YA!@bm&m%qmQOT0h( z@$uWT$s|bEk|I1aCApad0joOe?b*DG)I6yqXa2Q%LK?;6Mz|OZ7Bizd39qipYF|iFV3!57{bk+?#z~9D8at?(3RpWVaNMJ zd^x{<@n{&Q3IMoo`j_vj{=RLow^_C~H&*<$<%iFgyIX^M;J=LHMASI_x;TAzH6^mC zww9?8#OkL-anHh-{)HpQ~DJccmtmon016$nXRI3>T zmCntXPy%DESbawV6pk)zC}{_~>){^mMvlu$(CC?IBndN^6GY8yO~WwrqlatfSJlm& z6aaugH~~qJD6td|w=j;&J9~1tHtXFDWD;_NK}wZ~F5C_7a$|8DI)DCnH^A=o$u@wg nPK&$zhcX=Nvwn3CT>$t4lnCxhp-sT)00000NkvXXu0mjf6qgLu literal 0 HcmV?d00001 diff --git a/textures/library_empty_bookshelf_6.png b/textures/library_empty_bookshelf_6.png new file mode 100644 index 0000000000000000000000000000000000000000..a630219a0b4581766209137155e6098750ea6eb8 GIT binary patch literal 601 zcmV-f0;c_mP)HCLH@=P! z;yb!=p%D@n8ij}f<-(mgr_06Npw_CZmS6Mjn^%iv0+`0zgT1YA!@bm&m%qmQOT0h( z@$uWT$s|bEk|I1aCApad0joOe?b*DG)I6yqXa2Q%LK?;6Mz|OZ7Bizd39qipYF|iFV3!57{bk+?#z~9D8at?(3RpWVaNMJ zd^x{<@n{&Q3IMoo`j_vj{=RLow^_C~H&*<$<%iFgyIX^M;J=LHMASI_x;TAzH6^mC zww9?8#OkL-anHh-{)HpQ~DJccmtmon016$nXRI3>T zmCntXPy%DESbawV6pk)zC}{_~>){^mMvlu$(CC?IBndN^6GY8yO~WwrqlatfSJlm& z6aaugH~~qJD6td|w=j;&J9~1tHtXFDWD;_NK}wZ~F5C_7a$|8DI)DCnH^A=o$u@wg nPK&$zhcX=Nvwn3CT>$t4lnCxhp-sT)00000NkvXXu0mjfLdXp3 literal 0 HcmV?d00001 diff --git a/textures/library_empty_shelf_1.png b/textures/library_empty_shelf_1.png new file mode 100644 index 0000000000000000000000000000000000000000..c6d2d35c069958861ac7dfccef7c6c1f215beb28 GIT binary patch literal 599 zcmV-d0;v6oP)r1}<@a^5F z{czZ@&unL^s%$I5hJmZP-Ne)5DNm2)_n+66Yzo`G4+*3I5F9oEk_FBg$A_D2)7CzN z0iaxMoE#1AV~t)uRX{oV1nmDz{Kq@3ktWg0CKnevFT-F+eGRCMX131~;jPuJ{dyjzO zHYvn{3s`!`)jKxe6sC;1RXn(NkWxxPF8fX}sHzH*Lt2i!o0000QX;fHrLvL+uWo~o;00000O<`nZ zAa`kWXdp*PO;E^+ykr0X0o_SNK~yNuO_D*5990lRBQo<>S2H$dYfvjyf9|EyXt2Ii7K zYFVmeNB|wdZJ!Z*xZtOs-vZcYuS+H&!xkeYms%CbWM(SU?oo07e0}ox=C=>;N3xQ0 z3XBNasI0Kr?Uo3(dD;B=)SpkE0Gzj(q+lCCWky{t6JS-42(lPJKRV`N#6JJISu04A z+ukHvt}!YDlKSexI1Ie~>)b*H=j>$}ZDg>ejED?wyIPRZEy)1Be)j0@_CRt9b9T>Z zATu%;+nl)CwgFdSsaS^|&f4dUfZ?%ZBn1nIAW1|Zk|3tk?R7oAczRQrl^NuAnFNC= zse))jg3V>rHIQHb_}Fr{lyQCCEs`UnMpa5J8P13#*CoFD=JtF({r+K+AVoL>ur1WL y&kH~$ZjOg*!0S=~z~%c_Ujf+X{&3cR+5Zc*XB#jUy(u#Q0000Iyah literal 0 HcmV?d00001 diff --git a/textures/library_nonfiction_bookshelf_1.png b/textures/library_nonfiction_bookshelf_1.png new file mode 100644 index 0000000000000000000000000000000000000000..a0468a12fe6ff643306f75464a300281cb169cd2 GIT binary patch literal 962 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 YAD4YX)OA_kbWqrNy85}Sb4q9e0PFy)6951J literal 0 HcmV?d00001