From e9d35b854653e03626e459bb889b6e464c05e13d Mon Sep 17 00:00:00 2001 From: Gerold55 Date: Thu, 7 Mar 2019 18:06:08 -0500 Subject: [PATCH] Add files via upload --- CONTRIBUTING | 26 + LICENSE | 20 + README | 32 + README.md | 4 +- game.conf | 1 + menu/header.png | Bin 0 -> 6051 bytes mods/creative/README.txt | 17 + mods/creative/depends.txt | 2 + mods/creative/init.lua | 91 ++ mods/creative/inventory.lua | 234 ++++ mods/creative/license.txt | 61 + .../textures/crafting_table_bottom.png | Bin 0 -> 288 bytes .../creative/textures/crafting_table_side.png | Bin 0 -> 474 bytes .../textures/crafting_table_side2.png | Bin 0 -> 516 bytes .../textures/crafting_table_side3.png | Bin 0 -> 292 bytes mods/creative/textures/crafting_table_top.png | Bin 0 -> 321 bytes .../creative/textures/creative_clear_icon.png | Bin 0 -> 708 bytes mods/creative/textures/creative_next_icon.png | Bin 0 -> 727 bytes mods/creative/textures/creative_prev_icon.png | Bin 0 -> 728 bytes .../textures/creative_search_icon.png | Bin 0 -> 1908 bytes .../creative/textures/creative_trash_icon.png | Bin 0 -> 712 bytes mods/sfinv/README.txt | 13 + mods/sfinv/api.lua | 183 +++ mods/sfinv/init.lua | 22 + mods/sfinv/license.txt | 24 + mods/ws_core/README.txt | 301 +++++ mods/ws_core/aliases.lua | 74 + mods/ws_core/crafting.lua | 1185 +++++++++++++++++ mods/ws_core/craftitems.lua | 179 +++ mods/ws_core/depends.txt | 1 + mods/ws_core/functions.lua | 488 +++++++ mods/ws_core/init.lua | 41 + mods/ws_core/item_entity.lua | 74 + mods/ws_core/legacy.lua | 37 + mods/ws_core/license.txt | 154 +++ mods/ws_core/mapgen.lua | 981 ++++++++++++++ mods/ws_core/mp2.txt | 1168 ++++++++++++++++ mods/ws_core/nodes.lua | 170 +++ mods/ws_core/schematics.zip | Bin 0 -> 1451 bytes mods/ws_core/schematics/dead_fallen.mts | Bin 0 -> 60 bytes mods/ws_core/schematics/dead_tree.mts | Bin 0 -> 77 bytes mods/ws_core/schematics/dead_tree1.mts | Bin 0 -> 75 bytes mods/ws_core/schematics/dead_tree2.mts | Bin 0 -> 70 bytes mods/ws_core/schematics/dead_tree3.mts | Bin 0 -> 79 bytes mods/ws_core/schematics/dead_tree4.mts | Bin 0 -> 56 bytes mods/ws_core/schematics/dead_tree_fallen.mts | Bin 0 -> 77 bytes mods/ws_core/textures/crack_anylength.png | Bin 0 -> 2547 bytes mods/ws_core/textures/gui_formbg.png | Bin 0 -> 971 bytes mods/ws_core/textures/gui_hb_bg.png | Bin 0 -> 98 bytes mods/ws_core/textures/heart.png | Bin 0 -> 14830 bytes mods/ws_core/textures/wieldhand.png | Bin 0 -> 129 bytes mods/ws_core/textures/ws_coal.png | Bin 0 -> 304 bytes mods/ws_core/textures/ws_cobble.png | Bin 0 -> 827 bytes mods/ws_core/textures/ws_dead_tree.png | Bin 0 -> 666 bytes mods/ws_core/textures/ws_dead_tree_top.png | Bin 0 -> 693 bytes mods/ws_core/textures/ws_dirt.png | Bin 0 -> 750 bytes mods/ws_core/textures/ws_dirt_dry.png | Bin 0 -> 792 bytes mods/ws_core/textures/ws_dry_dirt.png | Bin 0 -> 745 bytes mods/ws_core/textures/ws_mineral_coal.png | Bin 0 -> 435 bytes mods/ws_core/textures/ws_rocky_dirt.png | Bin 0 -> 732 bytes mods/ws_core/textures/ws_sandy_dirt.png | Bin 0 -> 721 bytes mods/ws_core/textures/ws_stone.png | Bin 0 -> 772 bytes mods/ws_core/textures/ws_stone_block.png | Bin 0 -> 524 bytes mods/ws_core/textures/ws_water_flowing.png | Bin 0 -> 201 bytes mods/ws_core/textures/ws_water_source.png | Bin 0 -> 201 bytes mods/ws_core/textures/ws_wood.png | Bin 0 -> 218 bytes mods/ws_core/tools.lua | 15 + mods/ws_core/trees.lua | 189 +++ 68 files changed, 5785 insertions(+), 2 deletions(-) create mode 100644 CONTRIBUTING create mode 100644 LICENSE create mode 100644 README create mode 100644 game.conf create mode 100644 menu/header.png create mode 100644 mods/creative/README.txt create mode 100644 mods/creative/depends.txt create mode 100644 mods/creative/init.lua create mode 100644 mods/creative/inventory.lua create mode 100644 mods/creative/license.txt create mode 100644 mods/creative/textures/crafting_table_bottom.png create mode 100644 mods/creative/textures/crafting_table_side.png create mode 100644 mods/creative/textures/crafting_table_side2.png create mode 100644 mods/creative/textures/crafting_table_side3.png create mode 100644 mods/creative/textures/crafting_table_top.png create mode 100644 mods/creative/textures/creative_clear_icon.png create mode 100644 mods/creative/textures/creative_next_icon.png create mode 100644 mods/creative/textures/creative_prev_icon.png create mode 100644 mods/creative/textures/creative_search_icon.png create mode 100644 mods/creative/textures/creative_trash_icon.png create mode 100644 mods/sfinv/README.txt create mode 100644 mods/sfinv/api.lua create mode 100644 mods/sfinv/init.lua create mode 100644 mods/sfinv/license.txt create mode 100644 mods/ws_core/README.txt create mode 100644 mods/ws_core/aliases.lua create mode 100644 mods/ws_core/crafting.lua create mode 100644 mods/ws_core/craftitems.lua create mode 100644 mods/ws_core/depends.txt create mode 100644 mods/ws_core/functions.lua create mode 100644 mods/ws_core/init.lua create mode 100644 mods/ws_core/item_entity.lua create mode 100644 mods/ws_core/legacy.lua create mode 100644 mods/ws_core/license.txt create mode 100644 mods/ws_core/mapgen.lua create mode 100644 mods/ws_core/mp2.txt create mode 100644 mods/ws_core/nodes.lua create mode 100644 mods/ws_core/schematics.zip create mode 100644 mods/ws_core/schematics/dead_fallen.mts create mode 100644 mods/ws_core/schematics/dead_tree.mts create mode 100644 mods/ws_core/schematics/dead_tree1.mts create mode 100644 mods/ws_core/schematics/dead_tree2.mts create mode 100644 mods/ws_core/schematics/dead_tree3.mts create mode 100644 mods/ws_core/schematics/dead_tree4.mts create mode 100644 mods/ws_core/schematics/dead_tree_fallen.mts create mode 100644 mods/ws_core/textures/crack_anylength.png create mode 100644 mods/ws_core/textures/gui_formbg.png create mode 100644 mods/ws_core/textures/gui_hb_bg.png create mode 100644 mods/ws_core/textures/heart.png create mode 100644 mods/ws_core/textures/wieldhand.png create mode 100644 mods/ws_core/textures/ws_coal.png create mode 100644 mods/ws_core/textures/ws_cobble.png create mode 100644 mods/ws_core/textures/ws_dead_tree.png create mode 100644 mods/ws_core/textures/ws_dead_tree_top.png create mode 100644 mods/ws_core/textures/ws_dirt.png create mode 100644 mods/ws_core/textures/ws_dirt_dry.png create mode 100644 mods/ws_core/textures/ws_dry_dirt.png create mode 100644 mods/ws_core/textures/ws_mineral_coal.png create mode 100644 mods/ws_core/textures/ws_rocky_dirt.png create mode 100644 mods/ws_core/textures/ws_sandy_dirt.png create mode 100644 mods/ws_core/textures/ws_stone.png create mode 100644 mods/ws_core/textures/ws_stone_block.png create mode 100644 mods/ws_core/textures/ws_water_flowing.png create mode 100644 mods/ws_core/textures/ws_water_source.png create mode 100644 mods/ws_core/textures/ws_wood.png create mode 100644 mods/ws_core/tools.lua create mode 100644 mods/ws_core/trees.lua diff --git a/CONTRIBUTING b/CONTRIBUTING new file mode 100644 index 0000000..9067214 --- /dev/null +++ b/CONTRIBUTING @@ -0,0 +1,26 @@ +======================================================================== + +To contribute to this project, you must understand and agree to the +terms in this document at the time of contribution. + +- A "contribution" consists of all files, patches and changes, source + control commits, comments and other metadata submitted to the project + maintainer(s) for inclusion or other use in the project. + +- All contributions must consist only of your own original work, to + which you retain copyright, or to which copyright is not applicable. + +- All copyrightable portions must be non-exclusively, perpetually and + irrevocably licensed under the same license terms as the overall + project. + +- You will receive attribution in the project's license, in the form of + "Portions (C) ...", which shall cover all portions of all + contributions. You agree that this constitutes adequate attribution + under the terms of the license. + +- You may request to be attributed pseudonymously at the time of + submission. Unless otherwise specified, source control metadata + will be used for attribution. + +------------------------------------------------------------------------ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f2db39d --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Copyright (C)2018 Aaron Suen + +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. diff --git a/README b/README new file mode 100644 index 0000000..472f3e4 --- /dev/null +++ b/README @@ -0,0 +1,32 @@ +======================================================================== +CORE DESIGN PRINCIPLES +------------------------------------------------------------------------ + +- Do as much in node-space in the world as possible. + - Minimize use of off-grid entities. + - Avoid encapsulating things in inventories, machines, GUIs. + - Crafting and transforming in-world. +- Minimal set of primitive composable functions. + - Each node should do one job (or one part of a job). + - Only include the most primitive, fungible components. + - Avoid redundant functionality, include fewest possible + different elements. + - Complex emergent gameplay by combining simple nodes. +- Challenging and constrained gameplay. + - Limited inventories, very restricted item storage, e.g. one + stack per node. + - Large, complex machines to design and build for resource + transformations. + - Subtle environmental hazards, like deadfalls and pestilence. +- Rich, subtle interactions. + - Digging, placing, punching and battering. + - Different effects from different tools (including empty hand). + - Different faces of node may have different effects. +- Focus on puzzle-oriented single-player/cooperative gameplay. + - Avoid dependence on action, combat, PvP. + - Slow-moving hazards, players have a chance to think and plan. + - Acessible for slow reflexes, slow networks, mobile devices. + + +........................................................................ +======================================================================== diff --git a/README.md b/README.md index 0297048..ab828d0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# WasteLands_Survival -An apocalyptic based game for MT. +# WasteLand-Survival +An Apocalyptic style game diff --git a/game.conf b/game.conf new file mode 100644 index 0000000..236c38d --- /dev/null +++ b/game.conf @@ -0,0 +1 @@ +name = WasteLands: Survival diff --git a/menu/header.png b/menu/header.png new file mode 100644 index 0000000000000000000000000000000000000000..99318959ed75b4ef085b74ebaecc307c670622fe GIT binary patch literal 6051 zcmeHL2~d;Q77i-KLXj3lHX&M8QGyBrB9ek^K|lh^(g2ZNCpG)uf1kf`Eig2oRCY7+FG~VGC)9;}ey6uXLU>uYLYA$)Ei9+;h+Oopb;1&WW@z zHxlHR;0FKzf)HbUO8{U?BIozTt(!UDmkGH&oEuMorI8+>pmi6O^Jj~Pu9+?XP>c~+ zcH#v9HUlh7PZ@BY>nI5x2Z@<$%0Q3G+vqC8^ba_hsC$^{cviv9n60j!vOa-0l*?rUrp003;OTmA4f`sBKD9*PAT*alkp zxCf$~{M`V)PM*j>5YjDhw;Jdm=&-AiE$8(kybRITJ$24;B0bt)_DEhta{*`^H^>fJ zdgzdkGLz>E+caRZsP62nJ1vu){;JF)f{X_zAz;Z%E(0Cxg+)nIBuiTC_b@ zW6hKT$jNRF-K?icqqJg>KExyNI{q&}IdrBMp1R0IngtFW2;EomPB1D# zgN+}@^M^38#M-6#_k&)PyoY&*kG3m?+n=t%4kVbLS%WilUhDfcm>5H}Eo;d9ADhhE zW)l@P9@ZJ$WFb)}>Q>+uPXyo;MZ8QKQz9~4?&vw!1Z;-RL5V+}=DQ0Slil*k{1Y>O z=OXBQ94hA@y_KH(_^`T&vWY#)N7yXkxnzf~TS;8yN!0DtTGvNP5uR+=PGF^VOsQuo z5SLUjNp{`zAH4o$>jJr`TalKbE?T*!>W7%rNwqwkm&p%tb)u;$h5E>^_DCn5uch?b zk1pOQ=o0Qhrd1D-z%-;hu_|h{kV*O%xwObd`}}8iE2w=J0hibJpWfzRiU+> z{gZFDW9J(JD`2I21wnt+nr6C8t_nz;&D=rx zc^isz8mt{Xoyi|bZ5EZm}VGo4CwpKECTcBl^0k`fv6zJcb z(e$x>qj*nA>V#NU)|nHf2577cxu+2g2~SnQII!Y}_)tD)Gi7CWep&SLminW!njNj@ zm{-OiTF@Im(+<}7LC?E8;C)jI6UaG;bVJ;^pdH?x_*{e?5Z+uOMGa6z`{sooT7EVu zXqNEfgH4;Pr8?!s1wH!2r&gY5LlpA12ONvg04cTQH}5oOB>I!fVmfj~3S)mzZrPdW zXhimV1;>mBP%vF9d>PdmYEWTefvvVd7HO_(>7E`nOUD_qH*(D%&xs9I0ELb}hK!LuuGPsyQ?bwZPaPxK+i`*)w|(nVZv_szLMpA>3|56sj$*yD0; zICJK4mG_Vud~dlKd0rCB&8jjvHOcBpSa|mFGO+WXpKiQ#wVeY(JZlnjj5oW8rHc0W z+DFb~!xhnxJGWA~BB0fcapMas9GTc~HHZc6qK&(-V^4q|P}yB=8(=^)=3Dwp#it~1 zD02#4&w}V;mi%`u_D2B!N-lLK;V^#V+juO4+*v8OfqEMDN#GXs-LSC!TAts0F(Ux$#4q10%=X=Ia7CCxr_{ce_MPJBlR`G_0a>UT;TU~GTDTOhT{D9NF zr?Fv$vr};QXIXZu`WfRCZ9+-+Tp)5(HjTvZOv}R6En-9|yqAOuOOJ9^>;F7Qa|9TM0&tbiuj@TF`VqbCEIfVWK_zP@w#<`D<7a%`S|?nB5`SznvAX@nQ2 z#}v{SQp~DJEO_HdtbXi6m@ulpn!xHI (MIT) +Jean-Patrick G. (kilbith) (MIT) + +Author of media (textures) +-------------------------- +paramat (CC BY-SA 3.0): +* creative_prev_icon.png +* creative_next_icon.png +* creative_search_icon.png +* creative_clear_icon.png +* creative_trash_icon.png derived from a texture by kilbith (CC BY-SA 3.0) diff --git a/mods/creative/depends.txt b/mods/creative/depends.txt new file mode 100644 index 0000000..d2ab2e8 --- /dev/null +++ b/mods/creative/depends.txt @@ -0,0 +1,2 @@ +ws_core +sfinv \ No newline at end of file diff --git a/mods/creative/init.lua b/mods/creative/init.lua new file mode 100644 index 0000000..3142956 --- /dev/null +++ b/mods/creative/init.lua @@ -0,0 +1,91 @@ +creative = {} + +sfinv.override_page("sfinv:crafting", { + is_in_nav = function(self, player, context) + return not creative.is_enabled_for(player:get_player_name()) + end, +}) + +local function update_sfinv(name) + minetest.after(0, function() + local player = minetest.get_player_by_name(name) + if player then + if sfinv.get_page(player):sub(1, 9) == "creative:" then + sfinv.set_page(player, sfinv.get_homepage_name(player)) + else + sfinv.set_player_inventory_formspec(player) + end + end + end) +end + +minetest.register_privilege("creative", { + description = "Allow player to use creative inventory", + give_to_singleplayer = false, + give_to_admin = false, + on_grant = update_sfinv, + on_revoke = update_sfinv, +}) + +local creative_mode_cache = minetest.settings:get_bool("creative_mode") + +function creative.is_enabled_for(name) + return creative_mode_cache or + minetest.check_player_privs(name, {creative = true}) +end + +dofile(minetest.get_modpath("creative") .. "/inventory.lua") + +if creative_mode_cache then + -- Dig time is modified according to difference (leveldiff) between tool + -- 'maxlevel' and node 'level'. Digtime is divided by the larger of + -- leveldiff and 1. + -- To speed up digging in creative, hand 'maxlevel' and 'digtime' have been + -- increased such that nodes of differing levels have an insignificant + -- effect on digtime. + local digtime = 42 + local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256} + + minetest.register_item(":", { + type = "none", + wield_image = "wieldhand.png", + wield_scale = {x = 1, y = 1, z = 2.5}, + range = 10, + tool_capabilities = { + full_punch_interval = 0.5, + max_drop_level = 3, + groupcaps = { + crumbly = caps, + cracky = caps, + snappy = caps, + choppy = caps, + oddly_breakable_by_hand = caps, + }, + damage_groups = {fleshy = 10}, + } + }) +end + +-- Unlimited node placement +minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + if placer and placer:is_player() then + return creative.is_enabled_for(placer:get_player_name()) + end +end) + +-- Don't pick up if the item is already in the inventory +local old_handle_node_drops = minetest.handle_node_drops +function minetest.handle_node_drops(pos, drops, digger) + if not digger or not digger:is_player() or + not creative.is_enabled_for(digger:get_player_name()) then + return old_handle_node_drops(pos, drops, digger) + end + local inv = digger:get_inventory() + if inv then + for _, item in ipairs(drops) do + if not inv:contains_item("main", item, true) then + inv:add_item("main", item) + end + end + end +end diff --git a/mods/creative/inventory.lua b/mods/creative/inventory.lua new file mode 100644 index 0000000..8599186 --- /dev/null +++ b/mods/creative/inventory.lua @@ -0,0 +1,234 @@ +local player_inventory = {} +local inventory_cache = {} + +local function init_creative_cache(items) + inventory_cache[items] = {} + local i_cache = inventory_cache[items] + + for name, def in pairs(items) do + if def.groups.not_in_creative_inventory ~= 1 and + def.description and def.description ~= "" then + i_cache[name] = def + end + end + table.sort(i_cache) + return i_cache +end + +function creative.init_creative_inventory(player) + local player_name = player:get_player_name() + player_inventory[player_name] = { + size = 0, + filter = "", + start_i = 0 + } + + minetest.create_detached_inventory("creative_" .. player_name, { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player2) + local name = player2 and player2:get_player_name() or "" + if not creative.is_enabled_for(name) or + to_list == "main" then + return 0 + end + return count + end, + allow_put = function(inv, listname, index, stack, player2) + return 0 + end, + allow_take = function(inv, listname, index, stack, player2) + local name = player2 and player2:get_player_name() or "" + if not creative.is_enabled_for(name) then + return 0 + end + return -1 + end, + on_move = function(inv, from_list, from_index, to_list, to_index, count, player2) + end, + on_take = function(inv, listname, index, stack, player2) + if stack and stack:get_count() > 0 then + minetest.log("action", player_name .. " takes " .. stack:get_name().. " from creative inventory") + end + end, + }, player_name) + + return player_inventory[player_name] +end + +function creative.update_creative_inventory(player_name, tab_content) + local creative_list = {} + local inv = player_inventory[player_name] or + creative.init_creative_inventory(minetest.get_player_by_name(player_name)) + local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name}) + + local items = inventory_cache[tab_content] or init_creative_cache(tab_content) + + for name, def in pairs(items) do + if def.name:find(inv.filter, 1, true) or + def.description:lower():find(inv.filter, 1, true) then + creative_list[#creative_list+1] = name + end + end + + table.sort(creative_list) + player_inv:set_size("main", #creative_list) + player_inv:set_list("main", creative_list) + inv.size = #creative_list +end + +-- Create the trash field +local trash = minetest.create_detached_inventory("creative_trash", { + -- Allow the stack to be placed and remove it in on_put() + -- This allows the creative inventory to restore the stack + allow_put = function(inv, listname, index, stack, player) + return stack:get_count() + end, + on_put = function(inv, listname) + inv:set_list(listname, {}) + end, +}) +trash:set_size("main", 1) + +creative.formspec_add = "" + +function creative.register_tab(name, title, items) + sfinv.register_page("creative:" .. name, { + title = title, + is_in_nav = function(self, player, context) + return creative.is_enabled_for(player:get_player_name()) + end, + get = function(self, player, context) + local player_name = player:get_player_name() + creative.update_creative_inventory(player_name, items) + local inv = player_inventory[player_name] + local start_i = inv.start_i or 0 + local pagenum = math.floor(start_i / (6*4) + 1) + local pagemax = math.ceil(inv.size / (6*4)) + return sfinv.make_formspec(player, context, + "label[1.6,7.05;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" .. + [[ + image[4.85,1.6;0.8,0.8;creative_trash_icon.png] + listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF] + list[current_player;main;4.8,6.9;8,1;] + list[current_player;main;4.8,3.6;8,3;8] + list[detached:creative_trash;main;4.8,1.5;1,1;] + listring[] + list[current_player;craft;6.5,0.8;2,2;] + list[current_player;craftpreview;11,1.5;1,1;] + image[9,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270] + image_button[0.2,7;1,0.8;creative_prev_icon.png;creative_prev;] + image_button[2.8,7;1,0.8;creative_next_icon.png;creative_next;] + image_button[2.4,6;0.8,0.8;creative_search_icon.png;creative_search;] + image_button[3.05,6;0.8,0.8;creative_clear_icon.png;creative_clear;] + background[-.34,-.3;13.66,8.84;gui_formbg.png] + tooltip[creative_search;Search] + tooltip[creative_clear;Reset] + tooltip[creative_prev;Previous page] + tooltip[creative_next;Next page] + listring[current_player;main] + field_close_on_enter[creative_filter;false] + ]] .. + "field[0.4,6.23;2.4,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. "]" .. + "listring[detached:creative_" .. player_name .. ";main]" .. + "list[detached:creative_" .. player_name .. ";main;0,0;4,6;" .. tostring(start_i) .. "]" .. + ws_core.get_hotbar_bg(4.8,6.9) .. creative.formspec_add, false) + end, + on_enter = function(self, player, context) + local player_name = player:get_player_name() + local inv = player_inventory[player_name] + if inv then + inv.start_i = 0 + end + end, + on_player_receive_fields = function(self, player, context, fields) + local player_name = player:get_player_name() + local inv = player_inventory[player_name] + assert(inv) + + if fields.creative_clear then + inv.start_i = 0 + inv.filter = "" + creative.update_creative_inventory(player_name, items) + sfinv.set_player_inventory_formspec(player, context) + elseif fields.creative_search or + fields.key_enter_field == "creative_filter" then + inv.start_i = 0 + inv.filter = fields.creative_filter:lower() + creative.update_creative_inventory(player_name, items) + sfinv.set_player_inventory_formspec(player, context) + elseif not fields.quit then + local start_i = inv.start_i or 0 + + if fields.creative_prev then + start_i = start_i - 3*8 + if start_i < 0 then + start_i = inv.size - (inv.size % (3*8)) + if inv.size == start_i then + start_i = math.max(0, inv.size - (3*8)) + end + end + elseif fields.creative_next then + start_i = start_i + 3*8 + if start_i >= inv.size then + start_i = 0 + end + end + + inv.start_i = start_i + sfinv.set_player_inventory_formspec(player, context) + end + end + }) +end + +creative.register_tab("all", "All", minetest.registered_items) +creative.register_tab("nodes", "Nodes", minetest.registered_nodes) +creative.register_tab("tools", "Tools", minetest.registered_tools) +creative.register_tab("craftitems", "Items", minetest.registered_craftitems) + +local old_homepage_name = sfinv.get_homepage_name +function sfinv.get_homepage_name(player) + if creative.is_enabled_for(player:get_player_name()) then + return "creative:all" + else + return old_homepage_name(player) + end +end + + +minetest.register_node("creative:crafting_table", { + description = "WorkBench", + tiles = { + "crafting_table_top.png", + "crafting_table_bottom.png", + "crafting_table_side3.png", + "crafting_table_side2.png", + "crafting_table_side3.png", + "crafting_table_side.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + inv:set_size('main', 8*4) + inv:set_size('storage', 8*1) + meta:set_string('formspec', + 'size[8,7.5;]'.. + 'list[current_player;main;0,3.5;8,4;]'.. + 'list[current_player;craft;3,0;3,3;]'.. + 'list[current_player;craftpreview;7,1;1,1;]') + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty('storage') and inv:is_empty('storage1') + end, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + } + } +}) \ No newline at end of file diff --git a/mods/creative/license.txt b/mods/creative/license.txt new file mode 100644 index 0000000..50ff9c7 --- /dev/null +++ b/mods/creative/license.txt @@ -0,0 +1,61 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) + +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. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2016 Jean-Patrick G. (kilbith) +Copyright (C) 2018 paramat + +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/ diff --git a/mods/creative/textures/crafting_table_bottom.png b/mods/creative/textures/crafting_table_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..3260ddbccbe079711be1c79049b5b320de22f80b GIT binary patch literal 288 zcmV+*0pI?KP)Px#*-1n}R5%f(Q^5{`FbthzOb=YlzQHf?Bm8+T96Wmv6BSW;jfIzm$r73XUHe+v z*KTt<9zNBsG?(^aAp2@-+IwfZ*IRVhaE1V#IQJCBC}o8D;bKegUnFPy~!ej=%r_002ovPDHLkV1fX^7IL}( literal 0 HcmV?d00001 diff --git a/mods/creative/textures/crafting_table_side.png b/mods/creative/textures/crafting_table_side.png new file mode 100644 index 0000000000000000000000000000000000000000..0927ea2f9088c6518949c3aafea1f66f0b816c6b GIT binary patch literal 474 zcmV<00VV#4P)Px$l1W5CR5%fRQ#($>KoFfo>rb!)ih_^;i6T_F0u2a>3#8@_9D=)W0}2{Mjc6&M zK!8zX1SGK>I~HNzm|3sQXQb?`=grQ(eKTpDo*XTQgAIaBlZ<^g@M?R(n(>?4M^Z_e z(@Q+%gF(k-FNNeF2lZm-VUK(zAUuk}0LY#LjYTl{)@Xls3EWX_PFob8CcPJW^foJ> z1ss^22V7z4_gzY}f;wJ}5Ela0G~~j@aYhO^ASsFyljpl-p?O}Ay+;DR5g%-?X+~+O z0V)FMt$L=2w{<|%hfDq*?j6(J^_jt(0$UD7MEIj&KL_HgmYBtntzMz$?&2P7b`cFhKgKn&WOdf*x30<)ACl^Al zCY}fi(2QP1pR^`HZ8FO){S*{K$OSNx!UR<@-mtNrPCJg4gSPxXkn;uE3fz)-q~Q+$ Q0000Px$yh%hsR5%fRQ_D`mP!OG#@{or>A%+AaiORyg8(rwa81`=b3_rq;GI8n3g&Sj7 zXwU=$2_mLITd?I(d!|k;ES#iw=FT}YcV_Oba(#8~9qeuq#IzmOxlD4!7Hr-B(Cm%*|D|=2CZD2?s>rDn##1PV<*(4cO z&=zoDQ66v&OQ{r;9!5rt|FCw~CJiSDDP3!Xp@l*|v|$W~Bl>*0rQ^d*dVCo%hKg2Z zU|BY0vl#{vurB7rC1dQ8Jys~Q$(>WsxX*NddqmcJaOjK={i)Y#2L?~;-p-j)xBCZC>vg>1U8al4-FAa_N}%_TJ+jL zYW8(1={ii>(cZ#f>?IJk2w$UYFdW198(u=43B)>=4z61U$TP6MXEgPDgUE0sN#mqU z=o=pdS126BUM5@VdA?P`)8i^Y!lvI6;>1s;*b z3=DjSL74G){)!Z!pk#?_L`iUdT1k0gQ7S`0VrE{6US4X6f{C7io{`~4h0LiyMGHM$ z978PplQYhh#~K?-bv)bN${=XOe8^2~rN`!UhDVxP>l|1FkGd2@DsY;}E@X^k5@)(8 zkg}e~<>9$i4lIexft$9A#mG20NjMa;Dd=?@Yjj*`RwoQ!{ybecA zt}zq|2?(!ee3CiIWWrPSNzI}+J%0!WNS@#qP#3(y9N4_5QG(^G$%Rk{p{9m32Ek1n f6L>`$i{4IUto+Kbnt5LY$gvEbu6{1-oD!M<3F2Ar literal 0 HcmV?d00001 diff --git a/mods/creative/textures/crafting_table_top.png b/mods/creative/textures/crafting_table_top.png new file mode 100644 index 0000000000000000000000000000000000000000..6f54987be052ab0363cd9bc2e597c2539067baf5 GIT binary patch literal 321 zcmV-H0lxl;P)Px#`AI}UR5%fplRXN;KoCY_2#SPs78c&X*52EA1`lcL4J<6|LJ)1#xA?*kHcAGv z^Y_g+v$JG&JnUb^SL)@w=%0tT#7;c!nRl0-6Xi_zBfJ1`*gn2yER6$gJ6f~`1B)aJk$e*-GuwSf%L Tp?LrR002ovPDHLkV1fVu4=jZL literal 0 HcmV?d00001 diff --git a/mods/creative/textures/creative_clear_icon.png b/mods/creative/textures/creative_clear_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9244264adcf8a710ff13a2d684f148f997f1522f GIT binary patch literal 708 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVCwdCaSW-r_4ck|p0J|`+k@?8 z)4T38Ghetp_qK?~6E??3JeK}D7|j>(if@>5FNQ(xtQ%9xq#I|>oJ-rk-tWo9fB*MH zp5A261T+u{c%448b?emavpj!@3x2dSE|*=GYrgL7A+xn2b!l~{&a|J|bNs}_tEEWpk`5!2*`a}1RyVnJUKYCsTDmAJZ691N{Rw#iPDykKZKfD4SDBXYZavSfp zt(M8LUICfU&F8YHzp0s=(DY%oUz2h9J|Q20x{sb8K$MJ(p@+4@qz<4 z!kg0dK3Eysi%9);Rd;NiTfc_o`reublauX^hYkL8bi5ZVT=BywU-{9yDV`H%&hFSD z{eSy3XBU}c*&BW+C(O>xi5IGCE-m?*7^bhf!nSDs-Ve5G964XH7nBIy_{nX@*CKED zC9J9A$E62L@3|g1-|-{rXX!rIBX13O=8G=aFLdP6;d1{6XTq5t?lu(JC&Y2TP@!hB z!wW0ribzTW? zv>WHHXDQnUw9_l$Ihb?k|95ulYSoBmH}=bWKa)PledlLA%OVzTzIe`-^(=?Nn=}vK z|5|oXdfI~7>hssAan;KT<|{qg^yu`QKY#yx%+Ejmf9+EvCB5Qf=OwiwTl#JLZgovQ z!0-C6bfNb@zk-X!W`9H8=%_c!chCE&^5PxeZU@em`wuKW9OwuSX$khe@MP~-NmYTm zX3qx;1G)7Yj~~+PMrdBTn&4iAk_ zCzVg(Na=19?+|cZ@IbL5e8K}(p%j$~LCzBsW`=l_98+=LxOqcU#KxZ4bF1w%xt0{a z`}n5x5A!4yPfR4$8*;e!gynrkwWs^THJ8fwm6_+NZhvfNz`X2$*7H3+nrmg>zn$fk zcU;DTEsp7Yqx;j4fC<766bo4PXc+pOTKe$LWCb^d;0JOacKq4RS~rcuZuyjTGNpGJ zdGs?sCo&vRd%owBN{66>{6Xdinj19ZyXSmv6+FVRpg$o@?6BAl?l~2f9l{R##m}7n zuvdnKCqd%iW=9Tg|0WBd0qnUq*`xfMA{hVF3Oz`Y&}R^LW-c%^fl>ZU%pX(?803|t z4oqwB*k7+NsASMk@89(JA%AxN0fuev7cTA1*!Id^O!B}t4yQjGPcSs;x3LM-7@9OZ z=w8Uk63@e{@FOXM;ULghj(rkR4j+zQ04pijarA>!#Pd1(`(A$LlzLtR)BDcFwBi3|wtWop4gCi;u{`7xI8ZA2L-PYy1jFf#wRRI3-_)Pq&*Imx z{ps&h?Ts7z{(f(M7~k`?l9BmF{*UDcW^d%bulm8@@b{Ao7I4RluIDspxZ8IB{^$7q z%7?}cf4Be5TKAJ}!~JbQq4U|*l{*+&ZhqrE(0ZO>k$w%({XjJjxaR}i|AR;2$Dwqf z`|W`4{~+n`0jQ)&zs5XMrtS@Ycb-gLPVZrJhW300zWWR^`xq^1m zyWUxR_7M!z4@iFKeHXjyz0AM7AYOB&=QfLf7qn^Ky}aAIU0%C^v)*oIvhlX<8Qz#F e2P9I`9q-0Hd(Hm59fiOI%i!ti=d#Wzp$P!RnKjM; literal 0 HcmV?d00001 diff --git a/mods/creative/textures/creative_prev_icon.png b/mods/creative/textures/creative_prev_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b26cd157f95aec853fce734574e5d319686b8399 GIT binary patch literal 728 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrV4Cmg;uunK>+N0tY+*-+wvXwz zGV{>pV?eWW(PFe13zpU}_uI~@{8;u``%wXt0z|TCv@W=53 ztRMJxFuiNkXH!Uj7SHg$kzbdg{D8B3-}@7a_p+b$H~Jso*ufG9bg|50?E~*-*6%X= zp{oh6V%o%>4{WH7l z+KFfIj_uWexoBz8%lvY1e!z>W-gU6xbp)te5*7FQ4;`@FuSbT0~ zesG4L&*4{?z7>OZv;DH)_5U<-S8qQZ_~60(<+)##!W(qOD`oz)FjP!bw_p(4_kbbd zN0ax0R{aXr4Ifz94;&JgVc?E0V9=>KsCwa$_#P&pH1mab=j|8n_P%~ddT!%xg0c8qq1w4R9hWi^tX~{&$kePP23tw zeX`cxZ>W6Da{BQG9yOK(U6%RbeTUyBcriqA%*$HKuiaYEC*D%Tv|*dj8Y31>#v1}n zJC7RZFi3YLX3l4f(>TR(pe@NFWB$b5%@Y{bh#r3WZow{V4z7mX%*+XfCJbWEc&QD$ zCG=cd75-&De5v@MmhqvY0RuYzFUG_yAk(D%K>V)u6JCc14zZH;J^%Usm@rf-MqJoy zR_9bc``1JH*@t)U|JE_;r*hEgWpDPBKS7mN|uQ4@RU{bU;RZBGG9cM4QZ&YGw2;badcT z8^0=@n`5_k4cg)jkHrR_ZUs6C)#;ru{p*MnFzSSy14BnK9k99qvx%(Q|Ku6*tVeE= z;j}fOm}70k#m=-1{B|WKep=e`sqE6mH$a&vhfe)BT5{~=GqH7W4FDtAPF6XfUJMg0 zG)SRiFgWX|#Hdo<6h%bjftQL_(g^a6TBkuGS!%-M3?v2!!-LD$RV3F+$;z#Y3Lq&# z_lXLz)euUtSfqnLL7jl2b-JcIw!dO0JQC!^>f882mU~^SkXzr`0xD$%3+f2q+OnxW z1#r9If&|iNnfe3`b*4|E043HiVCS~J?2$Nf98bhA$TsSxMtQ>bU0iB`d;--0U8=Ry zJ$(nF6is0}714=%paq!4^8&7*G-=qVnCc)Uq1GXZTEy1xasEqQke2{%ythu6(G*D6 zDF?-+D!Ue41yd=tX`8nuzFuMdv3v8p=sx4(#)k(VUp+7uXc=E9WXOjk_@2pQs9(A3 z%Fe+(gW#yEwq~Ezh<5oM;;RAsmL}jVtqyDg;3RO6+(ZS+wa!eGy%Xv)cY8sdSn&;K z=Ps^SBI2ddjn|*vyW-*bv2?_ZIuz7pOr~qbsWd5m^(%dw z+V538xQ3H(-4_xppDzC3sA8pkh`&sY6Nru)^Z(SD+qXv7TA(SYSIuP68ayyP+H0?< zaowVMuFU-jk-0cLhl6vgDyMeXaRacK-*^{WOw9U|9&j|Vd<#9+JeGf*Iy5>ye)R3f z!qwGPGPOQQ{6H;&(Wc;AI2huTl){mQQt=*;F&g!IJS<08ZLf>0u+ENg7s343c&1m7mb$YSA$oW=Ou(;WVMAGQ+9 zU{v(RH~IzT(6ZnE)c?h#57hs2bs8di1zc28QeyD_;W>7ZU(8N^yT}Ash708loHCa&7K!Wixy30l1~_H zt%s71ttI{vsu(~*IL^WdO-8p|;mo$+Ut=}jyoU52j>@^LpIy;y;Aknl_Rb!tje;t0 z4`ZQ&Pd~ODxH|QAh4G_8Ov>8b6FKrNMcniQ{aQW-sL+^9m+j?+iW)Y8u-@$4+ZyKqr5_OPwunRDLxq8ZX8<(~$=F88q9F&sb0`#Qm~!Ma?^gL*o;c9xJrXIg(l#>Bs<*5P z_Oorurv`1CY#wa(+`Gd3dpUO9?{|2zxdX|~OX;BN^lt;g?q=M*AyZzwcOF=an-aR$ zWvqD9Pja5@lpfUFh3giFZ@YlBpa8ns&|&HPv69cekehvTx1-3K!uJ{pthx&pQMU_X zz_OYBuTku;iCT@2eL`2sndtrXyaIV!7w1Pc;qV4`&`*DVI@)O3>nZp58l2 zh86Z3I>$`!bGRg_`o{BU|3AaXW{t-BrPl3lJI0##E>?4JbBElN!tO>W;jyUC9TP&C zcdY$f=J{hbR^H#JQa?PKHouPy0s)EE-W+MDc;Xz%zs`T$`R%Yt?QXQVAN^tty#4`5(6Lbv2~siR@4 z@`h)pegmd;G66wTd;1v6$`5#mabMDZA>){oRw~(J+i2oaY0;7FQaR<-xTRoy>!JU5 oz)Hy+PJ7*y{67!tO!d0_mw-1lpr~N2?{5lnuywWJ5y{E_0lF-AYXATM literal 0 HcmV?d00001 diff --git a/mods/creative/textures/creative_trash_icon.png b/mods/creative/textures/creative_trash_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7d7a0a62f36472ffcc08cd07422d1c5e17e45e3b GIT binary patch literal 712 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVCwgDaSW-r_4e+?-dhe5trxww zq*naqXuWX$%VVcGb_I&R1tv_`WU!j2d1GzgmQ#n_%r@D(8r!SMY)V`@C3wbkp`zrO9YquH$qXGj<1H+Alhfi&G|FJ(}SLs?`@OU z=Ko=Q^1aIOQ@pdR=KhzuvG=pT`FdxDxp@Z+zq8vWPg;3>!84VT2}&@z?=%LBL9Hq~$8|9AiV@%4Xy%;s14dR}%* zon77A&m;qutR!##$3==^`3{2oa1xFUptOVYBf1?jSv-y|x zQ#1GeuC3o5=i4=WKHIvdyz#uX-M?+jJ8Bj`d-DSr7ho$7bd@n~t^F`3MPuolJ6-v_ z)3Z&!%~Jltw_qE;+@zXk@59#=*ZUcKouw=zcJKN8Nip?5uFpu(S=s~FpY@DkZE@4y u*Z=k$xWstn8Ot*UZhL(O28IL6Y8X5J> 1 then + return "tabheader[0,0;sfinv_nav_tabs;" .. table.concat(nav, ",") .. + ";" .. current_idx .. ";true;false]" + else + return "" + end +end + +local theme_inv = [[ + list[current_player;main;0,4.7;8,1;] + list[current_player;main;0,5.85;8,3;8] + ]] + +function sfinv.make_formspec(player, context, content, show_inv, size) + local tmp = { + size or "size[13,8]", + sfinv.get_nav_fs(player, context, context.nav_titles, context.nav_idx), + content + } + if show_inv then + tmp[#tmp + 1] = theme_inv + end + return table.concat(tmp, "") +end + +function sfinv.get_homepage_name(player) + return "sfinv:crafting" +end + +function sfinv.get_formspec(player, context) + -- Generate navigation tabs + local nav = {} + local nav_ids = {} + local current_idx = 1 + for i, pdef in pairs(sfinv.pages_unordered) do + if not pdef.is_in_nav or pdef:is_in_nav(player, context) then + nav[#nav + 1] = pdef.title + nav_ids[#nav_ids + 1] = pdef.name + if pdef.name == context.page then + current_idx = #nav_ids + end + end + end + context.nav = nav_ids + context.nav_titles = nav + context.nav_idx = current_idx + + -- Generate formspec + local page = sfinv.pages[context.page] or sfinv.pages["404"] + if page then + return page:get(player, context) + else + local old_page = context.page + local home_page = sfinv.get_homepage_name(player) + + if old_page == home_page then + minetest.log("error", "[sfinv] Couldn't find " .. dump(old_page) .. + ", which is also the old page") + + return "" + end + + context.page = home_page + assert(sfinv.pages[context.page], "[sfinv] Invalid homepage") + minetest.log("warning", "[sfinv] Couldn't find " .. dump(old_page) .. + " so switching to homepage") + + return sfinv.get_formspec(player, context) + end +end + +function sfinv.get_or_create_context(player) + local name = player:get_player_name() + local context = sfinv.contexts[name] + if not context then + context = { + page = sfinv.get_homepage_name(player) + } + sfinv.contexts[name] = context + end + return context +end + +function sfinv.set_context(player, context) + sfinv.contexts[player:get_player_name()] = context +end + +function sfinv.set_player_inventory_formspec(player, context) + local fs = sfinv.get_formspec(player, + context or sfinv.get_or_create_context(player)) + player:set_inventory_formspec(fs) +end + +function sfinv.set_page(player, pagename) + local context = sfinv.get_or_create_context(player) + local oldpage = sfinv.pages[context.page] + if oldpage and oldpage.on_leave then + oldpage:on_leave(player, context) + end + context.page = pagename + local page = sfinv.pages[pagename] + if page.on_enter then + page:on_enter(player, context) + end + sfinv.set_player_inventory_formspec(player, context) +end + +function sfinv.get_page(player) + local context = sfinv.contexts[player:get_player_name()] + return context and context.page or sfinv.get_homepage_name(player) +end + +minetest.register_on_joinplayer(function(player) + if sfinv.enabled then + sfinv.set_player_inventory_formspec(player) + end +end) + +minetest.register_on_leaveplayer(function(player) + sfinv.contexts[player:get_player_name()] = nil +end) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "" or not sfinv.enabled then + return false + end + + -- Get Context + local name = player:get_player_name() + local context = sfinv.contexts[name] + if not context then + sfinv.set_player_inventory_formspec(player) + return false + end + + -- Was a tab selected? + if fields.sfinv_nav_tabs and context.nav then + local tid = tonumber(fields.sfinv_nav_tabs) + if tid and tid > 0 then + local id = context.nav[tid] + local page = sfinv.pages[id] + if id and page then + sfinv.set_page(player, id) + end + end + else + -- Pass event to page + local page = sfinv.pages[context.page] + if page and page.on_player_receive_fields then + return page:on_player_receive_fields(player, context, fields) + end + end +end) diff --git a/mods/sfinv/init.lua b/mods/sfinv/init.lua new file mode 100644 index 0000000..1d12c6b --- /dev/null +++ b/mods/sfinv/init.lua @@ -0,0 +1,22 @@ +dofile(minetest.get_modpath("sfinv") .. "/api.lua") + +sfinv.register_page("sfinv:crafting", { + title = "Crafting", + get = function(self, player, context) + return sfinv.make_formspec(player, context, [[ + list[current_player;craft;1.75,0.5;3,3;] + list[current_player;craftpreview;5.75,1.5;1,1;] + image[4.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270] + listring[current_player;main] + listring[current_player;craft] + image[0,4.7;1,1;gui_hb_bg.png] + image[1,4.7;1,1;gui_hb_bg.png] + image[2,4.7;1,1;gui_hb_bg.png] + image[3,4.7;1,1;gui_hb_bg.png] + image[4,4.7;1,1;gui_hb_bg.png] + image[5,4.7;1,1;gui_hb_bg.png] + image[6,4.7;1,1;gui_hb_bg.png] + image[7,4.7;1,1;gui_hb_bg.png] + ]], true) + end +}) \ No newline at end of file diff --git a/mods/sfinv/license.txt b/mods/sfinv/license.txt new file mode 100644 index 0000000..e27dc85 --- /dev/null +++ b/mods/sfinv/license.txt @@ -0,0 +1,24 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2016-2018 rubenwardy + +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. + +For more details: +https://opensource.org/licenses/MIT diff --git a/mods/ws_core/README.txt b/mods/ws_core/README.txt new file mode 100644 index 0000000..1c5e9e3 --- /dev/null +++ b/mods/ws_core/README.txt @@ -0,0 +1,301 @@ +Minetest Game mod: default +========================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by celeron55, Perttu Ahola (LGPL 2.1) +Various Minetest developers and contributors (LGPL 2.1) + +Authors of media (textures, models and sounds) +---------------------------------------------- +Everything not listed in here: +celeron55, Perttu Ahola (CC BY-SA 3.0) + +Cisoun's texture pack (CC BY-SA 3.0): + default_jungletree.png + default_lava.png + default_leaves.png + default_sapling.png + default_bush_sapling.png + default_stone.png + default_tree.png + default_tree_top.png + default_water.png + +Originating from G4JC's Almost MC Texture Pack (CC BY-SA 3.0): + default_torch.png + default_torch_on_ceiling.png + default_torch_on_floor.png + +VanessaE's animated torches (CC BY-SA 3.0): + default_torch_animated.png + default_torch_on_ceiling_animated.png + default_torch_on_floor_animated.png + default_torch_on_floor.png + +RealBadAngel's animated water (CC BY-SA 3.0): + default_water_source_animated.png + default_water_flowing_animated.png + +VanessaE (CC BY-SA 3.0): + default_desert_sand.png + default_desert_stone.png + default_sand.png + default_mese_crystal.png + default_mese_crystal_fragment.png + +Calinou (CC BY-SA 3.0): + default_brick.png + default_papyrus.png + default_mineral_copper.png + default_glass_detail.png + +PilzAdam (CC BY-SA 3.0): + default_jungleleaves.png + default_junglesapling.png + default_obsidian_glass.png + default_obsidian_shard.png + default_mineral_gold.png + +jojoa1997 (CC BY-SA 3.0): + default_obsidian.png + +InfinityProject (CC BY-SA 3.0): + default_mineral_diamond.png + +Splizard (CC BY-SA 3.0): + default_pine_sapling.png + default_pine_needles.png + +Zeg9 (CC BY-SA 3.0): + default_coal_block.png + +paramat (CC BY-SA 3.0): + wieldhand.png -- Copied from character.png by Jordach (CC BY-SA 3.0) + default_pinetree.png + default_pinetree_top.png + default_pinewood.png + default_acacia_leaves.png + default_acacia_leaves_simple.png + default_acacia_sapling.png + default_acacia_bush_sapling.png + default_acacia_tree.png + default_acacia_tree_top.png + default_acacia_wood.png + default_acacia_bush_stem.png + default_bush_stem.png + default_junglewood.png + default_jungletree_top.png + default_sandstone_brick.png + default_obsidian_brick.png + default_stone_brick.png + default_desert_stone_brick.png + default_sandstone_block.png + default_obsidian_block.png + default_stone_block.png + default_desert_stone_block.png + default_river_water.png + default_river_water_source_animated.png + default_river_water_flowing_animated.png + default_dry_grass.png + default_dry_grass_side.png + default_dry_grass_*.png + default_grass.png + default_grass_side.png + default_mese_block.png + default_silver_sand.png + default_mese_post_light_side.png + default_mese_post_light_side_dark.png + default_mese_post_light_top.png + default_silver_sandstone.png -- Derived from a texture by GreenXenith (CC-BY-SA 3.0) + default_silver_sandstone_brick.png -- Derived from a texture by GreenXenith (CC-BY-SA 3.0) + default_silver_sandstone_block.png -- Derived from a texture by GreenXenith (CC-BY-SA 3.0) + default_bookshelf_slot.png -- Derived from a texture by Gambit (CC-BY-SA 3.0) + default_marram_grass_*.png -- Derived from textures by TumeniNodes (CC-BY-SA 3.0) + default_emergent_jungle_sapling.png + +TumeniNodes (CC BY-SA 3.0): + default_desert_cobble.png -- Derived from a texture by brunob.santos (CC BY-SA 3.0) + default_coniferous_litter.png + default_coniferous_litter_side.png + +BlockMen (CC BY-SA 3.0): + default_aspen_leaves.png -- Derived from Sofar's texture + default_wood.png + default_clay_brick.png + default_iron_ingot.png + default_gold_ingot.png + default_tool_steelsword.png + default_diamond.png + default_tool_*.png + default_lava_source_animated.png + default_lava_flowing_animated.png + default_stick.png + default_chest_front.png + default_chest_lock.png + default_chest_side.png + default_chest_top.png + default_mineral_mese.png + default_meselamp.png + bubble.png + gui_*.png + +sofar (CC BY-SA 3.0): + default_aspen_sapling + default_aspen_tree + default_aspen_tree_top, derived from default_pine_tree_top (by paramat) + default_aspen_wood, derived from default_pine_wood (by paramat) + default_chest_inside + +sofar (CC0 1.0): + default_gravel.png -- Derived from Gambit's PixelBOX texture pack light gravel + +Neuromancer (CC BY-SA 3.0): + default_cobble.png, based on texture by Brane praefect + default_mossycobble.png, based on texture by Brane praefect + default_dirt.png + default_furnace_*.png + +Gambit (CC BY-SA 3.0): + default_bronze_ingot.png + default_copper_ingot.png + default_copper_lump.png + default_iron_lump.png + default_gold_lump.png + default_clay_lump.png + default_coal.png + default_grass_*.png + default_paper.png + default_diamond_block.png + default_ladder_steel.png + default_sign_wall_wood.png + default_flint.png + default_snow.png + default_snow_side.png + default_snowball.png + default_key.png + default_key_skeleton.png + default_book.png + +asl97 (CC BY-SA 3.0): + default_ice.png + +KevDoy (CC BY-SA 3.0): + heart.png + +Pithydon (CC BY-SA 3.0) + default_coral_brown.png + default_coral_orange.png + default_coral_skeleton.png + +Ferk (CC0 1.0): + default_item_smoke.png + default_item_smoke.ogg, based on sound by http://opengameart.org/users/bart + +npx (CC BY-SA 3.0): + default_rainforest_litter.png + default_rainforest_litter_side.png + +kaeza (CC-BY-SA 3.0): + default_desert_sandstone.png + default_desert_sandstone_brick.png + default_desert_sandstone_block.png + +kilbith (CC BY-SA 3.0): + default_steel_block.png + default_copper_block.png + default_bronze_block.png + default_gold_block.png + default_tin_block.png + default_mineral_tin.png + default_tin_ingot.png + default_tin_lump.png + +tobyplowy (CC BY-SA 3.0): + default_kelp.png + +CloudyProton (CC BY-SA 3.0): + default_book_written.png, based on default_book.png by Gambit + +Mossmanikin (CC BY-SA 3.0): + default_fern_*.png + +Glass breaking sounds (CC BY 3.0): + 1: http://www.freesound.org/people/cmusounddesign/sounds/71947/ + 2: http://www.freesound.org/people/Tomlija/sounds/97669/ + 3: http://www.freesound.org/people/lsprice/sounds/88808/ + +sonictechtonic (CC BY 3.0): +https://www.freesound.org/people/sonictechtonic/sounds/241872/ + player_damage.ogg + +Mito551 (sounds) (CC BY-SA 3.0): + default_dig_choppy.ogg + default_dig_cracky.ogg + default_dig_crumbly.1.ogg + default_dig_crumbly.2.ogg + default_dig_dig_immediate.ogg + default_dig_oddly_breakable_by_hand.ogg + default_dug_node.1.ogg + default_dug_node.2.ogg + default_grass_footstep.1.ogg + default_grass_footstep.2.ogg + default_grass_footstep.3.ogg + default_gravel_footstep.1.ogg + default_gravel_footstep.2.ogg + default_gravel_footstep.3.ogg + default_gravel_footstep.4.ogg + default_grass_footstep.1.ogg + default_place_node.1.ogg + default_place_node.2.ogg + default_place_node.3.ogg + default_place_node_hard.1.ogg + default_place_node_hard.2.ogg + default_hard_footstep.1.ogg + default_hard_footstep.2.ogg + default_hard_footstep.3.ogg + default_sand_footstep.1.ogg + default_sand_footstep.2.ogg + default_wood_footstep.1.ogg + default_wood_footstep.2.ogg + default_dirt_footstep.1.ogg + default_dirt_footstep.2.ogg + default_glass_footstep.ogg + +Metal sounds: + default_dig_metal.ogg - yadronoff - CC-BY-3.0 + - https://www.freesound.org/people/yadronoff/sounds/320397/ + default_dug_metal.*.ogg - Iwan Gabovitch - qubodup - CC0 + - http://opengameart.org/users/qubodup + default_metal_footstep.*.ogg - Ottomaani138 - CC0 + - https://www.freesound.org/people/Ottomaani138/sounds/232692/ + default_place_node_metal.*.ogg - Ogrebane - CC0 + - http://opengameart.org/content/wood-and-metal-sound-effects-volume-2 + +Tool breaking sounds added by sofar: CC-BY-3.0 + default_tool_breaks.* - http://www.freesound.org/people/HerbertBoland/sounds/33206/ + +AGFX (CC BY 3.0): +https://www.freesound.org/people/AGFX/packs/1253/ + default_water_footstep.1.ogg + default_water_footstep.2.ogg + default_water_footstep.3.ogg +(default_water_footstep.4.ogg is silent) + +blukotek (CC0 1.0): +https://www.freesound.org/people/blukotek/sounds/251660/ + default_dig_snappy.ogg + +Chests sounds added by sofar, derived of several files mixed together: + default_chest_open.ogg + default_chest_close.ogg + - http://www.freesound.org/people/Sevin7/sounds/269722/ CC0 + - http://www.freesound.org/people/Percy%20Duke/sounds/23448/ CC-BY-3.0 + - http://www.freesound.org/people/kingsamas/sounds/135576/ CC-BY-3.0 + - http://www.freesound.org/people/bulbastre/sounds/126887/ CC-BY-3.0 + - http://www.freesound.org/people/Yoyodaman234/sounds/183541/ CC0 + +Ryding (CC0 1.0): +http://freesound.org/people/Ryding/sounds/94337/ + default_snow_footstep.*.ogg diff --git a/mods/ws_core/aliases.lua b/mods/ws_core/aliases.lua new file mode 100644 index 0000000..ca9829a --- /dev/null +++ b/mods/ws_core/aliases.lua @@ -0,0 +1,74 @@ +-- mods/ws_core/aliases.lua + +-- Aliases to support loading worlds using nodes following the old naming convention +-- These can also be helpful when using chat commands, for example /giveme +minetest.register_alias("stone", "ws_core:stone") +minetest.register_alias("stone_with_coal", "ws_core:stone_with_coal") +minetest.register_alias("stone_with_iron", "ws_core:stone_with_iron") +minetest.register_alias("dirt_with_grass", "ws_core:dirt_dry") +minetest.register_alias("dirt_with_grass_footsteps", "ws_core:dirt_dry") +minetest.register_alias("dirt", "ws_core:dirt_dry") +minetest.register_alias("sand", "ws_core:sandy_dirt") +minetest.register_alias("gravel", "ws_core:dirt_dry") +minetest.register_alias("sandstone", "ws_core:sandstone") +minetest.register_alias("clay", "ws_core:clay") +minetest.register_alias("brick", "ws_core:brick") +minetest.register_alias("tree", "ws_core:dead_tree") +minetest.register_alias("leaves", "ws_core:air") +minetest.register_alias("bookshelf", "ws_core:bookshelf") +minetest.register_alias("glass", "ws_core:glass") +minetest.register_alias("wooden_fence", "ws_core:fence_wood") +minetest.register_alias("rail", "carts:rail") +minetest.register_alias("ladder", "ws_core:ladder_wood") +minetest.register_alias("wood", "ws_core:wood") +minetest.register_alias("mese", "ws_core:mese") +minetest.register_alias("cloud", "ws_core:cloud") +minetest.register_alias("water_flowing", "ws_core:water_flowing") +minetest.register_alias("water_source", "ws_core:water_source") +minetest.register_alias("lava_flowing", "ws_core:lava_flowing") +minetest.register_alias("lava_source", "ws_core:lava_source") +minetest.register_alias("torch", "ws_core:torch") +minetest.register_alias("sign_wall", "ws_core:sign_wall_wood") +minetest.register_alias("furnace", "ws_core:furnace") +minetest.register_alias("chest", "ws_core:chest") +minetest.register_alias("locked_chest", "ws_core:chest_locked") +minetest.register_alias("cobble", "ws_core:cobble") +minetest.register_alias("mossycobble", "ws_core:mossycobble") +minetest.register_alias("steelblock", "ws_core:steelblock") +minetest.register_alias("sapling", "ws_core:sapling") +minetest.register_alias("apple", "ws_core:apple") +minetest.register_alias("jungletree", "default:ignore") + +minetest.register_alias("WPick", "ws_core:pick_wood") +minetest.register_alias("STPick", "ws_core:pick_stone") +minetest.register_alias("SteelPick", "ws_core:pick_steel") +minetest.register_alias("MesePick", "ws_core:pick_mese") +minetest.register_alias("WShovel", "ws_core:shovel_wood") +minetest.register_alias("STShovel", "ws_core:shovel_stone") +minetest.register_alias("SteelShovel", "ws_core:shovel_steel") +minetest.register_alias("WAxe", "ws_core:axe_wood") +minetest.register_alias("STAxe", "ws_core:axe_stone") +minetest.register_alias("SteelAxe", "ws_core:axe_steel") +minetest.register_alias("WSword", "ws_core:sword_wood") +minetest.register_alias("STSword", "ws_core:sword_stone") +minetest.register_alias("SteelSword", "ws_core:sword_steel") + +minetest.register_alias("Stick", "ws_core:stick") +minetest.register_alias("paper", "ws_core:paper") +minetest.register_alias("book", "ws_core:book") +minetest.register_alias("lump_of_coal", "ws_core:coal") +minetest.register_alias("lump_of_iron", "ws_core:steel_ingot") +minetest.register_alias("lump_of_clay", "ws_core:clay_lump") +minetest.register_alias("steel_ingot", "ws_core:steel_ingot") +minetest.register_alias("clay_brick", "ws_core:clay_brick") +minetest.register_alias("snow", "ws_core:snow") + +-- 'mese_block' was used for a while for the block form of mese +minetest.register_alias("ws_core:mese_block", "ws_core:mese") + +-- Aliases for corrected pine node names +minetest.register_alias("ws_core:pinetree", "ws_core:dead_tree") +minetest.register_alias("ws_core:pinewood", "ws_core:wood") + +minetest.register_alias("ws_core:ladder", "ws_core:ladder_wood") +minetest.register_alias("ws_core:sign_wall", "ws_core:sign_wall_wood") diff --git a/mods/ws_core/crafting.lua b/mods/ws_core/crafting.lua new file mode 100644 index 0000000..26cb97b --- /dev/null +++ b/mods/ws_core/crafting.lua @@ -0,0 +1,1185 @@ +-- mods/ws_core/crafting.lua + +minetest.register_craft({ + output = 'ws_core:wood 4', + recipe = { + {'ws_core:tree'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:junglewood 4', + recipe = { + {'ws_core:jungletree'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:pine_wood 4', + recipe = { + {'ws_core:pine_tree'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:acacia_wood 4', + recipe = { + {'ws_core:acacia_tree'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:aspen_wood 4', + recipe = { + {'ws_core:aspen_tree'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:wood', + recipe = { + {'ws_core:bush_stem'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:acacia_wood', + recipe = { + {'ws_core:acacia_bush_stem'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:stick 4', + recipe = { + {'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:sign_wall_steel 3', + recipe = { + {'ws_core:steel_ingot', 'ws_core:steel_ingot', 'ws_core:steel_ingot'}, + {'ws_core:steel_ingot', 'ws_core:steel_ingot', 'ws_core:steel_ingot'}, + {'', 'group:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'ws_core:sign_wall_wood 3', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', 'group:wood', 'group:wood'}, + {'', 'group:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'ws_core:torch 4', + recipe = { + {'ws_core:coal_lump'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:pick_wood', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'', 'group:stick', ''}, + {'', 'group:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'ws_core:pick_stone', + recipe = { + {'group:stone', 'group:stone', 'group:stone'}, + {'', 'group:stick', ''}, + {'', 'group:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'ws_core:pick_steel', + recipe = { + {'ws_core:steel_ingot', 'ws_core:steel_ingot', 'ws_core:steel_ingot'}, + {'', 'group:stick', ''}, + {'', 'group:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'ws_core:pick_bronze', + recipe = { + {'ws_core:bronze_ingot', 'ws_core:bronze_ingot', 'ws_core:bronze_ingot'}, + {'', 'group:stick', ''}, + {'', 'group:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'ws_core:pick_mese', + recipe = { + {'ws_core:mese_crystal', 'ws_core:mese_crystal', 'ws_core:mese_crystal'}, + {'', 'group:stick', ''}, + {'', 'group:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'ws_core:pick_diamond', + recipe = { + {'ws_core:diamond', 'ws_core:diamond', 'ws_core:diamond'}, + {'', 'group:stick', ''}, + {'', 'group:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'ws_core:shovel_wood', + recipe = { + {'group:wood'}, + {'group:stick'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:shovel_stone', + recipe = { + {'group:stone'}, + {'group:stick'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:shovel_steel', + recipe = { + {'ws_core:steel_ingot'}, + {'group:stick'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:shovel_bronze', + recipe = { + {'ws_core:bronze_ingot'}, + {'group:stick'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:shovel_mese', + recipe = { + {'ws_core:mese_crystal'}, + {'group:stick'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:shovel_diamond', + recipe = { + {'ws_core:diamond'}, + {'group:stick'}, + {'group:stick'}, + } +}) + +-- Axes +-- Recipes face left to match appearence in textures and inventory + +minetest.register_craft({ + output = 'ws_core:axe_wood', + recipe = { + {'group:wood', 'group:wood'}, + {'group:wood', 'group:stick'}, + {'', 'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:axe_stone', + recipe = { + {'group:stone', 'group:stone'}, + {'group:stone', 'group:stick'}, + {'', 'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:axe_steel', + recipe = { + {'ws_core:steel_ingot', 'ws_core:steel_ingot'}, + {'ws_core:steel_ingot', 'group:stick'}, + {'', 'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:axe_bronze', + recipe = { + {'ws_core:bronze_ingot', 'ws_core:bronze_ingot'}, + {'ws_core:bronze_ingot', 'group:stick'}, + {'', 'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:axe_mese', + recipe = { + {'ws_core:mese_crystal', 'ws_core:mese_crystal'}, + {'ws_core:mese_crystal', 'group:stick'}, + {'', 'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:axe_diamond', + recipe = { + {'ws_core:diamond', 'ws_core:diamond'}, + {'ws_core:diamond', 'group:stick'}, + {'', 'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:sword_wood', + recipe = { + {'group:wood'}, + {'group:wood'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:sword_stone', + recipe = { + {'group:stone'}, + {'group:stone'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:sword_steel', + recipe = { + {'ws_core:steel_ingot'}, + {'ws_core:steel_ingot'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:sword_bronze', + recipe = { + {'ws_core:bronze_ingot'}, + {'ws_core:bronze_ingot'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:sword_mese', + recipe = { + {'ws_core:mese_crystal'}, + {'ws_core:mese_crystal'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:sword_diamond', + recipe = { + {'ws_core:diamond'}, + {'ws_core:diamond'}, + {'group:stick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:skeleton_key', + recipe = { + {'ws_core:gold_ingot'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:chest', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', '', 'group:wood'}, + {'group:wood', 'group:wood', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:chest_locked', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', 'ws_core:steel_ingot', 'group:wood'}, + {'group:wood', 'group:wood', 'group:wood'}, + } +}) + +minetest.register_craft( { + type = "shapeless", + output = "ws_core:chest_locked", + recipe = {"ws_core:chest", "ws_core:steel_ingot"}, +}) + +minetest.register_craft({ + output = 'ws_core:furnace', + recipe = { + {'group:stone', 'group:stone', 'group:stone'}, + {'group:stone', '', 'group:stone'}, + {'group:stone', 'group:stone', 'group:stone'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:coalblock', + recipe = { + {'ws_core:coal_lump', 'ws_core:coal_lump', 'ws_core:coal_lump'}, + {'ws_core:coal_lump', 'ws_core:coal_lump', 'ws_core:coal_lump'}, + {'ws_core:coal_lump', 'ws_core:coal_lump', 'ws_core:coal_lump'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:coal_lump 9', + recipe = { + {'ws_core:coalblock'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:steelblock', + recipe = { + {'ws_core:steel_ingot', 'ws_core:steel_ingot', 'ws_core:steel_ingot'}, + {'ws_core:steel_ingot', 'ws_core:steel_ingot', 'ws_core:steel_ingot'}, + {'ws_core:steel_ingot', 'ws_core:steel_ingot', 'ws_core:steel_ingot'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:steel_ingot 9', + recipe = { + {'ws_core:steelblock'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:copperblock', + recipe = { + {'ws_core:copper_ingot', 'ws_core:copper_ingot', 'ws_core:copper_ingot'}, + {'ws_core:copper_ingot', 'ws_core:copper_ingot', 'ws_core:copper_ingot'}, + {'ws_core:copper_ingot', 'ws_core:copper_ingot', 'ws_core:copper_ingot'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:copper_ingot 9', + recipe = { + {'ws_core:copperblock'}, + } +}) + +minetest.register_craft({ + output = "ws_core:tinblock", + recipe = { + {"ws_core:tin_ingot", "ws_core:tin_ingot", "ws_core:tin_ingot"}, + {"ws_core:tin_ingot", "ws_core:tin_ingot", "ws_core:tin_ingot"}, + {"ws_core:tin_ingot", "ws_core:tin_ingot", "ws_core:tin_ingot"}, + } +}) + +minetest.register_craft({ + output = "ws_core:tin_ingot 9", + recipe = { + {"ws_core:tinblock"}, + } +}) + +minetest.register_craft({ + output = "ws_core:bronze_ingot 9", + recipe = { + {"ws_core:copper_ingot", "ws_core:copper_ingot", "ws_core:copper_ingot"}, + {"ws_core:copper_ingot", "ws_core:tin_ingot", "ws_core:copper_ingot"}, + {"ws_core:copper_ingot", "ws_core:copper_ingot", "ws_core:copper_ingot"}, + } +}) + +minetest.register_craft({ + output = 'ws_core:bronzeblock', + recipe = { + {'ws_core:bronze_ingot', 'ws_core:bronze_ingot', 'ws_core:bronze_ingot'}, + {'ws_core:bronze_ingot', 'ws_core:bronze_ingot', 'ws_core:bronze_ingot'}, + {'ws_core:bronze_ingot', 'ws_core:bronze_ingot', 'ws_core:bronze_ingot'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:bronze_ingot 9', + recipe = { + {'ws_core:bronzeblock'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:goldblock', + recipe = { + {'ws_core:gold_ingot', 'ws_core:gold_ingot', 'ws_core:gold_ingot'}, + {'ws_core:gold_ingot', 'ws_core:gold_ingot', 'ws_core:gold_ingot'}, + {'ws_core:gold_ingot', 'ws_core:gold_ingot', 'ws_core:gold_ingot'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:gold_ingot 9', + recipe = { + {'ws_core:goldblock'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:diamondblock', + recipe = { + {'ws_core:diamond', 'ws_core:diamond', 'ws_core:diamond'}, + {'ws_core:diamond', 'ws_core:diamond', 'ws_core:diamond'}, + {'ws_core:diamond', 'ws_core:diamond', 'ws_core:diamond'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:diamond 9', + recipe = { + {'ws_core:diamondblock'}, + } +}) + +minetest.register_craft({ + output = "ws_core:sandstone", + recipe = { + {"ws_core:sand", "ws_core:sand"}, + {"ws_core:sand", "ws_core:sand"}, + } +}) + +minetest.register_craft({ + output = "ws_core:sand 4", + recipe = { + {"ws_core:sandstone"}, + } +}) + +minetest.register_craft({ + output = "ws_core:sandstonebrick 4", + recipe = { + {"ws_core:sandstone", "ws_core:sandstone"}, + {"ws_core:sandstone", "ws_core:sandstone"}, + } +}) + +minetest.register_craft({ + output = "ws_core:sandstone_block 9", + recipe = { + {"ws_core:sandstone", "ws_core:sandstone", "ws_core:sandstone"}, + {"ws_core:sandstone", "ws_core:sandstone", "ws_core:sandstone"}, + {"ws_core:sandstone", "ws_core:sandstone", "ws_core:sandstone"}, + } +}) + +minetest.register_craft({ + output = "ws_core:desert_sandstone", + recipe = { + {"ws_core:desert_sand", "ws_core:desert_sand"}, + {"ws_core:desert_sand", "ws_core:desert_sand"}, + } +}) + +minetest.register_craft({ + output = "ws_core:desert_sand 4", + recipe = { + {"ws_core:desert_sandstone"}, + } +}) + +minetest.register_craft({ + output = "ws_core:desert_sandstone_brick 4", + recipe = { + {"ws_core:desert_sandstone", "ws_core:desert_sandstone"}, + {"ws_core:desert_sandstone", "ws_core:desert_sandstone"}, + } +}) + +minetest.register_craft({ + output = "ws_core:desert_sandstone_block 9", + recipe = { + {"ws_core:desert_sandstone", "ws_core:desert_sandstone", "ws_core:desert_sandstone"}, + {"ws_core:desert_sandstone", "ws_core:desert_sandstone", "ws_core:desert_sandstone"}, + {"ws_core:desert_sandstone", "ws_core:desert_sandstone", "ws_core:desert_sandstone"}, + } +}) + +minetest.register_craft({ + output = "ws_core:silver_sandstone", + recipe = { + {"ws_core:silver_sand", "ws_core:silver_sand"}, + {"ws_core:silver_sand", "ws_core:silver_sand"}, + } +}) + +minetest.register_craft({ + output = "ws_core:silver_sand 4", + recipe = { + {"ws_core:silver_sandstone"}, + } +}) + +minetest.register_craft({ + output = "ws_core:silver_sandstone_brick 4", + recipe = { + {"ws_core:silver_sandstone", "ws_core:silver_sandstone"}, + {"ws_core:silver_sandstone", "ws_core:silver_sandstone"}, + } +}) + +minetest.register_craft({ + output = "ws_core:silver_sandstone_block 9", + recipe = { + {"ws_core:silver_sandstone", "ws_core:silver_sandstone", "ws_core:silver_sandstone"}, + {"ws_core:silver_sandstone", "ws_core:silver_sandstone", "ws_core:silver_sandstone"}, + {"ws_core:silver_sandstone", "ws_core:silver_sandstone", "ws_core:silver_sandstone"}, + } +}) + +minetest.register_craft({ + output = 'ws_core:clay', + recipe = { + {'ws_core:clay_lump', 'ws_core:clay_lump'}, + {'ws_core:clay_lump', 'ws_core:clay_lump'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:clay_lump 4', + recipe = { + {'ws_core:clay'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:brick', + recipe = { + {'ws_core:clay_brick', 'ws_core:clay_brick'}, + {'ws_core:clay_brick', 'ws_core:clay_brick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:clay_brick 4', + recipe = { + {'ws_core:brick'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:paper', + recipe = { + {'ws_core:papyrus', 'ws_core:papyrus', 'ws_core:papyrus'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:book', + recipe = { + {'ws_core:paper'}, + {'ws_core:paper'}, + {'ws_core:paper'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:bookshelf', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'ws_core:book', 'ws_core:book', 'ws_core:book'}, + {'group:wood', 'group:wood', 'group:wood'}, + } +}) + +minetest.register_craft({ + output = "ws_core:ladder_wood 5", + recipe = { + {"group:stick", "", "group:stick"}, + {"group:stick", "group:stick", "group:stick"}, + {"group:stick", "", "group:stick"}, + } +}) + +minetest.register_craft({ + output = 'ws_core:ladder_steel 15', + recipe = { + {'ws_core:steel_ingot', '', 'ws_core:steel_ingot'}, + {'ws_core:steel_ingot', 'ws_core:steel_ingot', 'ws_core:steel_ingot'}, + {'ws_core:steel_ingot', '', 'ws_core:steel_ingot'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:mese', + recipe = { + {'ws_core:mese_crystal', 'ws_core:mese_crystal', 'ws_core:mese_crystal'}, + {'ws_core:mese_crystal', 'ws_core:mese_crystal', 'ws_core:mese_crystal'}, + {'ws_core:mese_crystal', 'ws_core:mese_crystal', 'ws_core:mese_crystal'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:mese_crystal 9', + recipe = { + {'ws_core:mese'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:mese_crystal_fragment 9', + recipe = { + {'ws_core:mese_crystal'}, + } +}) + +minetest.register_craft({ + output = "ws_core:mese_crystal", + recipe = { + {"ws_core:mese_crystal_fragment", "ws_core:mese_crystal_fragment", "ws_core:mese_crystal_fragment"}, + {"ws_core:mese_crystal_fragment", "ws_core:mese_crystal_fragment", "ws_core:mese_crystal_fragment"}, + {"ws_core:mese_crystal_fragment", "ws_core:mese_crystal_fragment", "ws_core:mese_crystal_fragment"}, + } +}) + +minetest.register_craft({ + output = 'ws_core:meselamp', + recipe = { + {'ws_core:glass'}, + {'ws_core:mese_crystal'}, + } +}) + +minetest.register_craft({ + output = "ws_core:mese_post_light 3", + recipe = { + {"", "ws_core:glass", ""}, + {"ws_core:mese_crystal", "ws_core:mese_crystal", "ws_core:mese_crystal"}, + {"", "group:wood", ""}, + } +}) + +minetest.register_craft({ + output = 'ws_core:obsidian_shard 9', + recipe = { + {'ws_core:obsidian'} + } +}) + +minetest.register_craft({ + output = 'ws_core:obsidian', + recipe = { + {'ws_core:obsidian_shard', 'ws_core:obsidian_shard', 'ws_core:obsidian_shard'}, + {'ws_core:obsidian_shard', 'ws_core:obsidian_shard', 'ws_core:obsidian_shard'}, + {'ws_core:obsidian_shard', 'ws_core:obsidian_shard', 'ws_core:obsidian_shard'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:obsidianbrick 4', + recipe = { + {'ws_core:obsidian', 'ws_core:obsidian'}, + {'ws_core:obsidian', 'ws_core:obsidian'} + } +}) + +minetest.register_craft({ + output = 'ws_core:obsidian_block 9', + recipe = { + {'ws_core:obsidian', 'ws_core:obsidian', 'ws_core:obsidian'}, + {'ws_core:obsidian', 'ws_core:obsidian', 'ws_core:obsidian'}, + {'ws_core:obsidian', 'ws_core:obsidian', 'ws_core:obsidian'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:stonebrick 4', + recipe = { + {'ws_core:stone', 'ws_core:stone'}, + {'ws_core:stone', 'ws_core:stone'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:stone_block 9', + recipe = { + {'ws_core:stone', 'ws_core:stone', 'ws_core:stone'}, + {'ws_core:stone', 'ws_core:stone', 'ws_core:stone'}, + {'ws_core:stone', 'ws_core:stone', 'ws_core:stone'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:desert_stonebrick 4', + recipe = { + {'ws_core:desert_stone', 'ws_core:desert_stone'}, + {'ws_core:desert_stone', 'ws_core:desert_stone'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:desert_stone_block 9', + recipe = { + {'ws_core:desert_stone', 'ws_core:desert_stone', 'ws_core:desert_stone'}, + {'ws_core:desert_stone', 'ws_core:desert_stone', 'ws_core:desert_stone'}, + {'ws_core:desert_stone', 'ws_core:desert_stone', 'ws_core:desert_stone'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:snowblock', + recipe = { + {'ws_core:snow', 'ws_core:snow', 'ws_core:snow'}, + {'ws_core:snow', 'ws_core:snow', 'ws_core:snow'}, + {'ws_core:snow', 'ws_core:snow', 'ws_core:snow'}, + } +}) + +minetest.register_craft({ + output = 'ws_core:snow 9', + recipe = { + {'ws_core:snowblock'}, + } +}) + +minetest.register_craft({ + output = "ws_core:emergent_jungle_sapling", + recipe = { + {"ws_core:junglesapling", "ws_core:junglesapling", "ws_core:junglesapling"}, + {"ws_core:junglesapling", "ws_core:junglesapling", "ws_core:junglesapling"}, + {"ws_core:junglesapling", "ws_core:junglesapling", "ws_core:junglesapling"}, + } +}) + + +-- +-- Crafting (tool repair) +-- + +minetest.register_craft({ + type = "toolrepair", + additional_wear = -0.02, +}) + + +-- +-- Cooking recipes +-- + +minetest.register_craft({ + type = "cooking", + output = "ws_core:glass", + recipe = "group:sand", +}) + +minetest.register_craft({ + type = "cooking", + output = "ws_core:obsidian_glass", + recipe = "ws_core:obsidian_shard", +}) + +minetest.register_craft({ + type = "cooking", + output = "ws_core:stone", + recipe = "ws_core:cobble", +}) + +minetest.register_craft({ + type = "cooking", + output = "ws_core:stone", + recipe = "ws_core:mossycobble", +}) + +minetest.register_craft({ + type = "cooking", + output = "ws_core:desert_stone", + recipe = "ws_core:desert_cobble", +}) + +minetest.register_craft({ + type = "cooking", + output = "ws_core:steel_ingot", + recipe = "ws_core:iron_lump", +}) + +minetest.register_craft({ + type = "cooking", + output = "ws_core:copper_ingot", + recipe = "ws_core:copper_lump", +}) + +minetest.register_craft({ + type = "cooking", + output = "ws_core:tin_ingot", + recipe = "ws_core:tin_lump", +}) + +minetest.register_craft({ + type = "cooking", + output = "ws_core:gold_ingot", + recipe = "ws_core:gold_lump", +}) + +minetest.register_craft({ + type = "cooking", + output = "ws_core:clay_brick", + recipe = "ws_core:clay_lump", +}) + +minetest.register_craft({ + type = 'cooking', + output = 'ws_core:gold_ingot', + recipe = 'ws_core:skeleton_key', + cooktime = 5, +}) + +minetest.register_craft({ + type = 'cooking', + output = 'ws_core:gold_ingot', + recipe = 'ws_core:key', + cooktime = 5, +}) + + +-- +-- Fuels +-- + +-- Support use of group:tree, includes ws_core:tree which has the same burn time +minetest.register_craft({ + type = "fuel", + recipe = "group:tree", + burntime = 30, +}) + +-- Burn time for all woods are in order of wood density, +-- which is also the order of wood colour darkness: +-- aspen, pine, apple, acacia, jungle + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:aspen_tree", + burntime = 22, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:pine_tree", + burntime = 26, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:acacia_tree", + burntime = 34, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:jungletree", + burntime = 38, +}) + + +-- Support use of group:wood, includes ws_core:wood which has the same burn time +minetest.register_craft({ + type = "fuel", + recipe = "group:wood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:aspen_wood", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:pine_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:acacia_wood", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:junglewood", + burntime = 9, +}) + + +-- Support use of group:sapling, includes ws_core:sapling which has the same burn time +minetest.register_craft({ + type = "fuel", + recipe = "group:sapling", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:bush_sapling", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:acacia_bush_sapling", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:aspen_sapling", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:pine_sapling", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:acacia_sapling", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:junglesapling", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:emergent_jungle_sapling", + burntime = 7, +}) + + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:fence_aspen_wood", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:fence_pine_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:fence_wood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:fence_acacia_wood", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:fence_junglewood", + burntime = 9, +}) + + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:bush_stem", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:acacia_bush_stem", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:junglegrass", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "group:leaves", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:cactus", + burntime = 15, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:papyrus", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:bookshelf", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:ladder_wood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:lava_source", + burntime = 60, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:torch", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:sign_wall_wood", + burntime = 10, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:chest", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:chest_locked", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:coal_lump", + burntime = 40, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:coalblock", + burntime = 370, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:grass_1", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:dry_grass_1", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:fern_1", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:marram_grass_1", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:paper", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:book", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:book_written", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:dry_shrub", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "group:stick", + burntime = 1, +}) + + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:pick_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:shovel_wood", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:axe_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "ws_core:sword_wood", + burntime = 5, +}) diff --git a/mods/ws_core/craftitems.lua b/mods/ws_core/craftitems.lua new file mode 100644 index 0000000..0b9a029 --- /dev/null +++ b/mods/ws_core/craftitems.lua @@ -0,0 +1,179 @@ +-- mods/ws_core/craftitems.lua + +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]" .. ws_core.gui_bg .. + ws_core.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]" .. ws_core.gui_bg .. + ws_core.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, "ws_core:book", formspec) + return itemstack +end + +local max_text_size = 10000 +local max_title_size = 80 +local short_title_size = 35 +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "ws_core:book" then return end + local inv = player:get_inventory() + local stack = player:get_wielded_item() + + if fields.save and fields.title and fields.text + and fields.title ~= "" and fields.text ~= "" then + local new_stack, data + if stack:get_name() ~= "ws_core:book_written" then + local count = stack:get_count() + if count == 1 then + stack:set_name("ws_core:book_written") + else + stack:set_count(count - 1) + new_stack = ItemStack("ws_core:book_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:sub(1, max_title_size) + data.owner = player:get_player_name() + local short_title = data.title + -- Don't bother triming the title if the trailing dots would make it longer + if #short_title > short_title_size + 3 then + short_title = short_title:sub(1, short_title_size) .. "..." + end + data.description = "\""..short_title.."\" by "..data.owner + data.text = fields.text:sub(1, max_text_size) + data.text = data.text:gsub("\r\n", "\n"):gsub("\r", "\n") + 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_on_craft(function(itemstack, player, old_craft_grid, craft_inv) + if itemstack:get_name() ~= "ws_core:book_written" then + return + end + + local original + local index + for i = 1, player:get_inventory():get_size("craft") do + if old_craft_grid[i]:get_name() == "ws_core:book_written" then + original = old_craft_grid[i] + index = i + end + end + if not original then + return + end + local copymeta = original:get_meta():to_table() + -- copy of the book held by player's mouse cursor + itemstack:get_meta():from_table(copymeta) + -- put the book with metadata back in the craft grid + craft_inv:set_stack("craft", index, original) +end) + + +minetest.register_craftitem("ws_core:coal", { + description = "Coal", + inventory_image = "ws_coal.png", + groups = {coal = 1, flammable = 1} +}) + +minetest.register_craftitem("ws_core:iron_lump", { + description = "Iron Lump", + inventory_image = "ws_core_iron_lump.png", +}) diff --git a/mods/ws_core/depends.txt b/mods/ws_core/depends.txt new file mode 100644 index 0000000..e1c3818 --- /dev/null +++ b/mods/ws_core/depends.txt @@ -0,0 +1 @@ +player_api? diff --git a/mods/ws_core/functions.lua b/mods/ws_core/functions.lua new file mode 100644 index 0000000..a664034 --- /dev/null +++ b/mods/ws_core/functions.lua @@ -0,0 +1,488 @@ +-- +-- Sounds +-- + +function ws_core.node_sound_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "", gain = 1.0} + table.dug = table.dug or + {name = "ws_core_dug_node", gain = 0.25} + table.place = table.place or + {name = "ws_core_place_node_hard", gain = 1.0} + return table +end + +function ws_core.node_sound_stone_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_hard_footstep", gain = 0.3} + table.dug = table.dug or + {name = "ws_core_hard_footstep", gain = 1.0} + ws_core.node_sound_ws_cores(table) + return table +end + +function ws_core.node_sound_dirt_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_dirt_footstep", gain = 0.4} + table.dug = table.dug or + {name = "ws_core_dirt_footstep", gain = 1.0} + table.place = table.place or + {name = "ws_core_place_node", gain = 1.0} + ws_core.node_sound_ws_cores(table) + return table +end + +function ws_core.node_sound_sand_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_sand_footstep", gain = 0.12} + table.dug = table.dug or + {name = "ws_core_sand_footstep", gain = 0.24} + table.place = table.place or + {name = "ws_core_place_node", gain = 1.0} + ws_core.node_sound_ws_cores(table) + return table +end + +function ws_core.node_sound_gravel_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_gravel_footstep", gain = 0.4} + table.dug = table.dug or + {name = "ws_core_gravel_footstep", gain = 1.0} + table.place = table.place or + {name = "ws_core_place_node", gain = 1.0} + ws_core.node_sound_ws_cores(table) + return table +end + +function ws_core.node_sound_wood_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_wood_footstep", gain = 0.3} + table.dug = table.dug or + {name = "ws_core_wood_footstep", gain = 1.0} + ws_core.node_sound_ws_cores(table) + return table +end + +function ws_core.node_sound_leaves_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_grass_footstep", gain = 0.45} + table.dug = table.dug or + {name = "ws_core_grass_footstep", gain = 0.7} + table.place = table.place or + {name = "ws_core_place_node", gain = 1.0} + ws_core.node_sound_ws_cores(table) + return table +end + +function ws_core.node_sound_glass_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_glass_footstep", gain = 0.3} + table.dig = table.dig or + {name = "ws_core_glass_footstep", gain = 0.5} + table.dug = table.dug or + {name = "ws_core_break_glass", gain = 1.0} + ws_core.node_sound_ws_cores(table) + return table +end + +function ws_core.node_sound_metal_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_metal_footstep", gain = 0.4} + table.dig = table.dig or + {name = "ws_core_dig_metal", gain = 0.5} + table.dug = table.dug or + {name = "ws_core_dug_metal", gain = 0.5} + table.place = table.place or + {name = "ws_core_place_node_metal", gain = 0.5} + ws_core.node_sound_ws_cores(table) + return table +end + +function ws_core.node_sound_water_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_water_footstep", gain = 0.2} + ws_core.node_sound_ws_cores(table) + return table +end + +function ws_core.node_sound_snow_ws_cores(table) + table = table or {} + table.footstep = table.footstep or + {name = "ws_core_snow_footstep", gain = 0.2} + table.dig = table.dig or + {name = "ws_core_snow_footstep", gain = 0.3} + table.dug = table.dug or + {name = "ws_core_snow_footstep", gain = 0.3} + table.place = table.place or + {name = "ws_core_place_node", gain = 1.0} + ws_core.node_sound_ws_cores(table) + return table +end + + +-- +-- Lavacooling +-- + +ws_core.cool_lava = function(pos, node) + if node.name == "ws_core:lava_source" then + minetest.set_node(pos, {name = "ws_core:obsidian"}) + else -- Lava flowing + minetest.set_node(pos, {name = "ws_core:stone"}) + end + minetest.sound_play("ws_core_cool_lava", + {pos = pos, max_hear_distance = 16, gain = 0.25}) +end + +if minetest.settings:get_bool("enable_lavacooling") ~= false then + minetest.register_abm({ + label = "Lava cooling", + nodenames = {"ws_core:lava_source", "ws_core:lava_flowing"}, + neighbors = {"group:cools_lava", "group:water"}, + interval = 2, + chance = 2, + catch_up = false, + action = function(...) + ws_core.cool_lava(...) + end, + }) +end + + +-- +-- Optimized helper to put all items in an inventory into a drops list +-- + +function ws_core.get_inventory_drops(pos, inventory, drops) + local inv = minetest.get_meta(pos):get_inventory() + local n = #drops + for i = 1, inv:get_size(inventory) do + local stack = inv:get_stack(inventory, i) + if stack:get_count() > 0 then + drops[n+1] = stack:to_table() + n = n + 1 + end + end +end + + +-- +-- Papyrus and cactus growing +-- + +-- Wrapping the functions in ABM action is necessary to make overriding them possible + +function ws_core.grow_cactus(pos, node) + if node.param2 >= 4 then + return + end + pos.y = pos.y - 1 + if minetest.get_item_group(minetest.get_node(pos).name, "sand") == 0 then + return + end + pos.y = pos.y + 1 + local height = 0 + while node.name == "ws_core:cactus" and height < 4 do + height = height + 1 + pos.y = pos.y + 1 + node = minetest.get_node(pos) + end + if height == 4 or node.name ~= "air" then + return + end + if minetest.get_node_light(pos) < 13 then + return + end + minetest.set_node(pos, {name = "ws_core:cactus"}) + return true +end + +function ws_core.grow_papyrus(pos, node) + pos.y = pos.y - 1 + local name = minetest.get_node(pos).name + if name ~= "ws_core:dirt_with_grass" and name ~= "ws_core:dirt" then + return + end + if not minetest.find_node_near(pos, 3, {"group:water"}) then + return + end + pos.y = pos.y + 1 + local height = 0 + while node.name == "ws_core:papyrus" and height < 4 do + height = height + 1 + pos.y = pos.y + 1 + node = minetest.get_node(pos) + end + if height == 4 or node.name ~= "air" then + return + end + if minetest.get_node_light(pos) < 13 then + return + end + minetest.set_node(pos, {name = "ws_core:papyrus"}) + return true +end + +minetest.register_abm({ + label = "Grow cactus", + nodenames = {"ws_core:cactus"}, + neighbors = {"group:sand"}, + interval = 12, + chance = 83, + action = function(...) + ws_core.grow_cactus(...) + end +}) + +minetest.register_abm({ + label = "Grow papyrus", + nodenames = {"ws_core:papyrus"}, + neighbors = {"ws_core:dirt", "ws_core:dirt_with_grass"}, + interval = 14, + chance = 71, + action = function(...) + ws_core.grow_papyrus(...) + end +}) + + +-- +-- Dig upwards +-- + +function ws_core.dig_up(pos, node, digger) + if digger == nil then return end + local np = {x = pos.x, y = pos.y + 1, z = pos.z} + local nn = minetest.get_node(np) + if nn.name == node.name then + minetest.node_dig(np, nn, digger) + end +end + + +-- +-- Fence registration helper +-- + +function ws_core.register_fence(name, def) + minetest.register_craft({ + output = name .. " 4", + recipe = { + { def.material, 'group:stick', def.material }, + { def.material, 'group:stick', def.material }, + } + }) + + local fence_texture = "ws_core_fence_overlay.png^" .. def.texture .. + "^ws_core_fence_overlay.png^[makealpha:255,126,126" + -- Allow almost everything to be overridden + local ws_core_fields = { + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {{-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}}, + -- connect_top = + -- connect_bottom = + connect_front = {{-1/16,3/16,-1/2,1/16,5/16,-1/8}, + {-1/16,-5/16,-1/2,1/16,-3/16,-1/8}}, + connect_left = {{-1/2,3/16,-1/16,-1/8,5/16,1/16}, + {-1/2,-5/16,-1/16,-1/8,-3/16,1/16}}, + connect_back = {{-1/16,3/16,1/8,1/16,5/16,1/2}, + {-1/16,-5/16,1/8,1/16,-3/16,1/2}}, + connect_right = {{1/8,3/16,-1/16,1/2,5/16,1/16}, + {1/8,-5/16,-1/16,1/2,-3/16,1/16}}, + }, + connects_to = {"group:fence", "group:wood", "group:tree"}, + inventory_image = fence_texture, + wield_image = fence_texture, + tiles = {def.texture}, + sunlight_propagates = true, + is_ground_content = false, + groups = {}, + } + for k, v in pairs(ws_core_fields) do + if def[k] == nil then + def[k] = v + end + end + + -- Always add to the fence group, even if no group provided + def.groups.fence = 1 + + def.texture = nil + def.material = nil + + minetest.register_node(name, def) +end + + +-- +-- Leafdecay +-- + +-- Prevent decay of placed leaves + + +-- +-- Convert dirt to something that fits the environment +-- + +minetest.register_abm({ + label = "Grass spread", + nodenames = {"ws_core:dirt"}, + neighbors = { + "air", + "group:grass", + "group:dry_grass", + "ws_core:snow", + }, + interval = 6, + chance = 50, + catch_up = false, + action = function(pos, node) + -- Check for darkness: night, shadow or under a light-blocking node + -- Returns if ignore above + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + if (minetest.get_node_light(above) or 0) < 13 then + return + end + + -- Look for spreading dirt-type neighbours + local p2 = minetest.find_node_near(pos, 1, "group:spreading_dirt_type") + if p2 then + local n3 = minetest.get_node(p2) + minetest.set_node(pos, {name = n3.name}) + return + end + + -- Else, any seeding nodes on top? + local name = minetest.get_node(above).name + -- Snow check is cheapest, so comes first + if name == "ws_core:snow" then + minetest.set_node(pos, {name = "ws_core:dirt_with_snow"}) + -- Most likely case first + elseif minetest.get_item_group(name, "grass") ~= 0 then + minetest.set_node(pos, {name = "ws_core:dirt_with_grass"}) + elseif minetest.get_item_group(name, "dry_grass") ~= 0 then + minetest.set_node(pos, {name = "ws_core:dirt_with_dry_grass"}) + end + end +}) + + +-- +-- Grass and dry grass removed in darkness +-- + +minetest.register_abm({ + label = "Grass covered", + nodenames = {"group:spreading_dirt_type"}, + interval = 8, + chance = 50, + catch_up = false, + action = function(pos, node) + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local name = minetest.get_node(above).name + local nodedef = minetest.registered_nodes[name] + if name ~= "ignore" and nodedef and not ((nodedef.sunlight_propagates or + nodedef.paramtype == "light") and + nodedef.liquidtype == "none") then + minetest.set_node(pos, {name = "ws_core:dirt"}) + end + end +}) + + +-- +-- Moss growth on cobble near water +-- + +minetest.register_abm({ + label = "Moss growth", + nodenames = {"ws_core:cobble", "stairs:slab_cobble", "stairs:stair_cobble", "walls:cobble"}, + neighbors = {"group:water"}, + interval = 16, + chance = 200, + catch_up = false, + action = function(pos, node) + if node.name == "ws_core:cobble" then + minetest.set_node(pos, {name = "ws_core:mossycobble"}) + elseif node.name == "stairs:slab_cobble" then + minetest.set_node(pos, {name = "stairs:slab_mossycobble", param2 = node.param2}) + elseif node.name == "stairs:stair_cobble" then + minetest.set_node(pos, {name = "stairs:stair_mossycobble", param2 = node.param2}) + elseif node.name == "walls:cobble" then + minetest.set_node(pos, {name = "walls:mossycobble", param2 = node.param2}) + end + end +}) + + +-- +-- Coral death near air +-- + +minetest.register_abm({ + nodenames = {"ws_core:coral_brown", "ws_core:coral_orange"}, + neighbors = {"air"}, + interval = 17, + chance = 5, + catch_up = false, + action = function(pos, node) + minetest.set_node(pos, {name = "ws_core:coral_skeleton"}) + end, +}) + + +-- +-- NOTICE: This method is not an official part of the API yet. +-- This method may change in future. +-- + +function ws_core.can_interact_with_node(player, pos) + if player then + if minetest.check_player_privs(player, "protection_bypass") then + return true + end + else + return false + end + + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + + if not owner or owner == "" or owner == player:get_player_name() then + return true + end + + -- Is player wielding the right key? + local item = player:get_wielded_item() + if item:get_name() == "ws_core:key" then + local key_meta = item:get_meta() + + if key_meta:get_string("secret") == "" then + local key_oldmeta = item:get_metadata() + if key_oldmeta == "" or not minetest.parse_json(key_oldmeta) then + return false + end + + key_meta:set_string("secret", minetest.parse_json(key_oldmeta).secret) + item:set_metadata("") + end + + return meta:get_string("key_lock_secret") == key_meta:get_string("secret") + end + + return false +end diff --git a/mods/ws_core/init.lua b/mods/ws_core/init.lua new file mode 100644 index 0000000..efc9750 --- /dev/null +++ b/mods/ws_core/init.lua @@ -0,0 +1,41 @@ +-- Minetest 0.4 mod: ws_core +-- See README.txt for licensing and other information. + +-- The API documentation in here was moved into game_api.txt + +-- Definitions made by this mod that other mods can use too +ws_core = {} + +ws_core.LIGHT_MAX = 14 + +function ws_core.get_hotbar_bg(x,y) + local out = "" + for i=0,7,1 do + out = out .."image["..x+i..","..y..";1,1;gui_hb_bg.png]" + end + return out +end + +ws_core.gui_survival_form = "size[8,8.5]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + "list[current_player;craft;1.75,0.5;2,2;]".. + "list[current_player;craftpreview;5.75,1.5;1,1;]".. + "image[4.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "listring[current_player;main]".. + "listring[current_player;craft]".. + ws_core.get_hotbar_bg(0,4.25) + +-- Load files +local ws_core_path = minetest.get_modpath("ws_core") + +dofile(ws_core_path.."/functions.lua") +dofile(ws_core_path.."/nodes.lua") +dofile(ws_core_path.."/item_entity.lua") +dofile(ws_core_path.."/craftitems.lua") +dofile(ws_core_path.."/crafting.lua") +dofile(ws_core_path.."/mapgen.lua") +dofile(ws_core_path.."/aliases.lua") +dofile(ws_core_path.."/legacy.lua") +dofile(ws_core_path.."/trees.lua") +dofile(ws_core_path.."/tools.lua") \ No newline at end of file diff --git a/mods/ws_core/item_entity.lua b/mods/ws_core/item_entity.lua new file mode 100644 index 0000000..21ac276 --- /dev/null +++ b/mods/ws_core/item_entity.lua @@ -0,0 +1,74 @@ +-- mods/ws_core/item_entity.lua + +local builtin_item = minetest.registered_entities["__builtin:item"] + +local item = { + set_item = function(self, itemstring) + builtin_item.set_item(self, itemstring) + + local stack = ItemStack(itemstring) + local itemdef = minetest.registered_items[stack:get_name()] + if itemdef and itemdef.groups.flammable ~= 0 then + self.flammable = itemdef.groups.flammable + end + end, + + burn_up = function(self) + -- disappear in a smoke puff + self.object:remove() + local p = self.object:getpos() + minetest.sound_play("ws_core_item_smoke", { + pos = p, + max_hear_distance = 8, + }) + minetest.add_particlespawner({ + amount = 3, + time = 0.1, + minpos = {x = p.x - 0.1, y = p.y + 0.1, z = p.z - 0.1 }, + maxpos = {x = p.x + 0.1, y = p.y + 0.2, z = p.z + 0.1 }, + minvel = {x = 0, y = 2.5, z = 0}, + maxvel = {x = 0, y = 2.5, z = 0}, + minacc = {x = -0.15, y = -0.02, z = -0.15}, + maxacc = {x = 0.15, y = -0.01, z = 0.15}, + minexptime = 4, + maxexptime = 6, + minsize = 5, + maxsize = 5, + collisiondetection = true, + texture = "ws_core_item_smoke.png" + }) + end, + + on_step = function(self, dtime) + builtin_item.on_step(self, dtime) + + if self.flammable then + -- flammable, check for igniters + self.ignite_timer = (self.ignite_timer or 0) + dtime + if self.ignite_timer > 10 then + self.ignite_timer = 0 + + local node = minetest.get_node_or_nil(self.object:getpos()) + if not node then + return + end + + -- Immediately burn up flammable items in lava + if minetest.get_item_group(node.name, "lava") > 0 then + self:burn_up() + else + -- otherwise there'll be a chance based on its igniter value + local burn_chance = self.flammable + * minetest.get_item_group(node.name, "igniter") + if burn_chance > 0 and math.random(0, burn_chance) ~= 0 then + self:burn_up() + end + end + end + end + end, +} + +-- set defined item as new __builtin:item, with the old one as fallback table +setmetatable(item, builtin_item) +minetest.register_entity(":__builtin:item", item) diff --git a/mods/ws_core/legacy.lua b/mods/ws_core/legacy.lua new file mode 100644 index 0000000..f68b277 --- /dev/null +++ b/mods/ws_core/legacy.lua @@ -0,0 +1,37 @@ +-- mods/ws_core/legacy.lua + +-- Horrible stuff to support old code registering falling nodes +-- Don't use this and never do what this does, it's completely wrong! +-- (More specifically, the client and the C++ code doesn't get the group) +function ws_core.register_falling_node(nodename, texture) + minetest.log("error", debug.traceback()) + minetest.log('error', "WARNING: ws_core.register_falling_node is deprecated") + if minetest.registered_nodes[nodename] then + minetest.registered_nodes[nodename].groups.falling_node = 1 + end +end + +function ws_core.spawn_falling_node(p, nodename) + spawn_falling_node(p, nodename) +end + +-- Formspecs +ws_core.gui_suvival_form = ws_core.gui_survival_form + +-- Players +if minetest.get_modpath("player_api") then + ws_core.registered_player_models = player_api.registered_models + ws_core.player_register_model = player_api.register_model + ws_core.player_attached = player_api.player_attached + ws_core.player_get_animation = player_api.get_animation + ws_core.player_set_model = player_api.set_model + ws_core.player_set_textures = player_api.set_textures + ws_core.player_set_animation = player_api.set_animation +end + +-- Check for a volume intersecting protection +function ws_core.intersects_protection(minp, maxp, player_name, interval) + minetest.log("warning", "ws_core.intersects_protection() is " .. + "deprecated, use minetest.is_area_protected() instead.") + minetest.is_area_protected(minp, maxp, player_name, interval) +end diff --git a/mods/ws_core/license.txt b/mods/ws_core/license.txt new file mode 100644 index 0000000..4610bac --- /dev/null +++ b/mods/ws_core/license.txt @@ -0,0 +1,154 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2011-2016 celeron55, Perttu Ahola +Copyright (C) 2011-2016 Various Minetest developers and contributors + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 2.1 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + +Licenses of media (textures, models and sounds) +----------------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2010-2017: + + celeron55, Perttu Ahola + Cisoun + G4JC + VanessaE + RealBadAngel + Calinou + MirceaKitsune + Jordach + PilzAdam + jojoa1997 + InfinityProject + Splizard + Zeg9 + paramat + BlockMen + sofar + Neuromancer + Gambit + asl97 + KevDoy + Mito551 + GreenXenith + kaeza + kilbith + tobyplowy + CloudyProton + TumeniNodes + Mossmanikin + +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/ + +----------------------- + +Attribution 3.0 Unported (CC BY 3.0) + +Copyright (C) 2009 cmusounddesign +Copyright (C) 2010 Tomlija +Copyright (C) 2010 lsprice +Copyright (C) 2014 sonictechtonic +Copyright (C) 2015 yadronoff +Copyright (C) 2007 HerbertBoland +Copyright (C) 2006 AGFX + +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. + +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/3.0/ + +----------------------- + +CC0 1.0 Universal (CC0 1.0) Public Domain Dedication + +Iwan Gabovitch +Ottomaani138 +Ogrebane +blukotek +Sevin7 +Yoyodaman234 +Ryding + +No Copyright + +The person who associated a work with this deed has dedicated the work to the +public domain by waiving all of his or her rights to the work worldwide under +copyright law, including all related and neighboring rights, to the extent +allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial +purposes, all without asking permission. See Other Information below. + +Other Information: + +In no way are the patent or trademark rights of any person affected by CC0, nor +are the rights that other persons may have in the work or in how the work is +used, such as publicity or privacy rights. + +Unless expressly stated otherwise, the person who associated a work with this +deed makes no warranties about the work, and disclaims liability for all uses +of the work, to the fullest extent permitted by applicable law. + +When using or citing the work, you should not imply endorsement by the author +or the affirmer. + +For more details: +https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/mods/ws_core/mapgen.lua b/mods/ws_core/mapgen.lua new file mode 100644 index 0000000..4de0074 --- /dev/null +++ b/mods/ws_core/mapgen.lua @@ -0,0 +1,981 @@ +-- +-- Aliases for map generators +-- + +minetest.register_alias("mapgen_stone", "ws_core:stone") +minetest.register_alias("mapgen_dirt", "ws_core:dirt_dry") +minetest.register_alias("default:dirt", "ws_core:dirt") +minetest.register_alias("mapgen_dirt_with_grass", "ws_core:dirt_dry1") +minetest.register_alias("mapgen_sand", "ws_core:sandy_dirt") +minetest.register_alias("mapgen_water_source", "ws_core:water_source") +minetest.register_alias("mapgen_river_water_source", "ws_core:river_water_source") +minetest.register_alias("mapgen_lava_source", "ws_core:lava_source") +minetest.register_alias("mapgen_gravel", "ws_core:gravel") +minetest.register_alias("mapgen_desert_stone", "ws_core:desert_stone") +minetest.register_alias("mapgen_desert_sand", "ws_core:sandy_dirt") +minetest.register_alias("mapgen_dirt_with_snow", "ws_core:dirt_dry") +minetest.register_alias("mapgen_snowblock", "ws_core:snowblock") +minetest.register_alias("mapgen_snow", "ws_core:snow") +minetest.register_alias("mapgen_ice", "ws_core:ice") +minetest.register_alias("mapgen_sandstone", "ws_core:sandstone") +minetest.register_alias("mapgen_jungletree", "ws_core:dead_tree") +minetest.register_alias("mapgen_jungleleaves", "air") + +-- Flora + +minetest.register_alias("mapgen_tree", "ws_core:dead_tree") +minetest.register_alias("mapgen_apple", "ws_core:air") + +-- Dungeons + +minetest.register_alias("mapgen_cobble", "ws_core:cobble") +minetest.register_alias("mapgen_stair_cobble", "stairs:stair_cobble") +minetest.register_alias("mapgen_mossycobble", "ws_core:mossycobble") +minetest.register_alias("mapgen_stair_desert_stone", "stairs:stair_desert_stone") +minetest.register_alias("mapgen_sandstonebrick", "ws_core:sandstonebrick") +minetest.register_alias("mapgen_stair_sandstone_block", "stairs:stair_sandstone_block") + + +-- +-- Register ores +-- + +-- Mgv6 + +function ws_core.register_mgv6_ores() + + -- Blob ore + -- These first to avoid other ores in blobs + -- Sand + + minetest.register_ore({ + ore_type = "blob", + ore = "ws_core:sandy_dirt", + wherein = {"ws_core:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 30, + y_min = -31, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 2316, + octaves = 1, + persist = 0.0 + }, + }) + + -- Gravel + + minetest.register_ore({ + ore_type = "blob", + ore = "ws_core:gravel", + wherein = {"ws_core:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 31000, + y_min = -31000, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 766, + octaves = 1, + persist = 0.0 + }, + }) + + -- Scatter ores + minetest.register_ore({ + ore_type = "blob", + ore = "ws_core:dirt_dry", + wherein = {"ws_core:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 31000, + y_min = -31, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 17676, + octaves = 1, + persist = 0.0 + }, + }) + + -- Coal + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_coal", + wherein = "ws_core:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 9, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_coal", + wherein = "ws_core:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 8, + clust_size = 3, + y_max = 64, + y_min = -31000, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_coal", + wherein = "ws_core:stone", + clust_scarcity = 24 * 24 * 24, + clust_num_ores = 27, + clust_size = 6, + y_max = 0, + y_min = -31000, + }) + + -- Iron + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_iron", + wherein = "ws_core:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 12, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_iron", + wherein = "ws_core:stone", + clust_scarcity = 7 * 7 * 7, + clust_num_ores = 5, + clust_size = 3, + y_max = 0, + y_min = -31000, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_iron", + wherein = "ws_core:stone", + clust_scarcity = 24 * 24 * 24, + clust_num_ores = 27, + clust_size = 6, + y_max = -64, + y_min = -31000, + }) + + -- Copper + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_copper", + wherein = "ws_core:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_copper", + wherein = "ws_core:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 4, + clust_size = 3, + y_max = -16, + y_min = -63, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_copper", + wherein = "ws_core:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = -64, + y_min = -31000, + }) + + -- Tin + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_tin", + wherein = "ws_core:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_tin", + wherein = "ws_core:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 4, + clust_size = 3, + y_max = -32, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_tin", + wherein = "ws_core:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = -128, + y_min = -31000, + }) + + -- Gold + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_gold", + wherein = "ws_core:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_gold", + wherein = "ws_core:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 3, + clust_size = 2, + y_max = -64, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_gold", + wherein = "ws_core:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Mese crystal + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_mese", + wherein = "ws_core:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_mese", + wherein = "ws_core:stone", + clust_scarcity = 18 * 18 * 18, + clust_num_ores = 3, + clust_size = 2, + y_max = -64, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_mese", + wherein = "ws_core:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Diamond + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_diamond", + wherein = "ws_core:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_diamond", + wherein = "ws_core:stone", + clust_scarcity = 17 * 17 * 17, + clust_num_ores = 4, + clust_size = 3, + y_max = -128, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_diamond", + wherein = "ws_core:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Mese block + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:mese", + wherein = "ws_core:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:mese", + wherein = "ws_core:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = -1024, + y_min = -31000, + }) +end + + +-- All mapgens except mgv6 + +function ws_core.register_ores() + + -- Stratum ores. + -- These obviously first. + -- Desert sandstone + + minetest.register_ore({ + ore_type = "stratum", + ore = "ws_core:desert_sandstone", + wherein = {"ws_core:desert_stone"}, + clust_scarcity = 1, + y_max = 46, + y_min = 10, + noise_params = { + offset = 28, + scale = 16, + spread = {x = 128, y = 128, z = 128}, + seed = 90122, + octaves = 1, + }, + stratum_thickness = 4, + biomes = {"desert"}, + }) + + minetest.register_ore({ + ore_type = "stratum", + ore = "ws_core:desert_sandstone", + wherein = {"ws_core:desert_stone"}, + clust_scarcity = 1, + y_max = 42, + y_min = 6, + noise_params = { + offset = 24, + scale = 16, + spread = {x = 128, y = 128, z = 128}, + seed = 90122, + octaves = 1, + }, + stratum_thickness = 2, + biomes = {"desert"}, + }) + + -- Sandstone + + minetest.register_ore({ + ore_type = "stratum", + ore = "ws_core:sandstone", + wherein = {"ws_core:desert_stone"}, + clust_scarcity = 1, + y_max = 39, + y_min = 3, + noise_params = { + offset = 21, + scale = 16, + spread = {x = 128, y = 128, z = 128}, + seed = 90122, + octaves = 1, + }, + stratum_thickness = 2, + biomes = {"desert"}, + }) + + -- Blob ore. + -- These before scatter ores to avoid other ores in blobs. + + -- Gravel + + minetest.register_ore({ + ore_type = "blob", + ore = "ws_core:gravel", + wherein = {"ws_core:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 31000, + y_min = -31000, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 766, + octaves = 1, + persist = 0.0 + }, + biomes = {"dirtland", "desert"} + }) + + -- Scatter ores + + -- Coal + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_coal", + wherein = "ws_core:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 9, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_coal", + wherein = "ws_core:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 8, + clust_size = 3, + y_max = 64, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_coal", + wherein = "ws_core:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 30, + clust_size = 5, + y_max = -128, + y_min = -31000, + }) + + -- Tin + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_tin", + wherein = "ws_core:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_tin", + wherein = "ws_core:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 4, + clust_size = 3, + y_max = -64, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_tin", + wherein = "ws_core:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = -128, + y_min = -31000, + }) + + -- Copper + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_copper", + wherein = "ws_core:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_copper", + wherein = "ws_core:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 4, + clust_size = 3, + y_max = -64, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_copper", + wherein = "ws_core:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = -128, + y_min = -31000, + }) + + -- Iron + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_iron", + wherein = "ws_core:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 12, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_iron", + wherein = "ws_core:stone", + clust_scarcity = 7 * 7 * 7, + clust_num_ores = 5, + clust_size = 3, + y_max = -128, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_iron", + wherein = "ws_core:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 29, + clust_size = 5, + y_max = -256, + y_min = -31000, + }) + + -- Gold + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_gold", + wherein = "ws_core:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_gold", + wherein = "ws_core:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 3, + clust_size = 2, + y_max = -256, + y_min = -511, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_gold", + wherein = "ws_core:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = -512, + y_min = -31000, + }) + + -- Mese crystal + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_mese", + wherein = "ws_core:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_mese", + wherein = "ws_core:stone", + clust_scarcity = 18 * 18 * 18, + clust_num_ores = 3, + clust_size = 2, + y_max = -512, + y_min = -1023, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_mese", + wherein = "ws_core:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = -1024, + y_min = -31000, + }) + + -- Diamond + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_diamond", + wherein = "ws_core:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_diamond", + wherein = "ws_core:stone", + clust_scarcity = 17 * 17 * 17, + clust_num_ores = 4, + clust_size = 3, + y_max = -1024, + y_min = -2047, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:stone_with_diamond", + wherein = "ws_core:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = -2048, + y_min = -31000, + }) + + -- Mese block + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:mese", + wherein = "ws_core:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:mese", + wherein = "ws_core:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = -2048, + y_min = -4095, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "ws_core:mese", + wherein = "ws_core:stone", + clust_scarcity = 28 * 28 * 28, + clust_num_ores = 5, + clust_size = 3, + y_max = -4096, + y_min = -31000, + }) +end + + +-- +-- Register biomes +-- + +-- All mapgens except mgv6 + +function ws_core.register_biomes(upper_limit) + + -- Grassland + + minetest.register_biome({ + name = "dirtland", + node_top = "ws_core:dirt_dry1", + depth_top = 1, + node_filler = "ws_core:dirt_dry", + depth_filler = 2, + node_riverbed = "ws_core:sandy_dirt", + depth_riverbed = 4, + y_max = 31000, + y_min = -31, + heat_point = 50, + humidity_point = 35, + }) + + minetest.register_biome({ + name = "dirtland_dunes", + node_top = "ws_core:sandy_dirt", + depth_top = 1, + node_filler = "ws_core:sandy_dirt", + depth_filler = 2, + node_riverbed = "ws_core:sandy_dirt", + depth_riverbed = 4, + vertical_blend = 1, + y_max = 5, + y_min = 4, + heat_point = 50, + humidity_point = 35, + }) + + minetest.register_biome({ + name = "dirtland_ocean", + node_top = "ws_core:sandy_dirt", + depth_top = 1, + node_filler = "ws_core:sandy_dirt", + depth_filler = 2, + node_riverbed = "ws_core:sandy_dirt", + depth_riverbed = 2, + y_max = 3, + y_min = -112, + heat_point = 50, + humidity_point = 35, + }) + + -- Desert + + minetest.register_biome({ + name = "desert", + node_top = "ws_core:sandy_dirt", + depth_top = 1, + node_filler = "ws_core:sandy_dirt", + depth_filler = 2, + node_stone = "ws_core:sandstone", + node_riverbed = "ws_core:sandy_dirt", + depth_riverbed = 6, + y_max = upper_limit, + y_min = 4, + heat_point = 92, + humidity_point = 16, + }) + + minetest.register_biome({ + name = "desert_ocean", + node_top = "ws_core:sandy_dirt", + depth_top = 1, + node_filler = "ws_core:sandy_dirt", + depth_filler = 2, + node_stone = "ws_core:sandstone", + node_riverbed = "ws_core:sandy_dirt", + depth_riverbed = 10, + vertical_blend = 1, + y_max = 3, + y_min = -112, + heat_point = 92, + humidity_point = 16, + }) +end + +-- Biomes for floatlands + +-- TODO Temporary simple biomes to be replaced by special floatland biomes later. + +function ws_core.register_floatland_biomes(floatland_level, shadow_limit) + + minetest.register_biome({ + name = "floatland_dirtland", + node_top = "ws_core:dirt_dry", + depth_top = 1, + node_filler = "ws_core:dirt_dry", + depth_filler = 2, + y_max = 31000, + y_min = floatland_level + 2, + heat_point = 50, + humidity_point = 25, + }) + + minetest.register_biome({ + name = "floatland_coniferous_forest", + node_top = "ws_core:dirt_dry", + depth_top = 1, + node_filler = "ws_core:dirt_dry", + depth_filler = 2, + y_max = 31000, + y_min = floatland_level + 2, + heat_point = 50, + humidity_point = 75, + }) + + minetest.register_biome({ + name = "floatland_ocean", + node_top = "ws_core:sandy_dirt", + depth_top = 1, + node_filler = "ws_core:sandy_dirt", + depth_filler = 2, + y_max = floatland_level + 1, + y_min = shadow_limit, + heat_point = 50, + humidity_point = 50, + }) +end + + +-- +-- Register decorations +-- + +-- Mgv6 + +function ws_core.register_mgv6_decorations() + -- Dry shrubs + + minetest.register_decoration({ + name = "ws_core:dry_shrub", + deco_type = "simple", + place_on = {"ws_core:sandy_dirt"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.035, + spread = {x = 100, y = 100, z = 100}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + y_max = 30, + y_min = 1, + decoration = "ws_core:dry_shrub", + param2 = 4, + }) +end + +function ws_core.register_decorations() + -- Dry shrub + + minetest.register_decoration({ + name = "ws_core:dry_shrub", + deco_type = "simple", + place_on = {"ws_core:sandy_dirt", + "ws_core:sandy_dirt"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.02, + spread = {x = 200, y = 200, z = 200}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + biomes = {"desert"}, + y_max = 31000, + y_min = 2, + decoration = "ws_core:dry_shrub", + param2 = 4, + }) +end + +-- +-- Detect mapgen, flags and parameters to select functions +-- + +-- Get setting or ws_core +local mgv7_spflags = minetest.get_mapgen_setting("mgv7_spflags") or + "mountains, ridges, nofloatlands, caverns" +local captures_float = string.match(mgv7_spflags, "floatlands") +local captures_nofloat = string.match(mgv7_spflags, "nofloatlands") + +-- Get setting or ws_core +-- Make global for mods to use to register floatland biomes +ws_core.mgv7_floatland_level = + minetest.get_mapgen_setting("mgv7_floatland_level") or 1280 +ws_core.mgv7_shadow_limit = + minetest.get_mapgen_setting("mgv7_shadow_limit") or 1024 + +minetest.clear_registered_biomes() +minetest.clear_registered_ores() +minetest.clear_registered_decorations() + +local mg_name = minetest.get_mapgen_setting("mg_name") + +if mg_name == "v6" then + ws_core.register_mgv6_ores() + ws_core.register_mgv6_decorations() +-- Need to check for 'nofloatlands' because that contains +-- 'floatlands' which makes the second condition true. +elseif mg_name == "v7" and + captures_float == "floatlands" and + captures_nofloat ~= "nofloatlands" then + -- Mgv7 with floatlands and floatland biomes + ws_core.register_biomes(ws_core.mgv7_shadow_limit - 1) + ws_core.register_floatland_biomes( + ws_core.mgv7_floatland_level, ws_core.mgv7_shadow_limit) + ws_core.register_ores() + ws_core.register_decorations() +else + ws_core.register_biomes(31000) + ws_core.register_ores() + ws_core.register_decorations() +end diff --git a/mods/ws_core/mp2.txt b/mods/ws_core/mp2.txt new file mode 100644 index 0000000..b92a364 --- /dev/null +++ b/mods/ws_core/mp2.txt @@ -0,0 +1,1168 @@ +minetest.register_alias("mapgen_sand", "default:sand") +minetest.register_alias("mapgen_water_source", "default:water_source") +minetest.register_alias("mapgen_river_water_source", "default:river_water_source") +minetest.register_alias("mapgen_lava_source", "default:lava_source") +minetest.register_alias("mapgen_gravel", "default:gravel") +minetest.register_alias("mapgen_desert_stone", "default:desert_stone") +minetest.register_alias("mapgen_desert_sand", "default:desert_sand") +minetest.register_alias("mapgen_dirt_with_snow", "default:dirt_with_snow") +minetest.register_alias("mapgen_snowblock", "default:snowblock") +minetest.register_alias("mapgen_snow", "default:snow") +minetest.register_alias("mapgen_ice", "default:ice") +minetest.register_alias("mapgen_sandstone", "default:sandstone") + +-- Flora + +minetest.register_alias("mapgen_tree", "default:tree") +minetest.register_alias("mapgen_leaves", "default:leaves") +minetest.register_alias("mapgen_apple", "default:apple") +minetest.register_alias("mapgen_jungletree", "default:jungletree") +minetest.register_alias("mapgen_jungleleaves", "default:jungleleaves") +minetest.register_alias("mapgen_junglegrass", "default:junglegrass") +minetest.register_alias("mapgen_pine_tree", "default:pine_tree") +minetest.register_alias("mapgen_pine_needles", "default:pine_needles") + +-- Dungeons + +minetest.register_alias("mapgen_cobble", "default:cobble") +minetest.register_alias("mapgen_stair_cobble", "stairs:stair_cobble") +minetest.register_alias("mapgen_mossycobble", "default:mossycobble") +minetest.register_alias("mapgen_stair_desert_stone", "stairs:stair_desert_stone") +minetest.register_alias("mapgen_sandstonebrick", "default:sandstonebrick") +minetest.register_alias("mapgen_stair_sandstone_block", "stairs:stair_sandstone_block") + + +minetest.register_ore({ + ore_type = "blob", + ore = "default:clay", + wherein = {"default:sand"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 0, + y_min = -15, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = -316, + octaves = 1, + persist = 0.0 + }, + }) + + -- Sand + + minetest.register_ore({ + ore_type = "blob", + ore = "default:sand", + wherein = {"default:stone", "default:desert_stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 0, + y_min = -31, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 2316, + octaves = 1, + persist = 0.0 + }, + }) + + -- Gravel + + minetest.register_ore({ + ore_type = "blob", + ore = "default:gravel", + wherein = {"default:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 31000, + y_min = -31000, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 766, + octaves = 1, + persist = 0.0 + }, + }) + + -- Iron + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 12, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 7 * 7 * 7, + clust_num_ores = 5, + clust_size = 3, + y_max = 0, + y_min = -31000, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 24 * 24 * 24, + clust_num_ores = 27, + clust_size = 6, + y_max = -64, + y_min = -31000, + }) + + -- Copper + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 4, + clust_size = 3, + y_max = -16, + y_min = -63, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = -64, + y_min = -31000, + }) + + -- Tin + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 4, + clust_size = 3, + y_max = -32, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = -128, + y_min = -31000, + }) + + -- Gold + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 3, + clust_size = 2, + y_max = -64, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Mese crystal + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 18 * 18 * 18, + clust_num_ores = 3, + clust_size = 2, + y_max = -64, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Diamond + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 17 * 17 * 17, + clust_num_ores = 4, + clust_size = 3, + y_max = -128, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Mese block + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = -1024, + y_min = -31000, + }) +end + + + + + +minetest.register_ore({ + ore_type = "blob", + ore = "default:clay", + wherein = {"default:sand"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 0, + y_min = -15, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = -316, + octaves = 1, + persist = 0.0 + }, + }) + + -- Silver sand + + minetest.register_ore({ + ore_type = "blob", + ore = "default:silver_sand", + wherein = {"default:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 31000, + y_min = -31000, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 2316, + octaves = 1, + persist = 0.0 + }, + biomes = {"icesheet_ocean", "tundra", "tundra_beach", "tundra_ocean", + "taiga", "taiga_ocean", "snowy_grassland", "snowy_grassland_ocean", + "grassland", "grassland_dunes", "grassland_ocean", "coniferous_forest", + "coniferous_forest_dunes", "coniferous_forest_ocean", "deciduous_forest", + "deciduous_forest_shore", "deciduous_forest_ocean", "cold_desert", + "cold_desert_ocean", "savanna", "savanna_shore", "savanna_ocean", + "rainforest", "rainforest_swamp", "rainforest_ocean", "underground", + "floatland_coniferous_forest", "floatland_coniferous_forest_ocean"} + }) + + + + -- Gravel + + minetest.register_ore({ + ore_type = "blob", + ore = "default:gravel", + wherein = {"default:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 31000, + y_min = -31000, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 766, + octaves = 1, + persist = 0.0 + }, + biomes = {"icesheet_ocean", "tundra", "tundra_beach", "tundra_ocean", + "taiga", "taiga_ocean", "snowy_grassland", "snowy_grassland_ocean", + "grassland", "grassland_dunes", "grassland_ocean", "coniferous_forest", + "coniferous_forest_dunes", "coniferous_forest_ocean", "deciduous_forest", + "deciduous_forest_shore", "deciduous_forest_ocean", "cold_desert", + "cold_desert_ocean", "savanna", "savanna_shore", "savanna_ocean", + "rainforest", "rainforest_swamp", "rainforest_ocean", "underground", + "floatland_coniferous_forest", "floatland_coniferous_forest_ocean"} + }) + + + + -- Iron + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 12, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 7 * 7 * 7, + clust_num_ores = 5, + clust_size = 3, + y_max = 0, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 29, + clust_size = 5, + y_max = -128, + y_min = -31000, + }) + + -- Tin + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 4, + clust_size = 3, + y_max = -128, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Copper + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 4, + clust_size = 3, + y_max = -128, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Gold + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 3, + clust_size = 2, + y_max = -256, + y_min = -1023, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = -1024, + y_min = -31000, + }) + + -- Diamond + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 17 * 17 * 17, + clust_num_ores = 4, + clust_size = 3, + y_max = -512, + y_min = -1023, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = -1024, + y_min = -31000, + }) + + -- Mese crystal + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 18 * 18 * 18, + clust_num_ores = 3, + clust_size = 2, + y_max = -512, + y_min = -1023, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = -1024, + y_min = -31000, + }) + + -- Mese block + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = -1024, + y_min = -2047, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 28 * 28 * 28, + clust_num_ores = 5, + clust_size = 3, + y_max = -2048, + y_min = -31000, + }) +end + + +function default.register_decorations() + + -- Apple tree and log + + minetest.register_decoration({ + name = "default:apple_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0.036, + scale = 0.022, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"deciduous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/apple_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + minetest.register_decoration({ + name = "default:apple_log", + deco_type = "schematic", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0.0018, + scale = 0.0011, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"deciduous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/apple_log.mts", + flags = "place_center_x", + rotation = "random", + }) + + -- Emergent jungle tree + -- Due to 32 node height, altitude is limited and prescence depends on chunksize + + local chunksize = tonumber(minetest.get_mapgen_setting("chunksize")) + if chunksize >= 5 then + minetest.register_decoration({ + name = "default:emergent_jungle_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_rainforest_litter"}, + sidelen = 80, + noise_params = { + offset = 0.0, + scale = 0.0025, + spread = {x = 250, y = 250, z = 250}, + seed = 2685, + octaves = 3, + persist = 0.7 + }, + biomes = {"rainforest"}, + y_max = 32, + y_min = 1, + schematic = minetest.get_modpath("default") .. + "/schematics/emergent_jungle_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + place_offset_y = -4, + }) + end + + -- Jungle tree and log + + minetest.register_decoration({ + name = "default:jungle_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_rainforest_litter", "default:dirt"}, + sidelen = 80, + fill_ratio = 0.1, + biomes = {"rainforest", "rainforest_swamp"}, + y_max = 31000, + y_min = -1, + schematic = minetest.get_modpath("default") .. "/schematics/jungle_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + minetest.register_decoration({ + name = "default:jungle_log", + deco_type = "schematic", + place_on = {"default:dirt_with_rainforest_litter", "default:dirt"}, + sidelen = 80, + fill_ratio = 0.005, + biomes = {"rainforest", "rainforest_swamp"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/jungle_log.mts", + flags = "place_center_x", + rotation = "random", + }) + + -- Taiga and temperate coniferous forest pine tree, small pine tree and log + + minetest.register_decoration({ + name = "default:pine_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_snow", "default:dirt_with_coniferous_litter"}, + sidelen = 16, + noise_params = { + offset = 0.010, + scale = 0.048, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"taiga", "coniferous_forest", "floatland_coniferous_forest"}, + y_max = 31000, + y_min = 2, + schematic = minetest.get_modpath("default") .. "/schematics/pine_tree.mts", + flags = "place_center_x, place_center_z", + }) + + minetest.register_decoration({ + name = "default:small_pine_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_snow", "default:dirt_with_coniferous_litter"}, + sidelen = 16, + noise_params = { + offset = 0.010, + scale = -0.048, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"taiga", "coniferous_forest", "floatland_coniferous_forest"}, + y_max = 31000, + y_min = 2, + schematic = minetest.get_modpath("default") .. "/schematics/small_pine_tree.mts", + flags = "place_center_x, place_center_z", + }) + + minetest.register_decoration({ + name = "default:pine_log", + deco_type = "schematic", + place_on = {"default:dirt_with_snow", "default:dirt_with_coniferous_litter"}, + sidelen = 80, + fill_ratio = 0.0018, + biomes = {"taiga", "coniferous_forest", "floatland_coniferous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/pine_log.mts", + flags = "place_center_x", + rotation = "random", + }) + + -- Acacia tree and log + + minetest.register_decoration({ + name = "default:acacia_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_dry_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.002, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"savanna"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/acacia_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + minetest.register_decoration({ + name = "default:acacia_log", + deco_type = "schematic", + place_on = {"default:dirt_with_dry_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"savanna"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/acacia_log.mts", + flags = "place_center_x", + rotation = "random", + }) + + -- Aspen tree and log + + minetest.register_decoration({ + name = "default:aspen_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0.0, + scale = -0.015, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"deciduous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/aspen_tree.mts", + flags = "place_center_x, place_center_z", + }) + + minetest.register_decoration({ + name = "default:aspen_log", + deco_type = "schematic", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0.0, + scale = -0.0008, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"deciduous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/aspen_log.mts", + flags = "place_center_x", + rotation = "random", + }) + + -- Large cactus + + minetest.register_decoration({ + name = "default:large_cactus", + deco_type = "schematic", + place_on = {"default:desert_sand"}, + sidelen = 16, + noise_params = { + offset = -0.0003, + scale = 0.0009, + spread = {x = 200, y = 200, z = 200}, + seed = 230, + octaves = 3, + persist = 0.6 + }, + biomes = {"desert"}, + y_max = 31000, + y_min = 5, + schematic = minetest.get_modpath("default") .. "/schematics/large_cactus.mts", + flags = "place_center_x", + rotation = "random", + }) + + -- Cactus + + minetest.register_decoration({ + name = "default:cactus", + deco_type = "simple", + place_on = {"default:desert_sand"}, + sidelen = 16, + noise_params = { + offset = -0.0003, + scale = 0.0009, + spread = {x = 200, y = 200, z = 200}, + seed = 230, + octaves = 3, + persist = 0.6 + }, + biomes = {"desert"}, + y_max = 31000, + y_min = 5, + decoration = "default:cactus", + height = 2, + height_max = 5, + }) + + -- Papyrus + + minetest.register_decoration({ + name = "default:papyrus", + deco_type = "schematic", + place_on = {"default:dirt"}, + sidelen = 16, + noise_params = { + offset = -0.3, + scale = 0.7, + spread = {x = 200, y = 200, z = 200}, + seed = 354, + octaves = 3, + persist = 0.7 + }, + biomes = {"savanna_shore"}, + y_max = 0, + y_min = 0, + schematic = minetest.get_modpath("default") .. "/schematics/papyrus.mts", + }) + + -- Bush + + minetest.register_decoration({ + name = "default:bush", + deco_type = "schematic", + place_on = {"default:dirt_with_grass", "default:dirt_with_snow"}, + sidelen = 16, + noise_params = { + offset = -0.004, + scale = 0.01, + spread = {x = 100, y = 100, z = 100}, + seed = 137, + octaves = 3, + persist = 0.7, + }, + biomes = {"snowy_grassland", "grassland", "deciduous_forest", + "floatland_grassland"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/bush.mts", + flags = "place_center_x, place_center_z", + }) + + -- Acacia bush + + minetest.register_decoration({ + name = "default:acacia_bush", + deco_type = "schematic", + place_on = {"default:dirt_with_dry_grass"}, + sidelen = 16, + noise_params = { + offset = -0.004, + scale = 0.01, + spread = {x = 100, y = 100, z = 100}, + seed = 90155, + octaves = 3, + persist = 0.7, + }, + biomes = {"savanna"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/acacia_bush.mts", + flags = "place_center_x, place_center_z", + }) + + -- Grasses + + register_grass_decoration(-0.03, 0.09, 5) + register_grass_decoration(-0.015, 0.075, 4) + register_grass_decoration(0, 0.06, 3) + register_grass_decoration(0.015, 0.045, 2) + register_grass_decoration(0.03, 0.03, 1) + + -- Dry grasses + + register_dry_grass_decoration(0.01, 0.05, 5) + register_dry_grass_decoration(0.03, 0.03, 4) + register_dry_grass_decoration(0.05, 0.01, 3) + register_dry_grass_decoration(0.07, -0.01, 2) + register_dry_grass_decoration(0.09, -0.03, 1) + + -- Ferns + + register_fern_decoration(14936, 3) + register_fern_decoration(801, 2) + register_fern_decoration(5, 1) + + -- Junglegrass + + minetest.register_decoration({ + name = "default:junglegrass", + deco_type = "simple", + place_on = {"default:dirt_with_rainforest_litter"}, + sidelen = 80, + fill_ratio = 0.1, + biomes = {"rainforest"}, + y_max = 31000, + y_min = 1, + decoration = "default:junglegrass", + }) + + -- Dry shrub + + minetest.register_decoration({ + name = "default:dry_shrub", + deco_type = "simple", + place_on = {"default:desert_sand", + "default:sand", "default:silver_sand"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.02, + spread = {x = 200, y = 200, z = 200}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + biomes = {"desert", "sandstone_desert", "cold_desert"}, + y_max = 31000, + y_min = 2, + decoration = "default:dry_shrub", + param2 = 4, + }) + + -- Marram grass + + minetest.register_decoration({ + name = "default:marram_grass", + deco_type = "simple", + place_on = {"default:sand"}, + sidelen = 4, + noise_params = { + offset = -0.4, + scale = 3.0, + spread = {x = 16, y = 16, z = 16}, + seed = 513337, + octaves = 1, + persist = 0.5, + flags = "absvalue" + }, + biomes = {"coniferous_forest_dunes", "grassland_dunes"}, + y_max = 5, + y_min = 4, + decoration = { + "default:marram_grass_1", + "default:marram_grass_2", + "default:marram_grass_3", + }, + }) + + -- Coral reef + + minetest.register_decoration({ + name = "default:corals", + deco_type = "schematic", + place_on = {"default:sand"}, + noise_params = { + offset = -0.15, + scale = 0.1, + spread = {x = 100, y = 100, z = 100}, + seed = 7013, + octaves = 3, + persist = 1, + }, + biomes = { + "desert_ocean", + "savanna_ocean", + "rainforest_ocean", + }, + y_max = -2, + y_min = -8, + schematic = minetest.get_modpath("default") .. "/schematics/corals.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + -- Kelp + + minetest.register_decoration({ + name = "default:kelp", + deco_type = "simple", + place_on = {"default:sand"}, + place_offset_y = -1, + sidelen = 16, + noise_params = { + offset = -0.04, + scale = 0.1, + spread = {x = 200, y = 200, z = 200}, + seed = 87112, + octaves = 3, + persist = 0.7 + }, + biomes = { + "taiga_ocean", + "snowy_grassland_ocean", + "grassland_ocean", + "coniferous_forest_ocean", + "deciduous_forest_ocean", + "sandstone_desert_ocean", + "cold_desert_ocean"}, + y_max = -5, + y_min = -10, + flags = "force_placement", + decoration = "default:sand_with_kelp", + param2 = 48, + param2_max = 96, + }) +end + + + diff --git a/mods/ws_core/nodes.lua b/mods/ws_core/nodes.lua new file mode 100644 index 0000000..78fa6c1 --- /dev/null +++ b/mods/ws_core/nodes.lua @@ -0,0 +1,170 @@ +minetest.register_node("ws_core:dirt_dry", { + description = "Dry Dirt", + tiles = {"ws_dirt_dry.png", + {name = "ws_dirt_dry.png", + tileable_vertical = false}}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, +}) + +minetest.register_node("ws_core:dirt_dry1", { + description = "Dry Dirt (top)", + tiles = {"ws_dirt_dry.png", + {name = "ws_dirt_dry.png", + tileable_vertical = false}}, + groups = {crumbly = 3, soil = 1, not_in_creative_inventory = 1}, + drop= "ws_core:dirt_dry", +}) + +minetest.register_node("ws_core:sandy_dirt", { + description = "Sandy Dirt", + tiles = {"ws_sandy_dirt.png", + {name = "ws_sandy_dirt.png", + tileable_vertical = false}}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, +}) + +minetest.register_node("ws_core:stone_with_coal", { + description = "Coal Ore", + tiles = {"ws_stone.png^ws_mineral_coal.png"}, + groups = {cracky = 3}, + drop = 'ws_core:coal', +}) + +minetest.register_node("ws_core:stone_with_coal_dense", { + description = "Dense Coal Ore", + tiles = {"ws_stone.png^ws_coal_ore.png"}, + groups = {cracky = 3}, + drop = 'ws_core:coal 3', +}) + +minetest.register_node("ws_core:stone", { + description = "Stone", + tiles = {"ws_stone.png"}, + groups = {cracky = 3, stone = 1}, + drop = 'ws_core:cobble', + legacy_mineral = true, +}) + +minetest.register_node("ws_core:stone_block", { + description = "Stone Block", + tiles = {"ws_stone_block.png"}, + groups = {cracky = 3, stone = 1}, + legacy_mineral = true, +}) + +minetest.register_node("ws_core:cobble", { + description = "Cobblestone", + tiles = {"ws_cobble.png"}, + is_ground_content = false, + groups = {cracky = 3, stone = 2}, +}) + +minetest.register_node("ws_core:dead_tree", { + description = "Dead Log", + tiles = {"ws_dead_tree_top.png", "ws_dead_tree_top.png", "ws_dead_tree.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + + on_place = minetest.rotate_node +}) + +minetest.register_node("ws_core:wood", { + description = "Wooden Planks", + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"ws_wood.png"}, + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, +}) + +minetest.register_node("ws_core:water_source", { + description = "Water Source", + drawtype = "liquid", + tiles = { + { + name = "ws_water_source.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + { + name = "ws_water_source.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + alpha = 160, + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + damage_per_second = 5, + drop = "", + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "ws_core:water_flowing", + liquid_alternative_source = "ws_core:water_source", + liquid_viscosity = 1, + post_effect_color = {a = 103, r = 30, g = 60, b = 90}, + groups = {water = 3, liquid = 3, cools_lava = 1}, + sounds = ws_core.node_sound_water_ws_cores(), +}) + +minetest.register_node("ws_core:water_flowing", { + description = "Flowing Water", + drawtype = "flowingliquid", + tiles = {"ws_core_water.png"}, + special_tiles = { + { + name = "ws_water_flowing.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.8, + }, + }, + { + name = "ws_water_flowing.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.8, + }, + }, + }, + alpha = 160, + paramtype = "light", + paramtype2 = "flowingliquid", + damage_per_second = 5, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "ws_core:water_flowing", + liquid_alternative_source = "ws_core:water_source", + liquid_viscosity = 1, + post_effect_color = {a = 103, r = 30, g = 60, b = 90}, + groups = {water = 3, liquid = 3, not_in_creative_inventory = 1, + cools_lava = 1}, + sounds = ws_core.node_sound_water_ws_cores(), +}) diff --git a/mods/ws_core/schematics.zip b/mods/ws_core/schematics.zip new file mode 100644 index 0000000000000000000000000000000000000000..c05b170a1dcf39e4658e2410b3aaf8480e803ebd GIT binary patch literal 1451 zcmWIWW@Zs#U|`^2IK4U5kFDh8#%v%@n2~`&97q=@XQbvPmSiRu>!+k9ro@*NrKakY zry6h7^3v7RJr%rSU0>L$fUeLDp#~QMJHk%+>Uy$#Za9=VbET!`QGqyJ4_8hqrV&K1WkA3x3aJVl%Eior2HIIB}u5rm&=Vb6%s5tnb z&C*YgemwcJC}j1ND@UgMn6&6hi0T5f9ZTJwL`F@Bm@*@qMaY5+e6I`-X6 zhEK^rNA>|RF2@=J9qW3=o2$Wq$MxdcDLt|s4_pdVm4x01vqY<2%YS+As+Ps+o&1x; znYMR?-V5Inyw+=~+A1aH5r%$VeZ*F)82giXm9=h@+L=- z+~Ui9O-{|Fk69K7=pjP!4bWjF9-VsmKu660rc7K8GofoJx}b*Md!Qp7jWu#XQ7wxn zs!i$V$b>!vCyPTF1{Q~Ah`3*20;WqwCJ_eQxgF?o21W)25CsG{@;%@E5wim zI1E8#P-L^PWfg>3A;4(I<{(hUK{f?j8b+AH2#gnOrhrm3vMJaS9Kw`YI7|U0KV(y| gr3i#6_RQGb0!kkN-mGjOm25z`66o_cK(!1E0DsKPfdBvi literal 0 HcmV?d00001 diff --git a/mods/ws_core/schematics/dead_fallen.mts b/mods/ws_core/schematics/dead_fallen.mts new file mode 100644 index 0000000000000000000000000000000000000000..930c2516ddddc0d5b5d0811fae5b2dbf7acea8d3 GIT binary patch literal 60 zcmeYb3HD`RVPIomWMHgkU}6v~FOE;nFG{saNli?NFDXh*WnfOsEUK83oRE-^($G|8 PkdW|zk%>X(4YLja&mR$K literal 0 HcmV?d00001 diff --git a/mods/ws_core/schematics/dead_tree.mts b/mods/ws_core/schematics/dead_tree.mts new file mode 100644 index 0000000000000000000000000000000000000000..b0b547cb232349b3ad22079289210afc9b455ee2 GIT binary patch literal 77 zcmeYb3HD`RVPIrnWnioa0R|=pf%4+`!7 VgoK2a162Y*Dj|)HK}46S4FGDo7+U}U literal 0 HcmV?d00001 diff --git a/mods/ws_core/schematics/dead_tree1.mts b/mods/ws_core/schematics/dead_tree1.mts new file mode 100644 index 0000000000000000000000000000000000000000..cd612618febe578fa5448404353159afa05b3478 GIT binary patch literal 75 zcmeYb3HD`RVPFK|dLUq6Vh|`Vj!(`nO0`PKEGmglDXL@;go~smro@*NrKVQQNlr*e TU^!T&kdTm;#>Bv@!NdUoDA5*# literal 0 HcmV?d00001 diff --git a/mods/ws_core/schematics/dead_tree2.mts b/mods/ws_core/schematics/dead_tree2.mts new file mode 100644 index 0000000000000000000000000000000000000000..dc4b7a2534c765d431865fa693116d737882ddc6 GIT binary patch literal 70 zcmeYb3HD`RVPIrnVqmPV2aDMgirNJ6QJDe)ymsi_rnk`odV P)~ruYU}IqJWMl>aqtg{a literal 0 HcmV?d00001 diff --git a/mods/ws_core/schematics/dead_tree3.mts b/mods/ws_core/schematics/dead_tree3.mts new file mode 100644 index 0000000000000000000000000000000000000000..1e271c3fdd41ef88b531e50b92d239cc257f99a1 GIT binary patch literal 79 zcmeYb3HD`RVPIrnV_>WY0|q7rf%4+`!7 XgoK2agH;9z32A9bX>1HK_n7$rtDYIG literal 0 HcmV?d00001 diff --git a/mods/ws_core/schematics/dead_tree4.mts b/mods/ws_core/schematics/dead_tree4.mts new file mode 100644 index 0000000000000000000000000000000000000000..05b0985036045383273e1e7da7a85b87075f2608 GIT binary patch literal 56 zcmeYb3HD`RVPIrnVqmPV2aq;fDfhs literal 0 HcmV?d00001 diff --git a/mods/ws_core/schematics/dead_tree_fallen.mts b/mods/ws_core/schematics/dead_tree_fallen.mts new file mode 100644 index 0000000000000000000000000000000000000000..f698cd29d08c02cb8a3be9ef3a07d7bdb985e1cf GIT binary patch literal 77 zcmeYb3HD`RVPIrnVqmGS2aDMgirNJ6QJDe)ymsi_rnk`odV WQXCF_4LES%~xISfWKSY!cXq8eHN literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/crack_anylength.png b/mods/ws_core/textures/crack_anylength.png new file mode 100644 index 0000000000000000000000000000000000000000..99174e04dc0d570c8b1eb5409345068a3010ea0e GIT binary patch literal 2547 zcmVpOrAb6VR9HuCm|1UBR}#lhx7%%lF){lH4cokoMw$-*63ZY35eUX^ z2sQ+4gIOXNGVnZkM?A2IZP+&(gPqvvHXQr+}76SK3l&0i@=BgTo{Itg*5yhCweKun&R{sGrlzDMT-{I zvN5=Ua4gLs0BshuK}ElSzib{E8Cl=e)#W10L7&%-k}?E%Q^i;mBN{zpMMZ^!xw*O7 zGll5m9x=dGtj&E8Wn;W_>5_}b<6iTlM~|`ydH(Df{-e-p2CLtgNnXS4+qbj5y}eo8 zkFyl&8t3=9bLaB=c+u35;tE~MOBMtMQU@U&*YFd6lkHcov^8zo)PmXJ{TSD%0Ib18 ze1nM^$w!1(%GpQNvhN*1@hg|hL4{;FygpE9rz$N&6c<_%G)44UG~z9YGzS9N03iem zNHdGl<#_;oL4i+)UlM{giUT3ujIa>~7+Dk>78zgBS7Ic9n1~RF9zm1E!5F#1hr&YC z0`faeWR;2R{M2dF8VZF%A{L7k`d+^5)Nk*C06OwbLfWk#Fz-JibD=n8>Qu_`^Fe{j zgb5R}x+k?*z#gpgcu*rkdrajF5{-%mM1xPCK0QSjPMkQ=VL@Pm2kpKAW3qtgq8(;p z@S8ta2(p1Wqz(l8{8HI=g?DdtC4iJZf{4MO2|yz+D`;OqdTp^-q=B4L>@89i zCe+Sk0cKj>TVv_q0g!wnjh!b?o^2=-v(~U0>o2sR=zq5 z)GMGFF?=trYfhg&?M8-&X=5jW2=fhQzLl=DsOI1{NTu6iB_67DE~R|;?pox^m6KL?W?}GXWrS;lc&i-QDd{_4TVc zD|l<-@lUm%c^I8c9;V{>#QcBo;6YXZYVZ{g5LR*Ez=7;+b>i&Vvv-0@)}=lMdMK0c znKNh3pwUht{`^B>v8QIzq_s-zr&y?U{mGLjXD#adQbvlzyh-{s{Wu-i;eK0Fx?!#Zu^l7$gx=klBEQ*8Nq~N5t6^ z@G>V$Q&g)hkII;7W6jJ{`zF;77g2Ka)~#LSKY7ZO z7WD~8Rh>|8w+3@F!h($r>(*_+(-LL$P{yf1b%kn#0l5f&`|KD98AuJ zcKt!9gt^2eZzokfr|B6{-O-~*-Ip6Se5K!B#fd1`2M%7oe3|Pi0tz##bbwAn>V!~~QjX`B^CVdgN zyc;8?23j9nNJpdC($bPS6tYC-@FNw3a3)CEXt!!(lwrlwv6%9~9v%@VUxknff*U7At0mTAjK zjI+++!-t)|1vcuNpaVGDv113R%?NeR!-yLQM1f8zoHl6nqDp@iy}+T-FP%&~j~zSa z{_*wKPCejs*1RvM`&%@KdS>YSpo**&$gCg+v`8 z)&?8vS?V)oa%}_wL#vdK52qhw|aG*dfW#OUuANmrWR+${|8mbrC@I(_0~5fOk@*>%_xi+ z5_NWVma?L4pDW$l2tKj!l882-YJrIg0meAmV8K7X`Nm@cBap+FFK51mY=A`i!nEaktaqG>+gSsq? z3=S7P%cLb_-()2uOV4ONa&Rj1x~zi0hLsMB7&+5rGS20gI6V6H@AZS{{Esd23}+V_ z>fEh9t5_@1-&fw8y7j)?q3yfBu1t-Zn{zBtvaTv~=ZtT+Rcp5I`~R!;{Pq16mA~xQ z*MFKl?e@bInZEM$&Cl{~=|6n^Ir4MCZmX92XXcoj{;733Y`@I+;gmzBt=U}HMb>G? z1n*c@;QMeEnF1d^yq+1n=kbQ~T1x*E5JT7l+M@58do$zn=9N=)@bnn?JlE zt*Tkl7}(!$V({wYL^ii=$6I;#Si4ERn922J#{|Y`*W(<_w!xAOa^Y#7?2;S12x6(KX=xICUC1D{_C?OAt6%?vvZSZ0pUXO@ GgeCy_1gjVT literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/gui_hb_bg.png b/mods/ws_core/textures/gui_hb_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..99248e1768bb3e599db1496743d0d881f715c8c8 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzy3?w~+F2@5Y<^Z1%S0KH-%JvqJVk`;r3)X%U prKkqv@Orv9hDb;zORzRG0i`+^7$4|}O$16Xc)I$ztaD0e0svDU6Ey$; literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/heart.png b/mods/ws_core/textures/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..6d4e228930dd00bcff09f16a30e2873ce1c7feb3 GIT binary patch literal 14830 zcmeI3TWl0n7{^ar0a-$AF%fG5OsB2X%kEsdTiS7#UUmz+%FxoTp^b{2&Yta#?9Plc zvvgZA78(*suqZqTL?cFHObkR+u3BkGkl+(R6Q%JI69n~zMq-rufM;gg-Ij}TLP&f# zo9u1QZ@%-L-~8vi&DOTnE9bi&Z~*}3N5Y|Y^j%`V@1Bi5mt4Lop|81mxXT1!-o5s_ z0PK0=egNvKm1w8cDXtP^E#;A7S`YMOQaYjm@Hb?1NnQ^vst5KeYJk4<>2aD;VgY)s zPh>?s2op+pzyR?P~#M7Blp@tC6bF`?%lz9I&bWN14N08v-ucc8CW0ED^3Lle&xMrjzq*zHwy^zt>UT50eH57tc zQZrBosMDIMjzm$2sHP>UGK_=*G+L2IQDQ=!%*FY-9^PHUOOo5md%bQc4taNvkFBk( zW8*b4FHb8G(&V%qu&EL;{1UB(f^J_ad0VCI7zn5mYDKc|sQ}G6T{_1*?O-L-+2hN2 z7QGnG{>&p?|Bd8{CshT>=AE~{`jw~Y??eD+`VZ&Gpg3yN~?F+q~EYn1Iw!s+Jv8Zs%&} zs`MowlKby@&%ve^xB4UlHua+Ga%*=NGr3sC-V~=+>u0X>;dg*(yC^y@dkpQ)Xq#tp z`~0LY)YP4POCg~!&unb_qBwa)omH{l7q>JdnGJpk>bP-)x2C!g~ zE}{#|02WNrMRZ{qz=BD-h%PJxSTIQ!(S>CI3nu9zy08pj!6aQo7nT7mn52v7!ZLsb zlXMYXSO&0Qk}jeP%K#Sqe@K@r|M(wN(KCMrdbkh%kop=u7)Z(Cb`gMqDgXwD0Jw4$ zeg6tTng!suZUBT`04&sYJbQ8l00oVaP*XHB_Sw#n$BWjKY&l+9es1tw_cm9-$rE23 zK5(#PRmGa|s*RhXV=wRBa&Sz6TJLLL(%gdJ*~-$F^rBPrvL`lNmP^M+N8yo+-yJpM zs}_9RJzT~uX?=Rv>A_mPvTXFgZllrlZTe`*juX|J3WH6>Bl|1UhmO75ai-|~d9KE) zGwi9^fg|3pibvy%`L6JLiO)w~{pFAG4@7<6MB)Cy7uQDqnpJQfG|ao=3;+En6MuW% z(DnyEnfTMcutH4UQ@qY~wyg6<&`>m&sccREG^hIT;HB2grRIZ$-xqtID{U@IY%|LX zqJ#TREq#4_;{3&d(B8tzrAI%UbF5(2a@Tzm&ny{!s;&G&bEt7a%b7**oPVK>Te0{N zYU@x_Rgl?UvGM{nym|MbH%Go1?cZ3qC^^P2+7lT)eb?`A6<+=5mE%R=v7J9tYZDKj Qw4ca~w5$&8Z|>gw51Z)1CIA2c literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/wieldhand.png b/mods/ws_core/textures/wieldhand.png new file mode 100644 index 0000000000000000000000000000000000000000..69f4b7bf966270edd12d85cb6370433181d0354c GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^3h)VW1=5cXEWW#S+Pxh!AMBoU zYvaT`uCR+hQO1%WzhDN3XE)M-99d5n#}JO|$qM2dEVQi`7)h{B4_-d&|69Qz`0$A3jlMbdbTjgCilcJKbK+mapYKN*C^J#L5(fv!^ORd z?{@WVZsYy(fsi>c)I$ztaD0e0sx=tci8{{ literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/ws_cobble.png b/mods/ws_core/textures/ws_cobble.png new file mode 100644 index 0000000000000000000000000000000000000000..0bd8ca667b35f600d0ebcf1d19c807ac14af4ede GIT binary patch literal 827 zcmV-B1H}A^P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0? z(^eFQx3negtwWqRcACVtlGrA=A=6IcPy%Uy0tJQ}2Krci1Kx(|Ri;4N8G->LYy}_W z#+Gb(OR`Q|LR}Z@Vy%DvS>Hd4dG+egx9{Fm$|V_dbBEkIJ{b;&aYU`DHJwgGf#2Dw zMkyZ${?|^ctkz&*RSbN;uquCUU(z_~cG~jNiYO{qqyN5Y9oJoKZ2mCl_1|B7NC9*2 z-hH-SuSpmRND(l)d;e5YWWCdNT>@AZi^BSPo;bcuoHR)ee!kJa?7)YQ4s9p8b9{66 zT8$=27|}G2C*#p5S=R{y&-25`w8+GqV}y!p8<{kh zlSB+@nhcGr(a74WUUvv7t`*pBw|8`N-y<{6_oL9wc>MqQzRhe`k`)@KGzD0~A3uE< zoA%~rh2?oZn`YiLissHdt5&P!FT9Mktd@n0gM)v)e%;l&Nt$%K8f+f@m|vC?z+2`x z3Gg(L?116+Z|oz1$*(L) zk~|q-jSR#0!xw)%M~I6?sRwOZs=)mYBghPM9LI`(vxAz+LQe`Xf z7GcElf>5niR`Sci!dDbYQIv%r)M^dO8ar+l?3~32FvucK0LVND36!N`MO9gl zgyCW^Fy5X2&GQ1KRQsaATeq9K_L;{RBiSW0p5=Hf{&Rk=>w0Ok^7!!+Ro(d3??47l zr#4L}x7XM+jLYGro?Wc9HG4*6Ndh1hvB1D2``?M_GIPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0xwBKK~y+T6_RI? z+b|4;!6s6YC6~3Ga+e$-4=%*wf@#|GaX$@1 zDtLT5e!RaQj@!%UV2oCrU2ntpQ-7ZvcRn`Vei$ug{CmAW#|0o`&X3n7xk^<4z`2l0aVjuGAwWw_uS$s+Ft|XI ztn°+#qRCZ#GePlDnw)w<$J<`|?9lLuCUZn|k&x>_@qb3q~4YjVRdt^%^mfW??g zNxQ!B-ac=)uV23b6V9jL;&H!W0MGI11Kj|;U=~7r{P|rn00Y5zjM&yvuwt|X8eSL| zBw>ebw{D0?j?20#qp2GvxN|c(Ec8%-7+AZMQV!i_J)J1i$a#tT-7ZB(OeGhl(#tf5 z5EDXcs?W!3*Kb6nRsjueJ3UTg+cZWSS=Zi%u5BK#M~IO+Mr)JD{kET{Www?CbS~&t zlh3#F858E@xD>$=M@3Qi#cvudlsp}FN^%l_^Vqblk4Ww=mq7{e)LpHy*cb={)ug0? ztvTef%=4G?+wJrInr%klf+Hc2?07tllRqE&zV8Sq?Y4{O^vOuJ%rWPPsP4CG7HYDH zJ}|~v$wpVy>t?c+XaTS3(z?G~|D8{#=j)|)rFbPdg&DVpjx47FoI%}Itr0nALhh&W zvD=tTe++|GtG7c}c07*qoM6N<$g27TS A3jhEB literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/ws_dead_tree_top.png b/mods/ws_core/textures/ws_dead_tree_top.png new file mode 100644 index 0000000000000000000000000000000000000000..52fb88b7735dd180c774bfbb5feb2fa4c83dea5a GIT binary patch literal 693 zcmV;m0!safP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0!m3lK~y+TJyJVw z6G0H(*FAl4u!7@=pb$vFkOm>3LI{Zxi3ZWoQqck>6&=5bf{ua;2_znhoP^*A+fow6 zuY2F^-tw(a%IJ1>H8=Ckd^1Dezj;2L=DuwyM)Iso3+36I5E8f+G$dLW@qoS43h296 z&mKRxT2;z-t*SB}j2T^&5+5Fc??NY83H|Z&9|2%^hf&@ij+cUllw}yFmf%`z#|8v2 zLfaCIlJ?3nVgwGb`@^%fcFS`_!)pX>s zT|7Vq4+veUhG|IW_6+uf71nPnMB!FiTt=omBP7Xhy4G9fr)s#N<2 zgW>2@mL+)CnHOG0Se6yIN~wyXsFdj=D%M1YVGLvdm4%wjBiO;y1mHj%OXQ`Bl3Xf< z;Om>6?$$b^=C5TLx|}nN#gNXVnN|hTu1z#qU1=WvJO0@_>KzV#^!mPIqa&i8^e^?F-8R>f}P?MTwG5=NaZ~0yr0%(m2VemT8*K!*nu> zC{ZpaNs=cEo{)CaGLR?hUv*Tit}m~#-*&r^YmmIrCE`rd9&f76T5%M z^!3Z9PabVaDVu=@3^1#^aV~Lc;PXNXPCtD)q95MAIG#kQRPDeFvR-Cv^7(qBZs>aF bJFVb9@%1rq*e1%400000NkvXXu0mjf&MZQZ literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/ws_dirt.png b/mods/ws_core/textures/ws_dirt.png new file mode 100644 index 0000000000000000000000000000000000000000..18e0054d2d7be374a98d594c58b5cadc97b5501f GIT binary patch literal 750 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0)t6JK~y+T6_V+4 z+cp%10bFjNxIm(0nQ`RAl{0CxH2IOq^iOB{27QA*Mc=kFjU79#?11_Vs3amQ_^~_?}P`GTI;#_>Skft^=p4d7iKJtjoGX2*V|#s}+-KtzyYtpQDr1MvCH6*5Mv z!F8O+vQHMlMV=L9Teoe#%{E!04c11_1`S*SMx^J;8tr;nR2_BU;%r$roGlr~WSXX@ zV=W{fgcRH=lKVqJtj0QHRmT@$5C&e`^RDZkj>YHSK2@#YQU!sZMqv~!`kuS42k&2Q z2QgZzY?Un2#rV%o;sB z6*hSLVw$a69Z?#G)b{Y=*&5E%C{5^c;Rrc#p;jzfuaaSqLaAZkETT5?*_iKT+i=x( zJ^cRudejCmG`)~gP6kOKH>=bbW6@pD$uF<&@9xew>@v@=8xjoAwEg*R#}bM#_B{uJ z$n#*DW^jNIa(DCZYRLw!zTAI@S(5E0bqM+PG`^`fj>%Lzb)CZerv4?>RcVgD?S<5OALGM6#6 z5nVk$voPz67ou-pzs%z}l$>YF*q*L6M)K_n&oXeme8U#hw|+Pu3Btv<8#QW;Oy3RI g=wT4YQv*Q$2Y;A^d~J!Ca{vGU07*qoM6N<$f?644Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D01{8@9Afw_UBOtb_z;PkZ6WfdgE*Ao0iXCvf6~1ecZ29+ssl zZIiZkVmpaFcKj1_d|&B(-_u7A|MbncEDJ*zv(uydMYN8$o+E*1n@wy%O>HmU>@>iF z>xLrqLplXGvaEo@B1;#G8a%pU6^W-A|0r z{o+vyw%#Tt=bf}ID=&&yv(HyyR5mD#cWS$VzQLk(l&a+Fe9ClK2Jz8oh%kzi^m(=NL~!=upBrh2@o0D;u)!Gum=0}~<#C#I#;IeFck>AXVsO1f zp5?{=D`@InsxaU*Nf;N)$477Aa!p(K5vDph_fWads=7&&OlKM(#C4fw8A6!0coBs2 z*H_i>YnN_2#D2H|X>cj~E$Uk1D2h*ByqLWGkyN=Qu$K7%0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0)9zEK~y+T6_VRh z+(r~d`y#cvb#09Xh6x2R1+KEON&Jwa@{+3jLH;0Lk-v?TfCHGpGo#B$YIUnGZr;yX z`|N!-{Oiv@9>3hJj;p5WXhbHZfwK-E8U=)eVSqQ^>XN5}?RvF5s&ea~b=EjA3W*^=gHYaRKgeCvvk;#imu)9_$sr1~)-T(3 zl46|XBs>v4JnxWaEGyphB8h2C$zc$EKfG*rx4-_<93~+ZrBRW_X_^d!2t$Hz-mJ!H z_E%MlyeyK3O(SRh?((eO?esijjQ4fFZ~GuXMV9u1Kn}t~FN)>y)AM$->i}@Zf~S|A zHP%mP+_4xpZ{Sr8V6BU6@nOdhvDSxjOPqM7?A+e zln|`7!2w1H{eSoGqU7F2mc>KYq190lAn^76K9AX_kC#3dWaQs>8^5f)qEz0Ke*;4J z>$hf<3co*F&A?Yfg(3d(wDrsTrYo|zAEvrJXzR2wlQv4KRaJOFl*S|`co@aL=@%KZ z7Oa-M@N#JqdIkh}%FL{J7E7PEHYkb+&uED8`iL73lgjuIjMLNTOL4L)2}UUmeB8cB bF{9rB_Z)A}23m$<00000NkvXXu0mjfwNYQC literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/ws_mineral_coal.png b/mods/ws_core/textures/ws_mineral_coal.png new file mode 100644 index 0000000000000000000000000000000000000000..745fe2ec78291891f2756005329cad3a0fd727de GIT binary patch literal 435 zcmV;k0ZjghP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0Z2(iK~y+Ty;41E z!!Qs%N&cwoF6rbUg&LAlLQ6h8C;xwGn!N-M&EUy_#5N%gQS*dk9NUm~=>wsAr+atO zo#@~3G91dqd@eO5uJ>P~Je?>>63vL1-fsd`zc(9Y$8lWgD&x*!{^2NdO^Gw&XG!NM zie#Fm+IuYqswdRN0K}uwNbYw#dhGR-&xi$QRy3Q*dsjRtM;L}xQxF9H)bCTC=d{l< zA}J{d0>xLWPkS<%mg#n@V!08UD&WROP+69=UVm9=obUT�J%S>OusfnyCVxV=?zR z930e5ih|IWWx>r8-on;X=@ zSo_a(CTKcwUC-e@l6EC-ePz${v_)iF%o&fT$8hkPVVr1g6YVZG;M&}Kd!H0$G9Sz3 dP0b%b^aCFblQt|W577Vs002ovPDHLkV1ggnw=e(z literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/ws_rocky_dirt.png b/mods/ws_core/textures/ws_rocky_dirt.png new file mode 100644 index 0000000000000000000000000000000000000000..888e89d27f69c251b1dd862095d3d8d8f445004e GIT binary patch literal 732 zcmV<20wev2P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0&z)1K~y+T6_VL* z>_iZTdvh;d#-1&ci4x^NIEXuhgt+AekdSx|Uim0GC}^0)YkS=8%}t-%QkAOy`abyg zUw>HF0sxXE;f&7O6nUo9?7Ux>+pe#jch)*ak#`=`0x>$q?yeuT0bky~lzD!>TxT^V z7_@z(W_UW^7-O6D5fi+)5$TXvYmJ$2^=WZP8J!A7NRYDq@BGm;UjZ~=F-=$ZQe(pL zFW+wkqw8uHfSeE98d@Ty9O%_k)x|aOcr% z6@EMHfBO6xV=U6ldk~hG%|QTSDom)LNt))z{W?ht0--Vvf43_rg)|9S%G-W8-)g~g zh!SJNtgXDOGEY!YHr{2Iwr$Z5Z!huXgB%Arv~92x_? z+f-BmvIsO6)Xw%UyKbC@p+h*suLtg|%LTjDH#v@ivtm_Q@2*Y9ST@}afN;B6msy4q z^8U{U{`2?WvMh`FI8R@nKM~>~B6WSDB%)hrLNU^j14~mW^|~rhgsrBr9-0LE%jG?4 z$D=vbF3+fS!3XnAK5f;sTCz?u O0000H-P-MN4RirPSS~r_49V!%&+k5tW4!O*k) zp_F2#1j9IByW0~eV)g~%#KU@x$gAL!=LT&%BG%d~g2o-tliglp1oGqDI zlZpYKNTnx$XYhzgZc#V=nSvZ^Oz1{gmjnZ5`HU5@8*=d@KmJ)+BtR6n?{yGb32#BI zTSueE>2$>X=SNoHgPlwQozZoq0t!6Pw?+M?*T|^XKL25_G;!xnr%>(;Q<=Y{&&Qsio6p~nBU2Zui1y&y}IY2q> z5h;v_emua>rc2yheL~Crm(>Y%T~jz4oD{_r3d7K2KAQ%u6onOPZ<|-B`@3&J@l#b% z#D)(emWx%eWvLE!X|r>dV2VIM$sMSgns3|%X_K7H=4@w5zGO^z!zq-^ma`FB*KxV} z0f*B8RdrwjgRi%b=Vg+w>$<>ODyUgWI$HKRqfA^d&dST?`J5=tAXUrE$WEL^3}Qui zdi{$FinJny(3z&9pe;7rXRI!+v6#+-s8aPnE<*Dku<&Yco_^TL00000NkvXXu0mjf D9dSrF literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/ws_stone.png b/mods/ws_core/textures/ws_stone.png new file mode 100644 index 0000000000000000000000000000000000000000..da5b4b0bcbef8d2a36f0042fdc0235f7e37edc5c GIT binary patch literal 772 zcmV+f1N;1mP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0+~rfK~y+T9h1p! z)Ibo1-QC{z**r@iGZK)X96*X9A#sKm;SIQuH-G~?9a4}$9D)MlnX$)v+itsUQxl)s zb}j$+S2g z%d$1~Q_r%jIPcr0VRc0?A{UpNS67z>r4ZM!R@arbZOgLcosgwjCk(^TAESt15+x}J z&S`~TUOfBr@D~(_qNwX22EoB`oYl$`ut19k?7PIrGEAsx`TUAlVu3NLl z(6uzpK|&bD`$IsBN;qkT#_j1lWBxuA2|~BGA1u>?9~fikFmj!~?-^@F5RNfmTb9AQ zz8^Re@F6^ww86GzbzKk9Pz<_<$4Df^(3GMq!R4myw!1y>1VIjYwrQT7dAKNQz zkqg$%CKHK}`-dIm1AlM~lQgHaY8(1*yW8y_=Odm3A{bGeq+n>47r*Zxz$;Z%WmP#_ zda@*Dd0N%X^QP0OqsTJeoUb59mPwox5EdtyVW`8vec#{t2XK5c8P7d$vsq_(2?oMc z$j!~wBMcvpocU}T#Ze5|Wj&jYi=u!Mc|nDtPZHqagb+#_^zG{>zyMs+G=m@}WLPej zS(Y`dL6{i2j*$SuAV7qrLIMPn>+7pH$w3}~jYl>SMezC<#Cdrd6s6^9)4GX&T&xD2jAVHcY+mNf?Gn68{H{TBojHPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0ij7mK~y+TJ(EFF z!!Qg*ZO4w?(2H^gI1L+az=jnt12YT^%PzPDEo~Fq2~To~rsI5l%hH$Z+Q-LxV@%FD zgqZWl4^T>h#FnMvu9)@p?cF{++&w?N#Mpb^l~SFvY;>4&i!r#GQz`<;pcDwJEX$4QsRrSOFgk??F}# z6Jv&~jUgQ~lesBnVhqZzsw9je>uFW7Fe<^!02y*Eo%Grw5HF+FTWUoB^UN)2Kebd? z2xg;=>TPH=K;Mw$QtVrMqK)w#k7wjjjXfB$sA+aBMf7<*?f1WOr=9OojC96(AZ6eC zb}jk{r2?SyK^}4Ehhdb} literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/ws_water_flowing.png b/mods/ws_core/textures/ws_water_flowing.png new file mode 100644 index 0000000000000000000000000000000000000000..3644dfc66d5fe9b4ac7a319178dc201cba8ea92a GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL5ULAh?3y^w370~qEv>0#LT=By}Z;C1rt3( zJ<}BT2#_^ao-U3d7XC|57z#2d@GuyPgh`2Q=xXHoW0-O>s`{LG+CiNeteX?W&NM|D fa3eTBbI!3^&94@4sY^TuG=;&_)z4*}Q$iB}w*@)S literal 0 HcmV?d00001 diff --git a/mods/ws_core/textures/ws_water_source.png b/mods/ws_core/textures/ws_water_source.png new file mode 100644 index 0000000000000000000000000000000000000000..ce59152c6a9d31a10ca14e5f4b5a1d9798bcf5c8 GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL5ULAh?3y^w370~qEv>0#LT=By}Z;C1rt3( zJ<}BT2#_^ao-U3d7XC|57z#2d@Gux&xhfX4p{tSSk73HmsOod#X$N&?ux?HeJJS?t fz>VPi%sIze6PF_J*Wr;B&=dwwS3j3^P65k`LtNrDVJvzTJw_e=X