diff --git a/.gitignore b/.gitignore index 717f5fe0..ef02689c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,22 @@ -## Generic ignorable patterns and files -*~ -.*.swp -*bak* -tags -*.vim - ## Files related to minetest development cycle -*.patch +/*.patch +# GNU Patch reject file +*.rej + +## Editors and Development environments +*~ +*.swp +*.bak* +*.orig +# Vim +*.vim +# Kate +.*.kate-swp +.swp.* +# Eclipse (LDT) +.project +.settings/ +.buildpath +.metadata +# Idea IDE +.idea/* diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 00000000..52b25132 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,17 @@ +unused_args = false +allow_defined_top = true + +read_globals = { + "DIR_DELIM", + "minetest", "core", + "dump", + "vector", + "VoxelManip", "VoxelArea", + "PseudoRandom", "ItemStack", +} + +-- Overwrites minetest.handle_node_drops +files["mods/creative/init.lua"].globals = { "minetest" } + +-- Don't report on legacy definitions of globals. +files["mods/default/legacy.lua"].global = false diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..5253938a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +language: generic +sudo: false +addons: + apt: + packages: + - luarocks +before_install: + - luarocks install --local luacheck +script: +- $HOME/.luarocks/bin/luacheck --no-color ./mods +notifications: + email: false diff --git a/game_api.txt b/game_api.txt index 634b7f29..38718c36 100644 --- a/game_api.txt +++ b/game_api.txt @@ -12,22 +12,28 @@ Please note: * [XYZ] refers to a section the Minetest API * [#ABC] refers to a section in this document + * [pos] refers to a position table `{x = -5, y = 0, z = 200}` Bucket API ---------- The bucket API allows registering new types of buckets for non-default liquids. - bucket.register_liquid( "default:lava_source", -- name of the source node "default:lava_flowing", -- name of the flowing node "bucket:bucket_lava", -- name of the new bucket item (or nil if liquid is not takeable) "bucket_lava.png", -- texture of the new bucket item (ignored if itemname == nil) "Lava Bucket", -- text description of the bucket item - {lava_bucket = 1} -- groups of the bucket item, OPTIONAL + {lava_bucket = 1}, -- groups of the bucket item, OPTIONAL + false -- force-renew, OPTIONAL. Force the liquid source to renew if it has + -- a source neighbour, even if defined as 'liquid_renewable = false'. + -- Needed to avoid creating holes in sloping rivers. ) +The filled bucket item is returned to the player that uses an empty bucket pointing to the given liquid source. +When punching with an empty bucket pointing to an entity or a non-liquid node, the on_punch of the entity or node will be triggered. + Beds API -------- @@ -61,6 +67,21 @@ Beds API } } +Creative API +------------ + +Use `creative.register_tab(name, title, items)` to add a tab with filtered items. +For example, + + creative.register_tab("tools", "Tools", minetest.registered_tools) + +is used to show all tools. Name is used in the sfinv page name, title is the +human readable title. + +The contents of `creative.formspec_add` is appended to every creative inventory +page. Mods can use it to add additional formspec elements onto the default +creative inventory formspec to be drawn after each update. + Doors API --------- @@ -177,6 +198,9 @@ The farming API allows you to easily register plants and hoes. `farming.register_plant(name, Plant definition)` * Register a new growing plant, see [#Plant definition] +`farming.registered_plants[name] = definition` + * Table of registered plants, indexed by plant name + ### Hoe Definition @@ -213,6 +237,14 @@ New node def property: * Called when fire attempts to remove a burning node. * `pos` Position of the burning node. + `on_ignite(pos, igniter)` + + * Called when Flint and steel (or a mod defined ignitor) is used on a node. + Defining it may prevent the default action (spawning flames) from triggering. + * `pos` Position of the ignited node. + * `igniter` Player that used the tool, when available. + + Give Initial Stuff API ---------------------- @@ -244,6 +276,18 @@ Give Initial Stuff API ^ str is a comma separated list of initial stuff ^ Adds items to the list of items to be given +Nyancat API +----------- + +`nyancat.place(pos, facedir, length)` + +^ Place a cat at `pos` facing `facedir` with tail length `length` + Only accepts facedir 0-3, if facedir > 3 then it will be interpreted as facedir = 0 + +`nyancat.generate(minp, maxp, seed)` + +^ Called by `minetest.register_on_generated`. To disable nyancat generation, + you can redefine nyancat.generate() to be an empty function TNT API ---------- @@ -272,9 +316,9 @@ TNT API * `position` The center of explosion. * `definition` The TNT definion as passed to `tnt.register` -`tnt.burn(position)` +`tnt.burn(position, [nodename])` -^ Ignite TNT at position +^ Ignite TNT at position, nodename isn't required unless already known. To make dropping items from node inventories easier, you can use the @@ -330,9 +374,127 @@ To use it, add the `on_screwdriver` function to the node definition. * `new_param2` the new value of param2 that would have been set if on_rotate wasn't there * return value: false to disallow rotation, nil to keep default behaviour, true to allow it but to indicate that changed have already been made (so the screwdriver will wear out) - * use `on_rotate = screwdriver.disallow` to always disallow rotation + * use `on_rotate = false` to always disallow rotation * use `on_rotate = screwdriver.rotate_simple` to allow only face rotation + +Sethome API +----------- + +The sethome API adds three global functions to allow mods to read a players home position, +set a players home position and teleport a player to home position. + +`sethome.get(name)` + + * `name` Player who's home position you wish to get + * return value: false if no player home coords exist, position table if true + +`sethome.set(name, pos)` + + * `name` Player who's home position you wish to set + * `pos` Position table containing coords of home position + * return value: false if unable to set and save new home position, otherwise true + +`sethome.go(name)` + + * `name` Player you wish to teleport to their home position + * return value: false if player cannot be sent home, otherwise true + + +Sfinv API +--------- + +### sfinv Methods + +* sfinv.set_player_inventory_formspec(player, context) - builds page formspec + and calls set_inventory_formspec(). + If context is nil, it is either found or created. +* sfinv.get_formspec(player, context) - builds current page's formspec +* sfinv.get_nav_fs(player, context, nav, current_idx) - see above +* sfinv.get_homepage_name(player) - get the page name of the first page to show to a player +* sfinv.make_formspec(player, context, content, show_inv, size) - adds a theme to a formspec + * show_inv, defaults to false. Whether to show the player's main inventory + * size, defaults to `size[8,8.6]` if not specified +* sfinv.register_page(name, def) - register a page, see section below +* sfinv.override_page(name, def) - overrides fields of an page registered with register_page. + * Note: Page must already be defined, (opt)depend on the mod defining it. + +### sfinv Members + +* pages - table of pages[pagename] = def +* pages_unordered - array table of pages in order of addition (used to build navigation tabs). +* contexts - contexts[playername] = player_context +* enabled - set to false to disable. Good for inventory rehaul mods like unified inventory + +### Context + +A table with these keys: + +* page - current page name +* nav - a list of page names +* nav_titles - a list of page titles +* nav_idx - current nav index (in nav and nav_titles) +* any thing you want to store + * sfinv will clear the stored data on log out / log in + +### sfinv.register_page + +sfinv.register_page(name, def) + +def is a table containing: + +* `title` - human readable page name (required) +* `get(self, player, context)` - returns a formspec string. See formspec variables. (required) +* `is_in_nav(self, player, context)` - return true to show in the navigation (the tab header, by default) +* `on_player_receive_fields(self, player, context, fields)` - on formspec submit. +* `on_enter(self, player, context)` - called when the player changes pages, usually using the tabs. +* `on_leave(self, player, context)` - when leaving this page to go to another, called before other's on_enter + +### get formspec + +Use sfinv.make_formspec to apply a layout: + + 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.25;1,1;gui_hb_bg.png] + image[1,4.25;1,1;gui_hb_bg.png] + image[2,4.25;1,1;gui_hb_bg.png] + image[3,4.25;1,1;gui_hb_bg.png] + image[4,4.25;1,1;gui_hb_bg.png] + image[5,4.25;1,1;gui_hb_bg.png] + image[6,4.25;1,1;gui_hb_bg.png] + image[7,4.25;1,1;gui_hb_bg.png] + ]], true) + +See above (methods section) for more options. + +### Customising themes + +Simply override this function to change the navigation: + + function sfinv.get_nav_fs(player, context, nav, current_idx) + return "navformspec" + end + +And override this function to change the layout: + + function sfinv.make_formspec(player, context, content, show_inv, size) + local tmp = { + size or "size[8,8.6]", + theme_main, + sfinv.get_nav_fs(player, context, context.nav_titles, context.nav_idx), + content + } + if show_inv then + tmp[4] = theme_inv + end + return table.concat(tmp, "") + end + Stairs API ---------- @@ -343,7 +505,7 @@ delivered with Minetest Game, to keep them compatible with other mods. * Registers a stair. * `subname`: Basically the material name (e.g. cobble) used for the stair name. Nodename pattern: "stairs:stair_subname" - * `recipeitem`: Item used in the craft recipe, e.g. "default:cobble" + * `recipeitem`: Item used in the craft recipe, e.g. "default:cobble", may be `nil` * `groups`: see [Known damage and digging time defining groups] * `images`: see [Tile definition] * `description`: used for the description field in the stair's definition @@ -379,7 +541,7 @@ Creates panes that automatically connect to each other ### Pane definition { - textures = {"texture_Bottom_top", "texture_left_right", "texture_front_back"}, -- More tiles aren't supported + textures = {"texture for sides", (unused), "texture for top and bottom"}, -- More tiles aren't supported groups = {group = rating}, -- Uses the known node groups, see [Known damage and digging time defining groups] sounds = SoundSpec, -- See [#Default sounds] recipe = {{"","","","","","","","",""}}, -- Recipe field only @@ -416,6 +578,7 @@ Sounds inside the default table can be used within the sounds field of node defi * `default.node_sound_wood_defaults()` * `default.node_sound_leaves_defaults()` * `default.node_sound_glass_defaults()` + * `default.node_sound_metal_defaults()` Default constants ----------------- @@ -591,3 +754,83 @@ Trees * `default.grow_new_snowy_pine_tree(pos)` * Grows a new design snowy pine tree at pos + +Carts +----- + + carts.register_rail( + "mycarts:myrail", -- Rail name + nodedef, -- standard nodedef + railparams -- rail parameter struct (optional) + ) + + railparams = { + on_step(obj, dtime), -- Event handler called when + -- cart is on rail + acceleration, -- integer acceleration factor (negative + -- values to brake) + } + + The event handler is called after all default calculations + are made, so the custom on_step handler can override things + like speed, acceleration, player attachment. The handler will + likely be called many times per second, so the function needs + to make sure that the event is handled properly. + +Key API +------- + +The key API allows mods to add key functionality to nodes that have +ownership or specific permissions. Using the API will make it so +that a node owner can use skeleton keys on their nodes to create keys +for that node in that location, and give that key to other players, +allowing them some sort of access that they otherwise would not have +due to node protection. + +To make your new nodes work with the key API, you need to register +two callback functions in each nodedef: + + +`on_key_use(pos, player)` + * Is called when a player right-clicks (uses) a normal key on your + * node. + * `pos` - position of the node + * `player` - PlayerRef + * return value: none, ignored + +The `on_key_use` callback should validate that the player is wielding +a key item with the right key meta secret. If needed the code should +deny access to the node functionality. + +If formspecs are used, the formspec callbacks should duplicate these +checks in the metadata callback functions. + + +`on_skeleton_key_use(pos, player, newsecret)` + + * Is called when a player right-clicks (uses) a skeleton key on your + * node. + * `pos` - position of the node + * `player` - PlayerRef + * `newsecret` - a secret value(string) + * return values: + * `secret` - `nil` or the secret value that unlocks the door + * `name` - a string description of the node ("a locked chest") + * `owner` - name of the node owner + +The `on_skeleton_key_use` function should validate that the player has +the right permissions to make a new key for the item. The newsecret +value is useful if the node has no secret value. The function should +store this secret value somewhere so that in the future it may compare +key secrets and match them to allow access. If a node already has a +secret value, the function should return that secret value instead +of the newsecret value. The secret value stored for the node should +not be overwritten, as this would invalidate existing keys. + +Aside from the secret value, the function should retun a descriptive +name for the node and the owner name. The return values are all +encoded in the key that will be given to the player in replacement +for the wielded skeleton key. + +if `nil` is returned, it is assumed that the wielder did not have +permissions to create a key for this node, and no key is created. diff --git a/minetest.conf.example b/minetest.conf.example index 813f1957..3f20eb77 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -5,6 +5,12 @@ # Whether creative mode (fast digging of all blocks, unlimited resources) should be enabled #creative_mode = false +# Sets the behaviour of the inventory items when a player dies. +# "bones": Store all items inside a bone node but drop items if inside protected area +# "drop": Drop all items on the ground +# "keep": Player keeps all items +#bones_mode = "bones" + # The time in seconds after which the bones of a dead player can be looted by everyone # 0 to disable #share_bones_time = 1200 @@ -14,9 +20,12 @@ # 0 to disable. By default it is "share_bones_time" divide by four. #share_bones_time_early = 300 -# Whether standard fire should be disabled ('basic flame' nodes will disappear) -# 'permanent flame' nodes will remain with either setting -#disable_fire = false +# Whether fire should be enabled. If disabled, 'basic flame' nodes will disappear. +# 'permanent flame' nodes will remain with either setting. +#enable_fire = true + +# Enable flame sound. +#flame_sound = true # Whether the stuff in initial_stuff should be given to new players #give_initial_stuff = false diff --git a/mods/beds/README.txt b/mods/beds/README.txt index 9710c459..cda6ebd9 100644 --- a/mods/beds/README.txt +++ b/mods/beds/README.txt @@ -1,30 +1,26 @@ Minetest Game mod: beds ======================= -by BlockMen (c) 2014-2015 +See license.txt for license information. -Version: 1.1.1 +Authors of source code +---------------------- +Originally by BlockMen (MIT) +Various Minetest developers and contributors (MIT) -About -~~~~~ -This mod adds a bed to Minetest which allows to skip the night. To sleep rightclick the bed, if playing -in singleplayer mode the night gets skipped imideatly. If playing on server you get shown how many other -players are in bed too. If all players are sleeping the night gets skipped aswell. Also the night skip can be forced -if more than 50% of the players are lying in bed and use this option. +Authors of media (textures) +--------------------------- +BlockMen (CC BY-SA 3.0) -Another feature is a controled respawning. If you have slept in bed (not just lying in it) your respawn point -is set to the beds location and you will respawn there after death. -You can disable the respawn at beds by setting "enable_bed_respawn = false" in minetest.conf -You can also disable the night skip feature by setting "enable_bed_night_skip = false" in minetest.conf or by using -the /set command ingame. +This mod adds a bed to Minetest which allows to skip the night. +To sleep, rightclick the bed. If playing in singleplayer mode the night gets skipped +immediately. If playing multiplayer you get shown how many other players are in bed too, +if all players are sleeping the night gets skipped. The night skip can be forced if more +than 50% of the players are lying in bed and use this option. - -License of source code, textures: WTFPL ---------------------------------------- -(c) Copyright BlockMen (2014-2015) - - -This program is free software. It comes without any warranty, to -the extent permitted by applicable law. You can redistribute it -and/or modify it under the terms of the Do What The Fuck You Want -To Public License, Version 2, as published by Sam Hocevar. See -http://sam.zoy.org/wtfpl/COPYING for more details. +Another feature is a controlled respawning. If you have slept in bed (not just lying in +it) your respawn point is set to the beds location and you will respawn there after +death. +You can disable the respawn at beds by setting "enable_bed_respawn = false" in +minetest.conf. +You can disable the night skip feature by setting "enable_bed_night_skip = false" in +minetest.conf or by using the /set command in-game. diff --git a/mods/beds/api.lua b/mods/beds/api.lua index 53d4e488..3b2bb0d5 100644 --- a/mods/beds/api.lua +++ b/mods/beds/api.lua @@ -16,7 +16,7 @@ local function destruct_bed(pos, n) if reverse then reverse = not reverse minetest.remove_node(other) - nodeupdate(other) + minetest.check_for_falling(other) else reverse = not reverse end @@ -33,7 +33,7 @@ function beds.register_bed(name, def) paramtype2 = "facedir", is_ground_content = false, stack_max = 1, - groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1}, sounds = default.node_sound_wood_defaults(), node_box = { type = "fixed", @@ -59,8 +59,8 @@ function beds.register_bed(name, def) return itemstack end - local def = minetest.registered_nodes[minetest.get_node(pos).name] - if not def or not def.buildable_to then + local node_def = minetest.registered_nodes[minetest.get_node(pos).name] + if not node_def or not node_def.buildable_to then return itemstack end @@ -91,8 +91,9 @@ function beds.register_bed(name, def) destruct_bed(pos, 1) end, - on_rightclick = function(pos, node, clicker) + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) beds.on_rightclick(pos, clicker) + return itemstack end, on_rotate = function(pos, node, user, mode, new_param2) @@ -112,8 +113,8 @@ function beds.register_bed(name, def) end local newp = vector.add(pos, minetest.facedir_to_dir(new_param2)) local node3 = minetest.get_node_or_nil(newp) - local def = node3 and minetest.registered_nodes[node3.name] - if not def or not def.buildable_to then + local node_def = node3 and minetest.registered_nodes[node3.name] + if not node_def or not node_def.buildable_to then return false end if minetest.is_protected(newp, user:get_player_name()) then @@ -136,7 +137,7 @@ function beds.register_bed(name, def) paramtype2 = "facedir", is_ground_content = false, pointable = false, - groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 2}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 2}, sounds = default.node_sound_wood_defaults(), drop = name .. "_bottom", node_box = { diff --git a/mods/beds/beds.lua b/mods/beds/beds.lua index 5f31f136..bb2fd5d3 100644 --- a/mods/beds/beds.lua +++ b/mods/beds/beds.lua @@ -66,7 +66,7 @@ beds.register_bed("beds:bed", { }, top = { "beds_bed_top_top.png^[transformR90", - "default_wood.png", + "default_wood.png", "beds_bed_side_top_r.png", "beds_bed_side_top_r.png^[transformfx", "beds_bed_side_top.png", @@ -88,3 +88,17 @@ beds.register_bed("beds:bed", { minetest.register_alias("beds:bed_bottom_red", "beds:bed_bottom") minetest.register_alias("beds:bed_top_red", "beds:bed_top") + +-- Fuel + +minetest.register_craft({ + type = "fuel", + recipe = "beds:fancy_bed_bottom", + burntime = 13, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "beds:bed_bottom", + burntime = 12, +}) diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua index afc8e15a..896844e5 100644 --- a/mods/beds/functions.lua +++ b/mods/beds/functions.lua @@ -70,7 +70,7 @@ local function lay_down(player, pos, bed_pos, state, skip) -- physics, eye_offset, etc player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) - player:set_look_yaw(math.random(1, 180) / 100) + player:set_look_horizontal(math.random(1, 180) / 100) default.player_attached[name] = false player:set_physics_override(1, 1, 1) hud_flags.wielditem = true @@ -85,7 +85,7 @@ local function lay_down(player, pos, bed_pos, state, skip) -- physics, eye_offset, etc player:set_eye_offset({x = 0, y = -13, z = 0}, {x = 0, y = 0, z = 0}) local yaw, param2 = get_look_yaw(bed_pos) - player:set_look_yaw(yaw) + player:set_look_horizontal(yaw) local dir = minetest.facedir_to_dir(param2) local p = {x = bed_pos.x + dir.x / 2, y = bed_pos.y, z = bed_pos.z + dir.z / 2} player:set_physics_override(0, 0, 0) @@ -100,7 +100,7 @@ end local function update_formspecs(finished) local ges = #minetest.get_connected_players() - local form_n = "" + local form_n local is_majority = (ges / 2) < player_in_bed if finished then @@ -130,7 +130,6 @@ end function beds.skip_night() minetest.set_timeofday(0.23) - beds.set_spawns() end function beds.on_rightclick(pos, player) @@ -149,6 +148,7 @@ function beds.on_rightclick(pos, player) -- move to bed if not beds.player[name] then lay_down(player, ppos, pos) + beds.set_spawns() -- save respawn positions when entering bed else lay_down(player, nil, nil, false) end @@ -173,23 +173,18 @@ end -- Callbacks - -minetest.register_on_joinplayer(function(player) - beds.read_spawns() -end) - --- respawn player at bed if enabled and valid position is found -minetest.register_on_respawnplayer(function(player) - if not enable_respawn then - return false - end - local name = player:get_player_name() - local pos = beds.spawn[name] or nil - if pos then - player:setpos(pos) - return true - end -end) +-- Only register respawn callback if respawn enabled +if enable_respawn then + -- respawn player at bed if enabled and valid position is found + minetest.register_on_respawnplayer(function(player) + local name = player:get_player_name() + local pos = beds.spawn[name] + if pos then + player:setpos(pos) + return true + end + end) +end minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() diff --git a/mods/beds/license.txt b/mods/beds/license.txt new file mode 100644 index 00000000..0494b36b --- /dev/null +++ b/mods/beds/license.txt @@ -0,0 +1,60 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2014-2016 Various Minetest developers and contributors + +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) 2014-2016 BlockMen + +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/beds/spawns.lua b/mods/beds/spawns.lua index 48b8a669..6b1f4041 100644 --- a/mods/beds/spawns.lua +++ b/mods/beds/spawns.lua @@ -32,11 +32,11 @@ function beds.read_spawns() beds.save_spawns() os.rename(file, file .. ".backup") file = org_file - else - spawns = {} end end +beds.read_spawns() + function beds.save_spawns() if not beds.spawn then return diff --git a/mods/boats/README.txt b/mods/boats/README.txt index 1de71678..59631d9d 100644 --- a/mods/boats/README.txt +++ b/mods/boats/README.txt @@ -1,16 +1,15 @@ Minetest Game mod: boats ======================== -by PilzAdam +See license.txt for license information. -License of source code: ------------------------ -WTFPL +Authors of source code +---------------------- +Originally by PilzAdam (MIT) +Various Minetest developers and contributors (MIT) -License of media (textures and sounds): ---------------------------------------- -WTFPL - -Authors of media files: ------------------------ -textures: Zeg9 -model: thetoon and Zeg9, modified by PavelS(SokolovPavel) +Authors of media (textures and model) +------------------------------------- +Textures: Zeg9 (CC BY-SA 3.0) +Model: thetoon and Zeg9 (CC BY-SA 3.0), + modified by PavelS(SokolovPavel) (CC BY-SA 3.0), + modified by sofar (CC BY-SA 3.0) diff --git a/mods/boats/init.lua b/mods/boats/init.lua index f8d0ccb4..0591ef24 100644 --- a/mods/boats/init.lua +++ b/mods/boats/init.lua @@ -34,6 +34,8 @@ end local boat = { physical = true, + -- Warning: Do not change the position of the collisionbox top surface, + -- lowering it causes the boat to fall through the world if underwater collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, visual = "mesh", mesh = "boats_boat.obj", @@ -77,7 +79,7 @@ function boat.on_rightclick(self, clicker) minetest.after(0.2, function() default.player_set_animation(clicker, "sit" , 30) end) - self.object:setyaw(clicker:get_look_yaw() - math.pi / 2) + clicker:set_look_horizontal(self.object:getyaw()) end end @@ -107,18 +109,19 @@ function boat.on_punch(self, puncher) end if not self.driver then self.removed = true + local inv = puncher:get_inventory() + if not minetest.setting_getbool("creative_mode") + or not inv:contains_item("main", "boats:boat") then + local leftover = inv:add_item("main", "boats:boat") + -- if no room in inventory add a replacement boat to the world + if not leftover:is_empty() then + minetest.add_item(self.object:getpos(), leftover) + end + end -- delay remove to ensure player is detached minetest.after(0.1, function() self.object:remove() end) - if not minetest.setting_getbool("creative_mode") then - local inv = puncher:get_inventory() - if inv:room_for_item("main", "boats:boat") then - inv:add_item("main", "boats:boat") - else - minetest.add_item(self.object:getpos(), "boats:boat") - end - end end end @@ -165,7 +168,7 @@ function boat.on_step(self, dtime) local p = self.object:getpos() p.y = p.y - 0.5 - local new_velo = {x = 0, y = 0, z = 0} + local new_velo local new_acce = {x = 0, y = 0, z = 0} if not is_water(p) then local nodedef = minetest.registered_nodes[minetest.get_node(p).name] @@ -219,18 +222,22 @@ minetest.register_craftitem("boats:boat", { wield_image = "boats_wield.png", wield_scale = {x = 2, y = 2, z = 1}, liquids_pointable = true, + groups = {flammable = 2}, on_place = function(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" then - return + return itemstack end if not is_water(pointed_thing.under) then - return + return itemstack end pointed_thing.under.y = pointed_thing.under.y + 0.5 - minetest.add_entity(pointed_thing.under, "boats:boat") - if not minetest.setting_getbool("creative_mode") then - itemstack:take_item() + boat = minetest.add_entity(pointed_thing.under, "boats:boat") + if boat then + boat:setyaw(placer:get_look_horizontal()) + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end end return itemstack end, @@ -245,3 +252,9 @@ minetest.register_craft({ {"group:wood", "group:wood", "group:wood"}, }, }) + +minetest.register_craft({ + type = "fuel", + recipe = "boats:boat", + burntime = 20, +}) diff --git a/mods/boats/license.txt b/mods/boats/license.txt new file mode 100644 index 00000000..d4afe75f --- /dev/null +++ b/mods/boats/license.txt @@ -0,0 +1,63 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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 and model) +-------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Zeg9 +Copyright (C) 2012-2016 thetoon +Copyright (C) 2012-2016 PavelS(SokolovPavel) +Copyright (C) 2016 sofar (sofar@foo-projects.org) + +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/bones/README.txt b/mods/bones/README.txt index b40a384d..91bcd109 100644 --- a/mods/bones/README.txt +++ b/mods/bones/README.txt @@ -1,17 +1,12 @@ Minetest Game mod: bones ======================== +See license.txt for license information. -License of source code: ------------------------ -Copyright (C) 2012 PilzAdam - -WTFPL - -License of media (textures and sounds) --------------------------------------- -Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) -http://creativecommons.org/licenses/by-sa/3.0/ - -Authors of media files +Authors of source code ---------------------- -Bad_Command_ +Originally by PilzAdam (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +All textures: paramat (CC BY-SA 3.0) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 661bbab8..9542cab0 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -1,7 +1,5 @@ -- Minetest 0.4 mod: bones --- See README.txt for licensing and other information. - -bones = {} +-- See README.txt for licensing and other information. local function is_owner(pos, name) local owner = minetest.get_meta(pos):get_string("owner") @@ -11,7 +9,7 @@ local function is_owner(pos, name) return false end -bones.bones_formspec = +local bones_formspec = "size[8,9]" .. default.gui_bg .. default.gui_bg_img .. @@ -29,7 +27,7 @@ local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_e minetest.register_node("bones:bones", { description = "Bones", tiles = { - "bones_top.png", + "bones_top.png^[transform2", "bones_bottom.png", "bones_side.png", "bones_side.png", @@ -37,12 +35,9 @@ minetest.register_node("bones:bones", { "bones_front.png" }, paramtype2 = "facedir", - groups = {dig_immediate=2}, - sounds = default.node_sound_dirt_defaults({ - footstep = {name="default_gravel_footstep", gain=0.5}, - dug = {name="default_gravel_footstep", gain=1.0}, - }), - + groups = {dig_immediate = 2}, + sounds = default.node_sound_gravel_defaults(), + can_dig = function(pos, player) local inv = minetest.get_meta(pos):get_inventory() local name = "" @@ -51,46 +46,46 @@ minetest.register_node("bones:bones", { end return is_owner(pos, name) and inv:is_empty("main") end, - + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) if is_owner(pos, player:get_player_name()) then return count end return 0 end, - + allow_metadata_inventory_put = function(pos, listname, index, stack, player) return 0 end, - + allow_metadata_inventory_take = function(pos, listname, index, stack, player) if is_owner(pos, player:get_player_name()) then return stack:get_count() end return 0 end, - + on_metadata_inventory_take = function(pos, listname, index, stack, player) local meta = minetest.get_meta(pos) if meta:get_inventory():is_empty("main") then minetest.remove_node(pos) end end, - + on_punch = function(pos, node, player) - if(not is_owner(pos, player:get_player_name())) then + if not is_owner(pos, player:get_player_name()) then return end - - if(minetest.get_meta(pos):get_string("infotext") == "") then + + if minetest.get_meta(pos):get_string("infotext") == "" then return end - + local inv = minetest.get_meta(pos):get_inventory() local player_inv = player:get_inventory() local has_space = true - - for i=1,inv:get_size("main") do + + for i = 1, inv:get_size("main") do local stk = inv:get_stack("main", i) if player_inv:room_for_item("main", stk) then inv:set_stack("main", i, nil) @@ -100,7 +95,7 @@ minetest.register_node("bones:bones", { break end end - + -- remove bones if player emptied them if has_space then if player_inv:room_for_item("main", {name = "bones:bones"}) then @@ -111,12 +106,12 @@ minetest.register_node("bones:bones", { minetest.remove_node(pos) end end, - + on_timer = function(pos, elapsed) local meta = minetest.get_meta(pos) local time = meta:get_int("time") + elapsed if time >= share_bones_time then - meta:set_string("infotext", meta:get_string("owner").."'s old bones") + meta:set_string("infotext", meta:get_string("owner") .. "'s old bones") meta:set_string("owner", "") else meta:set_int("time", time) @@ -131,13 +126,9 @@ local function may_replace(pos, player) local node_name = minetest.get_node(pos).name local node_definition = minetest.registered_nodes[node_name] - -- if the node is unknown, we let the protection mod decide - -- this is consistent with when a player could dig or not dig it - -- unknown decoration would often be removed - -- while unknown building materials in use would usually be left + -- if the node is unknown, we return false if not node_definition then - -- only replace nodes that are not protected - return not minetest.is_protected(pos, player:get_player_name()) + return false end -- allow replacing air and liquids @@ -157,71 +148,92 @@ local function may_replace(pos, player) return node_definition.buildable_to and not minetest.is_protected(pos, player:get_player_name()) end +local drop = function(pos, itemstack) + local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count())) + if obj then + obj:setvelocity({ + x = math.random(-10, 10) / 9, + y = 5, + z = math.random(-10, 10) / 9, + }) + end +end + minetest.register_on_dieplayer(function(player) - if minetest.setting_getbool("creative_mode") then + + local bones_mode = minetest.setting_get("bones_mode") or "bones" + if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then + bones_mode = "bones" + end + + -- return if keep inventory set or in creative mode + if bones_mode == "keep" or minetest.setting_getbool("creative_mode") then return end - + local player_inv = player:get_inventory() if player_inv:is_empty("main") and player_inv:is_empty("craft") then return end - local pos = player:getpos() - pos.x = math.floor(pos.x+0.5) - pos.y = math.floor(pos.y+0.5) - pos.z = math.floor(pos.z+0.5) - local param2 = minetest.dir_to_facedir(player:get_look_dir()) + local pos = vector.round(player:getpos()) local player_name = player:get_player_name() - local player_inv = player:get_inventory() - if (not may_replace(pos, player)) then - if (may_replace({x=pos.x, y=pos.y+1, z=pos.z}, player)) then - -- drop one node above if there's space - -- this should solve most cases of protection related deaths in which players dig straight down - -- yet keeps the bones reachable - pos.y = pos.y+1 + -- check if it's possible to place bones, if not find space near player + if bones_mode == "bones" and not may_replace(pos, player) then + local air = minetest.find_node_near(pos, 1, {"air"}) + if air and not minetest.is_protected(air, player_name) then + pos = air else - -- drop items instead of delete - for i=1,player_inv:get_size("main") do - minetest.add_item(pos, player_inv:get_stack("main", i)) - end - for i=1,player_inv:get_size("craft") do - minetest.add_item(pos, player_inv:get_stack("craft", i)) - end - -- empty lists main and craft - player_inv:set_list("main", {}) - player_inv:set_list("craft", {}) - return + bones_mode = "drop" end end - - minetest.set_node(pos, {name="bones:bones", param2=param2}) - + + if bones_mode == "drop" then + + -- drop inventory items + for i = 1, player_inv:get_size("main") do + drop(pos, player_inv:get_stack("main", i)) + end + player_inv:set_list("main", {}) + + -- drop crafting grid items + for i = 1, player_inv:get_size("craft") do + drop(pos, player_inv:get_stack("craft", i)) + end + player_inv:set_list("craft", {}) + + drop(pos, ItemStack("bones:bones")) + return + end + + local param2 = minetest.dir_to_facedir(player:get_look_dir()) + minetest.set_node(pos, {name = "bones:bones", param2 = param2}) + local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - inv:set_size("main", 8*4) + inv:set_size("main", 8 * 4) inv:set_list("main", player_inv:get_list("main")) - - for i=1,player_inv:get_size("craft") do + + for i = 1, player_inv:get_size("craft") do local stack = player_inv:get_stack("craft", i) if inv:room_for_item("main", stack) then inv:add_item("main", stack) else --drop if no space left - minetest.add_item(pos, stack) + drop(pos, stack) end end - + player_inv:set_list("main", {}) player_inv:set_list("craft", {}) - - meta:set_string("formspec", bones.bones_formspec) + + meta:set_string("formspec", bones_formspec) meta:set_string("owner", player_name) - + if share_bones_time ~= 0 then - meta:set_string("infotext", player_name.."'s fresh bones") + meta:set_string("infotext", player_name .. "'s fresh bones") if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then meta:set_int("time", 0) diff --git a/mods/bones/license.txt b/mods/bones/license.txt new file mode 100644 index 00000000..fe525841 --- /dev/null +++ b/mods/bones/license.txt @@ -0,0 +1,58 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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 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. + diff --git a/mods/bones/textures/bones_bottom.png b/mods/bones/textures/bones_bottom.png index ada72cea..859c6bbe 100644 Binary files a/mods/bones/textures/bones_bottom.png and b/mods/bones/textures/bones_bottom.png differ diff --git a/mods/bones/textures/bones_front.png b/mods/bones/textures/bones_front.png index 9dcbb97b..1e524370 100644 Binary files a/mods/bones/textures/bones_front.png and b/mods/bones/textures/bones_front.png differ diff --git a/mods/bones/textures/bones_rear.png b/mods/bones/textures/bones_rear.png index 8e1ac10b..4cfe236d 100644 Binary files a/mods/bones/textures/bones_rear.png and b/mods/bones/textures/bones_rear.png differ diff --git a/mods/bones/textures/bones_side.png b/mods/bones/textures/bones_side.png index 3b4810c6..a07595f4 100644 Binary files a/mods/bones/textures/bones_side.png and b/mods/bones/textures/bones_side.png differ diff --git a/mods/bones/textures/bones_top.png b/mods/bones/textures/bones_top.png index 61198647..198a8a2d 100644 Binary files a/mods/bones/textures/bones_top.png and b/mods/bones/textures/bones_top.png differ diff --git a/mods/bucket/README.txt b/mods/bucket/README.txt index a6674b43..45e0ec54 100644 --- a/mods/bucket/README.txt +++ b/mods/bucket/README.txt @@ -1,26 +1,13 @@ Minetest Game mod: bucket ========================= +See license.txt for license information. -License of source code: ------------------------ -Copyright (C) 2011-2012 Kahrl -Copyright (C) 2011-2012 celeron55, Perttu Ahola - -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 of the License, or -(at your option) any later version. - -http://www.gnu.org/licenses/lgpl-2.1.html - -License of media (textures and sounds) --------------------------------------- -Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) -http://creativecommons.org/licenses/by-sa/3.0/ - -Authors of media files ------------------------ -Everything not listed in here: -Copyright (C) 2010-2012 celeron55, Perttu Ahola - +Authors of source code +---------------------- +Kahrl (LGPL 2.1) +celeron55, Perttu Ahola (LGPL 2.1) +Various Minetest developers and contributors (LGPL 2.1) +Authors of media (textures) +--------------------------- +ElementW (CC BY-SA 3.0) diff --git a/mods/bucket/init.lua b/mods/bucket/init.lua index 89730de7..5076dece 100644 --- a/mods/bucket/init.lua +++ b/mods/bucket/init.lua @@ -36,12 +36,17 @@ end -- inventory_image = texture of the new bucket item (ignored if itemname == nil) -- name = text description of the bucket item -- groups = (optional) groups of the bucket item, for example {water_bucket = 1} +-- force_renew = (optional) bool. Force the liquid source to renew if it has a +-- source neighbour, even if defined as 'liquid_renewable = false'. +-- Needed to avoid creating holes in sloping rivers. -- This function can be called from any mod (that depends on bucket). -function bucket.register_liquid(source, flowing, itemname, inventory_image, name, groups) +function bucket.register_liquid(source, flowing, itemname, inventory_image, name, + groups, force_renew) bucket.liquids[source] = { source = source, flowing = flowing, itemname = itemname, + force_renew = force_renew, } bucket.liquids[flowing] = bucket.liquids[source] @@ -52,54 +57,53 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name stack_max = 1, liquids_pointable = true, groups = groups, + on_place = function(itemstack, user, pointed_thing) -- Must be pointing to node if pointed_thing.type ~= "node" then return end - + local node = minetest.get_node_or_nil(pointed_thing.under) - local ndef - if node then - ndef = minetest.registered_nodes[node.name] - end + local ndef = node and minetest.registered_nodes[node.name] + -- Call on_rightclick if the pointed node defines it if ndef and ndef.on_rightclick and user and not user:get_player_control().sneak then return ndef.on_rightclick( pointed_thing.under, node, user, - itemstack) or itemstack + itemstack) end - local place_liquid = function(pos, node, source, flowing) - if check_protection(pos, - user and user:get_player_name() or "", - "place "..source) then - return - end - minetest.add_node(pos, {name=source}) - end + local lpos -- Check if pointing to a buildable node if ndef and ndef.buildable_to then -- buildable; replace the node - place_liquid(pointed_thing.under, node, - source, flowing) + lpos = pointed_thing.under else -- not buildable to; place the liquid above -- check if the node above can be replaced - local node = minetest.get_node_or_nil(pointed_thing.above) - if node and minetest.registered_nodes[node.name].buildable_to then - place_liquid(pointed_thing.above, - node, source, - flowing) - else + + lpos = pointed_thing.above + node = minetest.get_node_or_nil(lpos) + local above_ndef = node and minetest.registered_nodes[node.name] + + if not above_ndef or not above_ndef.buildable_to then -- do not remove the bucket with the liquid - return + return itemstack end end - return {name="bucket:bucket_empty"} + + if check_protection(lpos, user + and user:get_player_name() + or "", "place "..source) then + return + end + + minetest.set_node(lpos, {name = source}) + return ItemStack("bucket:bucket_empty") end }) end @@ -111,8 +115,11 @@ minetest.register_craftitem("bucket:bucket_empty", { stack_max = 99, liquids_pointable = true, on_use = function(itemstack, user, pointed_thing) - -- Must be pointing to node - if pointed_thing.type ~= "node" then + if pointed_thing.type == "object" then + pointed_thing.ref:punch(user, 1.0, { full_punch_interval=1.0 }, nil) + return user:get_wielded_item() + elseif pointed_thing.type ~= "node" then + -- do nothing if it's neither object nor node return end -- Check if pointing to a liquid source @@ -142,7 +149,7 @@ minetest.register_craftitem("bucket:bucket_empty", { else local pos = user:getpos() pos.y = math.floor(pos.y + 0.5) - core.add_item(pos, liquiddef.itemname) + minetest.add_item(pos, liquiddef.itemname) end -- set to return empty buckets minus 1 @@ -150,9 +157,24 @@ minetest.register_craftitem("bucket:bucket_empty", { end - minetest.add_node(pointed_thing.under, {name="air"}) + -- force_renew requires a source neighbour + local source_neighbor = false + if liquiddef.force_renew then + source_neighbor = + minetest.find_node_near(pointed_thing.under, 1, liquiddef.source) + end + if not (source_neighbor and liquiddef.force_renew) then + minetest.add_node(pointed_thing.under, {name = "air"}) + end return ItemStack(giving_back) + else + -- non-liquid nodes will have their on_punch triggered + local node_def = minetest.registered_nodes[node.name] + if node_def then + node_def.on_punch(pointed_thing.under, node, user, pointed_thing) + end + return user:get_wielded_item() end end, }) @@ -172,7 +194,8 @@ bucket.register_liquid( "bucket:bucket_river_water", "bucket_river_water.png", "River Water Bucket", - {water_bucket = 1} + {water_bucket = 1}, + true ) bucket.register_liquid( diff --git a/mods/bucket/license.txt b/mods/bucket/license.txt new file mode 100644 index 00000000..a5156ae6 --- /dev/null +++ b/mods/bucket/license.txt @@ -0,0 +1,51 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2011-2016 Kahrl +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) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2015-2016 ElementW + +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/carts/README.txt b/mods/carts/README.txt new file mode 100644 index 00000000..31ce6449 --- /dev/null +++ b/mods/carts/README.txt @@ -0,0 +1,22 @@ +Carts (formerly boost_cart) +========================== + +Carts, based almost entirely on the mod boost_cart [1], which +itself is based on (and fully compatible with) the carts mod [2]. + +The model was originally designed by stujones11 [3] (CC-0). + +Cart textures are based on original work from PixelBOX (WTFPL). + + +[1] https://github.com/SmallJoker/boost_cart/ +[2] https://github.com/PilzAdam/carts/ +[3] https://github.com/stujones11/railcart/ + + +Features +---------- +- A fast cart for your railway or roller coaster (up to 7 m/s!) +- Boost and brake rails +- Rail junction switching with the 'right-left' walking keys +- Handbrake with the 'back' key diff --git a/mods/carts/cart_entity.lua b/mods/carts/cart_entity.lua new file mode 100644 index 00000000..e8707fb4 --- /dev/null +++ b/mods/carts/cart_entity.lua @@ -0,0 +1,392 @@ +local cart_entity = { + physical = false, -- otherwise going uphill breaks + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + visual = "mesh", + mesh = "carts_cart.b3d", + visual_size = {x=1, y=1}, + textures = {"carts_cart.png"}, + + driver = nil, + punched = false, -- used to re-send velocity and position + velocity = {x=0, y=0, z=0}, -- only used on punch + old_dir = {x=1, y=0, z=0}, -- random value to start the cart on punch + old_pos = nil, + old_switch = 0, + railtype = nil, + attached_items = {} +} + +function cart_entity:on_rightclick(clicker) + if not clicker or not clicker:is_player() then + return + end + local player_name = clicker:get_player_name() + if self.driver and player_name == self.driver then + self.driver = nil + carts:manage_attachment(clicker, nil) + elseif not self.driver then + self.driver = player_name + carts:manage_attachment(clicker, self.object) + end +end + +function cart_entity:on_activate(staticdata, dtime_s) + self.object:set_armor_groups({immortal=1}) + if string.sub(staticdata, 1, string.len("return")) ~= "return" then + return + end + local data = minetest.deserialize(staticdata) + if not data or type(data) ~= "table" then + return + end + self.railtype = data.railtype + if data.old_dir then + self.old_dir = data.old_dir + end + if data.old_vel then + self.old_vel = data.old_vel + end +end + +function cart_entity:get_staticdata() + return minetest.serialize({ + railtype = self.railtype, + old_dir = self.old_dir, + old_vel = self.old_vel + }) +end + +function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) + local pos = self.object:getpos() + if not self.railtype then + local node = minetest.get_node(pos).name + self.railtype = minetest.get_item_group(node, "connect_to_raillike") + end + -- Punched by non-player + if not puncher or not puncher:is_player() then + local cart_dir = carts:get_rail_direction(pos, self.old_dir, nil, nil, self.railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return + end + self.velocity = vector.multiply(cart_dir, 2) + self.punched = true + return + end + -- Player digs cart by sneak-punch + if puncher:get_player_control().sneak then + if self.sound_handle then + minetest.sound_stop(self.sound_handle) + end + -- Detach driver and items + if self.driver then + if self.old_pos then + self.object:setpos(self.old_pos) + end + local player = minetest.get_player_by_name(self.driver) + carts:manage_attachment(player, nil) + end + for _,obj_ in ipairs(self.attached_items) do + if obj_ then + obj_:set_detach() + end + end + -- Pick up cart + local inv = puncher:get_inventory() + if not minetest.setting_getbool("creative_mode") + or not inv:contains_item("main", "carts:cart") then + local leftover = inv:add_item("main", "carts:cart") + -- If no room in inventory add a replacement cart to the world + if not leftover:is_empty() then + minetest.add_item(self.object:getpos(), leftover) + end + end + self.object:remove() + return + end + -- Player punches cart to alter velocity + local vel = self.object:getvelocity() + if puncher:get_player_name() == self.driver then + if math.abs(vel.x + vel.z) > carts.punch_speed_max then + return + end + end + + local punch_dir = carts:velocity_to_dir(puncher:get_look_dir()) + punch_dir.y = 0 + local cart_dir = carts:get_rail_direction(pos, punch_dir, nil, nil, self.railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return + end + + local punch_interval = 1 + if tool_capabilities and tool_capabilities.full_punch_interval then + punch_interval = tool_capabilities.full_punch_interval + end + time_from_last_punch = math.min(time_from_last_punch or punch_interval, punch_interval) + local f = 2 * (time_from_last_punch / punch_interval) + + self.velocity = vector.multiply(cart_dir, f) + self.old_dir = cart_dir + self.punched = true +end + +local function rail_on_step_event(handler, obj, dtime) + if handler then + handler(obj, dtime) + end +end + +-- sound refresh interval = 1.0sec +local function rail_sound(self, dtime) + if not self.sound_ttl then + self.sound_ttl = 1.0 + return + elseif self.sound_ttl > 0 then + self.sound_ttl = self.sound_ttl - dtime + return + end + self.sound_ttl = 1.0 + if self.sound_handle then + local handle = self.sound_handle + self.sound_handle = nil + minetest.after(0.2, minetest.sound_stop, handle) + end + local vel = self.object:getvelocity() + local speed = vector.length(vel) + if speed > 0 then + self.sound_handle = minetest.sound_play( + "carts_cart_moving", { + object = self.object, + gain = (speed / carts.speed_max) / 2, + loop = true, + }) + end +end + +local function get_railparams(pos) + local node = minetest.get_node(pos) + return carts.railparams[node.name] or {} +end + +local function rail_on_step(self, dtime) + local vel = self.object:getvelocity() + if self.punched then + vel = vector.add(vel, self.velocity) + self.object:setvelocity(vel) + self.old_dir.y = 0 + elseif vector.equals(vel, {x=0, y=0, z=0}) then + return + end + + local pos = self.object:getpos() + local update = {} + + -- stop cart if velocity vector flips + if self.old_vel and self.old_vel.y == 0 and + (self.old_vel.x * vel.x < 0 or self.old_vel.z * vel.z < 0) then + self.old_vel = {x = 0, y = 0, z = 0} + self.old_pos = pos + self.object:setvelocity(vector.new()) + self.object:setacceleration(vector.new()) + rail_on_step_event(get_railparams(pos).on_step, self, dtime) + return + end + self.old_vel = vector.new(vel) + + if self.old_pos and not self.punched then + local flo_pos = vector.round(pos) + local flo_old = vector.round(self.old_pos) + if vector.equals(flo_pos, flo_old) then + -- Do not check one node multiple times + return + end + end + + local ctrl, player + + -- Get player controls + if self.driver then + player = minetest.get_player_by_name(self.driver) + if player then + ctrl = player:get_player_control() + end + end + + if self.old_pos then + -- Detection for "skipping" nodes + local found_path = carts:pathfinder( + pos, self.old_pos, self.old_dir, ctrl, self.old_switch, self.railtype + ) + + if not found_path then + -- No rail found: reset back to the expected position + pos = vector.new(self.old_pos) + update.pos = true + end + end + + local cart_dir = carts:velocity_to_dir(vel) + local railparams + + -- dir: New moving direction of the cart + -- switch_keys: Currently pressed L/R key, used to ignore the key on the next rail node + local dir, switch_keys = carts:get_rail_direction( + pos, cart_dir, ctrl, self.old_switch, self.railtype + ) + + local new_acc = {x=0, y=0, z=0} + if vector.equals(dir, {x=0, y=0, z=0}) then + vel = {x = 0, y = 0, z = 0} + pos = vector.round(pos) + update.pos = true + update.vel = true + else + -- Direction change detected + if not vector.equals(dir, self.old_dir) then + vel = vector.multiply(dir, math.abs(vel.x + vel.z)) + update.vel = true + if dir.y ~= self.old_dir.y then + pos = vector.round(pos) + update.pos = true + end + end + -- Center on the rail + if dir.z ~= 0 and math.floor(pos.x + 0.5) ~= pos.x then + pos.x = math.floor(pos.x + 0.5) + update.pos = true + end + if dir.x ~= 0 and math.floor(pos.z + 0.5) ~= pos.z then + pos.z = math.floor(pos.z + 0.5) + update.pos = true + end + + -- Slow down or speed up.. + local acc = dir.y * -4.0 + + -- Get rail for corrected position + railparams = get_railparams(pos) + + -- no need to check for railparams == nil since we always make it exist. + local speed_mod = railparams.acceleration + if speed_mod and speed_mod ~= 0 then + -- Try to make it similar to the original carts mod + acc = acc + speed_mod + else + -- Handbrake or coast + if ctrl and ctrl.down then + acc = acc - 3 + else + acc = acc - 0.4 + end + end + + new_acc = vector.multiply(dir, acc) + end + + -- Limits + local max_vel = carts.speed_max + for _, v in pairs({"x","y","z"}) do + if math.abs(vel[v]) > max_vel then + vel[v] = carts:get_sign(vel[v]) * max_vel + new_acc[v] = 0 + update.vel = true + end + end + + self.object:setacceleration(new_acc) + self.old_pos = vector.new(pos) + if not vector.equals(dir, {x=0, y=0, z=0}) then + self.old_dir = vector.new(dir) + end + self.old_switch = switch_keys + + if self.punched then + -- Collect dropped items + for _, obj_ in pairs(minetest.get_objects_inside_radius(pos, 1)) do + if not obj_:is_player() and + obj_:get_luaentity() and + not obj_:get_luaentity().physical_state and + obj_:get_luaentity().name == "__builtin:item" then + + obj_:set_attach(self.object, "", {x=0, y=0, z=0}, {x=0, y=0, z=0}) + self.attached_items[#self.attached_items + 1] = obj_ + end + end + self.punched = false + update.vel = true + end + + railparams = railparams or get_railparams(pos) + + if not (update.vel or update.pos) then + rail_on_step_event(railparams.on_step, self, dtime) + return + end + + local yaw = 0 + if self.old_dir.x < 0 then + yaw = 0.5 + elseif self.old_dir.x > 0 then + yaw = 1.5 + elseif self.old_dir.z < 0 then + yaw = 1 + end + self.object:setyaw(yaw * math.pi) + + local anim = {x=0, y=0} + if dir.y == -1 then + anim = {x=1, y=1} + elseif dir.y == 1 then + anim = {x=2, y=2} + end + self.object:set_animation(anim, 1, 0) + + self.object:setvelocity(vel) + if update.pos then + self.object:setpos(pos) + end + + -- call event handler + rail_on_step_event(railparams.on_step, self, dtime) +end + +function cart_entity:on_step(dtime) + rail_on_step(self, dtime) + rail_sound(self, dtime) +end + +minetest.register_entity("carts:cart", cart_entity) + +minetest.register_craftitem("carts:cart", { + description = "Cart (Sneak+Click to pick up)", + inventory_image = minetest.inventorycube("carts_cart_top.png", "carts_cart_side.png", "carts_cart_side.png"), + wield_image = "carts_cart_side.png", + on_place = function(itemstack, placer, pointed_thing) + if not pointed_thing.type == "node" then + return + end + if carts:is_rail(pointed_thing.under) then + minetest.add_entity(pointed_thing.under, "carts:cart") + elseif carts:is_rail(pointed_thing.above) then + minetest.add_entity(pointed_thing.above, "carts:cart") + else + return + end + + minetest.sound_play({name = "default_place_node_metal", gain = 0.5}, + {pos = pointed_thing.above}) + + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + return itemstack + end, +}) + +minetest.register_craft({ + output = "carts:cart", + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + }, +}) diff --git a/mods/carts/depends.txt b/mods/carts/depends.txt new file mode 100644 index 00000000..4ad96d51 --- /dev/null +++ b/mods/carts/depends.txt @@ -0,0 +1 @@ +default diff --git a/mods/carts/functions.lua b/mods/carts/functions.lua new file mode 100644 index 00000000..285645cb --- /dev/null +++ b/mods/carts/functions.lua @@ -0,0 +1,221 @@ +function carts:get_sign(z) + if z == 0 then + return 0 + else + return z / math.abs(z) + end +end + +function carts:manage_attachment(player, obj) + if not player then + return + end + local status = obj ~= nil + local player_name = player:get_player_name() + if default.player_attached[player_name] == status then + return + end + default.player_attached[player_name] = status + + if status then + player:set_attach(obj, "", {x=0, y=6, z=0}, {x=0, y=0, z=0}) + player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0}) + else + player:set_detach() + player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) + end +end + +function carts:velocity_to_dir(v) + if math.abs(v.x) > math.abs(v.z) then + return {x=carts:get_sign(v.x), y=carts:get_sign(v.y), z=0} + else + return {x=0, y=carts:get_sign(v.y), z=carts:get_sign(v.z)} + end +end + +function carts:is_rail(pos, railtype) + local node = minetest.get_node(pos).name + if node == "ignore" then + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(pos, pos) + local area = VoxelArea:new{ + MinEdge = emin, + MaxEdge = emax, + } + local data = vm:get_data() + local vi = area:indexp(pos) + node = minetest.get_name_from_content_id(data[vi]) + end + if minetest.get_item_group(node, "rail") == 0 then + return false + end + if not railtype then + return true + end + return minetest.get_item_group(node, "connect_to_raillike") == railtype +end + +function carts:check_front_up_down(pos, dir_, check_up, railtype) + local dir = vector.new(dir_) + local cur + + -- Front + dir.y = 0 + cur = vector.add(pos, dir) + if carts:is_rail(cur, railtype) then + return dir + end + -- Up + if check_up then + dir.y = 1 + cur = vector.add(pos, dir) + if carts:is_rail(cur, railtype) then + return dir + end + end + -- Down + dir.y = -1 + cur = vector.add(pos, dir) + if carts:is_rail(cur, railtype) then + return dir + end + return nil +end + +function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) + local pos = vector.round(pos_) + local cur + local left_check, right_check = true, true + + -- Check left and right + local left = {x=0, y=0, z=0} + local right = {x=0, y=0, z=0} + if dir.z ~= 0 and dir.x == 0 then + left.x = -dir.z + right.x = dir.z + elseif dir.x ~= 0 and dir.z == 0 then + left.z = dir.x + right.z = -dir.x + end + + if ctrl then + if old_switch == 1 then + left_check = false + elseif old_switch == 2 then + right_check = false + end + if ctrl.left and left_check then + cur = carts:check_front_up_down(pos, left, false, railtype) + if cur then + return cur, 1 + end + left_check = false + end + if ctrl.right and right_check then + cur = carts:check_front_up_down(pos, right, false, railtype) + if cur then + return cur, 2 + end + right_check = true + end + end + + -- Normal + cur = carts:check_front_up_down(pos, dir, true, railtype) + if cur then + return cur + end + + -- Left, if not already checked + if left_check then + cur = carts:check_front_up_down(pos, left, false, railtype) + if cur then + return cur + end + end + + -- Right, if not already checked + if right_check then + cur = carts:check_front_up_down(pos, right, false, railtype) + if cur then + return cur + end + end + + -- Backwards + if not old_switch then + cur = carts:check_front_up_down(pos, { + x = -dir.x, + y = dir.y, + z = -dir.z + }, true, railtype) + if cur then + return cur + end + end + + return {x=0, y=0, z=0} +end + +function carts:pathfinder(pos_, old_pos, old_dir, ctrl, pf_switch, railtype) + local pos = vector.round(pos_) + local pf_pos = vector.round(old_pos) + local pf_dir = vector.new(old_dir) + + for i = 1, 3 do + if vector.equals(pf_pos, pos) then + -- Success! Cart moved on correctly + return true + end + + pf_dir, pf_switch = carts:get_rail_direction(pf_pos, pf_dir, ctrl, pf_switch, railtype) + if vector.equals(pf_dir, {x=0, y=0, z=0}) then + -- No way forwards + return false + end + + pf_pos = vector.add(pf_pos, pf_dir) + end + -- Cart not found + return false +end + +function carts:register_rail(name, def, railparams) + local def_default = { + drawtype = "raillike", + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + sounds = default.node_sound_metal_defaults() + } + for k, v in pairs(def_default) do + def[k] = v + end + if not def.inventory_image then + def.wield_image = def.tiles[1] + def.inventory_image = def.tiles[1] + end + + if railparams then + carts.railparams[name] = table.copy(railparams) + end + + minetest.register_node(name, def) +end + +function carts:get_rail_groups(additional_groups) + -- Get the default rail groups and add more when a table is given + local groups = {dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1} + if type(additional_groups) == "table" then + for k, v in pairs(additional_groups) do + groups[k] = v + end + end + return groups +end diff --git a/mods/carts/init.lua b/mods/carts/init.lua new file mode 100644 index 00000000..53b33cc2 --- /dev/null +++ b/mods/carts/init.lua @@ -0,0 +1,20 @@ + +carts = {} +carts.modpath = minetest.get_modpath("carts") +carts.railparams = {} + +-- Maximal speed of the cart in m/s (min = -1) +carts.speed_max = 7 +-- Set to -1 to disable punching the cart from inside (min = -1) +carts.punch_speed_max = 5 + + +dofile(carts.modpath.."/functions.lua") +dofile(carts.modpath.."/rails.lua") + +-- Support for non-default games +if not default.player_attached then + default.player_attached = {} +end + +dofile(carts.modpath.."/cart_entity.lua") diff --git a/mods/carts/license.txt b/mods/carts/license.txt new file mode 100644 index 00000000..6c5beb47 --- /dev/null +++ b/mods/carts/license.txt @@ -0,0 +1,54 @@ + +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 SmallJoker +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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 +----------------- + +CC-0, see: https://creativecommons.org/share-your-work/public-domain/cc0/, except +if other license is mentioned. + + +Authors +--------- +Originally from PixelBOX (Gambit): + carts_cart_side.png + carts_cart_top.png + carts_cart_front.png* + carts_cart.png* + +sofar + stujones11: + carts_cart.b3d and carts_cart.blend + +hexafraction, modified by sofar + carts_rail_*.png + +http://www.freesound.org/people/YleArkisto/sounds/253159/ - YleArkisto - CC-BY-3.0 + carts_cart_moving.*.ogg diff --git a/mods/carts/models/carts_cart.b3d b/mods/carts/models/carts_cart.b3d new file mode 100644 index 00000000..4e7eba36 Binary files /dev/null and b/mods/carts/models/carts_cart.b3d differ diff --git a/mods/carts/models/carts_cart.blend b/mods/carts/models/carts_cart.blend new file mode 100644 index 00000000..7d2515eb Binary files /dev/null and b/mods/carts/models/carts_cart.blend differ diff --git a/mods/carts/rails.lua b/mods/carts/rails.lua new file mode 100644 index 00000000..5da4ac4d --- /dev/null +++ b/mods/carts/rails.lua @@ -0,0 +1,59 @@ +carts:register_rail("carts:rail", { + description = "Rail", + tiles = { + "carts_rail_straight.png", "carts_rail_curved.png", + "carts_rail_t_junction.png", "carts_rail_crossing.png" + }, + inventory_image = "carts_rail_straight.png", + wield_image = "carts_rail_straight.png", + groups = carts:get_rail_groups(), +}, {}) + +minetest.register_craft({ + output = "carts:rail 16", + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "group:stick", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"}, + } +}) + +minetest.register_alias("default:rail", "carts:rail") + + +carts:register_rail("carts:powerrail", { + description = "Powered rail", + tiles = { + "carts_rail_straight_pwr.png", "carts_rail_curved_pwr.png", + "carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png" + }, + groups = carts:get_rail_groups(), +}, {acceleration = 5}) + +minetest.register_craft({ + output = "carts:powerrail 8", + recipe = { + {"default:steel_ingot", "default:mese_crystal_fragment", "default:steel_ingot"}, + {"default:steel_ingot", "group:stick", "default:steel_ingot"}, + {"default:steel_ingot", "default:mese_crystal_fragment", "default:steel_ingot"}, + } +}) + + +carts:register_rail("carts:brakerail", { + description = "Brake rail", + tiles = { + "carts_rail_straight_brk.png", "carts_rail_curved_brk.png", + "carts_rail_t_junction_brk.png", "carts_rail_crossing_brk.png" + }, + groups = carts:get_rail_groups(), +}, {acceleration = -3}) + +minetest.register_craft({ + output = "carts:brakerail 8", + recipe = { + {"default:steel_ingot", "default:coal_lump", "default:steel_ingot"}, + {"default:steel_ingot", "group:stick", "default:steel_ingot"}, + {"default:steel_ingot", "default:coal_lump", "default:steel_ingot"}, + } +}) diff --git a/mods/carts/sounds/carts_cart_moving.1.ogg b/mods/carts/sounds/carts_cart_moving.1.ogg new file mode 100644 index 00000000..869e765b Binary files /dev/null and b/mods/carts/sounds/carts_cart_moving.1.ogg differ diff --git a/mods/carts/sounds/carts_cart_moving.2.ogg b/mods/carts/sounds/carts_cart_moving.2.ogg new file mode 100644 index 00000000..b4cc5084 Binary files /dev/null and b/mods/carts/sounds/carts_cart_moving.2.ogg differ diff --git a/mods/carts/sounds/carts_cart_moving.3.ogg b/mods/carts/sounds/carts_cart_moving.3.ogg new file mode 100644 index 00000000..e19a782d Binary files /dev/null and b/mods/carts/sounds/carts_cart_moving.3.ogg differ diff --git a/mods/carts/textures/carts_cart.png b/mods/carts/textures/carts_cart.png new file mode 100644 index 00000000..965347c0 Binary files /dev/null and b/mods/carts/textures/carts_cart.png differ diff --git a/mods/carts/textures/carts_cart_front.png b/mods/carts/textures/carts_cart_front.png new file mode 100644 index 00000000..b85696f9 Binary files /dev/null and b/mods/carts/textures/carts_cart_front.png differ diff --git a/mods/carts/textures/carts_cart_side.png b/mods/carts/textures/carts_cart_side.png new file mode 100644 index 00000000..4362d6b1 Binary files /dev/null and b/mods/carts/textures/carts_cart_side.png differ diff --git a/mods/carts/textures/carts_cart_top.png b/mods/carts/textures/carts_cart_top.png new file mode 100644 index 00000000..5f775ff1 Binary files /dev/null and b/mods/carts/textures/carts_cart_top.png differ diff --git a/mods/carts/textures/carts_rail_crossing.png b/mods/carts/textures/carts_rail_crossing.png new file mode 100644 index 00000000..e10f3b1f Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing.png differ diff --git a/mods/carts/textures/carts_rail_crossing_brk.png b/mods/carts/textures/carts_rail_crossing_brk.png new file mode 100644 index 00000000..0bf455ef Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing_brk.png differ diff --git a/mods/carts/textures/carts_rail_crossing_pwr.png b/mods/carts/textures/carts_rail_crossing_pwr.png new file mode 100644 index 00000000..d763d508 Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing_pwr.png differ diff --git a/mods/carts/textures/carts_rail_curved.png b/mods/carts/textures/carts_rail_curved.png new file mode 100644 index 00000000..b320f0da Binary files /dev/null and b/mods/carts/textures/carts_rail_curved.png differ diff --git a/mods/carts/textures/carts_rail_curved_brk.png b/mods/carts/textures/carts_rail_curved_brk.png new file mode 100644 index 00000000..ca407236 Binary files /dev/null and b/mods/carts/textures/carts_rail_curved_brk.png differ diff --git a/mods/carts/textures/carts_rail_curved_pwr.png b/mods/carts/textures/carts_rail_curved_pwr.png new file mode 100644 index 00000000..781bbd0a Binary files /dev/null and b/mods/carts/textures/carts_rail_curved_pwr.png differ diff --git a/mods/carts/textures/carts_rail_straight.png b/mods/carts/textures/carts_rail_straight.png new file mode 100644 index 00000000..30dcafe8 Binary files /dev/null and b/mods/carts/textures/carts_rail_straight.png differ diff --git a/mods/carts/textures/carts_rail_straight_brk.png b/mods/carts/textures/carts_rail_straight_brk.png new file mode 100644 index 00000000..0c690529 Binary files /dev/null and b/mods/carts/textures/carts_rail_straight_brk.png differ diff --git a/mods/carts/textures/carts_rail_straight_pwr.png b/mods/carts/textures/carts_rail_straight_pwr.png new file mode 100644 index 00000000..e067ff1d Binary files /dev/null and b/mods/carts/textures/carts_rail_straight_pwr.png differ diff --git a/mods/carts/textures/carts_rail_t_junction.png b/mods/carts/textures/carts_rail_t_junction.png new file mode 100644 index 00000000..8b1b9462 Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction.png differ diff --git a/mods/carts/textures/carts_rail_t_junction_brk.png b/mods/carts/textures/carts_rail_t_junction_brk.png new file mode 100644 index 00000000..6b4f6faa Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction_brk.png differ diff --git a/mods/carts/textures/carts_rail_t_junction_pwr.png b/mods/carts/textures/carts_rail_t_junction_pwr.png new file mode 100644 index 00000000..dd0eede2 Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction_pwr.png differ diff --git a/mods/creative/README.txt b/mods/creative/README.txt index fa735524..82357f30 100644 --- a/mods/creative/README.txt +++ b/mods/creative/README.txt @@ -1,23 +1,12 @@ Minetest Game mod: creative =========================== +See license.txt for license information. -Implements creative mode. - -Switch on by using the "creative_mode" setting. - -Registered items that -- have a description, and -- do not have the group not_in_creative_inventory -are added to the creative inventory. - -License of source code and media files: ---------------------------------------- -Copyright (C) 2012 Perttu Ahola (celeron55) -Copyright (C) 2016 Jean-Patrick G. (kilbith) - -This program is free software. It comes without any warranty, to -the extent permitted by applicable law. You can redistribute it -and/or modify it under the terms of the Do What The Fuck You Want -To Public License, Version 2, as published by Sam Hocevar. See -http://sam.zoy.org/wtfpl/COPYING for more details. +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (MIT) +Jean-Patrick G. (kilbith) (MIT) +Author of media (textures) +-------------------------- +Jean-Patrick G. (kilbith) (CC BY-SA 3.0) diff --git a/mods/creative/depends.txt b/mods/creative/depends.txt index 4ad96d51..975e6525 100644 --- a/mods/creative/depends.txt +++ b/mods/creative/depends.txt @@ -1 +1,2 @@ default +sfinv diff --git a/mods/creative/init.lua b/mods/creative/init.lua index bc4687f7..868b802b 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -1,225 +1,14 @@ --- minetest/creative/init.lua +dofile(minetest.get_modpath("creative") .. "/inventory.lua") -creative = {} -local player_inventory = {} -local creative_mode = minetest.setting_getbool("creative_mode") - --- Create detached creative inventory after loading all mods -creative.init_creative_inventory = function(player) - local player_name = player:get_player_name() - player_inventory[player_name] = {} - player_inventory[player_name].size = 0 - player_inventory[player_name].filter = "" - player_inventory[player_name].start_i = 1 - player_inventory[player_name].tab_id = 2 - - minetest.create_detached_inventory("creative_" .. player_name, { - allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - if creative_mode and not to_list == "main" then - return count - else - return 0 - end - end, - allow_put = function(inv, listname, index, stack, player) - return 0 - end, - allow_take = function(inv, listname, index, stack, player) - if creative_mode then - return -1 - else - return 0 - end - end, - on_move = function(inv, from_list, from_index, to_list, to_index, count, player) - end, - on_put = function(inv, listname, index, stack, player) - end, - on_take = function(inv, listname, index, stack, player) - local player_name, stack_name = player:get_player_name(), stack:get_name() - --print(player_name .. " takes item from creative inventory; listname = " .. listname .. ", index = " .. index .. ", stack = " .. dump(stack:to_table())) - if stack then - minetest.log("action", player_name .. " takes " .. stack_name .. " from creative inventory") - --print("Stack name: " .. stack_name .. ", Stack count: " .. stack:get_count()) - end - end, - }) - - creative.update_creative_inventory(player_name) - --print("creative inventory size: " .. player_inventory[player_name].size) -end - -local function tab_category(tab_id) - local id_category = { - nil, -- Reserved for crafting tab. - minetest.registered_items, - minetest.registered_nodes, - minetest.registered_tools, - minetest.registered_craftitems - } - - -- If index out of range, show default ("All") page. - return id_category[tab_id] or id_category[2] -end - -function creative.update_creative_inventory(player_name) - local creative_list = {} - local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name}) - local inv = player_inventory[player_name] - - for name, def in pairs(tab_category(inv.tab_id)) do - if not (def.groups.not_in_creative_inventory == 1) and - def.description and def.description ~= "" and - (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) - if creative_mode then - return stack:get_count() - else - return 0 - end - end, - on_put = function(inv, listname) - inv:set_list(listname, {}) - end, -}) -trash:set_size("main", 1) - -creative.formspec_add = "" - -creative.set_creative_formspec = function(player, start_i) - local player_name = player:get_player_name() - local inv = player_inventory[player_name] - local pagenum = math.floor(start_i / (3*8) + 1) - local pagemax = math.ceil(inv.size / (3*8)) - - player:set_inventory_formspec([[ - size[8,8.6] - image[4.06,3.4;0.8,0.8;creative_trash_icon.png] - list[current_player;main;0,4.7;8,1;] - list[current_player;main;0,5.85;8,3;8] - list[detached:creative_trash;main;4,3.3;1,1;] - listring[] - tablecolumns[color;text;color;text] - tableoptions[background=#00000000;highlight=#00000000;border=false] - button[5.4,3.2;0.8,0.9;creative_prev;<] - button[7.25,3.2;0.8,0.9;creative_next;>] - button[2.1,3.4;0.8,0.5;creative_search;?] - button[2.75,3.4;0.8,0.5;creative_clear;X] - tooltip[creative_search;Search] - tooltip[creative_clear;Reset] - listring[current_player;main] - ]] .. - "field[0.3,3.5;2.2,1;creative_filter;;" .. inv.filter .. "]" .. - "listring[detached:creative_" .. player_name .. ";main]" .. - "tabheader[0,0;creative_tabs;Crafting,All,Nodes,Tools,Items;" .. tostring(inv.tab_id) .. ";true;false]" .. - "list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" .. - "table[6.05,3.35;1.15,0.5;pagenum;#FFFF00," .. tostring(pagenum) .. ",#FFFFFF,/ " .. tostring(pagemax) .. "]" .. - default.get_hotbar_bg(0,4.7) .. - default.gui_bg .. default.gui_bg_img .. default.gui_slots - .. creative.formspec_add - ) -end - -creative.set_crafting_formspec = function(player) - player:set_inventory_formspec([[ - size[8,8.6] - list[current_player;craft;2,0.75;3,3;] - list[current_player;craftpreview;6,1.75;1,1;] - list[current_player;main;0,4.7;8,1;] - list[current_player;main;0,5.85;8,3;8] - list[detached:creative_trash;main;0,2.75;1,1;] - image[0.06,2.85;0.8,0.8;creative_trash_icon.png] - image[5,1.75;1,1;gui_furnace_arrow_bg.png^[transformR270] - tabheader[0,0;creative_tabs;Crafting,All,Nodes,Tools,Items;1;true;false] - listring[current_player;main] - listring[current_player;craft] - ]] .. - default.get_hotbar_bg(0,4.7) .. - default.gui_bg .. default.gui_bg_img .. default.gui_slots - ) -end - -minetest.register_on_joinplayer(function(player) - -- If in creative mode, modify player's inventory forms - if not creative_mode then - return - end - creative.init_creative_inventory(player) - creative.set_creative_formspec(player, 0) -end) - -minetest.register_on_player_receive_fields(function(player, formname, fields) - if formname ~= "" or not creative_mode then - return - end - - local player_name = player:get_player_name() - local inv = player_inventory[player_name] - - if fields.quit then - if inv.tab_id == 1 then - creative.set_crafting_formspec(player) - end - elseif fields.creative_tabs then - local tab = tonumber(fields.creative_tabs) - inv.tab_id = tab - - if tab == 1 then - creative.set_crafting_formspec(player) - else - creative.update_creative_inventory(player_name) - creative.set_creative_formspec(player, 0) - end - elseif fields.creative_clear then - inv.filter = "" - creative.update_creative_inventory(player_name) - creative.set_creative_formspec(player, 0) - elseif fields.creative_search then - inv.filter = fields.creative_filter:lower() - creative.update_creative_inventory(player_name) - creative.set_creative_formspec(player, 0) - else - local formspec = player:get_inventory_formspec() - local start_i = player_inventory[player_name].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 - - player_inventory[player_name].start_i = start_i - creative.set_creative_formspec(player, start_i) - end -end) - -if creative_mode then - local digtime = 0.5 - local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 3} +if minetest.setting_getbool("creative_mode") 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", diff --git a/mods/creative/inventory.lua b/mods/creative/inventory.lua new file mode 100644 index 00000000..be24b3a2 --- /dev/null +++ b/mods/creative/inventory.lua @@ -0,0 +1,180 @@ +creative = {} +local player_inventory = {} + +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) + if not to_list == "main" then + return count + else + return 0 + end + end, + allow_put = function(inv, listname, index, stack, player2) + return 0 + end, + allow_take = function(inv, listname, index, stack, player2) + return -1 + end, + on_move = function(inv, from_list, from_index, to_list, to_index, count, player2) + end, + on_put = function(inv, listname, index, stack, 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) + + creative.update_creative_inventory(player_name, minetest.registered_items) +end + +function creative.update_creative_inventory(player_name, tab_content) + local creative_list = {} + local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name}) + local inv = player_inventory[player_name] + if not inv then + creative.init_creative_inventory(minetest.get_player_by_name(player_name)) + end + + for name, def in pairs(tab_content) do + if not (def.groups.not_in_creative_inventory == 1) and + def.description and def.description ~= "" and + (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 minetest.setting_getbool("creative_mode") + 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 / (3*8) + 1) + local pagemax = math.ceil(inv.size / (3*8)) + return sfinv.make_formspec(player, context, + "label[6.2,3.35;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" .. + [[ + image[4.06,3.4;0.8,0.8;creative_trash_icon.png] + listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF] + list[current_player;main;0,4.7;8,1;] + list[current_player;main;0,5.85;8,3;8] + list[detached:creative_trash;main;4,3.3;1,1;] + listring[] + button[5.4,3.2;0.8,0.9;creative_prev;<] + button[7.25,3.2;0.8,0.9;creative_next;>] + button[2.1,3.4;0.8,0.5;creative_search;?] + button[2.75,3.4;0.8,0.5;creative_clear;X] + tooltip[creative_search;Search] + tooltip[creative_clear;Reset] + listring[current_player;main] + field_close_on_enter[creative_filter;false] + ]] .. + "field[0.3,3.5;2.2,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. "]" .. + "listring[detached:creative_" .. player_name .. ";main]" .. + "list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" .. + default.get_hotbar_bg(0,4.7) .. + default.gui_bg .. default.gui_bg_img .. default.gui_slots + .. 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 + +minetest.register_on_joinplayer(function(player) + creative.init_creative_inventory(player) +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 minetest.setting_getbool("creative_mode") then + return "creative:all" + else + return old_homepage_name(player) + end +end diff --git a/mods/creative/license.txt b/mods/creative/license.txt new file mode 100644 index 00000000..4ad1d5ff --- /dev/null +++ b/mods/creative/license.txt @@ -0,0 +1,60 @@ +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) + +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/default/README.txt b/mods/default/README.txt index 8e72ca5e..d261b6b5 100644 --- a/mods/default/README.txt +++ b/mods/default/README.txt @@ -1,28 +1,18 @@ Minetest Game mod: default ========================== +See license.txt for license information. -License of source code: ------------------------ -Copyright (C) 2011-2012 celeron55, Perttu Ahola +Authors of source code +---------------------- +Originally by celeron55, Perttu Ahola (LGPL 2.1) +Various Minetest developers and contributors (LGPL 2.1) -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. - -http://www.gnu.org/licenses/lgpl-2.1.html - -License of media (textures and sounds) --------------------------------------- -Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) -http://creativecommons.org/licenses/by-sa/3.0/ - -Authors of media files ------------------------ +Authors of media (textures, models and sounds) +---------------------------------------------- Everything not listed in here: -Copyright (C) 2010-2012 celeron55, Perttu Ahola +celeron55, Perttu Ahola (CC BY-SA 3.0) -Cisoun's WTFPL texture pack: +Cisoun's texture pack (CC BY-SA 3.0): default_jungletree.png default_lava.png default_leaves.png @@ -32,61 +22,57 @@ Cisoun's WTFPL texture pack: default_tree_top.png default_water.png -Cisoun's conifers mod (WTFPL): +Cisoun's conifers mod (CC BY-SA 3.0): default_pine_needles.png -Originating from G4JC's Almost MC Texture Pack: +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 (WTFPL): +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 (WTFPL): +RealBadAngel's animated water (CC BY-SA 3.0): default_water_source_animated.png default_water_flowing_animated.png -VanessaE (WTFPL): - default_nc_back.png - default_nc_front.png - default_nc_rb.png - default_nc_side.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): +Calinou (CC BY-SA 3.0): default_brick.png default_papyrus.png default_mineral_copper.png default_glass_detail.png -MirceaKitsune (WTFPL): +MirceaKitsune (CC BY-SA 3.0): character.x Jordach (CC BY-SA 3.0): character.png -PilzAdam (WTFPL): +PilzAdam (CC BY-SA 3.0): default_jungleleaves.png default_junglesapling.png default_obsidian_glass.png default_obsidian_shard.png default_mineral_gold.png - default_snowball.png -jojoa1997 (WTFPL): +jojoa1997 (CC BY-SA 3.0): default_obsidian.png -InfinityProject (WTFPL): +InfinityProject (CC BY-SA 3.0): default_mineral_diamond.png Splizard (CC BY-SA 3.0): - default_snow.png default_pine_sapling.png Zeg9 (CC BY-SA 3.0): @@ -102,16 +88,23 @@ paramat (CC BY-SA 3.0): default_pinetree_top.png default_pinewood.png default_acacia_leaves.png + default_acacia_leaves_simple.png default_acacia_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 @@ -120,7 +113,8 @@ paramat (CC BY-SA 3.0): default_dry_grass_*.png default_grass.png default_grass_side.png - default_snow_side.png + default_mese_block.png + default_silver_sand.png brunob.santos (CC BY-SA 4.0): default_desert_cobble.png @@ -146,6 +140,9 @@ BlockMen (CC BY-SA 3.0): bubble.png gui_*.png +Wuzzy (CC BY-SA 3.0): + default_bookshelf_slot.png (based on default_book.png) + sofar (CC BY-SA 3.0): default_book_written.png, based on default_book.png default_aspen_sapling @@ -153,18 +150,17 @@ sofar (CC BY-SA 3.0): 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) - -sofar (WTFPL): default_gravel.png -- Derived from Gambit's PixelBOX texture pack light gravel Neuromancer (CC BY-SA 2.0): default_cobble.png, based on texture by Brane praefect default_mossycobble.png, based on texture by Brane praefect + Neuromancer (CC BY-SA 3.0): default_dirt.png default_furnace_*.png -Gambit (WTFPL): +Gambit (CC BY-SA 3.0): default_bronze_ingot.png default_copper_ingot.png default_copper_lump.png @@ -178,19 +174,37 @@ Gambit (WTFPL): 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 -asl97 (WTFPL): +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 + 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/ -Mito551 (sounds) (CC BY-SA): +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 @@ -224,3 +238,27 @@ Mito551 (sounds) (CC BY-SA): 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 diff --git a/mods/default/aliases.lua b/mods/default/aliases.lua index 63fe59b2..6db3fc8d 100644 --- a/mods/default/aliases.lua +++ b/mods/default/aliases.lua @@ -22,7 +22,7 @@ minetest.register_alias("papyrus", "default:papyrus") minetest.register_alias("bookshelf", "default:bookshelf") minetest.register_alias("glass", "default:glass") minetest.register_alias("wooden_fence", "default:fence_wood") -minetest.register_alias("rail", "default:rail") +minetest.register_alias("rail", "carts:rail") minetest.register_alias("ladder", "default:ladder_wood") minetest.register_alias("wood", "default:wood") minetest.register_alias("mese", "default:mese") @@ -39,8 +39,6 @@ minetest.register_alias("locked_chest", "default:chest_locked") minetest.register_alias("cobble", "default:cobble") minetest.register_alias("mossycobble", "default:mossycobble") minetest.register_alias("steelblock", "default:steelblock") -minetest.register_alias("nyancat", "default:nyancat") -minetest.register_alias("nyancat_rainbow", "default:nyancat_rainbow") minetest.register_alias("sapling", "default:sapling") minetest.register_alias("apple", "default:apple") @@ -77,4 +75,3 @@ minetest.register_alias("default:pinewood", "default:pine_wood") minetest.register_alias("default:ladder", "default:ladder_wood") minetest.register_alias("default:sign_wall", "default:sign_wall_wood") - diff --git a/mods/default/crafting.lua b/mods/default/crafting.lua index 998d86ba..483245c2 100644 --- a/mods/default/crafting.lua +++ b/mods/default/crafting.lua @@ -35,6 +35,20 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'default:wood', + recipe = { + {'default:bush_stem'}, + } +}) + +minetest.register_craft({ + output = 'default:acacia_wood', + recipe = { + {'default:acacia_bush_stem'}, + } +}) + minetest.register_craft({ output = 'default:stick 4', recipe = { @@ -339,11 +353,9 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'default:rail 24', + output = 'default:skeleton_key', recipe = { - {'default:steel_ingot', '', 'default:steel_ingot'}, - {'default:steel_ingot', 'group:stick', 'default:steel_ingot'}, - {'default:steel_ingot', '', 'default:steel_ingot'}, + {'default:gold_ingot'}, } }) @@ -365,6 +377,12 @@ minetest.register_craft({ } }) +minetest.register_craft( { + type = "shapeless", + output = "default:chest_locked", + recipe = {"default:chest", "default:steel_ingot"}, +}) + minetest.register_craft({ output = 'default:furnace', recipe = { @@ -499,6 +517,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'default:sandstone_block 9', + recipe = { + {'default:sandstone', 'default:sandstone', 'default:sandstone'}, + {'default:sandstone', 'default:sandstone', 'default:sandstone'}, + {'default:sandstone', 'default:sandstone', 'default:sandstone'}, + } +}) + minetest.register_craft({ output = 'default:clay', recipe = { @@ -595,6 +622,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = "default:mese_crystal", + recipe = { + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + } +}) + minetest.register_craft({ output = 'default:meselamp 1', recipe = { @@ -627,6 +663,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'default:obsidian_block 9', + recipe = { + {'default:obsidian', 'default:obsidian', 'default:obsidian'}, + {'default:obsidian', 'default:obsidian', 'default:obsidian'}, + {'default:obsidian', 'default:obsidian', 'default:obsidian'}, + } +}) + minetest.register_craft({ output = 'default:stonebrick 4', recipe = { @@ -635,6 +680,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'default:stone_block 9', + recipe = { + {'default:stone', 'default:stone', 'default:stone'}, + {'default:stone', 'default:stone', 'default:stone'}, + {'default:stone', 'default:stone', 'default:stone'}, + } +}) + minetest.register_craft({ output = 'default:desert_stonebrick 4', recipe = { @@ -643,6 +697,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'default:desert_stone_block 9', + recipe = { + {'default:desert_stone', 'default:desert_stone', 'default:desert_stone'}, + {'default:desert_stone', 'default:desert_stone', 'default:desert_stone'}, + {'default:desert_stone', 'default:desert_stone', 'default:desert_stone'}, + } +}) + minetest.register_craft({ output = 'default:snowblock', recipe = { @@ -725,16 +788,185 @@ minetest.register_craft({ recipe = "default:clay_lump", }) +minetest.register_craft({ + type = 'cooking', + output = 'default:gold_ingot', + recipe = 'default:skeleton_key', + cooktime = 5, +}) + +minetest.register_craft({ + type = 'cooking', + output = 'default:gold_ingot', + recipe = 'default:key', + cooktime = 5, +}) + -- -- Fuels -- +-- Support use of group:tree 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 = "default:aspen_tree", + burntime = 22, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:pine_tree", + burntime = 26, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:tree", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:acacia_tree", + burntime = 34, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:jungletree", + burntime = 38, +}) + + +-- Support use of group:wood +minetest.register_craft({ + type = "fuel", + recipe = "group:wood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:aspen_wood", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:pine_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:wood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:acacia_wood", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:junglewood", + burntime = 9, +}) + + +-- Support use of group:sapling +minetest.register_craft({ + type = "fuel", + recipe = "group:sapling", + burntime = 10, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:aspen_sapling", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:pine_sapling", + burntime = 9, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:sapling", + burntime = 10, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:acacia_sapling", + burntime = 11, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:junglesapling", + burntime = 12, +}) + + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_aspen_wood", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_pine_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_wood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_acacia_wood", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_junglewood", + burntime = 9, +}) + + +minetest.register_craft({ + type = "fuel", + recipe = "default:bush_stem", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:acacia_bush_stem", + burntime = 8, +}) + minetest.register_craft({ type = "fuel", recipe = "default:junglegrass", @@ -765,46 +997,10 @@ minetest.register_craft({ burntime = 30, }) -minetest.register_craft({ - type = "fuel", - recipe = "default:fence_wood", - burntime = 15, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "default:fence_acacia_wood", - burntime = 15, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "default:fence_junglewood", - burntime = 15, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "default:fence_pine_wood", - burntime = 15, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "default:fence_aspen_wood", - burntime = 15, -}) - minetest.register_craft({ type = "fuel", recipe = "default:ladder_wood", - burntime = 5, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "group:wood", - burntime = 7, + burntime = 2, }) minetest.register_craft({ @@ -837,24 +1033,6 @@ minetest.register_craft({ burntime = 30, }) -minetest.register_craft({ - type = "fuel", - recipe = "default:nyancat", - burntime = 1, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "default:nyancat_rainbow", - burntime = 1, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "group:sapling", - burntime = 10, -}) - minetest.register_craft({ type = "fuel", recipe = "default:apple", @@ -885,3 +1063,57 @@ minetest.register_craft({ burntime = 2, }) +minetest.register_craft({ + type = "fuel", + recipe = "default:paper", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_written", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:dry_shrub", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "group:stick", + burntime = 1, +}) + + +minetest.register_craft({ + type = "fuel", + recipe = "default:pick_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:shovel_wood", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:axe_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:sword_wood", + burntime = 5, +}) diff --git a/mods/default/craftitems.lua b/mods/default/craftitems.lua index 2fe59784..0c51c713 100644 --- a/mods/default/craftitems.lua +++ b/mods/default/craftitems.lua @@ -3,19 +3,20 @@ minetest.register_craftitem("default:stick", { description = "Stick", inventory_image = "default_stick.png", - groups = {stick = 1}, + groups = {stick = 1, flammable = 2}, }) minetest.register_craftitem("default:paper", { description = "Paper", inventory_image = "default_paper.png", + groups = {flammable = 3}, }) local lpp = 14 -- Lines per book's page local function book_on_use(itemstack, user) local player_name = user:get_player_name() local data = minetest.deserialize(itemstack:get_metadata()) - local formspec, title, text, owner = "", "", "", player_name + local title, text, owner = "", "", player_name local page, page_max, lines, string = 1, 1, {}, "" if data then @@ -38,6 +39,7 @@ local function book_on_use(itemstack, user) end end + local formspec if owner == player_name then formspec = "size[8,8]" .. default.gui_bg .. default.gui_bg_img .. @@ -104,7 +106,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) elseif fields.book_next or fields.book_prev then local data = minetest.deserialize(stack:get_metadata()) - if not data.page then return end + if not data or not data.page then + return + end if fields.book_next then data.page = data.page + 1 @@ -129,14 +133,14 @@ end) minetest.register_craftitem("default:book", { description = "Book", inventory_image = "default_book.png", - groups = {book = 1}, + groups = {book = 1, flammable = 3}, on_use = book_on_use, }) minetest.register_craftitem("default:book_written", { description = "Book With Text", inventory_image = "default_book_written.png", - groups = {book = 1, not_in_creative_inventory = 1}, + groups = {book = 1, not_in_creative_inventory = 1, flammable = 3}, stack_max = 1, on_use = book_on_use, }) @@ -152,7 +156,6 @@ minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv return end - local copy = ItemStack("default:book_written") local original local index for i = 1, player:get_inventory():get_size("craft") do @@ -174,7 +177,7 @@ end) minetest.register_craftitem("default:coal_lump", { description = "Coal Lump", inventory_image = "default_coal_lump.png", - groups = {coal = 1} + groups = {coal = 1, flammable = 1} }) minetest.register_craftitem("default:iron_lump", { diff --git a/mods/default/functions.lua b/mods/default/functions.lua index 7e594b31..3bda4bf0 100644 --- a/mods/default/functions.lua +++ b/mods/default/functions.lua @@ -18,7 +18,7 @@ end function default.node_sound_stone_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_hard_footstep", gain = 0.5} + {name = "default_hard_footstep", gain = 0.3} table.dug = table.dug or {name = "default_hard_footstep", gain = 1.0} default.node_sound_defaults(table) @@ -28,9 +28,9 @@ end function default.node_sound_dirt_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_dirt_footstep", gain = 1.0} + {name = "default_dirt_footstep", gain = 0.4} table.dug = table.dug or - {name = "default_dirt_footstep", gain = 1.5} + {name = "default_dirt_footstep", gain = 1.0} table.place = table.place or {name = "default_place_node", gain = 1.0} default.node_sound_defaults(table) @@ -52,7 +52,7 @@ end function default.node_sound_gravel_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_gravel_footstep", gain = 0.5} + {name = "default_gravel_footstep", gain = 0.4} table.dug = table.dug or {name = "default_gravel_footstep", gain = 1.0} table.place = table.place or @@ -64,7 +64,7 @@ end function default.node_sound_wood_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_wood_footstep", gain = 0.5} + {name = "default_wood_footstep", gain = 0.3} table.dug = table.dug or {name = "default_wood_footstep", gain = 1.0} default.node_sound_defaults(table) @@ -74,7 +74,7 @@ end function default.node_sound_leaves_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_grass_footstep", gain = 0.35} + {name = "default_grass_footstep", gain = 0.45} table.dug = table.dug or {name = "default_grass_footstep", gain = 0.7} table.dig = table.dig or @@ -88,6 +88,8 @@ end function default.node_sound_glass_defaults(table) table = table or {} table.footstep = table.footstep or + {name = "default_glass_footstep", gain = 0.3} + table.dig = table.dig or {name = "default_glass_footstep", gain = 0.5} table.dug = table.dug or {name = "default_break_glass", gain = 1.0} @@ -95,6 +97,27 @@ function default.node_sound_glass_defaults(table) return table end +function default.node_sound_metal_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_metal_footstep", gain = 0.4} + table.dig = table.dig or + {name = "default_dig_metal", gain = 0.5} + table.dug = table.dug or + {name = "default_dug_metal", gain = 0.5} + table.place = table.place or + {name = "default_place_node_metal", gain = 0.5} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_water_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_water_footstep", gain = 0.2} + default.node_sound_defaults(table) + return table +end -- -- Lavacooling @@ -111,8 +134,9 @@ default.cool_lava = function(pos, node) end minetest.register_abm({ + label = "Lava cooling", nodenames = {"default:lava_source", "default:lava_flowing"}, - neighbors = {"group:water"}, + neighbors = {"group:cools_lava", "group:water"}, interval = 1, chance = 1, catch_up = false, @@ -125,6 +149,7 @@ minetest.register_abm({ -- -- optimized helper to put all items in an inventory into a drops list -- + function default.get_inventory_drops(pos, inventory, drops) local inv = minetest.get_meta(pos):get_inventory() local n = #drops @@ -189,6 +214,7 @@ function default.grow_papyrus(pos, node) end minetest.register_abm({ + label = "Grow cactus", nodenames = {"default:cactus"}, neighbors = {"group:sand"}, interval = 12, @@ -199,6 +225,7 @@ minetest.register_abm({ }) minetest.register_abm({ + label = "Grow papyrus", nodenames = {"default:papyrus"}, neighbors = {"default:dirt", "default:dirt_with_grass"}, interval = 14, @@ -226,6 +253,7 @@ end -- -- Fence registration helper -- + function default.register_fence(name, def) minetest.register_craft({ output = name .. " 4", @@ -283,16 +311,7 @@ end -- Leafdecay -- -default.leafdecay_trunk_cache = {} -default.leafdecay_enable_cache = true --- Spread the load of finding trunks -default.leafdecay_trunk_find_allow_accumulator = 0 - -minetest.register_globalstep(function(dtime) - local finds_per_second = 5000 - default.leafdecay_trunk_find_allow_accumulator = - math.floor(dtime * finds_per_second) -end) +-- Prevent decay of placed leaves default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) if placer and not placer:get_player_control().sneak then @@ -302,79 +321,44 @@ default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) end end -minetest.register_abm({ - nodenames = {"group:leafdecay"}, - neighbors = {"air", "group:liquid"}, - -- A low interval and a high inverse chance spreads the load - interval = 2, - chance = 5, +-- Leafdecay ABM - action = function(p0, node, _, _) - --print("leafdecay ABM at "..p0.x..", "..p0.y..", "..p0.z..")") - local do_preserve = false - local d = minetest.registered_nodes[node.name].groups.leafdecay - if not d or d == 0 then - --print("not groups.leafdecay") +minetest.register_abm({ + label = "Leaf decay", + nodenames = {"group:leafdecay"}, + neighbors = {"air"}, + interval = 2, + chance = 10, + catch_up = false, + + action = function(pos, node, _, _) + -- Check if leaf is placed + if node.param2 ~= 0 then return end - local n0 = minetest.get_node(p0) - if n0.param2 ~= 0 then - --print("param2 ~= 0") + + local rad = minetest.registered_nodes[node.name].groups.leafdecay + -- Assume ignore is a trunk, to make this + -- work at the border of a loaded area + if minetest.find_node_near(pos, rad, {"ignore", "group:tree"}) then return end - local p0_hash = nil - if default.leafdecay_enable_cache then - p0_hash = minetest.hash_node_position(p0) - local trunkp = default.leafdecay_trunk_cache[p0_hash] - if trunkp then - local n = minetest.get_node(trunkp) - local reg = minetest.registered_nodes[n.name] - -- Assume ignore is a trunk, to make the thing - -- work at the border of the active area - if n.name == "ignore" or (reg and reg.groups.tree and - reg.groups.tree ~= 0) then - --print("cached trunk still exists") - return - end - --print("cached trunk is invalid") - -- Cache is invalid - table.remove(default.leafdecay_trunk_cache, p0_hash) + -- Drop stuff + local itemstacks = minetest.get_node_drops(node.name) + for _, itemname in ipairs(itemstacks) do + if itemname ~= node.name or + minetest.get_item_group(node.name, "leafdecay_drop") ~= 0 then + local p_drop = { + x = pos.x - 0.5 + math.random(), + y = pos.y - 0.5 + math.random(), + z = pos.z - 0.5 + math.random(), + } + minetest.add_item(p_drop, itemname) end end - if default.leafdecay_trunk_find_allow_accumulator <= 0 then - return - end - default.leafdecay_trunk_find_allow_accumulator = - default.leafdecay_trunk_find_allow_accumulator - 1 - -- Assume ignore is a trunk, to make the thing - -- work at the border of the active area - local p1 = minetest.find_node_near(p0, d, {"ignore", "group:tree"}) - if p1 then - do_preserve = true - if default.leafdecay_enable_cache then - --print("caching trunk") - -- Cache the trunk - default.leafdecay_trunk_cache[p0_hash] = p1 - end - end - if not do_preserve then - -- Drop stuff other than the node itself - local itemstacks = minetest.get_node_drops(n0.name) - for _, itemname in ipairs(itemstacks) do - if minetest.get_item_group(n0.name, "leafdecay_drop") ~= 0 or - itemname ~= n0.name then - local p_drop = { - x = p0.x - 0.5 + math.random(), - y = p0.y - 0.5 + math.random(), - z = p0.z - 0.5 + math.random(), - } - minetest.add_item(p_drop, itemname) - end - end - -- Remove node - minetest.remove_node(p0) - nodeupdate(p0) - end + -- Remove node + minetest.remove_node(pos) + minetest.check_for_falling(pos) end }) @@ -384,49 +368,39 @@ minetest.register_abm({ -- minetest.register_abm({ + label = "Grass spread", nodenames = {"default:dirt"}, neighbors = { - "default:dirt_with_grass", - "default:dirt_with_dry_grass", - "default:dirt_with_snow", + "air", "group:grass", "group:dry_grass", "default:snow", }, interval = 6, - chance = 67, + chance = 50, catch_up = false, action = function(pos, node) - -- Most likely case, half the time it's too dark for this. + -- 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 likely neighbors. - local p2 = minetest.find_node_near(pos, 1, {"default:dirt_with_grass", - "default:dirt_with_dry_grass", "default:dirt_with_snow"}) + -- Look for spreading dirt-type neighbours + local p2 = minetest.find_node_near(pos, 1, "group:spreading_dirt_type") if p2 then - -- But the node needs to be under air in this case. - local n2 = minetest.get_node(above) - if n2 and n2.name == "air" then - local n3 = minetest.get_node(p2) - minetest.set_node(pos, {name = n3.name}) - return - end - end - - -- Anything on top? - local n2 = minetest.get_node(above) - if not n2 then + local n3 = minetest.get_node(p2) + minetest.set_node(pos, {name = n3.name}) return end - local name = n2.name - -- Snow check is cheapest, so comes first. + -- Else, any seeding nodes on top? + local name = minetest.get_node(above).name + -- Snow check is cheapest, so comes first if name == "default:snow" then minetest.set_node(pos, {name = "default:dirt_with_snow"}) - -- Most likely case first. + -- Most likely case first elseif minetest.get_item_group(name, "grass") ~= 0 then minetest.set_node(pos, {name = "default:dirt_with_grass"}) elseif minetest.get_item_group(name, "dry_grass") ~= 0 then @@ -435,16 +409,14 @@ minetest.register_abm({ end }) + -- -- Grass and dry grass removed in darkness -- minetest.register_abm({ - nodenames = { - "default:dirt_with_grass", - "default:dirt_with_dry_grass", - "default:dirt_with_snow", - }, + label = "Grass covered", + nodenames = {"group:spreading_dirt_type"}, interval = 8, chance = 50, catch_up = false, @@ -466,12 +438,77 @@ minetest.register_abm({ -- minetest.register_abm({ - nodenames = {"default:cobble"}, + label = "Moss growth", + nodenames = {"default:cobble", "stairs:slab_cobble", "stairs:stair_cobble", "walls:cobble"}, neighbors = {"group:water"}, interval = 16, chance = 200, catch_up = false, action = function(pos, node) - minetest.set_node(pos, {name = "default:mossycobble"}) + if node.name == "default:cobble" then + minetest.set_node(pos, {name = "default: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 }) + + +-- +-- Checks if specified volume intersects a protected volume +-- + +function default.intersects_protection(minp, maxp, player_name, interval) + -- 'interval' is the largest allowed interval for the 3D lattice of checks + + -- Compute the optimal float step 'd' for each axis so that all corners and + -- borders are checked. 'd' will be smaller or equal to 'interval'. + -- Subtracting 1e-4 ensures that the max co-ordinate will be reached by the + -- for loop (which might otherwise not be the case due to rounding errors). + local d = {} + for _, c in pairs({"x", "y", "z"}) do + if maxp[c] > minp[c] then + d[c] = (maxp[c] - minp[c]) / math.ceil((maxp[c] - minp[c]) / interval) - 1e-4 + elseif maxp[c] == minp[c] then + d[c] = 1 -- Any value larger than 0 to avoid division by zero + else -- maxp[c] < minp[c], print error and treat as protection intersected + minetest.log("error", "maxp < minp in 'default.intersects_protection()'") + return true + end + end + + for zf = minp.z, maxp.z, d.z do + local z = math.floor(zf + 0.5) + for yf = minp.y, maxp.y, d.y do + local y = math.floor(yf + 0.5) + for xf = minp.x, maxp.x, d.x do + local x = math.floor(xf + 0.5) + if minetest.is_protected({x = x, y = y, z = z}, player_name) then + return true + end + end + end + end + + return false +end + + +-- +-- Coral death near air +-- + +minetest.register_abm({ + nodenames = {"default:coral_brown", "default:coral_orange"}, + neighbors = {"air"}, + interval = 17, + chance = 5, + catch_up = false, + action = function(pos, node) + minetest.set_node(pos, {name = "default:coral_skeleton"}) + end, +}) diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua index 3047dc41..4b822058 100644 --- a/mods/default/furnace.lua +++ b/mods/default/furnace.lua @@ -4,7 +4,7 @@ -- local function active_formspec(fuel_percent, item_percent) - local formspec = + local formspec = "size[8,8.5]".. default.gui_bg.. default.gui_bg_img.. @@ -22,6 +22,8 @@ local function active_formspec(fuel_percent, item_percent) "listring[current_player;main]".. "listring[current_name;src]".. "listring[current_player;main]".. + "listring[current_name;fuel]".. + "listring[current_player;main]".. default.get_hotbar_bg(0, 4.25) return formspec end @@ -42,6 +44,8 @@ local inactive_formspec = "listring[current_player;main]".. "listring[current_name;src]".. "listring[current_player;main]".. + "listring[current_name;fuel]".. + "listring[current_player;main]".. default.get_hotbar_bg(0, 4.25) -- @@ -109,74 +113,93 @@ local function furnace_node_timer(pos, elapsed) local fuel_totaltime = meta:get_float("fuel_totaltime") or 0 local inv = meta:get_inventory() - local srclist = inv:get_list("src") - local fuellist = inv:get_list("fuel") - local dstlist = inv:get_list("dst") + local srclist, fuellist - -- - -- Cooking - -- + local cookable, cooked + local fuel - -- Check if we have cookable content - local cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) - local cookable = true + local update = true + while update do + update = false - if cooked.time == 0 then - cookable = false - end + srclist = inv:get_list("src") + fuellist = inv:get_list("fuel") - -- Check if we have enough fuel to burn - if fuel_time < fuel_totaltime then - -- The furnace is currently active and has enough fuel - fuel_time = fuel_time + 1 + -- + -- Cooking + -- - -- If there is a cookable item then check if it is ready yet - if cookable then - src_time = src_time + 1 - if src_time >= cooked.time then - -- Place result in dst list if possible - if inv:room_for_item("dst", cooked.item) then - inv:add_item("dst", cooked.item) - inv:set_stack("src", 1, aftercooked.items[1]) - src_time = 0 + -- Check if we have cookable content + local aftercooked + cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cookable = cooked.time ~= 0 + + -- Check if we have enough fuel to burn + if fuel_time < fuel_totaltime then + -- The furnace is currently active and has enough fuel + fuel_time = fuel_time + elapsed + -- If there is a cookable item then check if it is ready yet + if cookable then + src_time = src_time + elapsed + if src_time >= cooked.time then + -- Place result in dst list if possible + if inv:room_for_item("dst", cooked.item) then + inv:add_item("dst", cooked.item) + inv:set_stack("src", 1, aftercooked.items[1]) + src_time = src_time - cooked.time + update = true + end end end - end - else - -- Furnace ran out of fuel - if cookable then - -- We need to get new fuel - local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) - - if fuel.time == 0 then - -- No valid fuel in fuel list - fuel_totaltime = 0 - fuel_time = 0 - src_time = 0 - else - -- Take fuel from fuel list - inv:set_stack("fuel", 1, afterfuel.items[1]) - - fuel_totaltime = fuel.time - fuel_time = 0 - end else - -- We don't need to get new fuel since there is no cookable item - fuel_totaltime = 0 + -- Furnace ran out of fuel + if cookable then + -- We need to get new fuel + local afterfuel + fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + + if fuel.time == 0 then + -- No valid fuel in fuel list + fuel_totaltime = 0 + src_time = 0 + else + -- Take fuel from fuel list + inv:set_stack("fuel", 1, afterfuel.items[1]) + update = true + fuel_totaltime = fuel.time + (fuel_time - fuel_totaltime) + src_time = src_time + elapsed + end + else + -- We don't need to get new fuel since there is no cookable item + fuel_totaltime = 0 + src_time = 0 + end fuel_time = 0 - src_time = 0 end + + elapsed = 0 + end + + if fuel and fuel_totaltime > fuel.time then + fuel_totaltime = fuel.time + end + if srclist[1]:is_empty() then + src_time = 0 end -- -- Update formspec, infotext and node -- local formspec = inactive_formspec - local item_state = "" + local item_state local item_percent = 0 if cookable then item_percent = math.floor(src_time / cooked.time * 100) - item_state = item_percent .. "%" + if item_percent > 100 then + item_state = "100% (output full)" + else + item_state = item_percent .. "%" + end else if srclist[1]:is_empty() then item_state = "Empty" @@ -189,7 +212,7 @@ local function furnace_node_timer(pos, elapsed) local active = "inactive " local result = false - if fuel_time <= fuel_totaltime and fuel_totaltime ~= 0 then + if fuel_totaltime ~= 0 then active = "active " local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100) fuel_state = fuel_percent .. "%" @@ -203,8 +226,7 @@ local function furnace_node_timer(pos, elapsed) end swap_node(pos, "default:furnace") -- stop timer on the inactive furnace - local timer = minetest.get_node_timer(pos) - timer:stop() + minetest.get_node_timer(pos):stop() end local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")" @@ -252,13 +274,11 @@ minetest.register_node("default:furnace", { end, on_metadata_inventory_move = function(pos) - local timer = minetest.get_node_timer(pos) - timer:start(1.0) + minetest.get_node_timer(pos):start(1.0) end, on_metadata_inventory_put = function(pos) -- start timer function, it will sort out whether furnace can burn or not. - local timer = minetest.get_node_timer(pos) - timer:start(1.0) + minetest.get_node_timer(pos):start(1.0) end, on_blast = function(pos) local drops = {} diff --git a/mods/default/init.lua b/mods/default/init.lua index 6f1b148b..7b5f62f3 100644 --- a/mods/default/init.lua +++ b/mods/default/init.lua @@ -35,14 +35,18 @@ default.gui_survival_form = "size[8,8.5]".. default.get_hotbar_bg(0,4.25) -- Load files -dofile(minetest.get_modpath("default").."/functions.lua") -dofile(minetest.get_modpath("default").."/nodes.lua") -dofile(minetest.get_modpath("default").."/furnace.lua") -dofile(minetest.get_modpath("default").."/tools.lua") -dofile(minetest.get_modpath("default").."/craftitems.lua") -dofile(minetest.get_modpath("default").."/crafting.lua") -dofile(minetest.get_modpath("default").."/mapgen.lua") -dofile(minetest.get_modpath("default").."/player.lua") -dofile(minetest.get_modpath("default").."/trees.lua") -dofile(minetest.get_modpath("default").."/aliases.lua") -dofile(minetest.get_modpath("default").."/legacy.lua") +local default_path = minetest.get_modpath("default") + +dofile(default_path.."/functions.lua") +dofile(default_path.."/trees.lua") +dofile(default_path.."/nodes.lua") +dofile(default_path.."/furnace.lua") +dofile(default_path.."/torch.lua") +dofile(default_path.."/tools.lua") +dofile(default_path.."/item_entity.lua") +dofile(default_path.."/craftitems.lua") +dofile(default_path.."/crafting.lua") +dofile(default_path.."/mapgen.lua") +dofile(default_path.."/player.lua") +dofile(default_path.."/aliases.lua") +dofile(default_path.."/legacy.lua") diff --git a/mods/default/item_entity.lua b/mods/default/item_entity.lua new file mode 100644 index 00000000..c34e60e9 --- /dev/null +++ b/mods/default/item_entity.lua @@ -0,0 +1,74 @@ +-- mods/default/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("default_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 = "default_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/default/legacy.lua b/mods/default/legacy.lua index 76fcc8ed..a8c8ad56 100644 --- a/mods/default/legacy.lua +++ b/mods/default/legacy.lua @@ -1,6 +1,6 @@ -- mods/default/legacy.lua --- Horrible crap to support old code registering falling nodes +-- 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 default.register_falling_node(nodename, texture) diff --git a/mods/default/license.txt b/mods/default/license.txt new file mode 100644 index 00000000..e9267366 --- /dev/null +++ b/mods/default/license.txt @@ -0,0 +1,174 @@ +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-2016: + celeron55, Perttu Ahola + Cisoun + G4JC + VanessaE + RealBadAngel + Calinou + MirceaKitsune + Jordach + PilzAdam + jojoa1997 + InfinityProject + Splizard + Zeg9 + paramat + BlockMen + sofar + Neuromancer + Gambit + asl97 + KevDoy + Mito551 + +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-ShareAlike 4.0 International (CC BY-SA 4.0) +Copyright (C) 2014-2016 brunob.santos + +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/4.0/ + +----------------------- + +Attribution-ShareAlike 2.0 Generic (CC BY-SA 2.0) +Copyright (C) 2014-2016 Neuromancer + + +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/2.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/ diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua index 016d58de..d786a841 100644 --- a/mods/default/mapgen.lua +++ b/mods/default/mapgen.lua @@ -42,14 +42,15 @@ minetest.register_alias("mapgen_stair_sandstonebrick", "stairs:stair_sandstonebr -- Register ores -- --- All mapgens except singlenode --- Blob ore first to avoid other ores inside blobs - function default.register_ores() + minetest.clear_registered_ores() + -- Blob ores + -- These first to avoid other ores in blobs -- Clay + -- This first to avoid clay in sand blobs - minetest.register_ore({ + minetest.register_ore({ ore_type = "blob", ore = "default:clay", wherein = {"default:sand"}, @@ -70,7 +71,7 @@ function default.register_ores() -- Sand - minetest.register_ore({ + minetest.register_ore({ ore_type = "blob", ore = "default:sand", wherein = {"default:stone", "default:sandstone", @@ -78,7 +79,7 @@ function default.register_ores() clust_scarcity = 16 * 16 * 16, clust_size = 5, y_min = -31, - y_max = 4, + y_max = 0, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -95,7 +96,7 @@ function default.register_ores() minetest.register_ore({ ore_type = "blob", ore = "default:dirt", - wherein = {"default:stone", "default:sandstone"}, + wherein = {"default:stone"}, clust_scarcity = 16 * 16 * 16, clust_size = 5, y_min = -31, @@ -109,6 +110,8 @@ function default.register_ores() octaves = 1, persist = 0.0 }, + biomes = {"taiga", "snowy_grassland", "grassland", "coniferous_forest", + "deciduous_forest", "savanna", "rainforest"} }) -- Gravel @@ -132,8 +135,21 @@ function default.register_ores() }, }) + -- Scatter ores + -- Coal + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_coal", + wherein = "default:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 9, + clust_size = 3, + y_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_coal", @@ -158,26 +174,15 @@ function default.register_ores() -- Iron - minetest.register_ore({ - ore_type = "scatter", - ore = "default:stone_with_iron", - wherein = "default:stone", - clust_scarcity = 12 * 12 * 12, - clust_num_ores = 3, - clust_size = 2, - y_min = -15, - y_max = 2, - }) - minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_iron", wherein = "default:stone", clust_scarcity = 9 * 9 * 9, - clust_num_ores = 5, + clust_num_ores = 12, clust_size = 3, - y_min = -63, - y_max = -16, + y_min = 1025, + y_max = 31000, }) minetest.register_ore({ @@ -188,7 +193,7 @@ function default.register_ores() clust_num_ores = 5, clust_size = 3, y_min = -31000, - y_max = -64, + y_max = 0, }) minetest.register_ore({ @@ -202,43 +207,54 @@ function default.register_ores() y_max = -64, }) - --Mese + -- Copper minetest.register_ore({ ore_type = "scatter", - ore = "default:stone_with_mese", + ore = "default:stone_with_copper", wherein = "default:stone", - clust_scarcity = 18 * 18 * 18, - clust_num_ores = 3, - clust_size = 2, - y_min = -255, - y_max = -64, + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_min = 1025, + y_max = 31000, }) minetest.register_ore({ ore_type = "scatter", - ore = "default:stone_with_mese", + ore = "default:stone_with_copper", wherein = "default:stone", - clust_scarcity = 14 * 14 * 14, + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 4, + clust_size = 3, + y_min = -63, + y_max = -16, + }) + + 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_min = -31000, - y_max = -256, - }) - - 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_min = -31000, - y_max = -1024, + y_max = -64, }) -- 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_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_gold", @@ -261,8 +277,54 @@ function default.register_ores() y_max = -256, }) + -- 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_min = 1025, + y_max = 31000, + }) + + 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_min = -255, + y_max = -64, + }) + + 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_min = -31000, + y_max = -256, + }) + -- 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_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_diamond", @@ -285,28 +347,28 @@ function default.register_ores() y_max = -256, }) - -- Copper + -- Mese block minetest.register_ore({ ore_type = "scatter", - ore = "default:stone_with_copper", + ore = "default:mese", wherein = "default:stone", - clust_scarcity = 12 * 12 * 12, - clust_num_ores = 4, - clust_size = 3, - y_min = -63, - y_max = -16, + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_min = 1025, + y_max = 31000, }) minetest.register_ore({ ore_type = "scatter", - ore = "default:stone_with_copper", + ore = "default:mese", wherein = "default:stone", - clust_scarcity = 9 * 9 * 9, - clust_num_ores = 5, - clust_size = 3, + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, y_min = -31000, - y_max = -64, + y_max = -1024, }) end @@ -320,10 +382,10 @@ end function default.register_biomes() minetest.clear_registered_biomes() - -- Permanent ice + -- Icesheet minetest.register_biome({ - name = "glacier", + name = "icesheet", node_dust = "default:snowblock", node_top = "default:snowblock", depth_top = 1, @@ -334,48 +396,52 @@ function default.register_biomes() depth_water_top = 10, --node_water = "", node_river_water = "default:ice", + node_riverbed = "default:gravel", + depth_riverbed = 2, y_min = -8, y_max = 31000, heat_point = 0, - humidity_point = 50, + humidity_point = 73, }) minetest.register_biome({ - name = "glacier_ocean", + name = "icesheet_ocean", node_dust = "default:snowblock", node_top = "default:sand", depth_top = 1, node_filler = "default:sand", depth_filler = 3, --node_stone = "", - --node_water_top = "", - --depth_water_top = , + node_water_top = "default:ice", + depth_water_top = 10, --node_water = "", --node_river_water = "", y_min = -112, y_max = -9, heat_point = 0, - humidity_point = 50, + humidity_point = 73, }) - -- Cold + -- Tundra minetest.register_biome({ name = "tundra", - --node_dust = "", - node_top = "default:dirt_with_snow", - depth_top = 1, - node_filler = "default:dirt", - depth_filler = 1, + node_dust = "default:snowblock", + --node_top = , + --depth_top = , + --node_filler = , + --depth_filler = , --node_stone = "", --node_water_top = "", --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:gravel", + depth_riverbed = 2, y_min = 2, y_max = 31000, - heat_point = 15, - humidity_point = 35, + heat_point = 0, + humidity_point = 40, }) minetest.register_biome({ @@ -390,10 +456,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:gravel", + depth_riverbed = 2, y_min = -3, y_max = 1, - heat_point = 15, - humidity_point = 35, + heat_point = 0, + humidity_point = 40, }) minetest.register_biome({ @@ -408,12 +476,15 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:gravel", + depth_riverbed = 2, y_min = -112, y_max = -4, - heat_point = 15, - humidity_point = 35, + heat_point = 0, + humidity_point = 40, }) + -- Taiga minetest.register_biome({ name = "taiga", @@ -427,10 +498,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 2, y_max = 31000, - heat_point = 15, - humidity_point = 65, + heat_point = 25, + humidity_point = 70, }) minetest.register_biome({ @@ -445,18 +518,20 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = 1, - heat_point = 15, - humidity_point = 65, + heat_point = 25, + humidity_point = 70, }) - -- Temperate + -- Snowy grassland minetest.register_biome({ - name = "stone_grassland", - --node_dust = "", - node_top = "default:dirt_with_grass", + name = "snowy_grassland", + node_dust = "default:snow", + node_top = "default:dirt_with_snow", depth_top = 1, node_filler = "default:dirt", depth_filler = 1, @@ -465,32 +540,16 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", - y_min = 6, - y_max = 31000, - heat_point = 40, - humidity_point = 35, - }) - - minetest.register_biome({ - name = "stone_grassland_dunes", - --node_dust = "", - node_top = "default:sand", - depth_top = 1, - node_filler = "default:sand", - depth_filler = 2, - --node_stone = "", - --node_water_top = "", - --depth_water_top = , - --node_water = "", - --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 5, - y_max = 5, - heat_point = 40, + y_max = 31000, + heat_point = 20, humidity_point = 35, }) minetest.register_biome({ - name = "stone_grassland_ocean", + name = "snowy_grassland_ocean", --node_dust = "", node_top = "default:sand", depth_top = 1, @@ -501,12 +560,77 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = 4, - heat_point = 40, + heat_point = 20, humidity_point = 35, }) + -- Grassland + + minetest.register_biome({ + name = "grassland", + --node_dust = "", + node_top = "default:dirt_with_grass", + depth_top = 1, + node_filler = "default:dirt", + depth_filler = 1, + --node_stone = "", + --node_water_top = "", + --depth_water_top = , + --node_water = "", + --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = 6, + y_max = 31000, + heat_point = 50, + humidity_point = 35, + }) + + minetest.register_biome({ + name = "grassland_dunes", + --node_dust = "", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 2, + --node_stone = "", + --node_water_top = "", + --depth_water_top = , + --node_water = "", + --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = 5, + y_max = 5, + heat_point = 50, + humidity_point = 35, + }) + + minetest.register_biome({ + name = "grassland_ocean", + --node_dust = "", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + --node_stone = "", + --node_water_top = "", + --depth_water_top = , + --node_water = "", + --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = -112, + y_max = 4, + heat_point = 50, + humidity_point = 35, + }) + + -- Coniferous forest minetest.register_biome({ name = "coniferous_forest", @@ -520,10 +644,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 6, y_max = 31000, - heat_point = 40, - humidity_point = 65, + heat_point = 45, + humidity_point = 70, }) minetest.register_biome({ @@ -538,10 +664,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 5, y_max = 5, - heat_point = 40, - humidity_point = 65, + heat_point = 45, + humidity_point = 70, }) minetest.register_biome({ @@ -556,67 +684,15 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = 4, - heat_point = 40, - humidity_point = 65, - }) - - - minetest.register_biome({ - name = "sandstone_grassland", - --node_dust = "", - node_top = "default:dirt_with_grass", - depth_top = 1, - node_filler = "default:dirt", - depth_filler = 1, - node_stone = "default:sandstone", - --node_water_top = "", - --depth_water_top = , - --node_water = "", - --node_river_water = "", - y_min = 6, - y_max = 31000, - heat_point = 60, - humidity_point = 35, - }) - - minetest.register_biome({ - name = "sandstone_grassland_dunes", - --node_dust = "", - node_top = "default:sand", - depth_top = 1, - node_filler = "default:sand", - depth_filler = 2, - node_stone = "default:sandstone", - --node_water_top = "", - --depth_water_top = , - --node_water = "", - --node_river_water = "", - y_min = 5, - y_max = 5, - heat_point = 60, - humidity_point = 35, - }) - - minetest.register_biome({ - name = "sandstone_grassland_ocean", - --node_dust = "", - node_top = "default:sand", - depth_top = 1, - node_filler = "default:sand", - depth_filler = 3, - node_stone = "default:sandstone", - --node_water_top = "", - --depth_water_top = , - --node_water = "", - --node_river_water = "", - y_min = -112, - y_max = 4, - heat_point = 60, - humidity_point = 35, + heat_point = 45, + humidity_point = 70, }) + -- Deciduous forest minetest.register_biome({ name = "deciduous_forest", @@ -630,14 +706,16 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 1, y_max = 31000, heat_point = 60, - humidity_point = 65, + humidity_point = 68, }) minetest.register_biome({ - name = "deciduous_forest_swamp", + name = "deciduous_forest_shore", --node_dust = "", node_top = "default:dirt", depth_top = 1, @@ -648,10 +726,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", - y_min = -3, + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = -1, y_max = 0, heat_point = 60, - humidity_point = 65, + humidity_point = 68, }) minetest.register_biome({ @@ -666,13 +746,15 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, - y_max = -4, + y_max = -2, heat_point = 60, - humidity_point = 65, + humidity_point = 68, }) - -- Hot + -- Desert minetest.register_biome({ name = "desert", @@ -686,10 +768,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 5, y_max = 31000, - heat_point = 85, - humidity_point = 20, + heat_point = 92, + humidity_point = 16, }) minetest.register_biome({ @@ -704,12 +788,99 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = 4, - heat_point = 85, - humidity_point = 20, + heat_point = 92, + humidity_point = 16, }) + -- Sandstone desert + + minetest.register_biome({ + name = "sandstone_desert", + --node_dust = "", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 0, + node_stone = "default:sandstone", + --node_water_top = "", + --depth_water_top = , + --node_water = "", + --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = 5, + y_max = 31000, + heat_point = 60, + humidity_point = 0, + }) + + minetest.register_biome({ + name = "sandstone_desert_ocean", + --node_dust = "", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_stone = "default:sandstone", + --node_water_top = "", + --depth_water_top = , + --node_water = "", + --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = -112, + y_max = 4, + heat_point = 60, + humidity_point = 0, + }) + + -- Cold desert + + minetest.register_biome({ + name = "cold_desert", + --node_dust = "", + node_top = "default:silver_sand", + depth_top = 1, + node_filler = "default:silver_sand", + depth_filler = 1, + --node_stone = "", + --node_water_top = "", + --depth_water_top = , + --node_water = "", + --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = 5, + y_max = 31000, + heat_point = 40, + humidity_point = 0, + }) + + minetest.register_biome({ + name = "cold_desert_ocean", + --node_dust = "", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + --node_stone = "", + --node_water_top = "", + --depth_water_top = , + --node_water = "", + --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = -112, + y_max = 4, + heat_point = 40, + humidity_point = 0, + }) + + -- Savanna minetest.register_biome({ name = "savanna", @@ -723,14 +894,16 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 1, y_max = 31000, - heat_point = 85, - humidity_point = 50, + heat_point = 89, + humidity_point = 42, }) minetest.register_biome({ - name = "savanna_swamp", + name = "savanna_shore", --node_dust = "", node_top = "default:dirt", depth_top = 1, @@ -741,10 +914,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", - y_min = -3, + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = -1, y_max = 0, - heat_point = 85, - humidity_point = 50, + heat_point = 89, + humidity_point = 42, }) minetest.register_biome({ @@ -759,12 +934,15 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, - y_max = -4, - heat_point = 85, - humidity_point = 50, + y_max = -2, + heat_point = 89, + humidity_point = 42, }) + -- Rainforest minetest.register_biome({ name = "rainforest", @@ -778,10 +956,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 1, y_max = 31000, - heat_point = 85, - humidity_point = 80, + heat_point = 86, + humidity_point = 65, }) minetest.register_biome({ @@ -796,10 +976,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", - y_min = -3, + node_riverbed = "default:sand", + depth_riverbed = 2, + y_min = -1, y_max = 0, - heat_point = 85, - humidity_point = 80, + heat_point = 86, + humidity_point = 65, }) minetest.register_biome({ @@ -814,10 +996,12 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, - y_max = -4, - heat_point = 85, - humidity_point = 80, + y_max = -2, + heat_point = 86, + humidity_point = 65, }) -- Underground @@ -936,7 +1120,8 @@ function default.register_mgv6_decorations() }) end --- All mapgens except mgv6 and singlenode + +-- All mapgens except mgv6 local function register_grass_decoration(offset, scale, length) minetest.register_decoration({ @@ -951,13 +1136,11 @@ local function register_grass_decoration(offset, scale, length) octaves = 3, persist = 0.6 }, - biomes = {"stone_grassland", "sandstone_grassland", - "deciduous_forest", "coniferous_forest", - "stone_grassland_dunes", "sandstone_grassland_dunes", - "coniferous_forest_dunes"}, + biomes = {"grassland", "grassland_dunes", "deciduous_forest", + "coniferous_forest", "coniferous_forest_dunes"}, y_min = 1, y_max = 31000, - decoration = "default:grass_"..length, + decoration = "default:grass_" .. length, }) end @@ -977,10 +1160,11 @@ local function register_dry_grass_decoration(offset, scale, length) biomes = {"savanna"}, y_min = 1, y_max = 31000, - decoration = "default:dry_grass_"..length, + decoration = "default:dry_grass_" .. length, }) end + function default.register_decorations() minetest.clear_registered_decorations() @@ -1001,7 +1185,7 @@ function default.register_decorations() biomes = {"deciduous_forest"}, y_min = 1, y_max = 31000, - schematic = minetest.get_modpath("default").."/schematics/apple_tree.mts", + schematic = minetest.get_modpath("default") .. "/schematics/apple_tree.mts", flags = "place_center_x, place_center_z", }) @@ -1046,9 +1230,9 @@ function default.register_decorations() sidelen = 80, fill_ratio = 0.1, biomes = {"rainforest", "rainforest_swamp"}, - y_min = 0, + y_min = -1, y_max = 31000, - schematic = minetest.get_modpath("default").."/schematics/jungle_tree.mts", + schematic = minetest.get_modpath("default") .. "/schematics/jungle_tree.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -1096,7 +1280,7 @@ function default.register_decorations() biomes = {"taiga", "coniferous_forest"}, y_min = 2, y_max = 31000, - schematic = minetest.get_modpath("default").."/schematics/pine_tree.mts", + schematic = minetest.get_modpath("default") .. "/schematics/pine_tree.mts", flags = "place_center_x, place_center_z", }) @@ -1150,7 +1334,7 @@ function default.register_decorations() biomes = {"savanna"}, y_min = 1, y_max = 31000, - schematic = minetest.get_modpath("default").."/schematics/acacia_tree.mts", + schematic = minetest.get_modpath("default") .. "/schematics/acacia_tree.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -1202,7 +1386,7 @@ function default.register_decorations() biomes = {"deciduous_forest"}, y_min = 1, y_max = 31000, - schematic = minetest.get_modpath("default").."/schematics/aspen_tree.mts", + schematic = minetest.get_modpath("default") .. "/schematics/aspen_tree.mts", flags = "place_center_x, place_center_z", }) @@ -1238,6 +1422,7 @@ function default.register_decorations() flags = "place_center_x", rotation = "random", }) + -- Large cactus minetest.register_decoration({ @@ -1255,7 +1440,7 @@ function default.register_decorations() biomes = {"desert"}, y_min = 5, y_max = 31000, - schematic = minetest.get_modpath("default").."/schematics/large_cactus.mts", + schematic = minetest.get_modpath("default") .. "/schematics/large_cactus.mts", flags = "place_center_x", rotation = "random", }) @@ -1296,10 +1481,52 @@ function default.register_decorations() octaves = 3, persist = 0.7 }, - biomes = {"savanna_swamp"}, + biomes = {"savanna_shore"}, y_min = 0, y_max = 0, - schematic = minetest.get_modpath("default").."/schematics/papyrus.mts", + schematic = minetest.get_modpath("default") .. "/schematics/papyrus.mts", + }) + + -- Bush + + minetest.register_decoration({ + 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"}, + y_min = 1, + y_max = 31000, + schematic = minetest.get_modpath("default") .. "/schematics/bush.mts", + flags = "place_center_x, place_center_z", + }) + + -- Acacia bush + + minetest.register_decoration({ + 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_min = 1, + y_max = 31000, + schematic = minetest.get_modpath("default") .. "/schematics/acacia_bush.mts", + flags = "place_center_x, place_center_z", }) -- Grasses @@ -1335,7 +1562,8 @@ function default.register_decorations() minetest.register_decoration({ deco_type = "simple", - place_on = {"default:desert_sand", "default:dirt_with_snow"}, + place_on = {"default:desert_sand", + "default:sand", "default:silver_sand"}, sidelen = 16, noise_params = { offset = 0, @@ -1345,63 +1573,36 @@ function default.register_decorations() octaves = 3, persist = 0.6 }, - biomes = {"desert", "tundra"}, + biomes = {"desert", "sandstone_desert", "cold_desert"}, y_min = 2, y_max = 31000, decoration = "default:dry_shrub", }) -end + -- Coral reef --- --- Generate nyan cats --- - --- All mapgens except singlenode - -function default.make_nyancat(pos, facedir, length) - local tailvec = {x = 0, y = 0, z = 0} - if facedir == 0 then - tailvec.z = 1 - elseif facedir == 1 then - tailvec.x = 1 - elseif facedir == 2 then - tailvec.z = -1 - elseif facedir == 3 then - tailvec.x = -1 - else - facedir = 0 - tailvec.z = 1 - end - local p = {x = pos.x, y = pos.y, z = pos.z} - minetest.set_node(p, {name = "default:nyancat", param2 = facedir}) - for i = 1, length do - p.x = p.x + tailvec.x - p.z = p.z + tailvec.z - minetest.set_node(p, {name = "default:nyancat_rainbow", param2 = facedir}) - end -end - -function default.generate_nyancats(minp, maxp, seed) - local height_min = -31000 - local height_max = -32 - if maxp.y < height_min or minp.y > height_max then - return - end - local y_min = math.max(minp.y, height_min) - local y_max = math.min(maxp.y, height_max) - local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1) - local pr = PseudoRandom(seed + 9324342) - local max_num_nyancats = math.floor(volume / (16 * 16 * 16)) - for i = 1, max_num_nyancats do - if pr:next(0, 1000) == 0 then - local x0 = pr:next(minp.x, maxp.x) - local y0 = pr:next(minp.y, maxp.y) - local z0 = pr:next(minp.z, maxp.z) - local p0 = {x = x0, y = y0, z = z0} - default.make_nyancat(p0, pr:next(0, 3), pr:next(3, 15)) - end - end + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"default:sand"}, + noise_params = { + offset = -0.1, + scale = 0.1, + spread = {x = 200, y = 200, z = 200}, + seed = 7013, + octaves = 3, + persist = 1, + }, + biomes = { + "desert_ocean", + "savanna_ocean", + "rainforest_ocean", + }, + y_min = -8, + y_max = -2, + schematic = minetest.get_modpath("default") .. "/schematics/corals.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) end @@ -1409,17 +1610,12 @@ end -- Detect mapgen to select functions -- --- Mods using singlenode mapgen can call these functions to enable --- the use of minetest.generate_ores or minetest.generate_decorations - -local mg_params = minetest.get_mapgen_params() -if mg_params.mgname == "v6" then +local mg_name = minetest.get_mapgen_setting("mg_name") +if mg_name == "v6" then default.register_ores() default.register_mgv6_decorations() - minetest.register_on_generated(default.generate_nyancats) -elseif mg_params.mgname ~= "singlenode" then +else default.register_biomes() default.register_ores() default.register_decorations() - minetest.register_on_generated(default.generate_nyancats) end diff --git a/mods/default/models/character.b3d b/mods/default/models/character.b3d index 2699d65b..9ab45436 100644 Binary files a/mods/default/models/character.b3d and b/mods/default/models/character.b3d differ diff --git a/mods/default/models/character.blend b/mods/default/models/character.blend index b5c7fc3a..fca9f659 100644 Binary files a/mods/default/models/character.blend and b/mods/default/models/character.blend differ diff --git a/mods/default/models/torch_ceiling.obj b/mods/default/models/torch_ceiling.obj new file mode 100644 index 00000000..ea51f3ce --- /dev/null +++ b/mods/default/models/torch_ceiling.obj @@ -0,0 +1,58 @@ +# Blender v2.77 (sub 0) OBJ File: 'torch_ceiling.blend' +# www.blender.org +mtllib torch_ceiling.mtl +o Cube_Cube.001 +v -0.062469 -0.047331 0.068152 +v -0.062469 -0.559515 -0.164388 +v -0.062469 0.004344 -0.045667 +v -0.062469 -0.507839 -0.278206 +v 0.062531 -0.047331 0.068152 +v 0.062531 -0.559515 -0.164388 +v 0.062531 0.004344 -0.045667 +v 0.062531 -0.507839 -0.278206 +v 0.353584 0.040000 0.363553 +v 0.353584 -0.397500 0.363553 +v -0.353522 0.040000 -0.343553 +v -0.353522 -0.397500 -0.343553 +v 0.353584 0.040000 -0.343553 +v -0.353522 0.040000 0.363553 +v 0.353584 -0.397500 -0.343553 +v -0.353522 -0.397500 0.363553 +vt 0.5625 0.5000 +vt 0.5625 0.6250 +vt 0.4375 0.6250 +vt 0.4375 0.5000 +vt 0.4375 0.0000 +vt 0.5625 0.0000 +vt 0.5625 0.1250 +vt 0.4375 0.1250 +vt 0.5625 0.6250 +vt 0.4375 0.6250 +vt 0.4375 0.6250 +vt 0.4375 0.0000 +vt 0.5625 0.6250 +vt 0.5625 0.0000 +vt 1.0000 0.5625 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.5625 +vt 0.0000 0.5625 +vt 1.0000 0.5625 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vn 0.0000 0.9105 0.4134 +vn -0.0000 -0.4134 0.9105 +vn -1.0000 0.0000 0.0000 +vn 0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 0.7071 +usemtl Material.001 +s off +f 3/1/1 1/2/1 5/3/1 7/4/1 +f 8/5/1 4/6/1 2/7/1 6/8/1 +f 3/9/2 4/6/2 8/5/2 7/10/2 +f 1/11/3 3/9/3 4/6/3 2/12/3 +f 5/13/2 1/11/2 2/12/2 6/14/2 +f 7/10/3 8/5/3 6/14/3 5/13/3 +usemtl Material.002 +f 9/15/4 10/16/4 12/17/4 11/18/4 +f 13/19/5 14/20/5 16/21/5 15/22/5 diff --git a/mods/default/models/torch_floor.obj b/mods/default/models/torch_floor.obj new file mode 100644 index 00000000..e2487efe --- /dev/null +++ b/mods/default/models/torch_floor.obj @@ -0,0 +1,50 @@ +# Blender v2.76 (sub 11) OBJ File: 'torch_floor.blend' +# www.blender.org +mtllib torch_floor.mtl +o Cube_Cube.001 +v 0.062500 0.062500 -0.062500 +v 0.062500 -0.500000 -0.062500 +v 0.062500 0.062500 0.062500 +v 0.062500 -0.500000 0.062500 +v -0.062500 0.062500 -0.062500 +v -0.062500 -0.500000 -0.062500 +v -0.062500 0.062500 0.062500 +v -0.062500 -0.500000 0.062500 +v -0.353553 -0.500000 0.353553 +v -0.353553 0.500000 0.353553 +v 0.353553 -0.500000 -0.353553 +v 0.353553 0.500000 -0.353553 +v -0.353553 -0.500000 -0.353553 +v 0.353553 -0.500000 0.353553 +v -0.353553 0.500000 -0.353553 +v 0.353553 0.500000 0.353553 +vt 0.562500 0.500000 +vt 0.562500 0.625000 +vt 0.437500 0.625000 +vt 0.437500 0.500000 +vt 0.437500 0.000000 +vt 0.562500 0.000000 +vt 0.562500 0.125000 +vt 0.437500 0.125000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 1.000000 0.000000 0.000000 +vn -0.707100 0.000000 -0.707100 +vn -0.707100 -0.000000 0.707100 +g Cube_Cube.001_Cube_Cube.001_Material.001 +usemtl Material.001 +s off +f 3/1/1 1/2/1 5/3/1 7/4/1 +f 8/5/1 4/6/1 2/7/1 6/8/1 +f 3/2/2 4/6/2 8/5/2 7/3/2 +f 1/3/3 3/2/3 4/6/3 2/5/3 +f 5/2/2 1/3/2 2/5/2 6/6/2 +f 7/3/3 8/5/3 6/6/3 5/2/3 +g Cube_Cube.001_Cube_Cube.001_Material.002 +usemtl Material.002 +f 9/9/4 10/10/4 12/11/4 11/12/4 +f 13/12/5 14/9/5 16/10/5 15/11/5 diff --git a/mods/default/models/torch_wall.obj b/mods/default/models/torch_wall.obj new file mode 100644 index 00000000..57baa9e6 --- /dev/null +++ b/mods/default/models/torch_wall.obj @@ -0,0 +1,64 @@ +# Blender v2.76 (sub 11) OBJ File: 'torch_wall.blend' +# www.blender.org +mtllib torch_wall.mtl +o Cube_Cube.001 +v 0.062469 -0.195248 0.023570 +v 0.062469 -0.476498 -0.463570 +v 0.062469 -0.303502 0.086070 +v 0.062469 -0.584752 -0.401070 +v -0.062531 -0.195248 0.023570 +v -0.062531 -0.476498 -0.463570 +v -0.062531 -0.303502 0.086070 +v -0.062531 -0.584752 -0.401070 +v -0.353584 -0.613553 0.022500 +v -0.353584 -0.613553 0.460000 +v 0.353522 0.093553 0.022500 +v 0.353522 0.093553 0.460000 +v -0.353584 0.093553 0.022500 +v 0.353522 -0.613553 0.022500 +v -0.353584 0.093553 0.460000 +v 0.353522 -0.613553 0.460000 +v 0.353553 0.056811 -0.121957 +v 0.353553 -0.224439 -0.609096 +v -0.353553 -0.555561 0.231596 +v -0.353553 -0.836811 -0.255543 +v -0.353553 0.056811 -0.121957 +v -0.353553 -0.224439 -0.609096 +v 0.353553 -0.555561 0.231596 +v 0.353553 -0.836811 -0.255543 +vt 0.562500 0.500000 +vt 0.562500 0.625000 +vt 0.437500 0.625000 +vt 0.437500 0.500000 +vt 0.437500 0.000000 +vt 0.562500 0.000000 +vt 0.562500 0.125000 +vt 0.437500 0.125000 +vt 0.000000 0.562500 +vt 0.000000 -0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.562500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn -0.000000 0.500000 0.866000 +vn -0.000000 0.866000 -0.500000 +vn 1.000000 0.000000 0.000000 +vn -0.707100 0.612400 -0.353600 +vn -0.707100 -0.612400 0.353600 +vn -0.707100 0.707100 -0.000000 +vn -0.707100 -0.707100 -0.000000 +g Cube_Cube.001_Cube_Cube.001_Material.001 +usemtl Material.001 +s off +f 3/1/1 1/2/1 5/3/1 7/4/1 +f 8/5/1 4/6/1 2/7/1 6/8/1 +f 3/2/2 4/6/2 8/5/2 7/3/2 +f 1/3/3 3/2/3 4/6/3 2/5/3 +f 5/2/2 1/3/2 2/5/2 6/6/2 +f 7/3/3 8/5/3 6/6/3 5/2/3 +f 17/9/4 18/10/4 20/11/4 19/12/4 +f 21/9/5 22/10/5 24/11/5 23/12/5 +g Cube_Cube.001_Cube_Cube.001_Material.002 +usemtl Material.002 +f 9/12/6 10/13/6 12/14/6 11/9/6 +f 13/9/7 14/12/7 16/13/7 15/14/7 diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index d494e1af..3e781091 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -19,17 +19,21 @@ Stone default:stone default:cobble default:stonebrick +default:stone_block default:mossycobble default:desert_stone default:desert_cobble default:desert_stonebrick +default:desert_stone_block default:sandstone default:sandstonebrick +default:sandstone_block default:obsidian default:obsidianbrick +default:obsidian_block Soft / Non-Stone ---------------- @@ -43,6 +47,7 @@ default:dirt_with_snow default:sand default:desert_sand +default:silver_sand default:gravel @@ -106,8 +111,8 @@ default:mese default:stone_with_diamond default:diamondblock -Plantlife (non-cubic) ---------------------- +Plantlife +--------- default:cactus default:papyrus @@ -126,6 +131,18 @@ default:dry_grass_3 default:dry_grass_4 default:dry_grass_5 +default:bush_stem +default:bush_leaves +default:acacia_bush_stem +default:acacia_bush_leaves + +Corals +------ + +default:coral_brown +default:coral_orange +default:coral_skeleton + Liquids ------- (1. Source 2. Flowing) @@ -142,8 +159,6 @@ default:lava_flowing Tools / "Advanced" crafting / Non-"natural" ------------------------------------------- -default:torch - default:chest default:chest_locked @@ -164,8 +179,6 @@ default:fence_aspen_wood default:glass default:obsidian_glass -default:rail - default:brick default:meselamp @@ -174,8 +187,6 @@ Misc ---- default:cloud -default:nyancat -default:nyancat_rainbow --]] @@ -202,12 +213,22 @@ minetest.register_node("default:cobble", { minetest.register_node("default:stonebrick", { description = "Stone Brick", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_stone_brick.png"}, is_ground_content = false, groups = {cracky = 2, stone = 1}, sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:stone_block", { + description = "Stone Block", + tiles = {"default_stone_block.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + minetest.register_node("default:mossycobble", { description = "Mossy Cobblestone", tiles = {"default_mossycobble.png"}, @@ -236,12 +257,22 @@ minetest.register_node("default:desert_cobble", { minetest.register_node("default:desert_stonebrick", { description = "Desert Stone Brick", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_desert_stone_brick.png"}, is_ground_content = false, groups = {cracky = 2, stone = 1}, sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:desert_stone_block", { + description = "Desert Stone Block", + tiles = {"default_desert_stone_block.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + minetest.register_node("default:sandstone", { description = "Sandstone", @@ -252,12 +283,22 @@ minetest.register_node("default:sandstone", { minetest.register_node("default:sandstonebrick", { description = "Sandstone Brick", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_sandstone_brick.png"}, is_ground_content = false, groups = {cracky = 2}, sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:sandstone_block", { + description = "Sandstone Block", + tiles = {"default_sandstone_block.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + minetest.register_node("default:obsidian", { description = "Obsidian", @@ -268,12 +309,22 @@ minetest.register_node("default:obsidian", { minetest.register_node("default:obsidianbrick", { description = "Obsidian Brick", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_obsidian_brick.png"}, is_ground_content = false, sounds = default.node_sound_stone_defaults(), groups = {cracky = 1, level = 2}, }) +minetest.register_node("default:obsidian_block", { + description = "Obsidian Block", + tiles = {"default_obsidian_block.png"}, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + groups = {cracky = 1, level = 2}, +}) + -- -- Soft / Non-Stone -- @@ -290,7 +341,7 @@ minetest.register_node("default:dirt_with_grass", { tiles = {"default_grass.png", "default_dirt.png", {name = "default_dirt.png^default_grass_side.png", tileable_vertical = false}}, - groups = {crumbly = 3, soil = 1}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, drop = 'default:dirt', sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_grass_footstep", gain = 0.25}, @@ -315,7 +366,7 @@ minetest.register_node("default:dirt_with_dry_grass", { "default_dirt.png", {name = "default_dirt.png^default_dry_grass_side.png", tileable_vertical = false}}, - groups = {crumbly = 3, soil = 1}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, drop = 'default:dirt', sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_grass_footstep", gain = 0.4}, @@ -327,7 +378,7 @@ minetest.register_node("default:dirt_with_snow", { tiles = {"default_snow.png", "default_dirt.png", {name = "default_dirt.png^default_snow_side.png", tileable_vertical = false}}, - groups = {crumbly = 3, soil = 1}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, drop = 'default:dirt', sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_snow_footstep", gain = 0.15}, @@ -348,6 +399,13 @@ minetest.register_node("default:desert_sand", { sounds = default.node_sound_sand_defaults(), }) +minetest.register_node("default:silver_sand", { + description = "Silver Sand", + tiles = {"default_silver_sand.png"}, + groups = {crumbly = 3, falling_node = 1, sand = 1}, + sounds = default.node_sound_sand_defaults(), +}) + minetest.register_node("default:gravel", { description = "Gravel", @@ -405,12 +463,19 @@ minetest.register_node("default:snow", { minetest.register_node("default:snowblock", { description = "Snow Block", tiles = {"default_snow.png"}, - groups = {crumbly = 3, puts_out_fire = 1}, + groups = {crumbly = 3, puts_out_fire = 1, cools_lava = 1}, sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_snow_footstep", gain = 0.15}, dug = {name = "default_snow_footstep", gain = 0.2}, dig = {name = "default_snow_footstep", gain = 0.2} }), + + on_construct = function(pos) + pos.y = pos.y - 1 + if minetest.get_node(pos).name == "default:dirt_with_grass" then + minetest.set_node(pos, {name = "default:dirt_with_snow"}) + end + end, }) minetest.register_node("default:ice", { @@ -418,7 +483,7 @@ minetest.register_node("default:ice", { tiles = {"default_ice.png"}, is_ground_content = false, paramtype = "light", - groups = {cracky = 3, puts_out_fire = 1}, + groups = {cracky = 3, puts_out_fire = 1, cools_lava = 1}, sounds = default.node_sound_glass_defaults(), }) @@ -439,9 +504,11 @@ minetest.register_node("default:tree", { minetest.register_node("default:wood", { description = "Wooden Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_wood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, sounds = default.node_sound_wood_defaults(), }) @@ -455,20 +522,37 @@ minetest.register_node("default:sapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, selection_box = { type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} }, groups = {snappy = 2, dig_immediate = 3, flammable = 2, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 6, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) minetest.register_node("default:leaves", { description = "Leaves", drawtype = "allfaces_optional", waving = 1, - visual_scale = 1.3, tiles = {"default_leaves.png"}, special_tiles = {"default_leaves_simple.png"}, paramtype = "light", @@ -506,7 +590,7 @@ minetest.register_node("default:apple", { is_ground_content = false, selection_box = { type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2} + fixed = {-3 / 16, -7 / 16, -3 / 16, 3 / 16, 4 / 16, 3 / 16} }, groups = {fleshy = 3, dig_immediate = 3, flammable = 2, leafdecay = 3, leafdecay_drop = 1}, @@ -535,9 +619,11 @@ minetest.register_node("default:jungletree", { minetest.register_node("default:junglewood", { description = "Junglewood Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_junglewood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, sounds = default.node_sound_wood_defaults(), }) @@ -545,7 +631,6 @@ minetest.register_node("default:jungleleaves", { description = "Jungle Leaves", drawtype = "allfaces_optional", waving = 1, - visual_scale = 1.3, tiles = {"default_jungleleaves.png"}, special_tiles = {"default_jungleleaves_simple.png"}, paramtype = "light", @@ -573,13 +658,31 @@ minetest.register_node("default:junglesapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, selection_box = { type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} }, groups = {snappy = 2, dig_immediate = 3, flammable = 2, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:junglesapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 15, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) @@ -589,7 +692,7 @@ minetest.register_node("default:pine_tree", { "default_pine_tree.png"}, paramtype2 = "facedir", is_ground_content = false, - groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + groups = {tree = 1, choppy = 3, oddly_breakable_by_hand = 1, flammable = 3}, sounds = default.node_sound_wood_defaults(), on_place = minetest.rotate_node @@ -597,16 +700,17 @@ minetest.register_node("default:pine_tree", { minetest.register_node("default:pine_wood", { description = "Pine Wood Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_pine_wood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, sounds = default.node_sound_wood_defaults(), }) minetest.register_node("default:pine_needles",{ description = "Pine Needles", drawtype = "allfaces_optional", - visual_scale = 1.3, tiles = {"default_pine_needles.png"}, waving = 1, paramtype = "light", @@ -634,13 +738,31 @@ minetest.register_node("default:pine_sapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, selection_box = { type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} }, - groups = {snappy = 2, dig_immediate = 3, flammable = 2, + groups = {snappy = 2, dig_immediate = 3, flammable = 3, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:pine_sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 12, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) @@ -658,17 +780,19 @@ minetest.register_node("default:acacia_tree", { minetest.register_node("default:acacia_wood", { description = "Acacia Wood Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_acacia_wood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, sounds = default.node_sound_wood_defaults(), }) minetest.register_node("default:acacia_leaves", { description = "Acacia Leaves", drawtype = "allfaces_optional", - visual_scale = 1.3, tiles = {"default_acacia_leaves.png"}, + special_tiles = {"default_acacia_leaves_simple.png"}, waving = 1, paramtype = "light", is_ground_content = false, @@ -695,13 +819,31 @@ minetest.register_node("default:acacia_sapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, selection_box = { type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} }, groups = {snappy = 2, dig_immediate = 3, flammable = 2, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:acacia_sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -4, y = 1, z = -4}, + {x = 4, y = 6, z = 4}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) minetest.register_node("default:aspen_tree", { @@ -710,7 +852,7 @@ minetest.register_node("default:aspen_tree", { "default_aspen_tree.png"}, paramtype2 = "facedir", is_ground_content = false, - groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + groups = {tree = 1, choppy = 3, oddly_breakable_by_hand = 1, flammable = 3}, sounds = default.node_sound_wood_defaults(), on_place = minetest.rotate_node @@ -718,16 +860,17 @@ minetest.register_node("default:aspen_tree", { minetest.register_node("default:aspen_wood", { description = "Aspen Wood Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_aspen_wood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, sounds = default.node_sound_wood_defaults(), }) minetest.register_node("default:aspen_leaves", { description = "Aspen Leaves", drawtype = "allfaces_optional", - visual_scale = 1.3, tiles = {"default_aspen_leaves.png"}, waving = 1, paramtype = "light", @@ -755,14 +898,33 @@ minetest.register_node("default:aspen_sapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, selection_box = { type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + fixed = {-3 / 16, -0.5, -3 / 16, 3 / 16, 0.5, 3 / 16} }, - groups = {snappy = 2, dig_immediate = 3, flammable = 2, + groups = {snappy = 2, dig_immediate = 3, flammable = 3, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:aspen_sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 12, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) + -- -- Ores -- @@ -797,7 +959,7 @@ minetest.register_node("default:steelblock", { tiles = {"default_steel_block.png"}, is_ground_content = false, groups = {cracky = 1, level = 2}, - sounds = default.node_sound_stone_defaults(), + sounds = default.node_sound_metal_defaults(), }) @@ -814,7 +976,7 @@ minetest.register_node("default:copperblock", { tiles = {"default_copper_block.png"}, is_ground_content = false, groups = {cracky = 1, level = 2}, - sounds = default.node_sound_stone_defaults(), + sounds = default.node_sound_metal_defaults(), }) minetest.register_node("default:bronzeblock", { @@ -822,7 +984,7 @@ minetest.register_node("default:bronzeblock", { tiles = {"default_bronze_block.png"}, is_ground_content = false, groups = {cracky = 1, level = 2}, - sounds = default.node_sound_stone_defaults(), + sounds = default.node_sound_metal_defaults(), }) @@ -857,7 +1019,7 @@ minetest.register_node("default:goldblock", { tiles = {"default_gold_block.png"}, is_ground_content = false, groups = {cracky = 1}, - sounds = default.node_sound_stone_defaults(), + sounds = default.node_sound_metal_defaults(), }) @@ -886,7 +1048,7 @@ minetest.register_node("default:cactus", { tiles = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"}, paramtype2 = "facedir", - groups = {snappy = 1, choppy = 3}, + groups = {choppy = 3}, sounds = default.node_sound_wood_defaults(), on_place = minetest.rotate_node, }) @@ -902,7 +1064,7 @@ minetest.register_node("default:papyrus", { walkable = false, selection_box = { type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.3} + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, 0.5, 6 / 16}, }, groups = {snappy = 3, flammable = 2}, sounds = default.node_sound_leaves_defaults(), @@ -928,7 +1090,7 @@ minetest.register_node("default:dry_shrub", { sounds = default.node_sound_leaves_defaults(), selection_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + fixed = {-5 / 16, -0.5, -5 / 16, 5 / 16, 4 / 16, 5 / 16}, }, }) @@ -944,11 +1106,11 @@ minetest.register_node("default:junglegrass", { sunlight_propagates = true, walkable = false, buildable_to = true, - groups = {snappy = 3, flora = 1, attached_node = 1, grass = 1}, + groups = {snappy = 3, flora = 1, attached_node = 1, grass = 1, flammable = 1}, sounds = default.node_sound_leaves_defaults(), selection_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + fixed = {-7 / 16, -0.5, -7 / 16, 7 / 16, 1.19, 7 / 16}, }, }) @@ -965,11 +1127,11 @@ minetest.register_node("default:grass_1", { sunlight_propagates = true, walkable = false, buildable_to = true, - groups = {snappy = 3, flora = 1, attached_node = 1, grass = 1}, + groups = {snappy = 3, flora = 1, attached_node = 1, grass = 1, flammable = 1}, sounds = default.node_sound_leaves_defaults(), selection_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -5 / 16, 6 / 16}, }, on_place = function(itemstack, placer, pointed_thing) @@ -995,11 +1157,11 @@ for i = 2, 5 do buildable_to = true, drop = "default:grass_1", groups = {snappy = 3, flora = 1, attached_node = 1, - not_in_creative_inventory = 1, grass = 1}, + not_in_creative_inventory = 1, grass = 1, flammable = 1}, sounds = default.node_sound_leaves_defaults(), selection_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -3 / 16, 6 / 16}, }, }) end @@ -1021,7 +1183,7 @@ minetest.register_node("default:dry_grass_1", { sounds = default.node_sound_leaves_defaults(), selection_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -3 / 16, 6 / 16}, }, on_place = function(itemstack, placer, pointed_thing) @@ -1051,11 +1213,95 @@ for i = 2, 5 do sounds = default.node_sound_leaves_defaults(), selection_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -1 / 16, 6 / 16}, }, }) end + +minetest.register_node("default:bush_stem", { + description = "Bush Stem", + drawtype = "plantlike", + visual_scale = 1.18, + tiles = {"default_bush_stem.png"}, + inventory_image = "default_bush_stem.png", + wield_image = "default_bush_stem.png", + paramtype = "light", + sunlight_propagates = true, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + selection_box = { + type = "fixed", + fixed = {-7 / 16, -0.5, -7 / 16, 7 / 16, 0.54, 7 / 16}, + }, +}) + +minetest.register_node("default:bush_leaves", { + description = "Bush Leaves", + drawtype = "allfaces_optional", + waving = 1, + tiles = {"default_leaves_simple.png"}, + paramtype = "light", + groups = {snappy = 3, flammable = 2, leaves = 1}, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("default:acacia_bush_stem", { + description = "Acacia Bush Stem", + drawtype = "plantlike", + visual_scale = 1.18, + tiles = {"default_acacia_bush_stem.png"}, + inventory_image = "default_acacia_bush_stem.png", + wield_image = "default_acacia_bush_stem.png", + paramtype = "light", + sunlight_propagates = true, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + selection_box = { + type = "fixed", + fixed = {-7 / 16, -0.5, -7 / 16, 7 / 16, 0.54, 7 / 16}, + }, +}) + +minetest.register_node("default:acacia_bush_leaves", { + description = "Acacia Bush Leaves", + drawtype = "allfaces_optional", + waving = 1, + tiles = {"default_acacia_leaves_simple.png"}, + paramtype = "light", + groups = {snappy = 3, flammable = 2, leaves = 1}, + sounds = default.node_sound_leaves_defaults(), +}) + + +-- +-- Corals +-- + +minetest.register_node("default:coral_brown", { + description = "Brown Coral", + tiles = {"default_coral_brown.png"}, + groups = {cracky = 3}, + drop = "default:coral_skeleton", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:coral_orange", { + description = "Orange Coral", + tiles = {"default_coral_orange.png"}, + groups = {cracky = 3}, + drop = "default:coral_skeleton", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:coral_skeleton", { + description = "Coral Skeleton", + tiles = {"default_coral_skeleton.png"}, + groups = {cracky = 3}, + sounds = default.node_sound_stone_defaults(), +}) + + -- -- Liquids -- @@ -1101,7 +1347,8 @@ minetest.register_node("default:water_source", { liquid_alternative_source = "default:water_source", liquid_viscosity = 1, post_effect_color = {a = 103, r = 30, g = 60, b = 90}, - groups = {water = 3, liquid = 3, puts_out_fire = 1}, + groups = {water = 3, liquid = 3, puts_out_fire = 1, cools_lava = 1}, + sounds = default.node_sound_water_defaults(), }) minetest.register_node("default:water_flowing", { @@ -1146,7 +1393,8 @@ minetest.register_node("default:water_flowing", { liquid_viscosity = 1, post_effect_color = {a = 103, r = 30, g = 60, b = 90}, groups = {water = 3, liquid = 3, puts_out_fire = 1, - not_in_creative_inventory = 1}, + not_in_creative_inventory = 1, cools_lava = 1}, + sounds = default.node_sound_water_defaults(), }) @@ -1192,7 +1440,8 @@ minetest.register_node("default:river_water_source", { liquid_renewable = false, liquid_range = 2, post_effect_color = {a = 103, r = 30, g = 76, b = 90}, - groups = {water = 3, liquid = 3, puts_out_fire = 1}, + groups = {water = 3, liquid = 3, puts_out_fire = 1, cools_lava = 1}, + sounds = default.node_sound_water_defaults(), }) minetest.register_node("default:river_water_flowing", { @@ -1239,7 +1488,8 @@ minetest.register_node("default:river_water_flowing", { liquid_range = 2, post_effect_color = {a = 103, r = 30, g = 76, b = 90}, groups = {water = 3, liquid = 3, puts_out_fire = 1, - not_in_creative_inventory = 1}, + not_in_creative_inventory = 1, cools_lava = 1}, + sounds = default.node_sound_water_defaults(), }) @@ -1286,7 +1536,7 @@ minetest.register_node("default:lava_source", { liquid_renewable = false, damage_per_second = 4 * 2, post_effect_color = {a = 191, r = 255, g = 64, b = 0}, - groups = {lava = 3, liquid = 2, hot = 3, igniter = 1}, + groups = {lava = 3, liquid = 2, igniter = 1}, }) minetest.register_node("default:lava_flowing", { @@ -1332,7 +1582,7 @@ minetest.register_node("default:lava_flowing", { liquid_renewable = false, damage_per_second = 4 * 2, post_effect_color = {a = 191, r = 255, g = 64, b = 0}, - groups = {lava = 3, liquid = 2, hot = 3, igniter = 1, + groups = {lava = 3, liquid = 2, igniter = 1, not_in_creative_inventory = 1}, }) @@ -1340,58 +1590,6 @@ minetest.register_node("default:lava_flowing", { -- Tools / "Advanced" crafting / Non-"natural" -- -minetest.register_node("default:torch", { - description = "Torch", - drawtype = "torchlike", - tiles = { - { - name = "default_torch_on_floor_animated.png", - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 3.0 - }, - }, - { - name="default_torch_on_ceiling_animated.png", - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 3.0 - }, - }, - { - name="default_torch_animated.png", - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 3.0 - }, - }, - }, - inventory_image = "default_torch_on_floor.png", - wield_image = "default_torch_on_floor.png", - paramtype = "light", - paramtype2 = "wallmounted", - sunlight_propagates = true, - is_ground_content = false, - walkable = false, - light_source = default.LIGHT_MAX - 1, - selection_box = { - type = "wallmounted", - wall_top = {-0.1, 0.5 - 0.6, -0.1, 0.1, 0.5, 0.1}, - wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5 + 0.6, 0.1}, - wall_side = {-0.5, -0.3, -0.1, -0.5 + 0.3, 0.3, 0.1}, - }, - groups = {choppy = 2, dig_immediate = 3, flammable = 1, attached_node = 1}, - legacy_wallmounted = true, - sounds = default.node_sound_defaults(), -}) - - local chest_formspec = "size[8,9]" .. default.gui_bg .. @@ -1421,16 +1619,30 @@ local function get_locked_chest_formspec(pos) end local function has_locked_chest_privilege(meta, player) - local name = "" if player then if minetest.check_player_privs(player, "protection_bypass") then return true end - name = player:get_player_name() - end - if name ~= meta:get_string("owner") then + else return false end + + -- is player wielding the right key? + local item = player:get_wielded_item() + if item:get_name() == "default:key" then + local key_meta = minetest.parse_json(item:get_metadata()) + local secret = meta:get_string("key_lock_secret") + if secret ~= key_meta.secret then + return false + end + + return true + end + + if player:get_player_name() ~= meta:get_string("owner") then + return false + end + return true end @@ -1447,7 +1659,6 @@ minetest.register_node("default:chest", { on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string("formspec", chest_formspec) - meta:set_string("infotext", "Chest") local inv = meta:get_inventory() inv:set_size("main", 8*4) end, @@ -1498,7 +1709,6 @@ minetest.register_node("default:chest_locked", { end, on_construct = function(pos) local meta = minetest.get_meta(pos) - meta:set_string("infotext", "Locked Chest") meta:set_string("owner", "") local inv = meta:get_inventory() inv:set_size("main", 8 * 4) @@ -1540,7 +1750,7 @@ minetest.register_node("default:chest_locked", { " takes " .. stack:get_name() .. " from locked chest at " .. minetest.pos_to_string(pos)) end, - on_rightclick = function(pos, node, clicker) + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) local meta = minetest.get_meta(pos) if has_locked_chest_privilege(meta, clicker) then minetest.show_formspec( @@ -1549,8 +1759,44 @@ minetest.register_node("default:chest_locked", { get_locked_chest_formspec(pos) ) end + return itemstack end, on_blast = function() end, + on_key_use = function(pos, player) + local secret = minetest.get_meta(pos):get_string("key_lock_secret") + local itemstack = player:get_wielded_item() + local key_meta = minetest.parse_json(itemstack:get_metadata()) + + if secret ~= key_meta.secret then + return + end + + minetest.show_formspec( + player:get_player_name(), + "default:chest_locked", + get_locked_chest_formspec(pos) + ) + end, + on_skeleton_key_use = function(pos, player, newsecret) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + local name = player:get_player_name() + + -- verify placer is owner of lockable chest + if owner ~= name then + minetest.record_protection_violation(pos, name) + minetest.chat_send_player(name, "You do not own this chest.") + return nil + end + + local secret = meta:get_string("key_lock_secret") + if secret == "" then + secret = newsecret + meta:set_string("key_lock_secret", secret) + end + + return secret, "a locked chest", owner + end, }) @@ -1566,16 +1812,37 @@ local bookshelf_formspec = "listring[current_player;main]" .. default.get_hotbar_bg(0,2.85) +local function get_bookshelf_formspec(inv) + local formspec = bookshelf_formspec + local invlist = inv and inv:get_list("books") + -- Inventory slots overlay + local bx, by = 0, 0.3 + for i = 1, 16 do + if i == 9 then + bx = 0 + by = by + 1 + end + if not invlist or invlist[i]:is_empty() then + formspec = formspec .. + "image[" .. bx .. "," .. by .. ";1,1;default_bookshelf_slot.png]" + end + bx = bx + 1 + end + return formspec +end + minetest.register_node("default:bookshelf", { description = "Bookshelf", - tiles = {"default_wood.png", "default_wood.png", "default_bookshelf.png"}, + tiles = {"default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "default_bookshelf.png", "default_bookshelf.png"}, + paramtype2 = "facedir", is_ground_content = false, groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, sounds = default.node_sound_wood_defaults(), on_construct = function(pos) local meta = minetest.get_meta(pos) - meta:set_string("formspec", bookshelf_formspec) + meta:set_string("formspec", get_bookshelf_formspec(nil)) local inv = meta:get_inventory() inv:set_size("books", 8 * 2) end, @@ -1592,14 +1859,20 @@ minetest.register_node("default:bookshelf", { on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) minetest.log("action", player:get_player_name() .. " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) minetest.log("action", player:get_player_name() .. " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) minetest.log("action", player:get_player_name() .. " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_bookshelf_formspec(meta:get_inventory())) end, on_blast = function(pos) local drops = {} @@ -1636,7 +1909,6 @@ local function register_sign(material, desc, def) --local n = minetest.get_node(pos) local meta = minetest.get_meta(pos) meta:set_string("formspec", "field[text;;${text}]") - meta:set_string("infotext", "\"\"") end, on_receive_fields = function(pos, formname, fields, sender) --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields)) @@ -1661,7 +1933,7 @@ register_sign("wood", "Wooden", { }) register_sign("steel", "Steel", { - sounds = default.node_sound_defaults(), + sounds = default.node_sound_metal_defaults(), groups = {cracky = 2, attached_node = 1} }) @@ -1707,12 +1979,14 @@ minetest.register_node("default:ladder_steel", { --wall_side = = }, groups = {cracky = 2}, - sounds = default.node_sound_stone_defaults(), + sounds = default.node_sound_metal_defaults(), }) default.register_fence("default:fence_wood", { description = "Wooden Fence", texture = "default_fence_wood.png", + inventory_image = "default_fence_overlay.png^default_wood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:wood", groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, sounds = default.node_sound_wood_defaults() @@ -1721,6 +1995,8 @@ default.register_fence("default:fence_wood", { default.register_fence("default:fence_acacia_wood", { description = "Acacia Fence", texture = "default_fence_acacia_wood.png", + inventory_image = "default_fence_overlay.png^default_acacia_wood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_acacia_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:acacia_wood", groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, sounds = default.node_sound_wood_defaults() @@ -1729,6 +2005,8 @@ default.register_fence("default:fence_acacia_wood", { default.register_fence("default:fence_junglewood", { description = "Junglewood Fence", texture = "default_fence_junglewood.png", + inventory_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:junglewood", groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, sounds = default.node_sound_wood_defaults() @@ -1737,16 +2015,20 @@ default.register_fence("default:fence_junglewood", { default.register_fence("default:fence_pine_wood", { description = "Pine Fence", texture = "default_fence_pine_wood.png", + inventory_image = "default_fence_overlay.png^default_pine_wood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_pine_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:pine_wood", - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, sounds = default.node_sound_wood_defaults() }) default.register_fence("default:fence_aspen_wood", { description = "Aspen Fence", texture = "default_fence_aspen_wood.png", + inventory_image = "default_fence_overlay.png^default_aspen_wood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_aspen_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:aspen_wood", - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, sounds = default.node_sound_wood_defaults() }) @@ -1773,29 +2055,10 @@ minetest.register_node("default:obsidian_glass", { }) -minetest.register_node("default:rail", { - description = "Rail", - drawtype = "raillike", - tiles = {"default_rail.png", "default_rail_curved.png", - "default_rail_t_junction.png", "default_rail_crossing.png"}, - inventory_image = "default_rail.png", - wield_image = "default_rail.png", - paramtype = "light", - sunlight_propagates = true, - walkable = false, - is_ground_content = false, - selection_box = { - type = "fixed", - -- but how to specify the dimensions for curved and sideways rails? - fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, - }, - groups = {bendy = 2, dig_immediate = 2, attached_node = 1, - connect_to_raillike = minetest.raillike_group("rail")}, -}) - - minetest.register_node("default:brick", { description = "Brick Block", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_brick.png"}, is_ground_content = false, groups = {cracky = 3}, @@ -1826,26 +2089,3 @@ minetest.register_node("default:cloud", { sounds = default.node_sound_defaults(), groups = {not_in_creative_inventory = 1}, }) - -minetest.register_node("default:nyancat", { - description = "Nyan Cat", - tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png", - "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"}, - paramtype2 = "facedir", - groups = {cracky = 2}, - is_ground_content = false, - legacy_facedir_simple = true, - sounds = default.node_sound_defaults(), -}) - -minetest.register_node("default:nyancat_rainbow", { - description = "Nyan Cat Rainbow", - tiles = { - "default_nc_rb.png^[transformR90", "default_nc_rb.png^[transformR90", - "default_nc_rb.png", "default_nc_rb.png" - }, - paramtype2 = "facedir", - groups = {cracky = 2}, - is_ground_content = false, - sounds = default.node_sound_defaults(), -}) diff --git a/mods/default/player.lua b/mods/default/player.lua index e4fb2adf..fd7341f4 100644 --- a/mods/default/player.lua +++ b/mods/default/player.lua @@ -25,7 +25,6 @@ default.player_register_model("character.b3d", { walk = { x=168, y=187, }, mine = { x=189, y=198, }, walk_mine = { x=200, y=219, }, - -- Extra animations (not currently used by the game). sit = { x= 81, y=160, }, }, }) @@ -95,7 +94,7 @@ minetest.register_on_joinplayer(function(player) default.player_attached[player:get_player_name()] = false default.player_set_model(player, "character.b3d") player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30) - + -- set GUI if not minetest.setting_getbool("creative_mode") then player:set_inventory_formspec(default.gui_survival_form) diff --git a/mods/default/schematics/acacia_bush.mts b/mods/default/schematics/acacia_bush.mts new file mode 100644 index 00000000..df955861 Binary files /dev/null and b/mods/default/schematics/acacia_bush.mts differ diff --git a/mods/default/schematics/aspen_tree.mts b/mods/default/schematics/aspen_tree.mts index 3bccd4b5..724aae08 100644 Binary files a/mods/default/schematics/aspen_tree.mts and b/mods/default/schematics/aspen_tree.mts differ diff --git a/mods/default/schematics/aspen_tree_from_sapling.mts b/mods/default/schematics/aspen_tree_from_sapling.mts index 6bf0f186..b7ca1619 100644 Binary files a/mods/default/schematics/aspen_tree_from_sapling.mts and b/mods/default/schematics/aspen_tree_from_sapling.mts differ diff --git a/mods/default/schematics/bush.mts b/mods/default/schematics/bush.mts new file mode 100644 index 00000000..d08cf5f5 Binary files /dev/null and b/mods/default/schematics/bush.mts differ diff --git a/mods/default/schematics/corals.mts b/mods/default/schematics/corals.mts new file mode 100644 index 00000000..e1bd7ded Binary files /dev/null and b/mods/default/schematics/corals.mts differ diff --git a/mods/default/schematics/papyrus.mts b/mods/default/schematics/papyrus.mts index a3b67776..1333a7c4 100644 Binary files a/mods/default/schematics/papyrus.mts and b/mods/default/schematics/papyrus.mts differ diff --git a/mods/default/sounds/default_dig_metal.ogg b/mods/default/sounds/default_dig_metal.ogg new file mode 100644 index 00000000..0b585097 Binary files /dev/null and b/mods/default/sounds/default_dig_metal.ogg differ diff --git a/mods/default/sounds/default_dig_snappy.ogg b/mods/default/sounds/default_dig_snappy.ogg new file mode 100644 index 00000000..3686fcdd Binary files /dev/null and b/mods/default/sounds/default_dig_snappy.ogg differ diff --git a/mods/default/sounds/default_dug_metal.1.ogg b/mods/default/sounds/default_dug_metal.1.ogg new file mode 100644 index 00000000..5d6cb5b1 Binary files /dev/null and b/mods/default/sounds/default_dug_metal.1.ogg differ diff --git a/mods/default/sounds/default_dug_metal.2.ogg b/mods/default/sounds/default_dug_metal.2.ogg new file mode 100644 index 00000000..63567fc0 Binary files /dev/null and b/mods/default/sounds/default_dug_metal.2.ogg differ diff --git a/mods/default/sounds/default_item_smoke.ogg b/mods/default/sounds/default_item_smoke.ogg new file mode 100644 index 00000000..038a46e4 Binary files /dev/null and b/mods/default/sounds/default_item_smoke.ogg differ diff --git a/mods/default/sounds/default_metal_footstep.1.ogg b/mods/default/sounds/default_metal_footstep.1.ogg new file mode 100644 index 00000000..841286bd Binary files /dev/null and b/mods/default/sounds/default_metal_footstep.1.ogg differ diff --git a/mods/default/sounds/default_metal_footstep.2.ogg b/mods/default/sounds/default_metal_footstep.2.ogg new file mode 100644 index 00000000..aa61ed33 Binary files /dev/null and b/mods/default/sounds/default_metal_footstep.2.ogg differ diff --git a/mods/default/sounds/default_metal_footstep.3.ogg b/mods/default/sounds/default_metal_footstep.3.ogg new file mode 100644 index 00000000..4cc1ca47 Binary files /dev/null and b/mods/default/sounds/default_metal_footstep.3.ogg differ diff --git a/mods/default/sounds/default_place_node_metal.1.ogg b/mods/default/sounds/default_place_node_metal.1.ogg new file mode 100644 index 00000000..5da085ea Binary files /dev/null and b/mods/default/sounds/default_place_node_metal.1.ogg differ diff --git a/mods/default/sounds/default_place_node_metal.2.ogg b/mods/default/sounds/default_place_node_metal.2.ogg new file mode 100644 index 00000000..5ee67fcf Binary files /dev/null and b/mods/default/sounds/default_place_node_metal.2.ogg differ diff --git a/mods/default/sounds/default_tool_breaks.1.ogg b/mods/default/sounds/default_tool_breaks.1.ogg new file mode 100644 index 00000000..2a571ae2 Binary files /dev/null and b/mods/default/sounds/default_tool_breaks.1.ogg differ diff --git a/mods/default/sounds/default_tool_breaks.2.ogg b/mods/default/sounds/default_tool_breaks.2.ogg new file mode 100644 index 00000000..17893520 Binary files /dev/null and b/mods/default/sounds/default_tool_breaks.2.ogg differ diff --git a/mods/default/sounds/default_tool_breaks.3.ogg b/mods/default/sounds/default_tool_breaks.3.ogg new file mode 100644 index 00000000..a99c4b7e Binary files /dev/null and b/mods/default/sounds/default_tool_breaks.3.ogg differ diff --git a/mods/default/sounds/default_water_footstep.1.ogg b/mods/default/sounds/default_water_footstep.1.ogg new file mode 100644 index 00000000..63b9744c Binary files /dev/null and b/mods/default/sounds/default_water_footstep.1.ogg differ diff --git a/mods/default/sounds/default_water_footstep.2.ogg b/mods/default/sounds/default_water_footstep.2.ogg new file mode 100644 index 00000000..8d79c1f4 Binary files /dev/null and b/mods/default/sounds/default_water_footstep.2.ogg differ diff --git a/mods/default/sounds/default_water_footstep.3.ogg b/mods/default/sounds/default_water_footstep.3.ogg new file mode 100644 index 00000000..f8891506 Binary files /dev/null and b/mods/default/sounds/default_water_footstep.3.ogg differ diff --git a/mods/default/sounds/default_water_footstep.4.ogg b/mods/default/sounds/default_water_footstep.4.ogg new file mode 100644 index 00000000..6f1eab82 Binary files /dev/null and b/mods/default/sounds/default_water_footstep.4.ogg differ diff --git a/mods/default/sounds/player_damage.ogg b/mods/default/sounds/player_damage.ogg new file mode 100644 index 00000000..78880871 Binary files /dev/null and b/mods/default/sounds/player_damage.ogg differ diff --git a/mods/default/textures/default_acacia_bush_stem.png b/mods/default/textures/default_acacia_bush_stem.png new file mode 100644 index 00000000..29039152 Binary files /dev/null and b/mods/default/textures/default_acacia_bush_stem.png differ diff --git a/mods/default/textures/default_acacia_leaves_simple.png b/mods/default/textures/default_acacia_leaves_simple.png new file mode 100644 index 00000000..3c7015bb Binary files /dev/null and b/mods/default/textures/default_acacia_leaves_simple.png differ diff --git a/mods/default/textures/default_acacia_tree.png b/mods/default/textures/default_acacia_tree.png index 169823d4..58bb3c40 100644 Binary files a/mods/default/textures/default_acacia_tree.png and b/mods/default/textures/default_acacia_tree.png differ diff --git a/mods/default/textures/default_acacia_tree_top.png b/mods/default/textures/default_acacia_tree_top.png index 2cf5ef0b..a8a0ce05 100644 Binary files a/mods/default/textures/default_acacia_tree_top.png and b/mods/default/textures/default_acacia_tree_top.png differ diff --git a/mods/default/textures/default_aspen_tree.png b/mods/default/textures/default_aspen_tree.png index 933b9cad..cfb05fca 100644 Binary files a/mods/default/textures/default_aspen_tree.png and b/mods/default/textures/default_aspen_tree.png differ diff --git a/mods/default/textures/default_aspen_wood.png b/mods/default/textures/default_aspen_wood.png index d16fdc97..2b584b31 100644 Binary files a/mods/default/textures/default_aspen_wood.png and b/mods/default/textures/default_aspen_wood.png differ diff --git a/mods/default/textures/default_bookshelf_slot.png b/mods/default/textures/default_bookshelf_slot.png new file mode 100644 index 00000000..31c4eb5e Binary files /dev/null and b/mods/default/textures/default_bookshelf_slot.png differ diff --git a/mods/default/textures/default_bush_stem.png b/mods/default/textures/default_bush_stem.png new file mode 100644 index 00000000..18b615f7 Binary files /dev/null and b/mods/default/textures/default_bush_stem.png differ diff --git a/mods/default/textures/default_coral_brown.png b/mods/default/textures/default_coral_brown.png new file mode 100644 index 00000000..8a775fe0 Binary files /dev/null and b/mods/default/textures/default_coral_brown.png differ diff --git a/mods/default/textures/default_coral_orange.png b/mods/default/textures/default_coral_orange.png new file mode 100644 index 00000000..cefac627 Binary files /dev/null and b/mods/default/textures/default_coral_orange.png differ diff --git a/mods/default/textures/default_coral_skeleton.png b/mods/default/textures/default_coral_skeleton.png new file mode 100644 index 00000000..fa48f151 Binary files /dev/null and b/mods/default/textures/default_coral_skeleton.png differ diff --git a/mods/default/textures/default_desert_stone_block.png b/mods/default/textures/default_desert_stone_block.png new file mode 100644 index 00000000..9eb8e924 Binary files /dev/null and b/mods/default/textures/default_desert_stone_block.png differ diff --git a/mods/default/textures/default_desert_stone_brick.png b/mods/default/textures/default_desert_stone_brick.png index 42d9f277..a603d18f 100644 Binary files a/mods/default/textures/default_desert_stone_brick.png and b/mods/default/textures/default_desert_stone_brick.png differ diff --git a/mods/default/textures/default_fence_aspen_wood.png b/mods/default/textures/default_fence_aspen_wood.png index 7fb624dc..0a6558e0 100644 Binary files a/mods/default/textures/default_fence_aspen_wood.png and b/mods/default/textures/default_fence_aspen_wood.png differ diff --git a/mods/default/textures/default_gravel.png b/mods/default/textures/default_gravel.png index 25a78b64..8852d384 100644 Binary files a/mods/default/textures/default_gravel.png and b/mods/default/textures/default_gravel.png differ diff --git a/mods/default/textures/default_ice.png b/mods/default/textures/default_ice.png index be8eadd9..2874e1e3 100644 Binary files a/mods/default/textures/default_ice.png and b/mods/default/textures/default_ice.png differ diff --git a/mods/default/textures/default_item_smoke.png b/mods/default/textures/default_item_smoke.png new file mode 100644 index 00000000..d62fb3b0 Binary files /dev/null and b/mods/default/textures/default_item_smoke.png differ diff --git a/mods/default/textures/default_jungleleaves.png b/mods/default/textures/default_jungleleaves.png index 870b4bb2..5afcc36d 100644 Binary files a/mods/default/textures/default_jungleleaves.png and b/mods/default/textures/default_jungleleaves.png differ diff --git a/mods/default/textures/default_jungleleaves_simple.png b/mods/default/textures/default_jungleleaves_simple.png index 689195f7..7165100c 100644 Binary files a/mods/default/textures/default_jungleleaves_simple.png and b/mods/default/textures/default_jungleleaves_simple.png differ diff --git a/mods/default/textures/default_jungletree.png b/mods/default/textures/default_jungletree.png index bf0403e9..2cf77a68 100644 Binary files a/mods/default/textures/default_jungletree.png and b/mods/default/textures/default_jungletree.png differ diff --git a/mods/default/textures/default_jungletree_top.png b/mods/default/textures/default_jungletree_top.png index 4844682b..439f0786 100644 Binary files a/mods/default/textures/default_jungletree_top.png and b/mods/default/textures/default_jungletree_top.png differ diff --git a/mods/default/textures/default_key.png b/mods/default/textures/default_key.png new file mode 100644 index 00000000..d59bfb6b Binary files /dev/null and b/mods/default/textures/default_key.png differ diff --git a/mods/default/textures/default_key_skeleton.png b/mods/default/textures/default_key_skeleton.png new file mode 100644 index 00000000..eafcc195 Binary files /dev/null and b/mods/default/textures/default_key_skeleton.png differ diff --git a/mods/default/textures/default_lava.png b/mods/default/textures/default_lava.png index b0d429eb..e8958de5 100644 Binary files a/mods/default/textures/default_lava.png and b/mods/default/textures/default_lava.png differ diff --git a/mods/default/textures/default_leaves.png b/mods/default/textures/default_leaves.png index e39535c6..ba09fe1d 100644 Binary files a/mods/default/textures/default_leaves.png and b/mods/default/textures/default_leaves.png differ diff --git a/mods/default/textures/default_leaves_simple.png b/mods/default/textures/default_leaves_simple.png index e492a32e..eb60f9f5 100644 Binary files a/mods/default/textures/default_leaves_simple.png and b/mods/default/textures/default_leaves_simple.png differ diff --git a/mods/default/textures/default_mese_block.png b/mods/default/textures/default_mese_block.png index 2e6895d3..e30994e2 100644 Binary files a/mods/default/textures/default_mese_block.png and b/mods/default/textures/default_mese_block.png differ diff --git a/mods/default/textures/default_meselamp.png b/mods/default/textures/default_meselamp.png index b227a254..0c3a1a12 100644 Binary files a/mods/default/textures/default_meselamp.png and b/mods/default/textures/default_meselamp.png differ diff --git a/mods/default/textures/default_obsidian_block.png b/mods/default/textures/default_obsidian_block.png new file mode 100644 index 00000000..7e1d4d3f Binary files /dev/null and b/mods/default/textures/default_obsidian_block.png differ diff --git a/mods/default/textures/default_pine_needles.png b/mods/default/textures/default_pine_needles.png index 1a32f632..ad7373b0 100644 Binary files a/mods/default/textures/default_pine_needles.png and b/mods/default/textures/default_pine_needles.png differ diff --git a/mods/default/textures/default_rail.png b/mods/default/textures/default_rail.png deleted file mode 100644 index 26fed02e..00000000 Binary files a/mods/default/textures/default_rail.png and /dev/null differ diff --git a/mods/default/textures/default_rail_crossing.png b/mods/default/textures/default_rail_crossing.png deleted file mode 100644 index ba66e015..00000000 Binary files a/mods/default/textures/default_rail_crossing.png and /dev/null differ diff --git a/mods/default/textures/default_rail_curved.png b/mods/default/textures/default_rail_curved.png deleted file mode 100644 index 9084ac24..00000000 Binary files a/mods/default/textures/default_rail_curved.png and /dev/null differ diff --git a/mods/default/textures/default_rail_t_junction.png b/mods/default/textures/default_rail_t_junction.png deleted file mode 100644 index 486c416a..00000000 Binary files a/mods/default/textures/default_rail_t_junction.png and /dev/null differ diff --git a/mods/default/textures/default_sandstone_block.png b/mods/default/textures/default_sandstone_block.png new file mode 100644 index 00000000..2e06491e Binary files /dev/null and b/mods/default/textures/default_sandstone_block.png differ diff --git a/mods/default/textures/default_silver_sand.png b/mods/default/textures/default_silver_sand.png new file mode 100644 index 00000000..c4a8f730 Binary files /dev/null and b/mods/default/textures/default_silver_sand.png differ diff --git a/mods/default/textures/default_snow.png b/mods/default/textures/default_snow.png index 2a2439fb..4ac35938 100644 Binary files a/mods/default/textures/default_snow.png and b/mods/default/textures/default_snow.png differ diff --git a/mods/default/textures/default_snow_side.png b/mods/default/textures/default_snow_side.png index f13ec940..f95b3af8 100644 Binary files a/mods/default/textures/default_snow_side.png and b/mods/default/textures/default_snow_side.png differ diff --git a/mods/default/textures/default_snowball.png b/mods/default/textures/default_snowball.png index ecdba9a3..e952b79c 100644 Binary files a/mods/default/textures/default_snowball.png and b/mods/default/textures/default_snowball.png differ diff --git a/mods/default/textures/default_stone_block.png b/mods/default/textures/default_stone_block.png new file mode 100644 index 00000000..3b771e72 Binary files /dev/null and b/mods/default/textures/default_stone_block.png differ diff --git a/mods/default/textures/default_stone_brick.png b/mods/default/textures/default_stone_brick.png index be949ab6..4dbb49db 100644 Binary files a/mods/default/textures/default_stone_brick.png and b/mods/default/textures/default_stone_brick.png differ diff --git a/mods/default/tools.lua b/mods/default/tools.lua index a948886a..9147f9b3 100644 --- a/mods/default/tools.lua +++ b/mods/default/tools.lua @@ -32,7 +32,10 @@ minetest.register_tool("default:pick_wood", { }, damage_groups = {fleshy=2}, }, + groups = {flammable = 2}, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:pick_stone", { description = "Stone Pickaxe", inventory_image = "default_tool_stonepick.png", @@ -44,7 +47,9 @@ minetest.register_tool("default:pick_stone", { }, damage_groups = {fleshy=3}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:pick_steel", { description = "Steel Pickaxe", inventory_image = "default_tool_steelpick.png", @@ -56,7 +61,9 @@ minetest.register_tool("default:pick_steel", { }, damage_groups = {fleshy=4}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:pick_bronze", { description = "Bronze Pickaxe", inventory_image = "default_tool_bronzepick.png", @@ -68,7 +75,9 @@ minetest.register_tool("default:pick_bronze", { }, damage_groups = {fleshy=4}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:pick_mese", { description = "Mese Pickaxe", inventory_image = "default_tool_mesepick.png", @@ -80,7 +89,9 @@ minetest.register_tool("default:pick_mese", { }, damage_groups = {fleshy=5}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:pick_diamond", { description = "Diamond Pickaxe", inventory_image = "default_tool_diamondpick.png", @@ -92,6 +103,7 @@ minetest.register_tool("default:pick_diamond", { }, damage_groups = {fleshy=5}, }, + sound = {breaks = "default_tool_breaks"}, }) -- @@ -110,7 +122,10 @@ minetest.register_tool("default:shovel_wood", { }, damage_groups = {fleshy=2}, }, + groups = {flammable = 2}, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:shovel_stone", { description = "Stone Shovel", inventory_image = "default_tool_stoneshovel.png", @@ -123,7 +138,9 @@ minetest.register_tool("default:shovel_stone", { }, damage_groups = {fleshy=2}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:shovel_steel", { description = "Steel Shovel", inventory_image = "default_tool_steelshovel.png", @@ -136,7 +153,9 @@ minetest.register_tool("default:shovel_steel", { }, damage_groups = {fleshy=3}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:shovel_bronze", { description = "Bronze Shovel", inventory_image = "default_tool_bronzeshovel.png", @@ -149,7 +168,9 @@ minetest.register_tool("default:shovel_bronze", { }, damage_groups = {fleshy=3}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:shovel_mese", { description = "Mese Shovel", inventory_image = "default_tool_meseshovel.png", @@ -162,7 +183,9 @@ minetest.register_tool("default:shovel_mese", { }, damage_groups = {fleshy=4}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:shovel_diamond", { description = "Diamond Shovel", inventory_image = "default_tool_diamondshovel.png", @@ -175,6 +198,7 @@ minetest.register_tool("default:shovel_diamond", { }, damage_groups = {fleshy=4}, }, + sound = {breaks = "default_tool_breaks"}, }) -- @@ -192,7 +216,10 @@ minetest.register_tool("default:axe_wood", { }, damage_groups = {fleshy=2}, }, + groups = {flammable = 2}, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:axe_stone", { description = "Stone Axe", inventory_image = "default_tool_stoneaxe.png", @@ -204,7 +231,9 @@ minetest.register_tool("default:axe_stone", { }, damage_groups = {fleshy=3}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:axe_steel", { description = "Steel Axe", inventory_image = "default_tool_steelaxe.png", @@ -216,7 +245,9 @@ minetest.register_tool("default:axe_steel", { }, damage_groups = {fleshy=4}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:axe_bronze", { description = "Bronze Axe", inventory_image = "default_tool_bronzeaxe.png", @@ -228,7 +259,9 @@ minetest.register_tool("default:axe_bronze", { }, damage_groups = {fleshy=4}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:axe_mese", { description = "Mese Axe", inventory_image = "default_tool_meseaxe.png", @@ -240,7 +273,9 @@ minetest.register_tool("default:axe_mese", { }, damage_groups = {fleshy=6}, }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:axe_diamond", { description = "Diamond Axe", inventory_image = "default_tool_diamondaxe.png", @@ -252,6 +287,7 @@ minetest.register_tool("default:axe_diamond", { }, damage_groups = {fleshy=7}, }, + sound = {breaks = "default_tool_breaks"}, }) -- @@ -268,8 +304,11 @@ minetest.register_tool("default:sword_wood", { snappy={times={[2]=1.6, [3]=0.40}, uses=10, maxlevel=1}, }, damage_groups = {fleshy=2}, - } + }, + groups = {flammable = 2}, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:sword_stone", { description = "Stone Sword", inventory_image = "default_tool_stonesword.png", @@ -280,8 +319,10 @@ minetest.register_tool("default:sword_stone", { snappy={times={[2]=1.4, [3]=0.40}, uses=20, maxlevel=1}, }, damage_groups = {fleshy=4}, - } + }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:sword_steel", { description = "Steel Sword", inventory_image = "default_tool_steelsword.png", @@ -292,8 +333,10 @@ minetest.register_tool("default:sword_steel", { snappy={times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=30, maxlevel=2}, }, damage_groups = {fleshy=6}, - } + }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:sword_bronze", { description = "Bronze Sword", inventory_image = "default_tool_bronzesword.png", @@ -304,8 +347,10 @@ minetest.register_tool("default:sword_bronze", { snappy={times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=40, maxlevel=2}, }, damage_groups = {fleshy=6}, - } + }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:sword_mese", { description = "Mese Sword", inventory_image = "default_tool_mesesword.png", @@ -316,8 +361,10 @@ minetest.register_tool("default:sword_mese", { snappy={times={[1]=2.0, [2]=1.00, [3]=0.35}, uses=30, maxlevel=3}, }, damage_groups = {fleshy=7}, - } + }, + sound = {breaks = "default_tool_breaks"}, }) + minetest.register_tool("default:sword_diamond", { description = "Diamond Sword", inventory_image = "default_tool_diamondsword.png", @@ -328,5 +375,78 @@ minetest.register_tool("default:sword_diamond", { snappy={times={[1]=1.90, [2]=0.90, [3]=0.30}, uses=40, maxlevel=3}, }, damage_groups = {fleshy=8}, - } + }, + sound = {breaks = "default_tool_breaks"}, +}) + +minetest.register_tool("default:skeleton_key", { + description = "Skeleton Key", + inventory_image = "default_key_skeleton.png", + groups = {key = 1}, + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local pos = pointed_thing.under + local node = minetest.get_node(pos) + + if not node then + return itemstack + end + + local on_skeleton_key_use = minetest.registered_nodes[node.name].on_skeleton_key_use + if on_skeleton_key_use then + -- make a new key secret in case the node callback needs it + local random = math.random + local newsecret = string.format( + "%04x%04x%04x%04x", + random(2^16) - 1, random(2^16) - 1, + random(2^16) - 1, random(2^16) - 1) + + local secret, _, _ = on_skeleton_key_use(pos, placer, newsecret) + + if secret then + -- finish and return the new key + itemstack:take_item() + itemstack:add_item("default:key") + itemstack:set_metadata(minetest.write_json({ + secret = secret + })) + return itemstack + end + end + return nil + end +}) + +minetest.register_tool("default:key", { + description = "Key", + inventory_image = "default_key.png", + groups = {key = 1, not_in_creative_inventory = 1}, + stack_max = 1, + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local pos = pointed_thing.under + local node = minetest.get_node(pos) + + if not node or node.name == "ignore" then + return itemstack + end + + local ndef = minetest.registered_nodes[node.name] + if not ndef then + return itemstack + end + + local on_key_use = ndef.on_key_use + if on_key_use then + on_key_use(pos, placer) + end + + return nil + end }) diff --git a/mods/default/torch.lua b/mods/default/torch.lua new file mode 100644 index 00000000..e94c5bd6 --- /dev/null +++ b/mods/default/torch.lua @@ -0,0 +1,147 @@ + +--[[ + +Torch mod - formerly mod "Torches" +====================== + +(c) Copyright BlockMen (2013-2015) +(C) Copyright sofar (2016) + +This mod changes the default torch drawtype from "torchlike" to "mesh", +giving the torch a three dimensional appearance. The mesh contains the +proper pixel mapping to make the animation appear as a particle above +the torch, while in fact the animation is just the texture of the mesh. + + +License: +~~~~~~~~ +(c) Copyright BlockMen (2013-2015) + +Textures and Meshes/Models: +CC-BY 3.0 BlockMen +Note that the models were entirely done from scratch by sofar. + +Code: +Licensed under the GNU LGPL version 2.1 or higher. +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; + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt + +--]] + +minetest.register_node("default:torch", { + description = "Torch", + drawtype = "mesh", + mesh = "torch_floor.obj", + inventory_image = "default_torch_on_floor.png", + wield_image = "default_torch_on_floor.png", + tiles = {{ + name = "default_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + liquids_pointable = false, + light_source = 13, + groups = {choppy=2, dig_immediate=3, flammable=1, attached_node=1, torch=1}, + drop = "default:torch", + selection_box = { + type = "wallmounted", + wall_bottom = {-1/8, -1/2, -1/8, 1/8, 2/16, 1/8}, + }, + sounds = default.node_sound_wood_defaults(), + on_place = function(itemstack, placer, pointed_thing) + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if def and def.on_rightclick and + ((not placer) or (placer and not placer:get_player_control().sneak)) then + return def.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + + local above = pointed_thing.above + local wdir = minetest.dir_to_wallmounted(vector.subtract(under, above)) + local fakestack = itemstack + if wdir == 0 then + fakestack:set_name("default:torch_ceiling") + elseif wdir == 1 then + fakestack:set_name("default:torch") + else + fakestack:set_name("default:torch_wall") + end + + itemstack = minetest.item_place(fakestack, placer, pointed_thing, wdir) + itemstack:set_name("default:torch") + + return itemstack + end +}) + +minetest.register_node("default:torch_wall", { + drawtype = "mesh", + mesh = "torch_wall.obj", + tiles = {{ + name = "default_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + light_source = 13, + groups = {choppy=2, dig_immediate=3, flammable=1, not_in_creative_inventory=1, attached_node=1, torch=1}, + drop = "default:torch", + selection_box = { + type = "wallmounted", + wall_side = {-1/2, -1/2, -1/8, -1/8, 1/8, 1/8}, + }, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("default:torch_ceiling", { + drawtype = "mesh", + mesh = "torch_ceiling.obj", + tiles = {{ + name = "default_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + light_source = 13, + groups = {choppy=2, dig_immediate=3, flammable=1, not_in_creative_inventory=1, attached_node=1, torch=1}, + drop = "default:torch", + selection_box = { + type = "wallmounted", + wall_top = {-1/8, -1/16, -5/16, 1/8, 1/2, 1/8}, + }, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_lbm({ + name = "default:3dtorch", + nodenames = {"default:torch", "torches:floor", "torches:wall"}, + action = function(pos, node) + if node.param2 == 0 then + minetest.set_node(pos, {name = "default:torch_ceiling", + param2 = node.param2}) + elseif node.param2 == 1 then + minetest.set_node(pos, {name = "default:torch", + param2 = node.param2}) + else + minetest.set_node(pos, {name = "default:torch_wall", + param2 = node.param2}) + end + end +}) + diff --git a/mods/default/trees.lua b/mods/default/trees.lua index de2452e4..0b95742c 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -27,90 +27,70 @@ end -- 'is snow nearby' function local function is_snow_nearby(pos) - local x, y, z = pos.x, pos.y, pos.z - local c_snow = minetest.get_content_id("default:snow") - local c_snowblock = minetest.get_content_id("default:snowblock") - local c_dirtsnow = minetest.get_content_id("default:dirt_with_snow") - - local vm = minetest.get_voxel_manip() - local minp, maxp = vm:read_from_map( - {x = x - 1, y = y - 1, z = z - 1}, - {x = x + 1, y = y + 1, z = z + 1} - ) - local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) - local data = vm:get_data() - - for yy = y - 1, y + 1 do - for zz = z - 1, z + 1 do - local vi = a:index(x - 1, yy, zz) - for xx = x - 1, x + 1 do - local nodid = data[vi] - if nodid == c_snow or nodid == c_snowblock or nodid == c_dirtsnow then - return true - end - vi = vi + 1 - end - end - end - - return false + return minetest.find_node_near(pos, 1, + {"default:snow", "default:snowblock", "default:dirt_with_snow"}) end -- Sapling ABM -minetest.register_abm({ - nodenames = {"default:sapling", "default:junglesapling", - "default:pine_sapling", "default:acacia_sapling", - "default:aspen_sapling"}, - interval = 10, - chance = 50, - action = function(pos, node) - if not default.can_grow(pos) then - return - end +function default.grow_sapling(pos) + if not default.can_grow(pos) then + -- try a bit later again + minetest.get_node_timer(pos):start(math.random(240, 600)) + return + end - local mapgen = minetest.get_mapgen_params().mgname - if node.name == "default:sapling" then - minetest.log("action", "A sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - if mapgen == "v6" then - default.grow_tree(pos, random(1, 4) == 1) - else - default.grow_new_apple_tree(pos) - end - elseif node.name == "default:junglesapling" then - minetest.log("action", "A jungle sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - if mapgen == "v6" then - default.grow_jungle_tree(pos) - else - default.grow_new_jungle_tree(pos) - end - elseif node.name == "default:pine_sapling" then - minetest.log("action", "A pine sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - local snow = is_snow_nearby(pos) - if mapgen == "v6" then - default.grow_pine_tree(pos, snow) - elseif snow then - default.grow_new_snowy_pine_tree(pos) - else - default.grow_new_pine_tree(pos) - end - elseif node.name == "default:acacia_sapling" then - minetest.log("action", "An acacia sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - default.grow_new_acacia_tree(pos) - elseif node.name == "default:aspen_sapling" then - minetest.log("action", "An aspen sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - default.grow_new_aspen_tree(pos) + local mg_name = minetest.get_mapgen_setting("mg_name") + local node = minetest.get_node(pos) + if node.name == "default:sapling" then + minetest.log("action", "A sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + if mg_name == "v6" then + default.grow_tree(pos, random(1, 4) == 1) + else + default.grow_new_apple_tree(pos) end + elseif node.name == "default:junglesapling" then + minetest.log("action", "A jungle sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + if mg_name == "v6" then + default.grow_jungle_tree(pos) + else + default.grow_new_jungle_tree(pos) + end + elseif node.name == "default:pine_sapling" then + minetest.log("action", "A pine sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + local snow = is_snow_nearby(pos) + if mg_name == "v6" then + default.grow_pine_tree(pos, snow) + elseif snow then + default.grow_new_snowy_pine_tree(pos) + else + default.grow_new_pine_tree(pos) + end + elseif node.name == "default:acacia_sapling" then + minetest.log("action", "An acacia sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + default.grow_new_acacia_tree(pos) + elseif node.name == "default:aspen_sapling" then + minetest.log("action", "An aspen sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + default.grow_new_aspen_tree(pos) + end +end + +minetest.register_lbm({ + name = "default:convert_saplings_to_node_timer", + nodenames = {"default:sapling", "default:junglesapling", + "default:pine_sapling", "default:acacia_sapling", + "default:aspen_sapling"}, + action = function(pos) + minetest.get_node_timer(pos):start(math.random(1200, 2400)) end }) - -- -- Tree generation -- @@ -194,8 +174,8 @@ function default.grow_tree(pos, is_apple_tree, bad) local vm = minetest.get_voxel_manip() local minp, maxp = vm:read_from_map( - {x = pos.x - 2, y = pos.y, z = pos.z - 2}, - {x = pos.x + 2, y = pos.y + height + 1, z = pos.z + 2} + {x = x - 2, y = y, z = z - 2}, + {x = x + 2, y = y + height + 1, z = z + 2} ) local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) local data = vm:get_data() @@ -229,8 +209,8 @@ function default.grow_jungle_tree(pos, bad) local vm = minetest.get_voxel_manip() local minp, maxp = vm:read_from_map( - {x = pos.x - 3, y = pos.y - 1, z = pos.z - 3}, - {x = pos.x + 3, y = pos.y + height + 1, z = pos.z + 3} + {x = x - 3, y = y - 1, z = z - 3}, + {x = x + 3, y = y + height + 1, z = z + 3} ) local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) local data = vm:get_data() @@ -349,7 +329,7 @@ function default.grow_pine_tree(pos, snow) end end - local dev = 2 + dev = 2 for yy = my + 1, my + 2 do for zz = z - dev, z + dev do local vi = a:index(x - dev, yy, zz) @@ -436,6 +416,7 @@ function default.grow_new_acacia_tree(pos) path, "random", nil, false) end + -- New aspen tree function default.grow_new_aspen_tree(pos) @@ -444,3 +425,53 @@ function default.grow_new_aspen_tree(pos) minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, path, "0", nil, false) end + + +-- +-- Sapling 'on place' function to check protection of node and resulting tree volume +-- + +function default.sapling_on_place(itemstack, placer, pointed_thing, + sapling_name, minp_relative, maxp_relative, interval) + -- Position of sapling + local pos = pointed_thing.under + local node = minetest.get_node_or_nil(pos) + local pdef = node and minetest.registered_nodes[node.name] + + if pdef and pdef.on_rightclick and not placer:get_player_control().sneak then + return pdef.on_rightclick(pos, node, placer, itemstack, pointed_thing) + end + + if not pdef or not pdef.buildable_to then + pos = pointed_thing.above + node = minetest.get_node_or_nil(pos) + pdef = node and minetest.registered_nodes[node.name] + if not pdef or not pdef.buildable_to then + return itemstack + end + end + + local player_name = placer:get_player_name() + -- Check sapling position for protection + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return itemstack + end + -- Check tree volume for protection + if not default.intersects_protection( + vector.add(pos, minp_relative), + vector.add(pos, maxp_relative), + player_name, + interval) then + minetest.set_node(pos, {name = sapling_name}) + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + else + minetest.record_protection_violation(pos, player_name) + -- Print extra information to explain + minetest.chat_send_player(player_name, "Tree will intersect protection") + end + + return itemstack +end diff --git a/mods/doors/README.txt b/mods/doors/README.txt index b1c1363e..9ad7093d 100644 --- a/mods/doors/README.txt +++ b/mods/doors/README.txt @@ -1,62 +1,62 @@ Minetest Game mod: doors ======================== -version: 2.0 +See license.txt for license information. -License of source code: ------------------------ -Copyright (C) 2012 PilzAdam -modified by BlockMen (added sounds, glassdoors[glass, obsidian glass], trapdoor) -Steel trapdoor added by sofar. -Copyright (C) 2016 sofar@foo-projects.org -Re-implemented most of the door algorithms, added meshes, UV wrapped texture +Authors of source code +---------------------- +Originally by PilzAdam (MIT) + +Modified by BlockMen (MIT): Added sounds, glass doors (glass, obsidian glass) and trapdoor. + +Modified by sofar (sofar@foo-projects.org) (MIT): +Added Steel trapdoor. +Re-implemented most of the door algorithms, added meshes, UV wrapped texture. Added doors API to facilitate coding mods accessing and operating doors. -Added Fence Gate model, code, and sounds +Added Fence Gate model, code, and sounds. -This program is free software. It comes without any warranty, to -the extent permitted by applicable law. You can redistribute it -and/or modify it under the terms of the Do What The Fuck You Want -To Public License, Version 2, as published by Sam Hocevar. See -http://sam.zoy.org/wtfpl/COPYING for more details. +Various Minetest developers and contributors (MIT) -License of textures --------------------------------------- -following Textures created by Fernando Zapata (CC BY-SA 3.0): + +Authors of media (textures) +--------------------------- +Following textures created by Fernando Zapata (CC BY-SA 3.0): door_wood.png door_wood_a.png door_wood_a_r.png door_wood_b.png door_wood_b_r.png -following Textures created by BlockMen (WTFPL): +Following textures created by BlockMen (CC BY-SA 3.0): door_trapdoor.png door_obsidian_glass_side.png -following textures created by celeron55 (CC BY-SA 3.0): +Following textures created by celeron55 (CC BY-SA 3.0): door_glass_a.png door_glass_b.png -following Textures created by PenguinDad (CC BY-SA 4.0): +Following textures created by PenguinDad (CC BY-SA 4.0): door_glass.png door_obsidian_glass.png -following textures created by sofar (CC-BY-SA-3.0) +Following textures created by sofar (CC-BY-SA-3.0): doors_trapdoor_steel.png doors_trapdoor_steel_side.png door_trapdoor_side.png - -Obsidian door textures by red-001 based on textures by Pilzadam and BlockMen: WTFPL +Obsidian door textures by red-001 based on textures by Pilzadam and BlockMen (CC BY-SA 3.0): door_obsidian_glass.png -Glass door textures by red-001 based on textures by celeron55: CC BY-SA 3.0 +Glass door textures by red-001 based on textures by celeron55 (CC BY-SA 3.0): door_glass.png -All other textures (created by PilzAdam): WTFPL + +All other textures (created by PilzAdam) (CC BY-SA 3.0): Door textures were converted to the new texture map by sofar, paramat and red-001, under the same license as the originals. -Models: --------------------------------------- + +Authors of media (models) +------------------------- Door 3d models by sofar (CC-BY-SA-3.0) - door_a.obj - door_b.obj @@ -64,18 +64,21 @@ Fence gate models by sofar (CC-BY-SA-3.0) - fencegate_open.obj - fencegate_closed.obj -License of sounds --------------------------------------- + +Authors of media (sounds) +------------------------- Opening-Sound created by CGEffex (CC BY 3.0), modified by BlockMen door_open.ogg Closing-Sound created by bennstir (CC BY 3.0) door_close.ogg fencegate_open.ogg: - http://www.freesound.org/people/mhtaylor67/sounds/126041/ - CC0 + http://www.freesound.org/people/mhtaylor67/sounds/126041/ - (CC0 1.0) fencegate_close.ogg: - http://www.freesound.org/people/BarkersPinhead/sounds/274807/ - CC-BY-3.0 - http://www.freesound.org/people/rivernile7/sounds/249573/ - CC-BY-3.0 -Steel door sounds (open & close (CC-BY-3.0) by HazMatt + http://www.freesound.org/people/BarkersPinhead/sounds/274807/ - (CC-BY-3.0) + http://www.freesound.org/people/rivernile7/sounds/249573/ - (CC-BY-3.0) +Steel door sounds open & close (CC-BY-3.0) by HazMatt - http://www.freesound.org/people/HazMattt/sounds/187283/ doors_steel_door_open.ogg doors_steel_door_close.ogg +doors_glass_door_open.ogg, doors_glass_door_close.ogg: + https://www.freesound.org/people/SkeetMasterFunk69/sounds/235546/ (CC0 1.0) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 90ddcc3d..c5d4a140 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -1,12 +1,3 @@ - ---[[ - -Copyright (C) 2012 PilzAdam - modified by BlockMen (added sounds, glassdoors[glass, obsidian glass], trapdoor) -Copyright (C) 2015 - Auke Kok - ---]] - -- our API object doors = {} @@ -17,7 +8,8 @@ _doors.registered_trapdoors = {} -- returns an object to a door object or nil function doors.get(pos) - if _doors.registered_doors[minetest.get_node(pos).name] then + local node_name = minetest.get_node(pos).name + if _doors.registered_doors[node_name] then -- A normal upright door return { pos = pos, @@ -25,23 +17,23 @@ function doors.get(pos) if self:state() then return false end - return _doors.door_toggle(self.pos, player) + return _doors.door_toggle(self.pos, nil, player) end, close = function(self, player) if not self:state() then return false end - return _doors.door_toggle(self.pos, player) + return _doors.door_toggle(self.pos, nil, player) end, toggle = function(self, player) - return _doors.door_toggle(self.pos, player) + return _doors.door_toggle(self.pos, nil, player) end, state = function(self) local state = minetest.get_meta(self.pos):get_int("state") return state %2 == 1 end } - elseif _doors.registered_trapdoors[minetest.get_node(pos).name] then + elseif _doors.registered_trapdoors[node_name] then -- A trapdoor return { pos = pos, @@ -49,20 +41,19 @@ function doors.get(pos) if self:state() then return false end - return _doors.trapdoor_toggle(self.pos, player) + return _doors.trapdoor_toggle(self.pos, nil, player) end, close = function(self, player) if not self:state() then return false end - return _doors.trapdoor_toggle(self.pos, player) + return _doors.trapdoor_toggle(self.pos, nil, player) end, toggle = function(self, player) - return _doors.trapdoor_toggle(self.pos, player) + return _doors.trapdoor_toggle(self.pos, nil, player) end, state = function(self) - local name = minetest.get_node(pos).name - return name:sub(-5) == "_open" + return minetest.get_node(self.pos).name:sub(-5) == "_open" end } else @@ -105,56 +96,67 @@ minetest.register_node("doors:hidden", { -- table used to aid door opening/closing local transform = { { - { v = "_a", param2 = 3 }, - { v = "_a", param2 = 0 }, - { v = "_a", param2 = 1 }, - { v = "_a", param2 = 2 }, + {v = "_a", param2 = 3}, + {v = "_a", param2 = 0}, + {v = "_a", param2 = 1}, + {v = "_a", param2 = 2}, }, { - { v = "_b", param2 = 1 }, - { v = "_b", param2 = 2 }, - { v = "_b", param2 = 3 }, - { v = "_b", param2 = 0 }, + {v = "_b", param2 = 1}, + {v = "_b", param2 = 2}, + {v = "_b", param2 = 3}, + {v = "_b", param2 = 0}, }, { - { v = "_b", param2 = 1 }, - { v = "_b", param2 = 2 }, - { v = "_b", param2 = 3 }, - { v = "_b", param2 = 0 }, + {v = "_b", param2 = 1}, + {v = "_b", param2 = 2}, + {v = "_b", param2 = 3}, + {v = "_b", param2 = 0}, }, { - { v = "_a", param2 = 3 }, - { v = "_a", param2 = 0 }, - { v = "_a", param2 = 1 }, - { v = "_a", param2 = 2 }, + {v = "_a", param2 = 3}, + {v = "_a", param2 = 0}, + {v = "_a", param2 = 1}, + {v = "_a", param2 = 2}, }, } -function _doors.door_toggle(pos, clicker) +function _doors.door_toggle(pos, node, clicker) local meta = minetest.get_meta(pos) - local def = minetest.registered_nodes[minetest.get_node(pos).name] + node = node or minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] local name = def.door.name local state = meta:get_string("state") if state == "" then -- fix up lvm-placed right-hinged doors, default closed - if minetest.get_node(pos).name:sub(-2) == "_b" then + if node.name:sub(-2) == "_b" then state = 2 + else + state = 0 end else state = tonumber(state) end if clicker and not minetest.check_player_privs(clicker, "protection_bypass") then + -- is player wielding the right key? + local item = clicker:get_wielded_item() local owner = meta:get_string("doors_owner") - if owner ~= "" then + if item:get_name() == "default:key" then + local key_meta = minetest.parse_json(item:get_metadata()) + local secret = meta:get_string("key_lock_secret") + if secret ~= key_meta.secret then + return false + end + + elseif owner ~= "" then if clicker:get_player_name() ~= owner then return false end end end - local old = state -- until Lua-5.2 we have no bitwise operators :( if state % 2 == 1 then state = state - 1 @@ -162,11 +164,13 @@ function _doors.door_toggle(pos, clicker) state = state + 1 end - local dir = minetest.get_node(pos).param2 + local dir = node.param2 if state % 2 == 0 then - minetest.sound_play(def.door.sounds[1], {pos = pos, gain = 0.3, max_hear_distance = 10}) + minetest.sound_play(def.door.sounds[1], + {pos = pos, gain = 0.3, max_hear_distance = 10}) else - minetest.sound_play(def.door.sounds[2], {pos = pos, gain = 0.3, max_hear_distance = 10}) + minetest.sound_play(def.door.sounds[2], + {pos = pos, gain = 0.3, max_hear_distance = 10}) end minetest.swap_node(pos, { @@ -179,24 +183,35 @@ function _doors.door_toggle(pos, clicker) end -local function on_place_node(place_to, newnode, placer, oldnode, itemstack, pointed_thing) +local function on_place_node(place_to, newnode, + placer, oldnode, itemstack, pointed_thing) -- Run script hook - local _, callback - for _, callback in ipairs(core.registered_on_placenodes) do + for _, callback in ipairs(minetest.registered_on_placenodes) do -- Deepcopy pos, node and pointed_thing because callback can modify them local place_to_copy = {x = place_to.x, y = place_to.y, z = place_to.z} - local newnode_copy = {name = newnode.name, param1 = newnode.param1, param2 = newnode.param2} - local oldnode_copy = {name = oldnode.name, param1 = oldnode.param1, param2 = oldnode.param2} + local newnode_copy = + {name = newnode.name, param1 = newnode.param1, param2 = newnode.param2} + local oldnode_copy = + {name = oldnode.name, param1 = oldnode.param1, param2 = oldnode.param2} local pointed_thing_copy = { type = pointed_thing.type, above = vector.new(pointed_thing.above), under = vector.new(pointed_thing.under), ref = pointed_thing.ref, } - callback(place_to_copy, newnode_copy, placer, oldnode_copy, itemstack, pointed_thing_copy) + callback(place_to_copy, newnode_copy, placer, + oldnode_copy, itemstack, pointed_thing_copy) end end +local function can_dig_door(pos, digger) + local digger_name = digger and digger:get_player_name() + if digger_name and minetest.get_player_privs(digger_name).protection_bypass then + return true + end + return minetest.get_meta(pos):get_string("doors_owner") == digger_name +end + function doors.register(name, def) if not name:find(":") then name = "doors:" .. name @@ -212,8 +227,8 @@ function doors.register(name, def) local h = meta:get_int("right") + 1 local p2 = node.param2 local replace = { - { { type = "a", state = 0 }, { type = "a", state = 3 } }, - { { type = "b", state = 1 }, { type = "b", state = 2 } } + {{type = "a", state = 0}, {type = "a", state = 3}}, + {{type = "b", state = 1}, {type = "b", state = 2}} } local new = replace[l][h] -- retain infotext and doors_owner fields @@ -242,7 +257,7 @@ function doors.register(name, def) inventory_image = def.inventory_image, on_place = function(itemstack, placer, pointed_thing) - local pos = nil + local pos if not pointed_thing.type == "node" then return itemstack @@ -252,7 +267,7 @@ function doors.register(name, def) local pdef = minetest.registered_nodes[node.name] if pdef and pdef.on_rightclick then return pdef.on_rightclick(pointed_thing.under, - node, placer, itemstack) + node, placer, itemstack, pointed_thing) end if pdef and pdef.buildable_to then @@ -266,8 +281,11 @@ function doors.register(name, def) end end - local above = { x = pos.x, y = pos.y + 1, z = pos.z } - if not minetest.registered_nodes[minetest.get_node(above).name].buildable_to then + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local top_node = minetest.get_node_or_nil(above) + local topdef = top_node and minetest.registered_nodes[top_node.name] + + if not topdef or not topdef.buildable_to then return itemstack end @@ -279,10 +297,10 @@ function doors.register(name, def) local dir = minetest.dir_to_facedir(placer:get_look_dir()) local ref = { - { x = -1, y = 0, z = 0 }, - { x = 0, y = 0, z = 1 }, - { x = 1, y = 0, z = 0 }, - { x = 0, y = 0, z = -1 }, + {x = -1, y = 0, z = 0}, + {x = 0, y = 0, z = 1}, + {x = 1, y = 0, z = 0}, + {x = 0, y = 0, z = -1}, } local aside = { @@ -305,7 +323,6 @@ function doors.register(name, def) meta:set_int("state", state) if def.protected then - local pn = placer:get_player_name() meta:set_string("doors_owner", pn) meta:set_string("infotext", "Owned by " .. pn) end @@ -314,26 +331,21 @@ function doors.register(name, def) itemstack:take_item() end - on_place_node(pos, minetest.get_node(pos), placer, node, itemstack, pointed_thing) + on_place_node(pos, minetest.get_node(pos), + placer, node, itemstack, pointed_thing) return itemstack end }) + def.inventory_image = nil - local can_dig = function(pos, digger) - if not def.protected then - return true - end - if minetest.check_player_privs(digger, "protection_bypass") then - return true - end - local meta = minetest.get_meta(pos) - local name = "" - if digger then - name = digger:get_player_name() - end - return meta:get_string("doors_owner") == name + if def.recipe then + minetest.register_craft({ + output = name, + recipe = def.recipe, + }) end + def.recipe = nil if not def.sounds then def.sounds = default.node_sound_wood_defaults() @@ -355,22 +367,43 @@ function doors.register(name, def) sounds = { def.sound_close, def.sound_open }, } - def.on_rightclick = function(pos, node, clicker) - _doors.door_toggle(pos, clicker) + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + _doors.door_toggle(pos, node, clicker) + return itemstack end def.after_dig_node = function(pos, node, meta, digger) minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) - nodeupdate({x = pos.x, y = pos.y + 1, z = pos.z}) - end - def.can_dig = function(pos, player) - return can_dig(pos, player) - end - def.on_rotate = function(pos, node, user, mode, new_param2) - return false + minetest.check_for_falling({x = pos.x, y = pos.y + 1, z = pos.z}) end + def.on_rotate = false if def.protected then + def.can_dig = can_dig_door def.on_blast = function() end + def.on_key_use = function(pos, player) + local door = doors.get(pos) + door:toggle(player) + end + def.on_skeleton_key_use = function(pos, player, newsecret) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("doors_owner") + local pname = player:get_player_name() + + -- verify placer is owner of lockable door + if owner ~= pname then + minetest.record_protection_violation(pos, pname) + minetest.chat_send_player(pname, "You do not own this locked door.") + return nil + end + + local secret = meta:get_string("key_lock_secret") + if secret == "" then + secret = newsecret + meta:set_string("key_lock_secret", secret) + end + + return secret, "a locked door", owner + end else def.on_blast = function(pos, intensity) minetest.remove_node(pos) @@ -384,76 +417,21 @@ function doors.register(name, def) minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) end - minetest.register_node(":" .. name .. "_a", { - description = def.description, - visual = "mesh", - mesh = "door_a.obj", - tiles = def.tiles, - drawtype = "mesh", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = true, - is_ground_content = false, - buildable_to = false, - drop = def.drop, - groups = def.groups, - sounds = def.sounds, - door = def.door, - on_rightclick = def.on_rightclick, - after_dig_node = def.after_dig_node, - can_dig = def.can_dig, - on_rotate = def.on_rotate, - on_blast = def.on_blast, - on_destruct = def.on_destruct, - selection_box = { - type = "fixed", - fixed = { -1/2,-1/2,-1/2,1/2,3/2,-6/16} - }, - collision_box = { - type = "fixed", - fixed = { -1/2,-1/2,-1/2,1/2,3/2,-6/16} - }, - }) + def.drawtype = "mesh" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.sunlight_propagates = true + def.walkable = true + def.is_ground_content = false + def.buildable_to = false + def.selection_box = {type = "fixed", fixed = {-1/2,-1/2,-1/2,1/2,3/2,-6/16}} + def.collision_box = {type = "fixed", fixed = {-1/2,-1/2,-1/2,1/2,3/2,-6/16}} - minetest.register_node(":" .. name .. "_b", { - description = def.description, - visual = "mesh", - mesh = "door_b.obj", - tiles = def.tiles, - drawtype = "mesh", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = true, - is_ground_content = false, - buildable_to = false, - drop = def.drop, - groups = def.groups, - sounds = def.sounds, - door = def.door, - on_rightclick = def.on_rightclick, - after_dig_node = def.after_dig_node, - can_dig = def.can_dig, - on_rotate = def.on_rotate, - on_blast = def.on_blast, - on_destruct = def.on_destruct, - selection_box = { - type = "fixed", - fixed = { -1/2,-1/2,-1/2,1/2,3/2,-6/16} - }, - collision_box = { - type = "fixed", - fixed = { -1/2,-1/2,-1/2,1/2,3/2,-6/16} - }, - }) + def.mesh = "door_a.obj" + minetest.register_node(":" .. name .. "_a", def) - if def.recipe then - minetest.register_craft({ - output = name, - recipe = def.recipe, - }) - end + def.mesh = "door_b.obj" + minetest.register_node(":" .. name .. "_b", def) _doors.registered_doors[name .. "_a"] = true _doors.registered_doors[name .. "_b"] = true @@ -463,7 +441,7 @@ doors.register("door_wood", { tiles = {{ name = "doors_door_wood.png", backface_culling = true }}, description = "Wooden Door", inventory_image = "doors_item_wood.png", - groups = { snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, recipe = { {"group:wood", "group:wood"}, {"group:wood", "group:wood"}, @@ -472,11 +450,12 @@ doors.register("door_wood", { }) doors.register("door_steel", { - tiles = {{ name = "doors_door_steel.png", backface_culling = true }}, + tiles = {{name = "doors_door_steel.png", backface_culling = true}}, description = "Steel Door", inventory_image = "doors_item_steel.png", protected = true, - groups = { snappy = 1, bendy = 2, cracky = 1, melty = 2, level = 2 }, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_metal_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", recipe = { @@ -487,11 +466,13 @@ doors.register("door_steel", { }) doors.register("door_glass", { - tiles = { "doors_door_glass.png"}, + tiles = {"doors_door_glass.png"}, description = "Glass Door", inventory_image = "doors_item_glass.png", - groups = { snappy=1, cracky=1, oddly_breakable_by_hand=3 }, + groups = {cracky=3, oddly_breakable_by_hand=3}, sounds = default.node_sound_glass_defaults(), + sound_open = "doors_glass_door_open", + sound_close = "doors_glass_door_close", recipe = { {"default:glass", "default:glass"}, {"default:glass", "default:glass"}, @@ -500,11 +481,13 @@ doors.register("door_glass", { }) doors.register("door_obsidian_glass", { - tiles = { "doors_door_obsidian_glass.png" }, + tiles = {"doors_door_obsidian_glass.png"}, description = "Obsidian Glass Door", inventory_image = "doors_item_obsidian_glass.png", - groups = { snappy=1, cracky=1, oddly_breakable_by_hand=3 }, + groups = {cracky=3}, sounds = default.node_sound_glass_defaults(), + sound_open = "doors_glass_door_open", + sound_close = "doors_glass_door_close", recipe = { {"default:obsidian_glass", "default:obsidian_glass"}, {"default:obsidian_glass", "default:obsidian_glass"}, @@ -538,44 +521,53 @@ end ----trapdoor---- -function _doors.trapdoor_toggle(pos, clicker) +function _doors.trapdoor_toggle(pos, node, clicker) + node = node or minetest.get_node(pos) if clicker and not minetest.check_player_privs(clicker, "protection_bypass") then + -- is player wielding the right key? + local item = clicker:get_wielded_item() local meta = minetest.get_meta(pos) local owner = meta:get_string("doors_owner") - if owner ~= "" then + if item:get_name() == "default:key" then + local key_meta = minetest.parse_json(item:get_metadata()) + local secret = meta:get_string("key_lock_secret") + if secret ~= key_meta.secret then + return false + end + + elseif owner ~= "" then if clicker:get_player_name() ~= owner then return false end end end - local node = minetest.get_node(pos) local def = minetest.registered_nodes[node.name] if string.sub(node.name, -5) == "_open" then - minetest.sound_play(def.sound_close, {pos = pos, gain = 0.3, max_hear_distance = 10}) - minetest.swap_node(pos, {name = string.sub(node.name, 1, string.len(node.name) - 5), param1 = node.param1, param2 = node.param2}) + minetest.sound_play(def.sound_close, + {pos = pos, gain = 0.3, max_hear_distance = 10}) + minetest.swap_node(pos, {name = string.sub(node.name, 1, + string.len(node.name) - 5), param1 = node.param1, param2 = node.param2}) else - minetest.sound_play(def.sound_open, {pos = pos, gain = 0.3, max_hear_distance = 10}) - minetest.swap_node(pos, {name = node.name .. "_open", param1 = node.param1, param2 = node.param2}) + minetest.sound_play(def.sound_open, + {pos = pos, gain = 0.3, max_hear_distance = 10}) + minetest.swap_node(pos, {name = node.name .. "_open", + param1 = node.param1, param2 = node.param2}) end end function doors.register_trapdoor(name, def) + if not name:find(":") then + name = "doors:" .. name + end + local name_closed = name local name_opened = name.."_open" - local function check_player_priv(pos, player) - if not def.protected or minetest.check_player_privs(player, "protection_bypass") then - return true - end - local meta = minetest.get_meta(pos) - local pn = player:get_player_name() - return meta:get_string("doors_owner") == pn - end - - def.on_rightclick = function(pos, node, clicker) - _doors.trapdoor_toggle(pos, clicker) + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + _doors.trapdoor_toggle(pos, node, clicker) + return itemstack end -- Common trapdoor configuration @@ -583,9 +575,9 @@ function doors.register_trapdoor(name, def) def.paramtype = "light" def.paramtype2 = "facedir" def.is_ground_content = false - def.can_dig = check_player_priv if def.protected then + def.can_dig = can_dig_door def.after_place_node = function(pos, placer, itemstack, pointed_thing) local pn = placer:get_player_name() local meta = minetest.get_meta(pos) @@ -596,11 +588,34 @@ function doors.register_trapdoor(name, def) end def.on_blast = function() end + def.on_key_use = function(pos, player) + local door = doors.get(pos) + door:toggle(player) + end + def.on_skeleton_key_use = function(pos, player, newsecret) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("doors_owner") + local pname = player:get_player_name() + + -- verify placer is owner of lockable door + if owner ~= pname then + minetest.record_protection_violation(pos, pname) + minetest.chat_send_player(pname, "You do not own this trapdoor.") + return nil + end + + local secret = meta:get_string("key_lock_secret") + if secret == "" then + secret = newsecret + meta:set_string("key_lock_secret", secret) + end + + return secret, "a locked trapdoor", owner + end else def.on_blast = function(pos, intensity) minetest.remove_node(pos) - minetest.remove_node({ x = pos.x, y = pos.y + 1, z = pos.z}) - return { name } + return {name} end end @@ -627,8 +642,10 @@ function doors.register_trapdoor(name, def) type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5} } - def_closed.tiles = { def.tile_front, def.tile_front, def.tile_side, def.tile_side, - def.tile_side, def.tile_side } + def_closed.tiles = {def.tile_front, + def.tile_front .. '^[transformFY', + def.tile_side, def.tile_side, + def.tile_side, def.tile_side} def_opened.node_box = { type = "fixed", @@ -638,10 +655,11 @@ function doors.register_trapdoor(name, def) type = "fixed", fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5} } - def_opened.tiles = { def.tile_side, def.tile_side, + def_opened.tiles = {def.tile_side, def.tile_side, def.tile_side .. '^[transform3', def.tile_side .. '^[transform1', - def.tile_front, def.tile_front } + def.tile_front .. '^[transform46', + def.tile_front .. '^[transform6'} def_opened.drop = name_closed def_opened.groups.not_in_creative_inventory = 1 @@ -659,7 +677,7 @@ doors.register_trapdoor("doors:trapdoor", { wield_image = "doors_trapdoor.png", tile_front = "doors_trapdoor.png", tile_side = "doors_trapdoor_side.png", - groups = {snappy=1, choppy=2, oddly_breakable_by_hand=2, flammable=2, door=1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, door = 1}, }) doors.register_trapdoor("doors:trapdoor_steel", { @@ -669,9 +687,10 @@ doors.register_trapdoor("doors:trapdoor_steel", { tile_front = "doors_trapdoor_steel.png", tile_side = "doors_trapdoor_steel_side.png", protected = true, + sounds = default.node_sound_metal_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", - groups = {snappy=1, bendy=2, cracky=1, melty=2, level=2, door=1}, + groups = {cracky = 1, level = 2, door = 1}, }) minetest.register_craft({ @@ -698,21 +717,21 @@ function doors.register_fencegate(name, def) local fence = { description = def.description, drawtype = "mesh", - tiles = { def.texture }, + tiles = {def.texture}, paramtype = "light", paramtype2 = "facedir", sunlight_propagates = true, is_ground_content = false, drop = name .. "_closed", - connect_sides = { "left", "right" }, + connect_sides = {"left", "right"}, groups = def.groups, sounds = def.sounds, - on_rightclick = function(pos, clicker) - local node = minetest.get_node(pos) + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) local node_def = minetest.registered_nodes[node.name] minetest.swap_node(pos, {name = node_def.gate, param2 = node.param2}) minetest.sound_play(node_def.sound, {pos = pos, gain = 0.3, max_hear_distance = 8}) + return itemstack end, selection_box = { type = "fixed", @@ -743,7 +762,7 @@ function doors.register_fencegate(name, def) fence_open.collision_box = { type = "fixed", fixed = {{-1/2, -1/2, -1/4, -3/8, 1/2, 1/4}, - {-5/8, -3/8, -14/16, -3/8, 3/8, 0}}, + {-1/2, -3/8, -1/2, -3/8, 3/8, 0}}, } minetest.register_node(":" .. name .. "_closed", fence_closed) @@ -783,12 +802,57 @@ doors.register_fencegate("doors:gate_pine_wood", { description = "Pine Fence Gate", texture = "default_pine_wood.png", material = "default:pine_wood", - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3} }) doors.register_fencegate("doors:gate_aspen_wood", { description = "Aspen Fence Gate", texture = "default_aspen_wood.png", material = "default:aspen_wood", - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3} +}) + + +----fuels---- + +minetest.register_craft({ + type = "fuel", + recipe = "doors:trapdoor", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:door_wood", + burntime = 14, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_wood_closed", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_acacia_wood_closed", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_junglewood_closed", + burntime = 9, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_pine_wood_closed", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_aspen_wood_closed", + burntime = 5, }) diff --git a/mods/doors/license.txt b/mods/doors/license.txt new file mode 100644 index 00000000..8ce73c49 --- /dev/null +++ b/mods/doors/license.txt @@ -0,0 +1,164 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2015-2016 sofar (sofar@foo-projects.org) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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, models and sounds) +----------------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2011-2016 Fernando Zapata +Copyright (C) 2014-2016 celeron55 +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2015-2016 sofar +Copyright (C) 2016 red-001 +Copyright (C) 2016 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/ + +----------------------- + +Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) +Copyright (C) 2014-2016 PenguinDad + +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/4.0/ + +----------------------- + +Attribution 3.0 Unported (CC BY 3.0) +Copyright (C) 2014 CGEffex +Copyright (C) 2014 bennstir +Copyright (C) 2016 BarkersPinhead +Copyright (C) 2016 rivernile7 +Copyright (C) 2016 HazMatt + +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 +mhtaylor67 +SkeetMasterFunk69 + +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/doors/sounds/doors_glass_door_close.ogg b/mods/doors/sounds/doors_glass_door_close.ogg new file mode 100644 index 00000000..b3c13559 Binary files /dev/null and b/mods/doors/sounds/doors_glass_door_close.ogg differ diff --git a/mods/doors/sounds/doors_glass_door_open.ogg b/mods/doors/sounds/doors_glass_door_open.ogg new file mode 100644 index 00000000..66e6812d Binary files /dev/null and b/mods/doors/sounds/doors_glass_door_open.ogg differ diff --git a/mods/dye/README.txt b/mods/dye/README.txt index b1035419..a2fbdd24 100644 --- a/mods/dye/README.txt +++ b/mods/dye/README.txt @@ -1,15 +1,13 @@ Minetest Game mod: dye ====================== - +See license.txt for license information. See init.lua for documentation. -License of source code and media files: ---------------------------------------- -Copyright (C) 2012 Perttu Ahola (celeron55) - -This program is free software. It comes without any warranty, to -the extent permitted by applicable law. You can redistribute it -and/or modify it under the terms of the Do What The Fuck You Want -To Public License, Version 2, as published by Sam Hocevar. See -http://sam.zoy.org/wtfpl/COPYING for more details. +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (MIT) +Various Minetest developers and contributors (MIT) +Authors of media (textures) +--------------------------- +Perttu Ahola (celeron55) (CC BY-SA 3.0) diff --git a/mods/dye/license.txt b/mods/dye/license.txt new file mode 100644 index 00000000..bf9d3501 --- /dev/null +++ b/mods/dye/license.txt @@ -0,0 +1,60 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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) 2012-2016 Perttu Ahola (celeron55) + +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/farming/README.txt b/mods/farming/README.txt index 143cf382..3ccd8c30 100644 --- a/mods/farming/README.txt +++ b/mods/farming/README.txt @@ -1,34 +1,23 @@ Minetest Game mod: farming ========================== +See license.txt for license information. -License of source code: ------------------------ -Copyright (C) 2014 webdesigner97 +Authors of source code +---------------------- +Originally by PilzAdam (MIT) +webdesigner97 (MIT) +Various Minetest developers and contributors (MIT) - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 - - Copyright (C) 2004 Sam Hocevar - - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. - -License of media (textures): ----------------------------- -Created by PilzAdam (License: WTFPL): +Authors of media (textures) +--------------------------- +Created by PilzAdam (CC BY 3.0): farming_bread.png farming_soil.png farming_soil_wet.png farming_soil_wet_side.png farming_string.png -Created by BlockMen (License: CC BY 3.0): +Created by BlockMen (CC BY 3.0): farming_tool_diamondhoe.png farming_tool_mesehoe.png farming_tool_bronzehoe.png @@ -36,10 +25,10 @@ Created by BlockMen (License: CC BY 3.0): farming_tool_stonehoe.png farming_tool_woodhoe.png -Created by MasterGollum (License: WTFPL): +Created by MasterGollum (CC BY 3.0): farming_straw.png -Created by Gambit (License: WTFPL): +Created by Gambit (CC BY 3.0): farming_wheat.png farming_wheat_*.png farming_cotton_*.png diff --git a/mods/farming/api.lua b/mods/farming/api.lua index 68f7be75..182e1b20 100644 --- a/mods/farming/api.lua +++ b/mods/farming/api.lua @@ -1,5 +1,8 @@ + -- Wear out hoes, place soil -- TODO Ignore group:flower +farming.registered_plants = {} + farming.hoe_on_use = function(itemstack, user, pointed_thing, uses) local pt = pointed_thing -- check if pointing at a node @@ -9,11 +12,11 @@ farming.hoe_on_use = function(itemstack, user, pointed_thing, uses) if pt.type ~= "node" then return end - + local under = minetest.get_node(pt.under) local p = {x=pt.under.x, y=pt.under.y+1, z=pt.under.z} local above = minetest.get_node(p) - + -- return if any of the nodes is not registered if not minetest.registered_nodes[under.name] then return @@ -21,23 +24,23 @@ farming.hoe_on_use = function(itemstack, user, pointed_thing, uses) if not minetest.registered_nodes[above.name] then return end - + -- check if the node above the pointed thing is air if above.name ~= "air" then return end - + -- check if pointing at soil if minetest.get_item_group(under.name, "soil") ~= 1 then return end - + -- check if (wet) soil defined local regN = minetest.registered_nodes if regN[under.name].soil == nil or regN[under.name].soil.wet == nil or regN[under.name].soil.dry == nil then return end - + if minetest.is_protected(pt.under, user:get_player_name()) then minetest.record_protection_violation(pt.under, user:get_player_name()) return @@ -47,16 +50,21 @@ farming.hoe_on_use = function(itemstack, user, pointed_thing, uses) return end - - -- turn the node into soil, wear out item and play sound + -- turn the node into soil and play sound minetest.set_node(pt.under, {name = regN[under.name].soil.dry}) minetest.sound_play("default_dig_crumbly", { pos = pt.under, gain = 0.5, }) - + if not minetest.setting_getbool("creative_mode") then + -- wear tool + local wdef = itemstack:get_definition() itemstack:add_wear(65535/(uses-1)) + -- tool break sound + if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then + minetest.sound_play(wdef.sound.breaks, {pos = pt.above, gain = 0.5}) + end end return itemstack end @@ -90,7 +98,9 @@ farming.register_hoe = function(name, def) inventory_image = def.inventory_image, on_use = function(itemstack, user, pointed_thing) return farming.hoe_on_use(itemstack, user, pointed_thing, def.max_uses) - end + end, + groups = def.groups, + sound = {breaks = "default_tool_breaks"}, }) -- Register its recipe if def.material == nil then @@ -119,20 +129,29 @@ farming.register_hoe = function(name, def) end end +-- how often node timers for plants will tick, +/- some random value +local function tick(pos) + minetest.get_node_timer(pos):start(math.random(166, 286)) +end +-- how often a growth failure tick is retried (e.g. too dark) +local function tick_again(pos) + minetest.get_node_timer(pos):start(math.random(40, 80)) +end + -- Seed placement farming.place_seed = function(itemstack, placer, pointed_thing, plantname) local pt = pointed_thing -- check if pointing at a node if not pt then - return + return itemstack end if pt.type ~= "node" then - return + return itemstack end - + local under = minetest.get_node(pt.under) local above = minetest.get_node(pt.above) - + if minetest.is_protected(pt.under, placer:get_player_name()) then minetest.record_protection_violation(pt.under, placer:get_player_name()) return @@ -142,38 +161,101 @@ farming.place_seed = function(itemstack, placer, pointed_thing, plantname) return end - -- return if any of the nodes is not registered if not minetest.registered_nodes[under.name] then - return + return itemstack end if not minetest.registered_nodes[above.name] then - return + return itemstack end - + -- check if pointing at the top of the node if pt.above.y ~= pt.under.y+1 then - return + return itemstack end - + -- check if you can replace the node above the pointed node if not minetest.registered_nodes[above.name].buildable_to then - return + return itemstack end - + -- check if pointing at soil if minetest.get_item_group(under.name, "soil") < 2 then - return + return itemstack end - + -- add the node and remove 1 item from the itemstack minetest.add_node(pt.above, {name = plantname, param2 = 1}) + tick(pt.above) if not minetest.setting_getbool("creative_mode") then itemstack:take_item() end return itemstack end +farming.grow_plant = function(pos, elapsed) + local node = minetest.get_node(pos) + local name = node.name + local def = minetest.registered_nodes[name] + + if not def.next_plant then + -- disable timer for fully grown plant + return + end + + -- grow seed + if minetest.get_item_group(node.name, "seed") and def.fertility then + local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z}) + if not soil_node then + tick_again(pos) + return + end + -- omitted is a check for light, we assume seeds can germinate in the dark. + for _, v in pairs(def.fertility) do + if minetest.get_item_group(soil_node.name, v) ~= 0 then + local placenode = {name = def.next_plant} + if def.place_param2 then + placenode.param2 = def.place_param2 + end + minetest.swap_node(pos, placenode) + if minetest.registered_nodes[def.next_plant].next_plant then + tick(pos) + return + end + end + end + + return + end + + -- check if on wet soil + local below = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}) + if minetest.get_item_group(below.name, "soil") < 3 then + tick_again(pos) + return + end + + -- check light + local light = minetest.get_node_light(pos) + if not light or light < def.minlight or light > def.maxlight then + tick_again(pos) + return + end + + -- grow + local placenode = {name = def.next_plant} + if def.place_param2 then + placenode.param2 = def.place_param2 + end + minetest.swap_node(pos, placenode) + + -- new timer needed? + if minetest.registered_nodes[def.next_plant].next_plant then + tick(pos) + end + return +end + -- Register plants farming.register_plant = function(name, def) local mname = name:split(":")[1] @@ -199,8 +281,11 @@ farming.register_plant = function(name, def) def.fertility = {} end + farming.registered_plants[pname] = def + -- Register seed - local g = {seed = 1, snappy = 3, attached_node = 1} + local lbm_nodes = {mname .. ":seed_" .. pname} + local g = {seed = 1, snappy = 3, attached_node = 1, flammable = 2} for k, v in pairs(def.fertility) do g[v] = 1 end @@ -213,6 +298,7 @@ farming.register_plant = function(name, def) groups = g, paramtype = "light", paramtype2 = "wallmounted", + place_param2 = def.place_param2 or nil, -- this isn't actually used for placement walkable = false, sunlight_propagates = true, selection_box = { @@ -221,6 +307,7 @@ farming.register_plant = function(name, def) }, fertility = def.fertility, sounds = default.node_sound_dirt_defaults({ + dig = {name = "", gain = 0}, dug = {name = "default_grass_footstep", gain = 0.2}, place = {name = "default_place_node", gain = 0.25}, }), @@ -228,16 +315,21 @@ farming.register_plant = function(name, def) on_place = function(itemstack, placer, pointed_thing) return farming.place_seed(itemstack, placer, pointed_thing, mname .. ":seed_" .. pname) end, + next_plant = mname .. ":" .. pname .. "_1", + on_timer = farming.grow_plant, + minlight = def.minlight, + maxlight = def.maxlight, }) -- Register harvest minetest.register_craftitem(":" .. mname .. ":" .. pname, { description = pname:gsub("^%l", string.upper), inventory_image = mname .. "_" .. pname .. ".png", + groups = {flammable = 2}, }) -- Register growing steps - for i=1,def.steps do + for i = 1, def.steps do local drop = { items = { {items = {mname .. ":" .. pname}, rarity = 9 - i}, @@ -248,11 +340,21 @@ farming.register_plant = function(name, def) } local nodegroups = {snappy = 3, flammable = 2, plant = 1, not_in_creative_inventory = 1, attached_node = 1} nodegroups[pname] = i - minetest.register_node(mname .. ":" .. pname .. "_" .. i, { + + local next_plant = nil + + if i < def.steps then + next_plant = mname .. ":" .. pname .. "_" .. (i + 1) + lbm_nodes[#lbm_nodes + 1] = mname .. ":" .. pname .. "_" .. i + end + + minetest.register_node(":" .. mname .. ":" .. pname .. "_" .. i, { drawtype = "plantlike", waving = 1, tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"}, paramtype = "light", + paramtype2 = def.paramtype2 or nil, + place_param2 = def.place_param2 or nil, walkable = false, buildable_to = true, drop = drop, @@ -262,61 +364,20 @@ farming.register_plant = function(name, def) }, groups = nodegroups, sounds = default.node_sound_leaves_defaults(), + next_plant = next_plant, + on_timer = farming.grow_plant, + minlight = def.minlight, + maxlight = def.maxlight, }) end - -- Growing ABM - minetest.register_abm({ - nodenames = {"group:" .. pname, "group:seed"}, - neighbors = {"group:soil"}, - interval = 9, - chance = 20, + -- replacement LBM for pre-nodetimer plants + minetest.register_lbm({ + name = ":" .. mname .. ":start_nodetimer_" .. pname, + nodenames = lbm_nodes, action = function(pos, node) - local plant_height = minetest.get_item_group(node.name, pname) - - -- return if already full grown - if plant_height == def.steps then - return - end - - local node_def = minetest.registered_items[node.name] or nil - - -- grow seed - if minetest.get_item_group(node.name, "seed") and node_def.fertility then - local can_grow = false - local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z}) - if not soil_node then - return - end - for _, v in pairs(node_def.fertility) do - if minetest.get_item_group(soil_node.name, v) ~= 0 then - can_grow = true - end - end - if can_grow then - minetest.set_node(pos, {name = node.name:gsub("seed_", "") .. "_1"}) - end - return - end - - -- check if on wet soil - pos.y = pos.y - 1 - local n = minetest.get_node(pos) - if minetest.get_item_group(n.name, "soil") < 3 then - return - end - pos.y = pos.y + 1 - - -- check light - local ll = minetest.get_node_light(pos) - - if not ll or ll < def.minlight or ll > def.maxlight then - return - end - - -- grow - minetest.set_node(pos, {name = mname .. ":" .. pname .. "_" .. plant_height + 1}) - end + tick_again(pos) + end, }) -- Return diff --git a/mods/farming/hoes.lua b/mods/farming/hoes.lua index 31da19ff..5aae3903 100644 --- a/mods/farming/hoes.lua +++ b/mods/farming/hoes.lua @@ -2,7 +2,8 @@ farming.register_hoe(":farming:hoe_wood", { description = "Wooden Hoe", inventory_image = "farming_tool_woodhoe.png", max_uses = 30, - material = "group:wood" + material = "group:wood", + groups = {flammable = 2}, }) farming.register_hoe(":farming:hoe_stone", { diff --git a/mods/farming/init.lua b/mods/farming/init.lua index 45370e73..97dc9b4a 100644 --- a/mods/farming/init.lua +++ b/mods/farming/init.lua @@ -10,21 +10,26 @@ dofile(farming.path .. "/hoes.lua") -- WHEAT farming.register_plant("farming:wheat", { description = "Wheat seed", + paramtype2 = "meshoptions", inventory_image = "farming_wheat_seed.png", steps = 8, minlight = 13, maxlight = default.LIGHT_MAX, - fertility = {"grassland"} + fertility = {"grassland"}, + groups = {flammable = 4}, + place_param2 = 3, }) minetest.register_craftitem("farming:flour", { description = "Flour", inventory_image = "farming_flour.png", + groups = {flammable = 1}, }) minetest.register_craftitem("farming:bread", { description = "Bread", inventory_image = "farming_bread.png", on_use = minetest.item_eat(5), + groups = {flammable = 2}, }) minetest.register_craft({ @@ -47,7 +52,8 @@ farming.register_plant("farming:cotton", { steps = 8, minlight = 13, maxlight = default.LIGHT_MAX, - fertility = {"grassland", "desert"} + fertility = {"grassland", "desert"}, + groups = {flammable = 4}, }) minetest.register_alias("farming:string", "farming:cotton") @@ -76,3 +82,28 @@ minetest.register_craft({ {"farming:straw"}, } }) + +-- Fuels +minetest.register_craft({ + type = "fuel", + recipe = "farming:straw", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:wheat", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:cotton", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:hoe_wood", + burntime = 5, +}) diff --git a/mods/farming/license.txt b/mods/farming/license.txt new file mode 100644 index 00000000..8cbb63a8 --- /dev/null +++ b/mods/farming/license.txt @@ -0,0 +1,61 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 webdesigner97 +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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 + + +License of media (textures) +--------------------------- + +Attribution 3.0 Unported (CC BY 3.0) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2015-2016 MasterGollum +Copyright (C) 2015-2016 Gambit + +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/ diff --git a/mods/farming/nodes.lua b/mods/farming/nodes.lua index b55a1aaa..09ad36f5 100644 --- a/mods/farming/nodes.lua +++ b/mods/farming/nodes.lua @@ -1,5 +1,4 @@ minetest.override_item("default:dirt", { - groups = {crumbly=3, soil=1}, soil = { base = "default:dirt", dry = "farming:soil", @@ -8,7 +7,6 @@ minetest.override_item("default:dirt", { }) minetest.override_item("default:dirt_with_grass", { - groups = {crumbly=3, soil=1}, soil = { base = "default:dirt_with_grass", dry = "farming:soil", @@ -17,7 +15,6 @@ minetest.override_item("default:dirt_with_grass", { }) minetest.override_item("default:dirt_with_dry_grass", { - groups = {crumbly=3, soil=1}, soil = { base = "default:dirt_with_dry_grass", dry = "farming:soil", @@ -89,11 +86,12 @@ minetest.register_node("farming:straw", { description = "Straw", tiles = {"farming_straw.png"}, is_ground_content = false, - groups = {snappy=3, flammable=4}, + groups = {snappy=3, flammable=4, fall_damage_add_percent=-30}, sounds = default.node_sound_leaves_defaults(), }) minetest.register_abm({ + label = "Farming soil", nodenames = {"group:field"}, interval = 15, chance = 4, @@ -113,7 +111,7 @@ minetest.register_abm({ end local nn_def = minetest.registered_nodes[nn.name] or nil pos.y = pos.y - 1 - + if nn_def and nn_def.walkable and minetest.get_item_group(nn.name, "plant") == 0 then minetest.set_node(pos, {name = base}) return @@ -135,7 +133,7 @@ minetest.register_abm({ if minetest.get_item_group(nn.name, "plant") == 0 and minetest.get_item_group(nn.name, "seed") == 0 then minetest.set_node(pos, {name = base}) end - + -- if its wet turn it back into dry soil elseif wet_lvl == 1 then minetest.set_node(pos, {name = dry}) @@ -146,7 +144,7 @@ minetest.register_abm({ }) -for i = 1, 5 do +for i = 1, 5 do minetest.override_item("default:grass_"..i, {drop = { max_items = 1, items = { @@ -155,7 +153,7 @@ for i = 1, 5 do } }}) end - + minetest.override_item("default:junglegrass", {drop = { max_items = 1, items = { diff --git a/mods/fire/README.txt b/mods/fire/README.txt index 14022f03..099da1c2 100644 --- a/mods/fire/README.txt +++ b/mods/fire/README.txt @@ -1,36 +1,35 @@ Minetest Game mod: fire ======================= +See license.txt for license information. -License of source code: ------------------------ -Copyright (C) 2012 Perttu Ahola (celeron55) +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (LGPL 2.1) +Various Minetest developers and contributors (LGPL 2.1) -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. - -http://www.gnu.org/licenses/lgpl-2.1.html - -License of media (textures and sounds) +Authors of media (textures and sounds) -------------------------------------- -Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) -http://creativecommons.org/licenses/by-sa/3.0/ - -Authors of media files ------------------------ Everything not listed in here: -Copyright (C) 2012 Perttu Ahola (celeron55) +Copyright (C) 2012 Perttu Ahola (celeron55) (CC BY-SA 3.0) -fire_small.ogg sampled from: - http://www.freesound.org/people/dobroide/sounds/4211/ +Muadtralk (CC BY-SA 3.0) + fire_basic_flame_animated.png -fire_large.ogg sampled from: - http://www.freesound.org/people/Dynamicell/sounds/17548/ +Gambit (CC BY-SA 3.0) + fire_flint_steel.png -fire_basic_flame_animated.png: - Muadtralk +dobroide (CC BY 3.0) +http://www.freesound.org/people/dobroide/sounds/4211/ + fire_small.ogg -fire_flint_steel.png - Gambit (WTFPL) +Dynamicell (CC BY 3.0) +http://www.freesound.org/people/Dynamicell/sounds/17548/ + fire_large.ogg + fire_fire.*.ogg +fire_small.ogg and fire_large.ogg are unused but kept temporarily to not break +other mods that may use them. + +Benboncan (CC BY 3.0) +https://www.freesound.org/people/Benboncan/sounds/66457/ + fire_flint_and_steel.ogg diff --git a/mods/fire/depends.txt b/mods/fire/depends.txt new file mode 100644 index 00000000..4ad96d51 --- /dev/null +++ b/mods/fire/depends.txt @@ -0,0 +1 @@ +default diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 457f6b5e..bee487a5 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -1,11 +1,13 @@ --- minetest/fire/init.lua - -- Global namespace for functions fire = {} --- Register flame nodes +-- +-- Items +-- + +-- Flame nodes minetest.register_node("fire:basic_flame", { drawtype = "firelike", @@ -28,18 +30,23 @@ minetest.register_node("fire:basic_flame", { sunlight_propagates = true, damage_per_second = 4, groups = {igniter = 2, dig_immediate = 3, not_in_creative_inventory = 1}, + on_timer = function(pos) + local f = minetest.find_node_near(pos, 1, {"group:flammable"}) + if not f then + minetest.remove_node(pos) + return + end + -- Restart timer + return true + end, drop = "", on_construct = function(pos) - minetest.after(0, fire.on_flame_add_at, pos) + minetest.get_node_timer(pos):start(math.random(30, 60)) end, - on_destruct = function(pos) - minetest.after(0, fire.on_flame_remove_at, pos) + on_blast = function() -- Unaffected by explosions end, - - on_blast = function() - end, -- unaffected by explosions }) minetest.register_node("fire:permanent_flame", { @@ -66,31 +73,50 @@ minetest.register_node("fire:permanent_flame", { groups = {igniter = 2, dig_immediate = 3}, drop = "", - on_blast = function() + on_blast = function() -- Unaffected by explosions end, }) + +-- Flint and steel + minetest.register_tool("fire:flint_and_steel", { description = "Flint and Steel", inventory_image = "fire_flint_steel.png", + sound = {breaks = "default_tool_breaks"}, + on_use = function(itemstack, user, pointed_thing) - local player_name = user:get_player_name() local pt = pointed_thing - - if pt.type == "node" and minetest.get_node(pt.above).name == "air" then - itemstack:add_wear(1000) + minetest.sound_play( + "fire_flint_and_steel", + {pos = pt.above, gain = 0.5, max_hear_distance = 8} + ) + if pt.type == "node" then local node_under = minetest.get_node(pt.under).name - - if minetest.get_item_group(node_under, "flammable") >= 1 then - if not minetest.is_protected(pt.above, player_name) then - minetest.set_node(pt.above, {name = "fire:basic_flame"}) - else - minetest.chat_send_player(player_name, "This area is protected") - end + local nodedef = minetest.registered_nodes[node_under] + if not nodedef then + return + end + local player_name = user:get_player_name() + if minetest.is_protected(pt.under, player_name) then + minetest.chat_send_player(player_name, "This area is protected") + return + end + if nodedef.on_ignite then + nodedef.on_ignite(pt.under, user) + elseif minetest.get_item_group(node_under, "flammable") >= 1 + and minetest.get_node(pt.above).name == "air" then + minetest.set_node(pt.above, {name = "fire:basic_flame"}) end end - if not minetest.setting_getbool("creative_mode") then + -- Wear tool + local wdef = itemstack:get_definition() + itemstack:add_wear(1000) + -- Tool break sound + if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then + minetest.sound_play(wdef.sound.breaks, {pos = pt.above, gain = 0.5}) + end return itemstack end end @@ -103,210 +129,237 @@ minetest.register_craft({ } }) --- Get sound area of position -fire.D = 6 -- size of sound areas +-- Override coalblock to enable permanent flame above +-- Coalblock is non-flammable to avoid unwanted basic_flame nodes -function fire.get_area_p0p1(pos) - local p0 = { - x = math.floor(pos.x / fire.D) * fire.D, - y = math.floor(pos.y / fire.D) * fire.D, - z = math.floor(pos.z / fire.D) * fire.D, - } - local p1 = { - x = p0.x + fire.D - 1, - y = p0.y + fire.D - 1, - z = p0.z + fire.D - 1 - } - return p0, p1 +minetest.override_item("default:coalblock", { + after_destruct = function(pos, oldnode) + pos.y = pos.y + 1 + if minetest.get_node(pos).name == "fire:permanent_flame" then + minetest.remove_node(pos) + end + end, + on_ignite = function(pos, igniter) + local flame_pos = {x = pos.x, y = pos.y + 1, z = pos.z} + if minetest.get_node(flame_pos).name == "air" then + minetest.set_node(flame_pos, {name = "fire:permanent_flame"}) + end + end, +}) + + +-- +-- Sound +-- + +local flame_sound = minetest.setting_getbool("flame_sound") +if flame_sound == nil then + -- Enable if no setting present + flame_sound = true +end + +if flame_sound then + + local handles = {} + local timer = 0 + + -- Parameters + + local radius = 8 -- Flame node search radius around player + local cycle = 3 -- Cycle time for sound updates + + -- Update sound for player + + function fire.update_player_sound(player) + local player_name = player:get_player_name() + -- Search for flame nodes in radius around player + local ppos = player:getpos() + local areamin = vector.subtract(ppos, radius) + local areamax = vector.add(ppos, radius) + local fpos, num = minetest.find_nodes_in_area( + areamin, + areamax, + {"fire:basic_flame", "fire:permanent_flame"} + ) + -- Total number of flames in radius + local flames = (num["fire:basic_flame"] or 0) + + (num["fire:permanent_flame"] or 0) + -- Stop previous sound + if handles[player_name] then + minetest.sound_stop(handles[player_name]) + handles[player_name] = nil + end + -- If flames + if flames > 0 then + -- Find centre of flame positions + local fposmid = fpos[1] + -- If more than 1 flame + if #fpos > 1 then + local fposmin = areamax + local fposmax = areamin + for i = 1, #fpos do + local fposi = fpos[i] + if fposi.x > fposmax.x then + fposmax.x = fposi.x + end + if fposi.y > fposmax.y then + fposmax.y = fposi.y + end + if fposi.z > fposmax.z then + fposmax.z = fposi.z + end + if fposi.x < fposmin.x then + fposmin.x = fposi.x + end + if fposi.y < fposmin.y then + fposmin.y = fposi.y + end + if fposi.z < fposmin.z then + fposmin.z = fposi.z + end + end + fposmid = vector.divide(vector.add(fposmin, fposmax), 2) + end + -- Play sound + local handle = minetest.sound_play( + "fire_fire", + { + pos = fposmid, + to_player = player_name, + gain = math.min(0.06 * (1 + flames * 0.125), 0.18), + max_hear_distance = 32, + loop = true, -- In case of lag + } + ) + -- Store sound handle for this player + if handle then + handles[player_name] = handle + end + end + end + + -- Cycle for updating players sounds + + minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer < cycle then + return + end + + timer = 0 + local players = minetest.get_connected_players() + for n = 1, #players do + fire.update_player_sound(players[n]) + end + end) + + -- Stop sound and clear handle on player leave + + minetest.register_on_leaveplayer(function(player) + local player_name = player:get_player_name() + if handles[player_name] then + minetest.sound_stop(handles[player_name]) + handles[player_name] = nil + end + end) end --- Fire sounds table --- key: position hash of low corner of area --- value: {handle=sound handle, name=sound name} -fire.sounds = {} - - --- Update fire sounds in sound area of position +-- Deprecated function kept temporarily to avoid crashes if mod fire nodes call it function fire.update_sounds_around(pos) - local p0, p1 = fire.get_area_p0p1(pos) - local cp = {x = (p0.x + p1.x) / 2, y = (p0.y + p1.y) / 2, z = (p0.z + p1.z) / 2} - local flames_p = minetest.find_nodes_in_area(p0, p1, {"fire:basic_flame"}) - --print("number of flames at "..minetest.pos_to_string(p0).."/" - -- ..minetest.pos_to_string(p1)..": "..#flames_p) - local should_have_sound = (#flames_p > 0) - local wanted_sound = nil - if #flames_p >= 9 then - wanted_sound = {name = "fire_large", gain = 0.7} - elseif #flames_p > 0 then - wanted_sound = {name = "fire_small", gain = 0.9} - end - local p0_hash = minetest.hash_node_position(p0) - local sound = fire.sounds[p0_hash] - if not sound then - if should_have_sound then - fire.sounds[p0_hash] = { - handle = minetest.sound_play(wanted_sound, - {pos = cp, max_hear_distance = 16, loop = true}), - name = wanted_sound.name, - } - end - else - if not wanted_sound then - minetest.sound_stop(sound.handle) - fire.sounds[p0_hash] = nil - elseif sound.name ~= wanted_sound.name then - minetest.sound_stop(sound.handle) - fire.sounds[p0_hash] = { - handle = minetest.sound_play(wanted_sound, - {pos = cp, max_hear_distance = 16, loop = true}), - name = wanted_sound.name, - } - end - end end --- Update fire sounds on flame node construct or destruct - -function fire.on_flame_add_at(pos) - fire.update_sounds_around(pos) -end - - -function fire.on_flame_remove_at(pos) - fire.update_sounds_around(pos) -end - - --- Return positions for flames around a burning node - -function fire.find_pos_for_flame_around(pos) - return minetest.find_node_near(pos, 1, {"air"}) -end - - --- Detect nearby extinguishing nodes - -function fire.flame_should_extinguish(pos) - return minetest.find_node_near(pos, 1, {"group:puts_out_fire"}) -end - +-- +-- ABMs +-- -- Extinguish all flames quickly with water, snow, ice minetest.register_abm({ + label = "Extinguish flame", nodenames = {"fire:basic_flame", "fire:permanent_flame"}, neighbors = {"group:puts_out_fire"}, interval = 3, chance = 1, catch_up = false, - action = function(p0, node, _, _) - minetest.remove_node(p0) + action = function(pos, node, active_object_count, active_object_count_wider) + minetest.remove_node(pos) minetest.sound_play("fire_extinguish_flame", - {pos = p0, max_hear_distance = 16, gain = 0.25}) + {pos = pos, max_hear_distance = 16, gain = 0.15}) end, }) --- Enable the following ABMs according to 'disable fire' setting +-- Enable the following ABMs according to 'enable fire' setting -if minetest.setting_getbool("disable_fire") then +local fire_enabled = minetest.setting_getbool("enable_fire") +if fire_enabled == nil then + -- New setting not specified, check for old setting. + -- If old setting is also not specified, 'not nil' is true. + fire_enabled = not minetest.setting_getbool("disable_fire") +end - -- Remove basic flames only +if not fire_enabled then + + -- Remove basic flames only if fire disabled minetest.register_abm({ + label = "Remove disabled fire", nodenames = {"fire:basic_flame"}, interval = 7, chance = 1, catch_up = false, - action = function(p0, node, _, _) - minetest.remove_node(p0) - end, + action = minetest.remove_node, }) -else +else -- Fire enabled -- Ignite neighboring nodes, add basic flames minetest.register_abm({ + label = "Ignite flame", nodenames = {"group:flammable"}, neighbors = {"group:igniter"}, interval = 7, chance = 12, catch_up = false, - action = function(p0, node, _, _) + action = function(pos, node, active_object_count, active_object_count_wider) -- If there is water or stuff like that around node, don't ignite - if fire.flame_should_extinguish(p0) then + if minetest.find_node_near(pos, 1, {"group:puts_out_fire"}) then return end - local p = fire.find_pos_for_flame_around(p0) + local p = minetest.find_node_near(pos, 1, {"air"}) if p then minetest.set_node(p, {name = "fire:basic_flame"}) end end, }) - -- Remove basic flames and flammable nodes + -- Remove flammable nodes around basic flame minetest.register_abm({ + label = "Remove flammable nodes", nodenames = {"fire:basic_flame"}, + neighbors = "group:flammable", interval = 5, - chance = 6, + chance = 18, catch_up = false, - action = function(p0, node, _, _) - -- If there are no flammable nodes around flame, remove flame - local p = minetest.find_node_near(p0, 1, {"group:flammable"}) - if not p then - minetest.remove_node(p0) - return - end - if math.random(1, 3) == 1 then - -- remove flammable nodes around flame - local node = minetest.get_node(p) - local def = minetest.registered_nodes[node.name] + action = function(pos, node, active_object_count, active_object_count_wider) + local p = minetest.find_node_near(pos, 1, {"group:flammable"}) + if p then + local flammable_node = minetest.get_node(p) + local def = minetest.registered_nodes[flammable_node.name] if def.on_burn then def.on_burn(p) else minetest.remove_node(p) - nodeupdate(p) + minetest.check_for_falling(p) end end end, }) end - - --- Rarely ignite things from far - ---[[ Currently disabled to reduce the chance of uncontrollable spreading - fires that disrupt servers. Also for less lua processing load. - -minetest.register_abm({ - nodenames = {"group:igniter"}, - neighbors = {"air"}, - interval = 5, - chance = 10, - action = function(p0, node, _, _) - local reg = minetest.registered_nodes[node.name] - if not reg or not reg.groups.igniter or reg.groups.igniter < 2 then - return - end - local d = reg.groups.igniter - local p = minetest.find_node_near(p0, d, {"group:flammable"}) - if p then - -- If there is water or stuff like that around flame, don't ignite - if fire.flame_should_extinguish(p) then - return - end - local p2 = fire.find_pos_for_flame_around(p) - if p2 then - minetest.set_node(p2, {name = "fire:basic_flame"}) - end - end - end, -}) ---]] diff --git a/mods/fire/license.txt b/mods/fire/license.txt new file mode 100644 index 00000000..43f9cd7f --- /dev/null +++ b/mods/fire/license.txt @@ -0,0 +1,84 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2012-2016 celeron55, Perttu Ahola +Copyright (C) 2012-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 and sounds) +--------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Muadtralk +Copyright (C) 2013-2016 Gambit + +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) 2005 dobroide +Copyright (C) 2006 Dynamicell +Copyright (C) 2009 Benboncan + +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/ diff --git a/mods/fire/sounds/fire_fire.1.ogg b/mods/fire/sounds/fire_fire.1.ogg new file mode 100644 index 00000000..cbfee4c6 Binary files /dev/null and b/mods/fire/sounds/fire_fire.1.ogg differ diff --git a/mods/fire/sounds/fire_fire.2.ogg b/mods/fire/sounds/fire_fire.2.ogg new file mode 100644 index 00000000..e8d0eb13 Binary files /dev/null and b/mods/fire/sounds/fire_fire.2.ogg differ diff --git a/mods/fire/sounds/fire_fire.3.ogg b/mods/fire/sounds/fire_fire.3.ogg new file mode 100644 index 00000000..5cad3d9b Binary files /dev/null and b/mods/fire/sounds/fire_fire.3.ogg differ diff --git a/mods/fire/sounds/fire_flint_and_steel.ogg b/mods/fire/sounds/fire_flint_and_steel.ogg new file mode 100644 index 00000000..6996e16f Binary files /dev/null and b/mods/fire/sounds/fire_flint_and_steel.ogg differ diff --git a/mods/flowers/README.txt b/mods/flowers/README.txt index ebd4a21f..2a5e4de3 100644 --- a/mods/flowers/README.txt +++ b/mods/flowers/README.txt @@ -1,23 +1,26 @@ Minetest Game mod: flowers ========================== +See license.txt for license information. -License of source code: ------------------------ -Copyright (C) 2012-2013 Ironzorg, VanessaE +Authors of source code +---------------------- +Originally by Ironzorg (MIT) and VanessaE (MIT) +Various Minetest developers and contributors (MIT) -This program is free software. It comes without any warranty, to -the extent permitted by applicable law. You can redistribute it -and/or modify it under the terms of the Do What The Fuck You Want -To Public License, Version 2, as published by Sam Hocevar. See -http://sam.zoy.org/wtfpl/COPYING for more details. +Authors of media (textures) +--------------------------- +RHRhino (CC BY-SA 3.0): + flowers_dandelion_white.png + flowers_dandelion_yellow.png + flowers_geranium.png + flowers_rose.png + flowers_tulip.png + flowers_viola.png -License of media (textures and sounds) --------------------------------------- -WTFPL +Gambit (CC BY-SA 3.0): + flowers_mushroom_brown.png + flowers_mushroom_red.png + flowers_waterlily.png -Gambit (WTFPL): - flowers_mushroom_*.png - flowers_waterlily.png - -DanDuncombe (WTFPL): - flowers_spores_*.png +yyt16384 (CC BY-SA 3.0): + flowers_waterlily_bottom.png, derived from Gambit's texture diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua index 2d8c93e4..c7cc670e 100644 --- a/mods/flowers/init.lua +++ b/mods/flowers/init.lua @@ -57,12 +57,42 @@ local function add_simple_flower(name, desc, box, f_groups) end flowers.datas = { - {"rose", "Rose", {-0.15, -0.5, -0.15, 0.15, 0.3, 0.15}, {color_red = 1}}, - {"tulip", "Orange Tulip", {-0.15, -0.5, -0.15, 0.15, 0.2, 0.15}, {color_orange = 1}}, - {"dandelion_yellow", "Yellow Dandelion", {-0.15, -0.5, -0.15, 0.15, 0.2, 0.15}, {color_yellow = 1}}, - {"geranium", "Blue Geranium", {-0.15, -0.5, -0.15, 0.15, 0.2, 0.15}, {color_blue = 1}}, - {"viola", "Viola", {-0.5, -0.5, -0.5, 0.5, -0.2, 0.5}, {color_violet = 1}}, - {"dandelion_white", "White dandelion", {-0.5, -0.5, -0.5, 0.5, -0.2, 0.5}, {color_white = 1}} + { + "rose", + "Rose", + {-2 / 16, -0.5, -2 / 16, 2 / 16, 5 / 16, 2 / 16}, + {color_red = 1, flammable = 1} + }, + { + "tulip", + "Orange Tulip", + {-2 / 16, -0.5, -2 / 16, 2 / 16, 3 / 16, 2 / 16}, + {color_orange = 1, flammable = 1} + }, + { + "dandelion_yellow", + "Yellow Dandelion", + {-2 / 16, -0.5, -2 / 16, 2 / 16, 4 / 16, 2 / 16}, + {color_yellow = 1, flammable = 1} + }, + { + "geranium", + "Blue Geranium", + {-2 / 16, -0.5, -2 / 16, 2 / 16, 2 / 16, 2 / 16}, + {color_blue = 1, flammable = 1} + }, + { + "viola", + "Viola", + {-5 / 16, -0.5, -5 / 16, 5 / 16, -1 / 16, 5 / 16}, + {color_violet = 1, flammable = 1} + }, + { + "dandelion_white", + "White dandelion", + {-5 / 16, -0.5, -5 / 16, 5 / 16, -2 / 16, 5 / 16}, + {color_white = 1, flammable = 1} + }, } for _,item in pairs(flowers.datas) do @@ -110,6 +140,7 @@ function flowers.flower_spread(pos, node) end minetest.register_abm({ + label = "Flower spread", nodenames = {"group:flora"}, neighbors = {"default:dirt_with_grass", "default:dirt_with_dry_grass", "default:desert_sand"}, @@ -135,12 +166,12 @@ minetest.register_node("flowers:mushroom_red", { sunlight_propagates = true, walkable = false, buildable_to = true, - groups = {snappy = 3, attached_node = 1}, + groups = {snappy = 3, attached_node = 1, flammable = 1}, sounds = default.node_sound_leaves_defaults(), on_use = minetest.item_eat(-5), selection_box = { type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.3} + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, -1 / 16, 4 / 16}, } }) @@ -154,12 +185,12 @@ minetest.register_node("flowers:mushroom_brown", { sunlight_propagates = true, walkable = false, buildable_to = true, - groups = {snappy = 3, attached_node = 1}, + groups = {snappy = 3, attached_node = 1, flammable = 1}, sounds = default.node_sound_leaves_defaults(), on_use = minetest.item_eat(1), selection_box = { type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.3} + fixed = {-3 / 16, -0.5, -3 / 16, 3 / 16, -2 / 16, 3 / 16}, } }) @@ -167,6 +198,7 @@ minetest.register_node("flowers:mushroom_brown", { -- Mushroom spread and death minetest.register_abm({ + label = "Mushroom spread", nodenames = {"flowers:mushroom_brown", "flowers:mushroom_red"}, interval = 11, chance = 50, @@ -206,6 +238,8 @@ minetest.register_alias("flowers:mushroom_spores_brown", "flowers:mushroom_brown minetest.register_alias("flowers:mushroom_spores_red", "flowers:mushroom_red") minetest.register_alias("flowers:mushroom_fertile_brown", "flowers:mushroom_brown") minetest.register_alias("flowers:mushroom_fertile_red", "flowers:mushroom_red") +minetest.register_alias("mushroom:brown_natural", "flowers:mushroom_brown") +minetest.register_alias("mushroom:red_natural", "flowers:mushroom_red") -- @@ -217,23 +251,24 @@ minetest.register_node("flowers:waterlily", { drawtype = "nodebox", paramtype = "light", paramtype2 = "facedir", - tiles = {"flowers_waterlily.png"}, + tiles = {"flowers_waterlily.png", "flowers_waterlily_bottom.png"}, inventory_image = "flowers_waterlily.png", wield_image = "flowers_waterlily.png", liquids_pointable = true, walkable = false, buildable_to = true, sunlight_propagates = true, - groups = {snappy = 3, flower = 1}, + floodable = true, + groups = {snappy = 3, flower = 1, flammable = 1}, sounds = default.node_sound_leaves_defaults(), node_placement_prediction = "", node_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -0.46875, 0.5} + fixed = {-0.5, -0.5, -0.5, 0.5, -15 / 32, 0.5} }, selection_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -0.4375, 0.5} + fixed = {-7 / 16, -0.5, -7 / 16, 7 / 16, -15 / 32, 7 / 16} }, on_place = function(itemstack, placer, pointed_thing) @@ -242,16 +277,20 @@ minetest.register_node("flowers:waterlily", { local def = minetest.registered_nodes[node] local player_name = placer:get_player_name() - if def and def.liquidtype == "source" and minetest.get_item_group(node, "water") > 0 then + if def and def.liquidtype == "source" and + minetest.get_item_group(node, "water") > 0 then if not minetest.is_protected(pos, player_name) then - minetest.set_node(pos, {name = "flowers:waterlily", param2 = math.random(0, 3)}) + minetest.set_node(pos, {name = "flowers:waterlily", + param2 = math.random(0, 3)}) + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end else - minetest.chat_send_player(player_name, "This area is protected") - end - if not minetest.setting_getbool("creative_mode") then - itemstack:take_item() - return itemstack + minetest.chat_send_player(player_name, "Node is protected") + minetest.record_protection_violation(pos, player_name) end end + + return itemstack end }) diff --git a/mods/flowers/license.txt b/mods/flowers/license.txt new file mode 100644 index 00000000..d3011622 --- /dev/null +++ b/mods/flowers/license.txt @@ -0,0 +1,62 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Ironzorg, VanessaE +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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) 2014-2016 RHRhino +Copyright (C) 2015-2016 Gambit +Copyright (C) 2016 yyt16384 + +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/flowers/mapgen.lua b/mods/flowers/mapgen.lua index 59ce97a3..ec03c9b2 100644 --- a/mods/flowers/mapgen.lua +++ b/mods/flowers/mapgen.lua @@ -94,8 +94,7 @@ local function register_flower(seed, name) octaves = 3, persist = 0.6 }, - biomes = {"stone_grassland", "sandstone_grassland", - "deciduous_forest", "coniferous_forest"}, + biomes = {"grassland", "deciduous_forest", "coniferous_forest"}, y_min = 1, y_max = 31000, decoration = "flowers:"..name, @@ -110,7 +109,7 @@ local function register_mushroom(name) noise_params = { offset = 0, scale = 0.006, - spread = {x = 200, y = 200, z = 200}, + spread = {x = 250, y = 250, z = 250}, seed = 2, octaves = 3, persist = 0.66 @@ -135,10 +134,10 @@ local function register_waterlily() octaves = 3, persist = 0.7 }, - biomes = {"rainforest_swamp", "savanna_swamp", "deciduous_forest_swamp"}, + biomes = {"rainforest_swamp", "savanna_shore", "deciduous_forest_shore"}, y_min = 0, y_max = 0, - schematic = minetest.get_modpath("flowers").."/schematics/waterlily.mts", + schematic = minetest.get_modpath("flowers") .. "/schematics/waterlily.mts", rotation = "random", }) end @@ -162,12 +161,9 @@ end -- Detect mapgen to select functions -- --- Mods using singlenode mapgen can call these functions to enable --- the use of minetest.generate_ores or minetest.generate_decorations - -local mg_params = minetest.get_mapgen_params() -if mg_params.mgname == "v6" then +local mg_name = minetest.get_mapgen_setting("mg_name") +if mg_name == "v6" then flowers.register_mgv6_decorations() -elseif mg_params.mgname ~= "singlenode" then +else flowers.register_decorations() end diff --git a/mods/flowers/schematics/waterlily.mts b/mods/flowers/schematics/waterlily.mts index 876310cc..69e1d8e0 100644 Binary files a/mods/flowers/schematics/waterlily.mts and b/mods/flowers/schematics/waterlily.mts differ diff --git a/mods/flowers/textures/flowers_waterlily_bottom.png b/mods/flowers/textures/flowers_waterlily_bottom.png new file mode 100644 index 00000000..3dbeaf40 Binary files /dev/null and b/mods/flowers/textures/flowers_waterlily_bottom.png differ diff --git a/mods/give_initial_stuff/README.txt b/mods/give_initial_stuff/README.txt new file mode 100644 index 00000000..cbd240fe --- /dev/null +++ b/mods/give_initial_stuff/README.txt @@ -0,0 +1,8 @@ +Minetest Game mod: give_initial_stuff +===================================== +See license.txt for license information. + +Authors of source code +---------------------- +Perttu Ahola (celeron55) (MIT) +Various Minetest developers and contributors (MIT) diff --git a/mods/give_initial_stuff/license.txt b/mods/give_initial_stuff/license.txt new file mode 100644 index 00000000..8134c920 --- /dev/null +++ b/mods/give_initial_stuff/license.txt @@ -0,0 +1,25 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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/nyancat/README.txt b/mods/nyancat/README.txt new file mode 100644 index 00000000..fadc1d23 --- /dev/null +++ b/mods/nyancat/README.txt @@ -0,0 +1,16 @@ +Minetest Game mod: nyancat +========================== +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 files +---------------------- +VanessaE (CC BY-SA 3.0): + nyancat_front.png + nyancat_back.png + nyancat_side.png + nyancat_rainbow.png diff --git a/mods/nyancat/depends.txt b/mods/nyancat/depends.txt new file mode 100644 index 00000000..4ad96d51 --- /dev/null +++ b/mods/nyancat/depends.txt @@ -0,0 +1 @@ +default diff --git a/mods/nyancat/init.lua b/mods/nyancat/init.lua new file mode 100644 index 00000000..7192beb8 --- /dev/null +++ b/mods/nyancat/init.lua @@ -0,0 +1,89 @@ +minetest.register_node("nyancat:nyancat", { + description = "Nyan Cat", + tiles = {"nyancat_side.png", "nyancat_side.png", "nyancat_side.png", + "nyancat_side.png", "nyancat_back.png", "nyancat_front.png"}, + paramtype = "light", + light_source = default.LIGHT_MAX, + paramtype2 = "facedir", + groups = {cracky = 2}, + is_ground_content = false, + legacy_facedir_simple = true, + sounds = default.node_sound_defaults(), +}) + +minetest.register_node("nyancat:nyancat_rainbow", { + description = "Nyan Cat Rainbow", + tiles = { + "nyancat_rainbow.png^[transformR90", + "nyancat_rainbow.png^[transformR90", + "nyancat_rainbow.png" + }, + paramtype = "light", + light_source = default.LIGHT_MAX, + paramtype2 = "facedir", + groups = {cracky = 2}, + is_ground_content = false, + sounds = default.node_sound_defaults(), +}) + +minetest.register_craft({ + type = "fuel", + recipe = "nyancat:nyancat", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "nyancat:nyancat_rainbow", + burntime = 1, +}) + +nyancat = {} + +function nyancat.place(pos, facedir, length) + if facedir > 3 then + facedir = 0 + end + local tailvec = minetest.facedir_to_dir(facedir) + local p = {x = pos.x, y = pos.y, z = pos.z} + minetest.set_node(p, {name = "nyancat:nyancat", param2 = facedir}) + for i = 1, length do + p.x = p.x + tailvec.x + p.z = p.z + tailvec.z + minetest.set_node(p, {name = "nyancat:nyancat_rainbow", param2 = facedir}) + end +end + +function nyancat.generate(minp, maxp, seed) + local height_min = -31000 + local height_max = -32 + if maxp.y < height_min or minp.y > height_max then + return + end + local y_min = math.max(minp.y, height_min) + local y_max = math.min(maxp.y, height_max) + local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1) + local pr = PseudoRandom(seed + 9324342) + local max_num_nyancats = math.floor(volume / (16 * 16 * 16)) + for i = 1, max_num_nyancats do + if pr:next(0, 1000) == 0 then + local x0 = pr:next(minp.x, maxp.x) + local y0 = pr:next(minp.y, maxp.y) + local z0 = pr:next(minp.z, maxp.z) + local p0 = {x = x0, y = y0, z = z0} + nyancat.place(p0, pr:next(0, 3), pr:next(3, 15)) + end + end +end + +minetest.register_on_generated(function(minp, maxp, seed) + nyancat.generate(minp, maxp, seed) +end) + +-- Legacy +minetest.register_alias("default:nyancat", "nyancat:nyancat") +minetest.register_alias("default:nyancat_rainbow", "nyancat:nyancat_rainbow") +minetest.register_alias("nyancat", "nyancat:nyancat") +minetest.register_alias("nyancat_rainbow", "nyancat:nyancat_rainbow") +default.make_nyancat = nyancat.place +default.generate_nyancats = nyancat.generate diff --git a/mods/nyancat/license.txt b/mods/nyancat/license.txt new file mode 100644 index 00000000..3aa38617 --- /dev/null +++ b/mods/nyancat/license.txt @@ -0,0 +1,50 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2011-2016 celeron55, Perttu Ahola +Copyright (C) 2012-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) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 VanessaE + +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/default/textures/default_nc_back.png b/mods/nyancat/textures/nyancat_back.png similarity index 100% rename from mods/default/textures/default_nc_back.png rename to mods/nyancat/textures/nyancat_back.png diff --git a/mods/default/textures/default_nc_front.png b/mods/nyancat/textures/nyancat_front.png similarity index 100% rename from mods/default/textures/default_nc_front.png rename to mods/nyancat/textures/nyancat_front.png diff --git a/mods/default/textures/default_nc_rb.png b/mods/nyancat/textures/nyancat_rainbow.png similarity index 100% rename from mods/default/textures/default_nc_rb.png rename to mods/nyancat/textures/nyancat_rainbow.png diff --git a/mods/default/textures/default_nc_side.png b/mods/nyancat/textures/nyancat_side.png similarity index 100% rename from mods/default/textures/default_nc_side.png rename to mods/nyancat/textures/nyancat_side.png diff --git a/mods/screwdriver/README.txt b/mods/screwdriver/README.txt new file mode 100644 index 00000000..9d39c58c --- /dev/null +++ b/mods/screwdriver/README.txt @@ -0,0 +1,13 @@ +Minetest Game mod: screwdriver +============================== +See license.txt for license information. + +License of source code +---------------------- +Originally by RealBadAngel, Maciej Kasatkin (LGPL 2.1) +Various Minetest developers and contributors (LGPL 2.1) + +License of media (textures) +--------------------------- +Created by Gambit (CC BY-SA 3.0): + screwdriver.png diff --git a/mods/screwdriver/init.lua b/mods/screwdriver/init.lua index 5e6df62f..e73b618f 100644 --- a/mods/screwdriver/init.lua +++ b/mods/screwdriver/init.lua @@ -64,6 +64,7 @@ screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses) end else if not ndef or not ndef.paramtype2 == "facedir" or + ndef.on_rotate == false or (ndef.drawtype == "nodebox" and not ndef.node_box.type == "fixed") or node.param2 == nil then diff --git a/mods/screwdriver/license.txt b/mods/screwdriver/license.txt new file mode 100644 index 00000000..d9b721bb --- /dev/null +++ b/mods/screwdriver/license.txt @@ -0,0 +1,50 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2013-2016 RealBadAngel, Maciej Kasatkin +Copyright (C) 2013-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) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2013-2016 Gambit + +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/screwdriver/readme.txt b/mods/screwdriver/readme.txt deleted file mode 100644 index bdf109b8..00000000 --- a/mods/screwdriver/readme.txt +++ /dev/null @@ -1,21 +0,0 @@ -Minetest Game mod: screwdriver -============================== - -License of source code: ------------------------ -Copyright (C) 2013 RealBadAngel, Maciej Kasatkin - -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 of the License, or -(at your option) any later version. - -http://www.gnu.org/licenses/lgpl-2.1.html - -License of media (textures and sounds) --------------------------------------- -Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) -http://creativecommons.org/licenses/by-sa/3.0/ - -Created by Gambit (WTFPL): - screwdriver.png diff --git a/mods/sethome/README.txt b/mods/sethome/README.txt new file mode 100644 index 00000000..6f0a282b --- /dev/null +++ b/mods/sethome/README.txt @@ -0,0 +1,7 @@ +Minetest Game mod: sethome +========================== +See license.txt for license information. + +Authors of source code +---------------------- +sfan5 (MIT) diff --git a/mods/sethome/init.lua b/mods/sethome/init.lua index 590086b4..e0fc453d 100644 --- a/mods/sethome/init.lua +++ b/mods/sethome/init.lua @@ -1,65 +1,88 @@ + +sethome = {} + local homes_file = minetest.get_worldpath() .. "/homes" local homepos = {} local function loadhomes() - local input = io.open(homes_file, "r") - if input then - repeat - local x = input:read("*n") - if x == nil then - break - end - local y = input:read("*n") - local z = input:read("*n") - local name = input:read("*l") - homepos[name:sub(2)] = {x = x, y = y, z = z} - until input:read(0) == nil - io.close(input) - else - homepos = {} - end + local input, err = io.open(homes_file, "r") + if not input then + return minetest.log("info", "Could not load player homes file: " .. err) + end + + -- Iterate over all stored positions in the format "x y z player" for each line + for pos, name in input:read("*a"):gmatch("(%S+ %S+ %S+)%s([%w_-]+)[\r\n]") do + homepos[name] = minetest.string_to_pos(pos) + end + input:close() end loadhomes() -minetest.register_privilege("home", "Can use /sethome and /home") +sethome.set = function(name, pos) + local player = minetest.get_player_by_name(name) + if not player or not pos then + return false + end -local changed = false + local data = {} + local output, err = io.open(homes_file, "w") + if output then + homepos[name] = pos + for i, v in pairs(homepos) do + table.insert(data, string.format("%.1f %.1f %.1f %s\n", v.x, v.y, v.z, i)) + end + output:write(table.concat(data)) + io.close(output) + return true + end + minetest.log("action", "Unable to write to player homes file: " .. err) + return false +end + +sethome.get = function(name) + local pos = homepos[name] + if pos then + return vector.new(pos) + else + return nil + end +end + +sethome.go = function(name) + local player = minetest.get_player_by_name(name) + if player and homepos[name] then + player:setpos(homepos[name]) + return true + end + return false +end + +minetest.register_privilege("home", { + description = "Can use /sethome and /home", + give_to_singleplayer = false +}) minetest.register_chatcommand("home", { - description = "Teleport you to your home point", - privs = {home=true}, - func = function(name) - local player = minetest.get_player_by_name(name) - if player == nil then - -- just a check to prevent the server crashing - return false - end - if homepos[player:get_player_name()] then - player:setpos(homepos[player:get_player_name()]) - minetest.chat_send_player(name, "Teleported to home!") - else - minetest.chat_send_player(name, "Set a home using /sethome") - end - end, + description = "Teleport you to your home point", + privs = {home = true}, + func = function(name) + if sethome.go(name) then + return true, "Teleported to home!" + end + return false, "Set a home using /sethome" + end, }) minetest.register_chatcommand("sethome", { - description = "Set your home point", - privs = {home=true}, - func = function(name) - local player = minetest.get_player_by_name(name) - local pos = player:getpos() - homepos[player:get_player_name()] = pos - minetest.chat_send_player(name, "Home set!") - changed = true - if changed then - local output = io.open(homes_file, "w") - for i, v in pairs(homepos) do - output:write(v.x.." "..v.y.." "..v.z.." "..i.."\n") - end - io.close(output) - changed = false - end - end, + description = "Set your home point", + privs = {home = true}, + func = function(name) + name = name or "" -- fallback to blank name if nil + local player = minetest.get_player_by_name(name) + if player and sethome.set(name, player:getpos()) then + return true, "Home set!" + end + return false, "Player not found!" + end, }) diff --git a/mods/sethome/license.txt b/mods/sethome/license.txt new file mode 100644 index 00000000..09f03b09 --- /dev/null +++ b/mods/sethome/license.txt @@ -0,0 +1,24 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 sfan5 + +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/sfinv/README.md b/mods/sfinv/README.md new file mode 100644 index 00000000..6ff33923 --- /dev/null +++ b/mods/sfinv/README.md @@ -0,0 +1,21 @@ +Simple Fast Inventory +==================== + +![SFINV Screeny](https://cdn.pbrd.co/images/1yQhd1TI.png) + +A cleaner, simpler, solution to having an advanced inventory in Minetest. + +Written by rubenwardy. +License: MIT + +See game_api.txt for this mod's API + +License of source code and media files: +--------------------------------------- +Copyright (C) 2016 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. diff --git a/mods/sfinv/api.lua b/mods/sfinv/api.lua new file mode 100644 index 00000000..2fef3c84 --- /dev/null +++ b/mods/sfinv/api.lua @@ -0,0 +1,161 @@ +sfinv = { + pages = {}, + pages_unordered = {}, + contexts = {}, + enabled = true +} + +function sfinv.register_page(name, def) + assert(name, "Invalid sfinv page. Requires a name") + assert(def, "Invalid sfinv page. Requires a def[inition] table") + assert(def.get, "Invalid sfinv page. Def requires a get function.") + assert(not sfinv.pages[name], "Attempt to register already registered sfinv page " .. dump(name)) + + sfinv.pages[name] = def + def.name = name + table.insert(sfinv.pages_unordered, def) +end + +function sfinv.override_page(name, def) + assert(name, "Invalid sfinv page override. Requires a name") + assert(def, "Invalid sfinv page override. Requires a def[inition] table") + local page = sfinv.pages[name] + assert(page, "Attempt to override sfinv page " .. dump(name) .. " which does not exist.") + for key, value in pairs(def) do + page[key] = value + end +end + +function sfinv.get_nav_fs(player, context, nav, current_idx) + -- Only show tabs if there is more than one page + if #nav > 1 then + return "tabheader[0,0;tabs;" .. table.concat(nav, ",") .. ";" .. current_idx .. ";true;false]" + else + return "" + end +end + +local theme_main = "bgcolor[#080808BB;true]" .. default.gui_bg .. + default.gui_bg_img + +local theme_inv = default.gui_slots .. [[ + 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[8,8.6]", + theme_main, + 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 = i + 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 + context.page = sfinv.get_homepage_name(player) + assert(sfinv.pages[context.page], "[sfinv] Invalid homepage") + minetest.log("warning", "[sfinv] Couldn't find " .. dump(old_page) .. " so using switching to homepage") + return sfinv.get_formspec(player, context) + end +end + +function sfinv.set_player_inventory_formspec(player, context) + if not context then + local name = player:get_player_name() + context = sfinv.contexts[name] + if not context then + context = { + page = sfinv.get_homepage_name(player) + } + sfinv.contexts[name] = context + end + end + + local fs = sfinv.get_formspec(player, context) + player:set_inventory_formspec(fs) +end + +minetest.register_on_joinplayer(function(player) + if sfinv.enabled then + minetest.after(0.5, function() + sfinv.set_player_inventory_formspec(player) + end) + 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 + + -- Handle Events + if fields.tabs and context.nav then + local tid = tonumber(fields.tabs) + if tid and tid > 0 then + local id = context.nav[tid] + local page = sfinv.pages[id] + if id and page then + local oldpage = sfinv.pages[context.page] + if oldpage and oldpage.on_leave then + oldpage:on_leave(player, context) + end + context.page = id + if page.on_enter then + page:on_enter(player, context) + end + sfinv.set_player_inventory_formspec(player, context) + end + end + return + end + + -- Pass 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) diff --git a/mods/sfinv/depends.txt b/mods/sfinv/depends.txt new file mode 100644 index 00000000..4ad96d51 --- /dev/null +++ b/mods/sfinv/depends.txt @@ -0,0 +1 @@ +default diff --git a/mods/sfinv/init.lua b/mods/sfinv/init.lua new file mode 100644 index 00000000..f030222c --- /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.75;1,1;gui_hb_bg.png] + image[1,4.75;1,1;gui_hb_bg.png] + image[2,4.75;1,1;gui_hb_bg.png] + image[3,4.75;1,1;gui_hb_bg.png] + image[4,4.75;1,1;gui_hb_bg.png] + image[5,4.75;1,1;gui_hb_bg.png] + image[6,4.75;1,1;gui_hb_bg.png] + image[7,4.75;1,1;gui_hb_bg.png] + ]], true) + end +}) diff --git a/mods/stairs/README.txt b/mods/stairs/README.txt index 9bd0b213..d32cd71b 100644 --- a/mods/stairs/README.txt +++ b/mods/stairs/README.txt @@ -1,26 +1,16 @@ Minetest Game mod: stairs ========================= +See license.txt for license information. -License of source code: ------------------------ -Copyright (C) 2011-2012 Kahrl -Copyright (C) 2011-2012 celeron55, Perttu Ahola +Authors of source code +---------------------- +Originally by Kahrl (LGPL 2.1) and +celeron55, Perttu Ahola (LGPL 2.1) +Various Minetest developers and contributors (LGPL 2.1) -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 of the License, or -(at your option) any later version. - -http://www.gnu.org/licenses/lgpl-2.1.html - -License of media (textures and sounds) --------------------------------------- -Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) -http://creativecommons.org/licenses/by-sa/3.0/ - -Authors of media files ------------------------ -Everything not listed in here: -Copyright (C) 2010-2012 celeron55, Perttu Ahola +Authors of media (models) +------------------------- +Jean-Patrick G. (kilbith) (CC BY-SA 3.0): + stairs_stair.obj diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index 7c28fa4f..191c78df 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -87,27 +87,48 @@ function stairs.register_stair(subname, recipeitem, groups, images, description, }) end - minetest.register_craft({ - output = 'stairs:stair_' .. subname .. ' 6', - recipe = { - {recipeitem, "", ""}, - {recipeitem, recipeitem, ""}, - {recipeitem, recipeitem, recipeitem}, - }, - }) + if recipeitem then + minetest.register_craft({ + output = 'stairs:stair_' .. subname .. ' 8', + recipe = { + {recipeitem, "", ""}, + {recipeitem, recipeitem, ""}, + {recipeitem, recipeitem, recipeitem}, + }, + }) - -- Flipped recipe for the silly minecrafters - minetest.register_craft({ - output = 'stairs:stair_' .. subname .. ' 6', - recipe = { - {"", "", recipeitem}, - {"", recipeitem, recipeitem}, - {recipeitem, recipeitem, recipeitem}, - }, - }) + -- Flipped recipe for the silly minecrafters + minetest.register_craft({ + output = 'stairs:stair_' .. subname .. ' 8', + recipe = { + {"", "", recipeitem}, + {"", recipeitem, recipeitem}, + {recipeitem, recipeitem, recipeitem}, + }, + }) + + -- Fuel + local baseburntime = minetest.get_craft_result({ + method = "fuel", + width = 1, + items = {recipeitem} + }).time + if baseburntime > 0 then + minetest.register_craft({ + type = "fuel", + recipe = 'stairs:stair_' .. subname, + burntime = math.floor(baseburntime * 0.75), + }) + end + end end +-- Slab facedir to placement 6d matching table +local slab_trans_dir = {[0] = 8, 0, 2, 1, 3, 4} +-- Slab facedir when placing initial slab against other surface +local slab_trans_dir_place = {[0] = 0, 20, 12, 16, 4, 8} + -- Register slabs. -- Node will be called stairs:slab_ @@ -127,86 +148,61 @@ function stairs.register_slab(subname, recipeitem, groups, images, description, fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, }, on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - return itemstack - end + local under = minetest.get_node(pointed_thing.under) + local wield_item = itemstack:get_name() - -- If it's being placed on an another similar one, replace it with - -- a full block - local slabpos = nil - local slabnode = nil - local p0 = pointed_thing.under - local p1 = pointed_thing.above - local n0 = minetest.get_node(p0) - local n1 = minetest.get_node(p1) - local param2 = 0 + if under and wield_item == under.name then + -- place slab using under node orientation + local dir = minetest.dir_to_facedir(vector.subtract( + pointed_thing.above, pointed_thing.under), true) - local n0_is_upside_down = (n0.name == "stairs:slab_" .. subname and - n0.param2 >= 20) + local p2 = under.param2 - if n0.name == "stairs:slab_" .. subname and not n0_is_upside_down and - p0.y + 1 == p1.y then - slabpos = p0 - slabnode = n0 - elseif n1.name == "stairs:slab_" .. subname then - slabpos = p1 - slabnode = n1 - end - if slabpos then - -- Remove the slab at slabpos - minetest.remove_node(slabpos) - -- Make a fake stack of a single item and try to place it - local fakestack = ItemStack(recipeitem) - fakestack:set_count(itemstack:get_count()) - - pointed_thing.above = slabpos - local success - fakestack, success = minetest.item_place(fakestack, placer, - pointed_thing) - -- If the item was taken from the fake stack, decrement original - if success then - itemstack:set_count(fakestack:get_count()) - -- Else put old node back - else - minetest.set_node(slabpos, slabnode) - end - return itemstack - end - - -- Upside down slabs - if p0.y - 1 == p1.y then - -- Turn into full block if pointing at a existing slab - if n0_is_upside_down then - -- Remove the slab at the position of the slab - minetest.remove_node(p0) - -- Make a fake stack of a single item and try to place it - local fakestack = ItemStack(recipeitem) - fakestack:set_count(itemstack:get_count()) - - pointed_thing.above = p0 - local success - fakestack, success = minetest.item_place(fakestack, placer, - pointed_thing) - -- If the item was taken from the fake stack, decrement original - if success then - itemstack:set_count(fakestack:get_count()) - -- Else put old node back - else - minetest.set_node(p0, n0) + -- combine two slabs if possible + if slab_trans_dir[math.floor(p2 / 4)] == dir then + if not recipeitem then + return itemstack + end + local player_name = placer:get_player_name() + if minetest.is_protected(pointed_thing.under, player_name) and not + minetest.check_player_privs(placer, "protection_bypass") then + minetest.record_protection_violation(pointed_thing.under, + player_name) + return + end + minetest.set_node(pointed_thing.under, {name = recipeitem, param2 = p2}) + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() end return itemstack end - -- Place upside down slab - param2 = 20 - end + -- Placing a slab on an upside down slab should make it right-side up. + if p2 >= 20 and dir == 8 then + p2 = p2 - 20 + -- same for the opposite case: slab below normal slab + elseif p2 <= 3 and dir == 4 then + p2 = p2 + 20 + end - -- If pointing at the side of a upside down slab - if n0_is_upside_down and p0.y + 1 ~= p1.y then - param2 = 20 - end + -- else attempt to place node with proper param2 + minetest.item_place_node(ItemStack(wield_item), placer, pointed_thing, p2) + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + return itemstack + else + -- place slab using look direction of player + local dir = minetest.dir_to_wallmounted(vector.subtract( + pointed_thing.above, pointed_thing.under), true) - return minetest.item_place(itemstack, placer, pointed_thing, param2) + local rot = slab_trans_dir_place[dir] + if rot == 0 or rot == 20 then + rot = rot + minetest.dir_to_facedir(placer:get_look_dir()) + end + + return minetest.item_place(itemstack, placer, pointed_thing, rot) + end end, }) @@ -218,12 +214,28 @@ function stairs.register_slab(subname, recipeitem, groups, images, description, }) end - minetest.register_craft({ - output = 'stairs:slab_' .. subname .. ' 6', - recipe = { - {recipeitem, recipeitem, recipeitem}, - }, - }) + if recipeitem then + minetest.register_craft({ + output = 'stairs:slab_' .. subname .. ' 6', + recipe = { + {recipeitem, recipeitem, recipeitem}, + }, + }) + + -- Fuel + local baseburntime = minetest.get_craft_result({ + method = "fuel", + width = 1, + items = {recipeitem} + }).time + if baseburntime > 0 then + minetest.register_craft({ + type = "fuel", + recipe = 'stairs:slab_' .. subname, + burntime = math.floor(baseburntime * 0.5), + }) + end + end end @@ -232,6 +244,7 @@ end if replace then minetest.register_abm({ + label = "Slab replace", nodenames = {"group:slabs_replace"}, interval = 16, chance = 1, @@ -252,8 +265,8 @@ end -- Stair/slab registration function. -- Nodes will be called stairs:{stair,slab}_ -function stairs.register_stair_and_slab(subname, recipeitem, groups, images, - desc_stair, desc_slab, sounds) +function stairs.register_stair_and_slab(subname, recipeitem, + groups, images, desc_stair, desc_slab, sounds) stairs.register_stair(subname, recipeitem, groups, images, desc_stair, sounds) stairs.register_slab(subname, recipeitem, groups, images, desc_slab, sounds) end @@ -261,149 +274,262 @@ end -- Register default stairs and slabs -stairs.register_stair_and_slab("wood", "default:wood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_wood.png"}, - "Wooden Stair", - "Wooden Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "wood", + "default:wood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + {"default_wood.png"}, + "Wooden Stair", + "Wooden Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("junglewood", "default:junglewood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_junglewood.png"}, - "Junglewood Stair", - "Junglewood Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "junglewood", + "default:junglewood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + {"default_junglewood.png"}, + "Jungle Wood Stair", + "Jungle Wood Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("pine_wood", "default:pine_wood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_pine_wood.png"}, - "Pine Wood Stair", - "Pine Wood Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "pine_wood", + "default:pine_wood", + {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + {"default_pine_wood.png"}, + "Pine Wood Stair", + "Pine Wood Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("acacia_wood", "default:acacia_wood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_acacia_wood.png"}, - "Acacia Wood Stair", - "Acacia Wood Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "acacia_wood", + "default:acacia_wood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + {"default_acacia_wood.png"}, + "Acacia Wood Stair", + "Acacia Wood Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("aspen_wood", "default:aspen_wood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_aspen_wood.png"}, - "Aspen Wood Stair", - "Aspen Wood Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "aspen_wood", + "default:aspen_wood", + {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + {"default_aspen_wood.png"}, + "Aspen Wood Stair", + "Aspen Wood Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("stone", "default:stone", - {cracky = 3}, - {"default_stone.png"}, - "Stone Stair", - "Stone Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "stone", + "default:stone", + {cracky = 3}, + {"default_stone.png"}, + "Stone Stair", + "Stone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("cobble", "default:cobble", - {cracky = 3}, - {"default_cobble.png"}, - "Cobblestone Stair", - "Cobblestone Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "cobble", + "default:cobble", + {cracky = 3}, + {"default_cobble.png"}, + "Cobblestone Stair", + "Cobblestone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("stonebrick", "default:stonebrick", - {cracky = 3}, - {"default_stone_brick.png"}, - "Stone Brick Stair", - "Stone Brick Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "mossycobble", + nil, + {cracky = 3}, + {"default_mossycobble.png"}, + "Mossy Cobblestone Stair", + "Mossy Cobblestone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("desert_stone", "default:desert_stone", - {cracky = 3}, - {"default_desert_stone.png"}, - "Desertstone Stair", - "Desertstone Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "stonebrick", + "default:stonebrick", + {cracky = 2}, + {"default_stone_brick.png"}, + "Stone Brick Stair", + "Stone Brick Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("desert_cobble", "default:desert_cobble", - {cracky = 3}, - {"default_desert_cobble.png"}, - "Desert Cobblestone Stair", - "Desert Cobblestone Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "stone_block", + "default:stone_block", + {cracky = 2}, + {"default_stone_block.png"}, + "Stone Block Stair", + "Stone Block Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("desert_stonebrick", "default:desert_stonebrick", - {cracky = 3}, - {"default_desert_stone_brick.png"}, - "Desert Stone Brick Stair", - "Desert Stone Brick Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "desert_stone", + "default:desert_stone", + {cracky = 3}, + {"default_desert_stone.png"}, + "Desert Stone Stair", + "Desert Stone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("sandstone", "default:sandstone", - {crumbly = 1, cracky = 3}, - {"default_sandstone.png"}, - "Sandstone Stair", - "Sandstone Slab", - default.node_sound_stone_defaults()) - -stairs.register_stair_and_slab("sandstonebrick", "default:sandstonebrick", - {cracky = 2}, - {"default_sandstone_brick.png"}, - "Sandstone Brick Stair", - "Sandstone Brick Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "desert_cobble", + "default:desert_cobble", + {cracky = 3}, + {"default_desert_cobble.png"}, + "Desert Cobblestone Stair", + "Desert Cobblestone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("obsidian", "default:obsidian", - {cracky = 1, level = 2}, - {"default_obsidian.png"}, - "Obsidian Stair", - "Obsidian Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "desert_stonebrick", + "default:desert_stonebrick", + {cracky = 2}, + {"default_desert_stone_brick.png"}, + "Desert Stone Brick Stair", + "Desert Stone Brick Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("obsidianbrick", "default:obsidianbrick", - {cracky = 1, level = 2}, - {"default_obsidian_brick.png"}, - "Obsidian Brick Stair", - "Obsidian Brick Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "desert_stone_block", + "default:desert_stone_block", + {cracky = 2}, + {"default_desert_stone_block.png"}, + "Desert Stone Block Stair", + "Desert Stone Block Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("brick", "default:brick", - {cracky = 3}, - {"default_brick.png"}, - "Brick Stair", - "Brick Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "sandstone", + "default:sandstone", + {crumbly = 1, cracky = 3}, + {"default_sandstone.png"}, + "Sandstone Stair", + "Sandstone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("straw", "farming:straw", - {snappy = 3, flammable = 4}, - {"farming_straw.png"}, - "Straw Stair", - "Straw Slab", - default.node_sound_leaves_defaults()) +stairs.register_stair_and_slab( + "sandstonebrick", + "default:sandstonebrick", + {cracky = 2}, + {"default_sandstone_brick.png"}, + "Sandstone Brick Stair", + "Sandstone Brick Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("steelblock", "default:steelblock", - {cracky = 1, level = 2}, - {"default_steel_block.png"}, - "Steel Block Stair", - "Steel Block Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "sandstone_block", + "default:sandstone_block", + {cracky = 2}, + {"default_sandstone_block.png"}, + "Sandstone Block Stair", + "Sandstone Block Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("copperblock", "default:copperblock", - {cracky = 1, level = 2}, - {"default_copper_block.png"}, - "Copper Block Stair", - "Copper Block Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "obsidian", + "default:obsidian", + {cracky = 1, level = 2}, + {"default_obsidian.png"}, + "Obsidian Stair", + "Obsidian Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("bronzeblock", "default:bronzeblock", - {cracky = 1, level = 2}, - {"default_bronze_block.png"}, - "Bronze Block Stair", - "Bronze Block Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "obsidianbrick", + "default:obsidianbrick", + {cracky = 1, level = 2}, + {"default_obsidian_brick.png"}, + "Obsidian Brick Stair", + "Obsidian Brick Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("goldblock", "default:goldblock", - {cracky = 1}, - {"default_gold_block.png"}, - "Gold Block Stair", - "Gold Block Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "obsidian_block", + "default:obsidian_block", + {cracky = 1, level = 2}, + {"default_obsidian_block.png"}, + "Obsidian Block Stair", + "Obsidian Block Slab", + default.node_sound_stone_defaults() +) + +stairs.register_stair_and_slab( + "brick", + "default:brick", + {cracky = 3}, + {"default_brick.png"}, + "Brick Stair", + "Brick Slab", + default.node_sound_stone_defaults() +) + +stairs.register_stair_and_slab( + "straw", + "farming:straw", + {snappy = 3, flammable = 4}, + {"farming_straw.png"}, + "Straw Stair", + "Straw Slab", + default.node_sound_leaves_defaults() +) + +stairs.register_stair_and_slab( + "steelblock", + "default:steelblock", + {cracky = 1, level = 2}, + {"default_steel_block.png"}, + "Steel Block Stair", + "Steel Block Slab", + default.node_sound_metal_defaults() +) + +stairs.register_stair_and_slab( + "copperblock", + "default:copperblock", + {cracky = 1, level = 2}, + {"default_copper_block.png"}, + "Copper Block Stair", + "Copper Block Slab", + default.node_sound_metal_defaults() +) + +stairs.register_stair_and_slab( + "bronzeblock", + "default:bronzeblock", + {cracky = 1, level = 2}, + {"default_bronze_block.png"}, + "Bronze Block Stair", + "Bronze Block Slab", + default.node_sound_metal_defaults() +) + +stairs.register_stair_and_slab( + "goldblock", + "default:goldblock", + {cracky = 1}, + {"default_gold_block.png"}, + "Gold Block Stair", + "Gold Block Slab", + default.node_sound_metal_defaults() +) diff --git a/mods/stairs/license.txt b/mods/stairs/license.txt new file mode 100644 index 00000000..8f16bbd7 --- /dev/null +++ b/mods/stairs/license.txt @@ -0,0 +1,51 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2011-2016 Kahrl +Copyright (C) 2011-2016 celeron55, Perttu Ahola +Copyright (C) 2012-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 (models) +-------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) + +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/tnt/README.txt b/mods/tnt/README.txt index df98f7e2..c1ca88d5 100644 --- a/mods/tnt/README.txt +++ b/mods/tnt/README.txt @@ -1,37 +1,41 @@ Minetest Game mod: tnt ====================== -by PilzAdam and ShadowNinja +See license.txt for license information. -Introduction: +Authors of source code +---------------------- +PilzAdam (MIT) +ShadowNinja (MIT) +sofar (sofar@foo-projects.org) (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +BlockMen (CC BY-SA 3.0): +All textures not mentioned below. + +ShadowNinja (CC BY-SA 3.0): +tnt_smoke.png + +Wuzzy (CC BY-SA 3.0): +All gunpowder textures except tnt_gunpowder_inventory.png. + +sofar (sofar@foo-projects.org) (CC BY-SA 3.0): +tnt_blast.png + +Introduction +------------ This mod adds TNT to Minetest. TNT is a tool to help the player in mining. How to use the mod: -Craft gunpowder by placing coal and gravel in the crafting area. The -gunpowder can be used to craft TNT or as fuze for TNT. To craft TNT -surround gunpowder with 4 wood in a + shape. +Craft gunpowder by placing coal and gravel in the crafting area. +The gunpowder can be used to craft TNT or as fuse for TNT. +To craft TNT surround gunpowder with 4 wood in a + shape. + There are different ways to blow up TNT: 1. Hit it with a torch. - 2. Hit a gunpowder fuze that leads to a TNT block with a torch. - 3. Activate it with mesecons (fastest way) -Be aware of the damage radius of 7 blocks! + 2. Hit a gunpowder fuse that leads to a TNT block with a torch or flint-and-steel. + 3. Activate it with mesecons (fastest way). -License: -WTFPL (see below) - -See also: -http://minetest.net/ - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 - - Copyright (C) 2004 Sam Hocevar - - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. +Be aware of the damage radius of 6 blocks! diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index 9fd97f49..f9bc307c 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -1,10 +1,9 @@ tnt = {} --- Default to enabled in singleplayer and disabled in multiplayer -local singleplayer = minetest.is_singleplayer() -local setting = minetest.setting_getbool("enable_tnt") -if (not singleplayer and setting ~= true) or - (singleplayer and setting == false) then - return + +-- Default to enabled when in singleplayer +local enable_tnt = minetest.setting_getbool("enable_tnt") +if enable_tnt == nil then + enable_tnt = minetest.is_singleplayer() end -- loss probabilities array (one in X will be lost) @@ -13,7 +12,7 @@ local loss_prob = {} loss_prob["default:cobble"] = 3 loss_prob["default:dirt"] = 4 -local radius = tonumber(minetest.setting_get("tnt_radius") or 3) +local tnt_radius = tonumber(minetest.setting_get("tnt_radius") or 3) -- Fill a list with data for content IDs, after all nodes are registered local cid_data = {} @@ -48,7 +47,7 @@ end local function eject_drops(drops, pos, radius) local drop_pos = vector.new(pos) for _, item in pairs(drops) do - local count = item:get_count() + local count = math.min(item:get_count(), item:get_stack_max()) while count > 0 do local take = math.max(1,math.min(radius * radius, count, @@ -84,7 +83,6 @@ local function add_drop(drops, item) end end - local function destroy(drops, npos, cid, c_air, c_fire, on_blast_queue, ignore_protection, ignore_on_blast) if not ignore_protection and minetest.is_protected(npos, "") then return cid @@ -101,14 +99,13 @@ local function destroy(drops, npos, cid, c_air, c_fire, on_blast_queue, ignore_p return c_fire else local node_drops = minetest.get_node_drops(def.name, "") - for _, item in ipairs(node_drops) do + for _, item in pairs(node_drops) do add_drop(drops, item) end return c_air end end - local function calc_velocity(pos1, pos2, old_vel, power) -- Avoid errors caused by a vector of zero length if vector.equals(pos1, pos2) then @@ -156,7 +153,7 @@ local function entity_physics(pos, radius, drops) local dir = vector.normalize(vector.subtract(obj_pos, pos)) local moveoff = vector.multiply(dir, dist + 1.0) local newpos = vector.add(pos, moveoff) - local newpos = vector.add(newpos, {x = 0, y = 0.2, z = 0}) + newpos = vector.add(newpos, {x = 0, y = 0.2, z = 0}) obj:setpos(newpos) obj:set_hp(obj:get_hp() - damage) @@ -184,7 +181,7 @@ local function entity_physics(pos, radius, drops) }, nil) end end - for _, item in ipairs(entity_drops) do + for _, item in pairs(entity_drops) do add_drop(drops, item) end end @@ -251,8 +248,8 @@ local function add_effects(pos, radius, drops) }) end -function tnt.burn(pos) - local name = minetest.get_node(pos).name +function tnt.burn(pos, nodename) + local name = nodename or minetest.get_node(pos).name local group = minetest.get_item_group(name, "tnt") if group > 0 then minetest.sound_play("tnt_ignite", {pos = pos}) @@ -264,7 +261,7 @@ function tnt.burn(pos) end local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) - local pos = vector.round(pos) + pos = vector.round(pos) -- scan for adjacent TNT nodes first, and enlarge the explosion local vm1 = VoxelManip() local p1 = vector.subtract(pos, 2) @@ -301,11 +298,11 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) -- perform the explosion local vm = VoxelManip() local pr = PseudoRandom(os.time()) - local p1 = vector.subtract(pos, radius) - local p2 = vector.add(pos, radius) - local minp, maxp = vm:read_from_map(p1, p2) - local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) - local data = vm:get_data() + p1 = vector.subtract(pos, radius) + p2 = vector.add(pos, radius) + minp, maxp = vm:read_from_map(p1, p2) + a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + data = vm:get_data() local drops = {} local on_blast_queue = {} @@ -335,25 +332,26 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) vm:update_map() vm:update_liquids() - -- call nodeupdate for everything within 1.5x blast radius + -- call check_single_for_falling for everything within 1.5x blast radius + for y = -radius * 1.5, radius * 1.5 do for z = -radius * 1.5, radius * 1.5 do for x = -radius * 1.5, radius * 1.5 do - for y = -radius * 1.5, radius * 1.5 do - local s = vector.add(pos, {x = x, y = y, z = z}) - local r = vector.distance(pos, s) + local rad = {x = x, y = y, z = z} + local s = vector.add(pos, rad) + local r = vector.length(rad) if r / radius < 1.4 then - nodeupdate(s) + minetest.check_single_for_falling(s) end end end end - for _, data in ipairs(on_blast_queue) do - local dist = math.max(1, vector.distance(data.pos, pos)) + for _, queued_data in pairs(on_blast_queue) do + local dist = math.max(1, vector.distance(queued_data.pos, pos)) local intensity = (radius * radius) / (dist * dist) - local node_drops = data.on_blast(data.pos, intensity) + local node_drops = queued_data.on_blast(queued_data.pos, intensity) if node_drops then - for _, item in ipairs(node_drops) do + for _, item in pairs(node_drops) do add_drop(drops, item) end end @@ -406,16 +404,23 @@ minetest.register_node("tnt:gunpowder", { type = "fixed", fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, }, - groups = {dig_immediate = 2, attached_node = 1, connect_to_raillike = minetest.raillike_group("gunpowder")}, + groups = {dig_immediate = 2, attached_node = 1, flammable = 5, + connect_to_raillike = minetest.raillike_group("gunpowder")}, sounds = default.node_sound_leaves_defaults(), on_punch = function(pos, node, puncher) if puncher:get_wielded_item():get_name() == "default:torch" then - tnt.burn(pos) + minetest.set_node(pos, {name = "tnt:gunpowder_burning"}) end end, on_blast = function(pos, intensity) - tnt.burn(pos) + minetest.set_node(pos, {name = "tnt:gunpowder_burning"}) + end, + on_burn = function(pos) + minetest.set_node(pos, {name = "tnt:gunpowder_burning"}) + end, + on_ignite = function(pos, igniter) + minetest.set_node(pos, {name = "tnt:gunpowder_burning"}) end, }) @@ -492,31 +497,36 @@ minetest.register_node("tnt:gunpowder_burning", { end, }) -minetest.register_abm({ - nodenames = {"group:tnt", "tnt:gunpowder"}, - neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"}, - interval = 4, - chance = 1, - action = tnt.burn, -}) - minetest.register_craft({ output = "tnt:gunpowder", type = "shapeless", recipe = {"default:coal_lump", "default:gravel"} }) -minetest.register_craft({ - output = "tnt:tnt", - recipe = { - {"", "group:wood", ""}, - {"group:wood", "tnt:gunpowder", "group:wood"}, - {"", "group:wood", ""} - } -}) +if enable_tnt then + minetest.register_craft({ + output = "tnt:tnt", + recipe = { + {"", "group:wood", ""}, + {"group:wood", "tnt:gunpowder", "group:wood"}, + {"", "group:wood", ""} + } + }) + + minetest.register_abm({ + label = "TNT ignition", + nodenames = {"group:tnt", "tnt:gunpowder"}, + neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"}, + interval = 4, + chance = 1, + action = function(pos, node) + tnt.burn(pos, node.name) + end, + }) +end function tnt.register_tnt(def) - local name = "" + local name if not def.name:find(':') then name = "tnt:" .. def.name else @@ -530,30 +540,38 @@ function tnt.register_tnt(def) local tnt_burning = def.tiles.burning or def.name .. "_top_burning_animated.png" if not def.damage_radius then def.damage_radius = def.radius * 2 end - minetest.register_node(":" .. name, { - description = def.description, - tiles = {tnt_top, tnt_bottom, tnt_side}, - is_ground_content = false, - groups = {dig_immediate = 2, mesecon = 2, tnt = 1}, - sounds = default.node_sound_wood_defaults(), - on_punch = function(pos, node, puncher) - if puncher:get_wielded_item():get_name() == "default:torch" then - minetest.set_node(pos, {name = name .. "_burning"}) - end - end, - on_blast = function(pos, intensity) - minetest.after(0.1, function() - tnt.boom(pos, def) - end) - end, - mesecons = {effector = - {action_on = - function(pos) - tnt.boom(pos, def) + if enable_tnt then + minetest.register_node(":" .. name, { + description = def.description, + tiles = {tnt_top, tnt_bottom, tnt_side}, + is_ground_content = false, + groups = {dig_immediate = 2, mesecon = 2, tnt = 1, flammable = 5}, + sounds = default.node_sound_wood_defaults(), + on_punch = function(pos, node, puncher) + if puncher:get_wielded_item():get_name() == "default:torch" then + minetest.set_node(pos, {name = name .. "_burning"}) end - } - }, - }) + end, + on_blast = function(pos, intensity) + minetest.after(0.1, function() + tnt.boom(pos, def) + end) + end, + mesecons = {effector = + {action_on = + function(pos) + tnt.boom(pos, def) + end + } + }, + on_burn = function(pos) + minetest.set_node(pos, {name = name .. "_burning"}) + end, + on_ignite = function(pos, igniter) + minetest.set_node(pos, {name = name .. "_burning"}) + end, + }) + end minetest.register_node(":" .. name .. "_burning", { tiles = { @@ -580,7 +598,7 @@ function tnt.register_tnt(def) on_construct = function(pos) minetest.sound_play("tnt_ignite", {pos = pos}) minetest.get_node_timer(pos):start(4) - nodeupdate(pos) + minetest.check_for_falling(pos) end, }) end @@ -588,6 +606,5 @@ end tnt.register_tnt({ name = "tnt:tnt", description = "TNT", - radius = radius, + radius = tnt_radius, }) - diff --git a/mods/tnt/license.txt b/mods/tnt/license.txt new file mode 100644 index 00000000..210f2bdc --- /dev/null +++ b/mods/tnt/license.txt @@ -0,0 +1,65 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 PilzAdam +Copyright (C) 2014-2016 ShadowNinja +Copyright (C) 2016 sofar (sofar@foo-projects.org) +Copyright (C) 2014-2016 Various Minetest developers and contributors + +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) 2014-2016 BlockMen +Copyright (C) 2014-2016 ShadowNinja +Copyright (C) 2015-2016 Wuzzy +Copyright (C) 2016 sofar (sofar@foo-projects.org) + +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/vessels/README.txt b/mods/vessels/README.txt index d5c3da84..5bb798c8 100644 --- a/mods/vessels/README.txt +++ b/mods/vessels/README.txt @@ -1,45 +1,22 @@ Minetest Game mod: vessels ========================== +See license.txt for license information. -Crafts -------- -Glass bottle (yields 10) +Authors of source code +---------------------- +Originally by Vanessa Ezekowitz (LGPL 2.1) +Modified by Perttu Ahola (LGPL 2.1) +Various Minetest developers and contributors (LGPL 2.1) - G - G - G - G - - G - +Authors of media (textures) +--------------------------- +All not listed below, Vanessa Ezekowitz (CC BY-SA 3.0) -Drinking Glass (yields 14) - - G - G - G - G - G G G - -Heavy Steel Bottle (yields 5) - - S - S - S - S - - S - - -License of source code: ------------------------ -Copyright (C) 2012 Vanessa Ezekowitz -Version 2012-09-02 -Modifications by Perttu Ahola - -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. - -http://www.gnu.org/licenses/lgpl-2.1.html - -License of media (textures and sounds) --------------------------------------- -WTFPL - -Authors of media files ------------------------ -Unless specifically noted, -Copyright (C) 2012 Vanessa Ezekowitz +The following textures were modified by Thomas-S (CC BY-SA 3.0): + vessels_drinking_glass.png + vessels_drinking_glass_inv.png + vessels_glass_bottle.png + vessels_steel_bottle.png +The following texture was created by Wuzzy (CC BY-SA 3.0): + vessels_shelf_slot.png (based on vessels_glass_bottle.png) diff --git a/mods/vessels/init.lua b/mods/vessels/init.lua index 165efbd5..688413f2 100644 --- a/mods/vessels/init.lua +++ b/mods/vessels/init.lua @@ -2,27 +2,48 @@ -- See README.txt for licensing and other information. local vessels_shelf_formspec = - "size[8,7;]".. - default.gui_bg.. - default.gui_bg_img.. - default.gui_slots.. - "list[context;vessels;0,0.3;8,2;]".. - "list[current_player;main;0,2.85;8,1;]".. - "list[current_player;main;0,4.08;8,3;8]".. - "listring[context;vessels]".. - "listring[current_player;main]".. - default.get_hotbar_bg(0,2.85) + "size[8,7;]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[context;vessels;0,0.3;8,2;]" .. + "list[current_player;main;0,2.85;8,1;]" .. + "list[current_player;main;0,4.08;8,3;8]" .. + "listring[context;vessels]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0, 2.85) + +local function get_vessels_shelf_formspec(inv) + local formspec = vessels_shelf_formspec + local invlist = inv and inv:get_list("vessels") + -- Inventory slots overlay + local vx, vy = 0, 0.3 + for i = 1, 16 do + if i == 9 then + vx = 0 + vy = vy + 1 + end + if not invlist or invlist[i]:is_empty() then + formspec = formspec .. + "image[" .. vx .. "," .. vy .. ";1,1;vessels_shelf_slot.png]" + end + vx = vx + 1 + end + return formspec +end minetest.register_node("vessels:shelf", { - description = "Vessels shelf", - tiles = {"default_wood.png", "default_wood.png", "vessels_shelf.png"}, + description = "Vessels Shelf", + tiles = {"default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "vessels_shelf.png", "vessels_shelf.png"}, + paramtype2 = "facedir", is_ground_content = false, - groups = {choppy=3,oddly_breakable_by_hand=2,flammable=3}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, sounds = default.node_sound_wood_defaults(), on_construct = function(pos) local meta = minetest.get_meta(pos) - meta:set_string("formspec", vessels_shelf_formspec) + meta:set_string("formspec", get_vessels_shelf_formspec(nil)) local inv = meta:get_inventory() inv:set_size("vessels", 8 * 2) end, @@ -39,30 +60,36 @@ minetest.register_node("vessels:shelf", { on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) minetest.log("action", player:get_player_name() .. " moves stuff in vessels shelf at ".. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_vessels_shelf_formspec(meta:get_inventory())) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) minetest.log("action", player:get_player_name() .. " moves stuff to vessels shelf at ".. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_vessels_shelf_formspec(meta:get_inventory())) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) minetest.log("action", player:get_player_name() .. " takes stuff from vessels shelf at ".. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_vessels_shelf_formspec(meta:get_inventory())) end, on_blast = function(pos) local drops = {} default.get_inventory_drops(pos, "vessels", drops) - drops[#drops+1] = "vessels:shelf" + drops[#drops + 1] = "vessels:shelf" minetest.remove_node(pos) return drops end, }) minetest.register_craft({ - output = 'vessels:shelf', + output = "vessels:shelf", recipe = { - {'group:wood', 'group:wood', 'group:wood'}, - {'group:vessel', 'group:vessel', 'group:vessel'}, - {'group:wood', 'group:wood', 'group:wood'}, + {"group:wood", "group:wood", "group:wood"}, + {"group:vessel", "group:vessel", "group:vessel"}, + {"group:wood", "group:wood", "group:wood"}, } }) @@ -70,25 +97,25 @@ minetest.register_node("vessels:glass_bottle", { description = "Glass Bottle (empty)", drawtype = "plantlike", tiles = {"vessels_glass_bottle.png"}, - inventory_image = "vessels_glass_bottle_inv.png", + inventory_image = "vessels_glass_bottle.png", wield_image = "vessels_glass_bottle.png", paramtype = "light", is_ground_content = false, walkable = false, selection_box = { type = "fixed", - fixed = {-0.25, -0.5, -0.25, 0.25, 0.4, 0.25} + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }, - groups = {vessel=1,dig_immediate=3,attached_node=1}, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, sounds = default.node_sound_glass_defaults(), }) minetest.register_craft( { output = "vessels:glass_bottle 10", recipe = { - { "default:glass", "", "default:glass" }, - { "default:glass", "", "default:glass" }, - { "", "default:glass", "" } + {"default:glass", "", "default:glass"}, + {"default:glass", "", "default:glass"}, + {"", "default:glass", ""} } }) @@ -103,18 +130,18 @@ minetest.register_node("vessels:drinking_glass", { walkable = false, selection_box = { type = "fixed", - fixed = {-0.25, -0.5, -0.25, 0.25, 0.4, 0.25} + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }, - groups = {vessel=1,dig_immediate=3,attached_node=1}, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, sounds = default.node_sound_glass_defaults(), }) minetest.register_craft( { output = "vessels:drinking_glass 14", recipe = { - { "default:glass", "", "default:glass" }, - { "default:glass", "", "default:glass" }, - { "default:glass", "default:glass", "default:glass" } + {"default:glass", "", "default:glass"}, + {"default:glass", "", "default:glass"}, + {"default:glass", "default:glass", "default:glass"} } }) @@ -122,30 +149,30 @@ minetest.register_node("vessels:steel_bottle", { description = "Heavy Steel Bottle (empty)", drawtype = "plantlike", tiles = {"vessels_steel_bottle.png"}, - inventory_image = "vessels_steel_bottle_inv.png", + inventory_image = "vessels_steel_bottle.png", wield_image = "vessels_steel_bottle.png", paramtype = "light", is_ground_content = false, walkable = false, selection_box = { type = "fixed", - fixed = {-0.25, -0.5, -0.25, 0.25, 0.4, 0.25} + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }, - groups = {vessel=1,dig_immediate=3,attached_node=1}, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, sounds = default.node_sound_defaults(), }) minetest.register_craft( { output = "vessels:steel_bottle 5", recipe = { - { "default:steel_ingot", "", "default:steel_ingot" }, - { "default:steel_ingot", "", "default:steel_ingot" }, - { "", "default:steel_ingot", "" } + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"}, + {"", "default:steel_ingot", ""} } }) --- Make sure we can recycle them +-- Glass and steel recycling minetest.register_craftitem("vessels:glass_fragments", { description = "Pile of Glass Fragments", @@ -182,3 +209,8 @@ minetest.register_craft( { recipe = "vessels:steel_bottle", }) +minetest.register_craft({ + type = "fuel", + recipe = "vessels:shelf", + burntime = 30, +}) diff --git a/mods/vessels/license.txt b/mods/vessels/license.txt new file mode 100644 index 00000000..de16a3b0 --- /dev/null +++ b/mods/vessels/license.txt @@ -0,0 +1,52 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2012-2016 Vanessa Ezekowitz +Copyright (C) 2012-2016 celeron55, Perttu Ahola +Copyright (C) 2012-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) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Vanessa Ezekowitz +Copyright (C) 2016 Thomas-S + +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/vessels/textures/vessels_drinking_glass.png b/mods/vessels/textures/vessels_drinking_glass.png index 4cff308c..d5037b85 100644 Binary files a/mods/vessels/textures/vessels_drinking_glass.png and b/mods/vessels/textures/vessels_drinking_glass.png differ diff --git a/mods/vessels/textures/vessels_drinking_glass_inv.png b/mods/vessels/textures/vessels_drinking_glass_inv.png index 4cff308c..9992bd9c 100644 Binary files a/mods/vessels/textures/vessels_drinking_glass_inv.png and b/mods/vessels/textures/vessels_drinking_glass_inv.png differ diff --git a/mods/vessels/textures/vessels_glass_bottle.png b/mods/vessels/textures/vessels_glass_bottle.png index e9dc6837..6ea37db6 100644 Binary files a/mods/vessels/textures/vessels_glass_bottle.png and b/mods/vessels/textures/vessels_glass_bottle.png differ diff --git a/mods/vessels/textures/vessels_glass_bottle_inv.png b/mods/vessels/textures/vessels_glass_bottle_inv.png deleted file mode 100644 index e9dc6837..00000000 Binary files a/mods/vessels/textures/vessels_glass_bottle_inv.png and /dev/null differ diff --git a/mods/vessels/textures/vessels_shelf_slot.png b/mods/vessels/textures/vessels_shelf_slot.png new file mode 100644 index 00000000..ff29082a Binary files /dev/null and b/mods/vessels/textures/vessels_shelf_slot.png differ diff --git a/mods/vessels/textures/vessels_steel_bottle.png b/mods/vessels/textures/vessels_steel_bottle.png index 834a3d5a..61d30719 100644 Binary files a/mods/vessels/textures/vessels_steel_bottle.png and b/mods/vessels/textures/vessels_steel_bottle.png differ diff --git a/mods/vessels/textures/vessels_steel_bottle_inv.png b/mods/vessels/textures/vessels_steel_bottle_inv.png deleted file mode 100644 index 834a3d5a..00000000 Binary files a/mods/vessels/textures/vessels_steel_bottle_inv.png and /dev/null differ diff --git a/mods/walls/README.txt b/mods/walls/README.txt new file mode 100644 index 00000000..0389174d --- /dev/null +++ b/mods/walls/README.txt @@ -0,0 +1,7 @@ +Minetest Game mod: walls +======================== +See license.txt for license information. + +Authors of source code +---------------------- +Auke Kok (LGPL 2.1) diff --git a/mods/walls/init.lua b/mods/walls/init.lua index 0b51bdb0..bee8e465 100644 --- a/mods/walls/init.lua +++ b/mods/walls/init.lua @@ -1,18 +1,3 @@ - ---[[ - -Walls mod for Minetest - -Copyright (C) 2015 Auke Kok - -This program is free software. It comes without any warranty, to -the extent permitted by applicable law. You can redistribute it -and/or modify it under the terms of the Do What The Fuck You Want -To Public License, Version 2, as published by Sam Hocevar. See -http://sam.zoy.org/wtfpl/COPYING for more details. - ---]] - walls = {} walls.register = function(wall_name, wall_desc, wall_texture, wall_mat, wall_sounds) diff --git a/mods/walls/license.txt b/mods/walls/license.txt new file mode 100644 index 00000000..ccfaf1cd --- /dev/null +++ b/mods/walls/license.txt @@ -0,0 +1,14 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2015 Auke Kok + +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 diff --git a/mods/wool/README.txt b/mods/wool/README.txt index f57b6dd3..a66677dd 100644 --- a/mods/wool/README.txt +++ b/mods/wool/README.txt @@ -1,28 +1,16 @@ Minetest Game mod: wool ======================= +See license.txt for license information. -Mostly backward-compatible with jordach's 16-color wool mod. - -License of source code: ------------------------ -Copyright (C) 2012 Perttu Ahola (celeron55) - -This program is free software. It comes without any warranty, to -the extent permitted by applicable law. You can redistribute it -and/or modify it under the terms of the Do What The Fuck You Want -To Public License, Version 2, as published by Sam Hocevar. See -http://sam.zoy.org/wtfpl/COPYING for more details. - -License of media (textures and sounds) --------------------------------------- -Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) -http://creativecommons.org/licenses/by-sa/3.0/ - -Authors of media files ------------------------ -Cisoun: -- wool_black.png wool_brown.png wool_dark_green.png wool_green.png -- wool_magenta.png wool_pink.png wool_violet.png wool_yellow.png wool_blue.png -- wool_cyan.png wool_dark_grey.png wool_grey.png wool_orange.png wool_red.png -- wool_white.png +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (MIT) +Various Minetest developers and contributors (MIT) +Authors of media (textures) +--------------------------- +Cisoun (CC BY-SA 3.0): + wool_black.png wool_brown.png wool_dark_green.png wool_green.png + wool_magenta.png wool_pink.png wool_violet.png wool_yellow.png + wool_blue.png wool_cyan.png wool_dark_grey.png wool_grey.png + wool_orange.png wool_red.png wool_white.png diff --git a/mods/wool/init.lua b/mods/wool/init.lua index f485e4fb..a36e4dd8 100644 --- a/mods/wool/init.lua +++ b/mods/wool/init.lua @@ -1,14 +1,8 @@ --- minetest/wool/init.lua - --- Backwards compatibility with jordach's 16-color wool mod -minetest.register_alias("wool:dark_blue", "wool:blue") -minetest.register_alias("wool:gold", "wool:yellow") - -local wool = {} -- This uses a trick: you can first define the recipes using all of the base -- colors, and then some recipes using more specific colors for a few non-base -- colors available. When crafting, the last recipes will be checked first. -wool.dyes = { + +local dyes = { {"white", "White", "basecolor_white"}, {"grey", "Grey", "basecolor_grey"}, {"black", "Black", "basecolor_black"}, @@ -26,25 +20,28 @@ wool.dyes = { {"dark_green", "Dark Green", "unicolor_dark_green"}, } -for _, row in ipairs(wool.dyes) do - local name = row[1] - local desc = row[2] - local craft_color_group = row[3] - -- Node Definition - minetest.register_node("wool:"..name, { - description = desc.." Wool", - tiles = {"wool_"..name..".png"}, +for i = 1, #dyes do + local name, desc, craft_color_group = unpack(dyes[i]) + + minetest.register_node("wool:" .. name, { + description = desc .. " Wool", + tiles = {"wool_" .. name .. ".png"}, is_ground_content = false, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3,flammable=3,wool=1}, + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, + flammable = 3, wool = 1}, sounds = default.node_sound_defaults(), }) - if craft_color_group then - -- Crafting from dye and white wool - minetest.register_craft({ - type = "shapeless", - output = 'wool:'..name, - recipe = {'group:dye,'..craft_color_group, 'group:wool'}, - }) - end + + minetest.register_craft{ + type = "shapeless", + output = "wool:" .. name, + recipe = {"group:dye," .. craft_color_group, "group:wool"}, + } end + +-- legacy + +-- Backwards compatibility with jordach's 16-color wool mod +minetest.register_alias("wool:dark_blue", "wool:blue") +minetest.register_alias("wool:gold", "wool:yellow") diff --git a/mods/wool/license.txt b/mods/wool/license.txt new file mode 100644 index 00000000..93101636 --- /dev/null +++ b/mods/wool/license.txt @@ -0,0 +1,60 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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) 2012-2016 Cisoun + +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/wool/textures/wool_black.png b/mods/wool/textures/wool_black.png index a9e566bb..700d439d 100644 Binary files a/mods/wool/textures/wool_black.png and b/mods/wool/textures/wool_black.png differ diff --git a/mods/wool/textures/wool_blue.png b/mods/wool/textures/wool_blue.png index 035a8da4..a0749867 100644 Binary files a/mods/wool/textures/wool_blue.png and b/mods/wool/textures/wool_blue.png differ diff --git a/mods/wool/textures/wool_cyan.png b/mods/wool/textures/wool_cyan.png index 4e1e4a3c..395b6ac7 100644 Binary files a/mods/wool/textures/wool_cyan.png and b/mods/wool/textures/wool_cyan.png differ diff --git a/mods/wool/textures/wool_dark_green.png b/mods/wool/textures/wool_dark_green.png index 92c56318..0e73999e 100644 Binary files a/mods/wool/textures/wool_dark_green.png and b/mods/wool/textures/wool_dark_green.png differ diff --git a/mods/wool/textures/wool_dark_grey.png b/mods/wool/textures/wool_dark_grey.png index 06245254..7253696e 100644 Binary files a/mods/wool/textures/wool_dark_grey.png and b/mods/wool/textures/wool_dark_grey.png differ diff --git a/mods/wool/textures/wool_green.png b/mods/wool/textures/wool_green.png index 554471a8..dcb663be 100644 Binary files a/mods/wool/textures/wool_green.png and b/mods/wool/textures/wool_green.png differ diff --git a/mods/wool/textures/wool_grey.png b/mods/wool/textures/wool_grey.png index ff38bf7c..2f4c3380 100644 Binary files a/mods/wool/textures/wool_grey.png and b/mods/wool/textures/wool_grey.png differ diff --git a/mods/wool/textures/wool_magenta.png b/mods/wool/textures/wool_magenta.png index 5b254e42..5c2c4a7a 100644 Binary files a/mods/wool/textures/wool_magenta.png and b/mods/wool/textures/wool_magenta.png differ diff --git a/mods/wool/textures/wool_orange.png b/mods/wool/textures/wool_orange.png index 64f34c00..a059f364 100644 Binary files a/mods/wool/textures/wool_orange.png and b/mods/wool/textures/wool_orange.png differ diff --git a/mods/wool/textures/wool_pink.png b/mods/wool/textures/wool_pink.png index 0513540a..8e901407 100644 Binary files a/mods/wool/textures/wool_pink.png and b/mods/wool/textures/wool_pink.png differ diff --git a/mods/wool/textures/wool_red.png b/mods/wool/textures/wool_red.png index de05af1c..da12ecff 100644 Binary files a/mods/wool/textures/wool_red.png and b/mods/wool/textures/wool_red.png differ diff --git a/mods/wool/textures/wool_violet.png b/mods/wool/textures/wool_violet.png index a41a9f47..d7d67831 100644 Binary files a/mods/wool/textures/wool_violet.png and b/mods/wool/textures/wool_violet.png differ diff --git a/mods/wool/textures/wool_white.png b/mods/wool/textures/wool_white.png index 2bbb9cf6..88f1e2f5 100644 Binary files a/mods/wool/textures/wool_white.png and b/mods/wool/textures/wool_white.png differ diff --git a/mods/wool/textures/wool_yellow.png b/mods/wool/textures/wool_yellow.png index a95bb348..2b0f0489 100644 Binary files a/mods/wool/textures/wool_yellow.png and b/mods/wool/textures/wool_yellow.png differ diff --git a/mods/xpanes/README.txt b/mods/xpanes/README.txt index b89e74a2..bcbc1294 100644 --- a/mods/xpanes/README.txt +++ b/mods/xpanes/README.txt @@ -1,16 +1,21 @@ Minetest Game mod: xpanes ========================= +See license.txt for license information. -License: --------- -Copyright (C) xyz -modified by BlockMen (iron bars) +Authors of source code +---------------------- +Originally by xyz (MIT) +BlockMen (MIT) +sofar (MIT) +Various Minetest developers and contributors (MIT) -Gambit (WTFPL): - xpanes_bar.png +Authors of media (textures) +--------------------------- +xyz (CC BY-SA 3.0): + All textures not mentioned below. -This program is free software. It comes without any warranty, to -the extent permitted by applicable law. You can redistribute it -and/or modify it under the terms of the Do What The Fuck You Want -To Public License, Version 2, as published by Sam Hocevar. See -http://sam.zoy.org/wtfpl/COPYING for more details. +Gambit (CC BY-SA 3.0): + xpanes_bar.png + +paramat (CC BY-SA 3.0): + xpanes_bar_top.png diff --git a/mods/xpanes/init.lua b/mods/xpanes/init.lua index 9189912e..77278a5c 100644 --- a/mods/xpanes/init.lua +++ b/mods/xpanes/init.lua @@ -1,156 +1,146 @@ -xpanes = {} -local function rshift(x, by) - return math.floor(x / 2 ^ by) +local function is_pane(pos) + return minetest.get_item_group(minetest.get_node(pos).name, "pane") > 0 end -local directions = { - {x = 1, y = 0, z = 0}, - {x = 0, y = 0, z = 1}, - {x = -1, y = 0, z = 0}, - {x = 0, y = 0, z = -1}, -} +local function connects_dir(pos, name, dir) + local aside = vector.add(pos, minetest.facedir_to_dir(dir)) + if is_pane(aside) then + return true + end -local function update_pane(pos, name) - if not minetest.get_node(pos).name:find("^xpanes:"..name) then + local connects_to = minetest.registered_nodes[name].connects_to + if not connects_to then + return false + end + local list = minetest.find_nodes_in_area(aside, aside, connects_to) + + if #list > 0 then + return true + end + + return false +end + +local function swap(pos, node, name, param2) + if node.name == name and node.param2 == param2 then return end - local sum = 0 - for i, dir in pairs(directions) do - local node = minetest.get_node(vector.add(pos, dir)) - local def = minetest.registered_nodes[node.name] - local pane_num = def and def.groups.pane or 0 - if pane_num > 0 or not def or (def.walkable ~= false and - def.drawtype ~= "nodebox") then - sum = sum + 2 ^ (i - 1) + + minetest.set_node(pos, {name = name, param2 = param2}) +end + +local function update_pane(pos) + if not is_pane(pos) then + return + end + local node = minetest.get_node(pos) + local name = node.name + if name:sub(-5) == "_flat" then + name = name:sub(1, -6) + end + + local any = node.param2 + local c = {} + local count = 0 + for dir = 0, 3 do + c[dir] = connects_dir(pos, name, dir) + if c[dir] then + any = dir + count = count + 1 end end - if sum == 0 then - sum = 15 - end - minetest.set_node(pos, {name = "xpanes:"..name.."_"..sum}) -end -local function update_nearby(pos, node) - node = node or minetest.get_node(pos) - local name = node.name - if not name or node.name:sub(1, 7) ~= "xpanes:" then - return - end - local underscore_pos = string.find(name, "_[^_]*$") or 0 - local len = name:len() - local num = tonumber(name:sub(underscore_pos+1, len)) - if not num or num < 1 or num > 15 then - name = name:sub(8) + if count == 0 then + swap(pos, node, name .. "_flat", any) + elseif count == 1 then + swap(pos, node, name .. "_flat", (any + 1) % 4) + elseif count == 2 then + if (c[0] and c[2]) or (c[1] and c[3]) then + swap(pos, node, name .. "_flat", (any + 1) % 4) + else + swap(pos, node, name, 0) + end else - name = name:sub(8, underscore_pos - 1) - end - for i, dir in pairs(directions) do - update_pane(vector.add(pos, dir), name) + swap(pos, node, name, 0) end end -minetest.register_on_placenode(update_nearby) -minetest.register_on_dignode(update_nearby) +minetest.register_on_placenode(function(pos, node) + if minetest.get_item_group(node, "pane") then + update_pane(pos) + end + for i = 0, 3 do + local dir = minetest.facedir_to_dir(i) + update_pane(vector.add(pos, dir)) + end +end) -local half_boxes = { - {0, -0.5, -1/32, 0.5, 0.5, 1/32}, - {-1/32, -0.5, 0, 1/32, 0.5, 0.5}, - {-0.5, -0.5, -1/32, 0, 0.5, 1/32}, - {-1/32, -0.5, -0.5, 1/32, 0.5, 0} -} - -local full_boxes = { - {-0.5, -0.5, -1/32, 0.5, 0.5, 1/32}, - {-1/32, -0.5, -0.5, 1/32, 0.5, 0.5} -} - -local sb_half_boxes = { - {0, -0.5, -0.06, 0.5, 0.5, 0.06}, - {-0.06, -0.5, 0, 0.06, 0.5, 0.5}, - {-0.5, -0.5, -0.06, 0, 0.5, 0.06}, - {-0.06, -0.5, -0.5, 0.06, 0.5, 0} -} - -local sb_full_boxes = { - {-0.5, -0.5, -0.06, 0.5, 0.5, 0.06}, - {-0.06, -0.5, -0.5, 0.06, 0.5, 0.5} -} - -local pane_def_fields = { - drawtype = "airlike", - paramtype = "light", - is_ground_content = false, - sunlight_propagates = true, - walkable = false, - pointable = false, - diggable = false, - buildable_to = true, - air_equivalent = true, -} +minetest.register_on_dignode(function(pos) + for i = 0, 3 do + local dir = minetest.facedir_to_dir(i) + update_pane(vector.add(pos, dir)) + end +end) +xpanes = {} function xpanes.register_pane(name, def) for i = 1, 15 do - local need = {} - local cnt = 0 - for j = 1, 4 do - if rshift(i, j - 1) % 2 == 1 then - need[j] = true - cnt = cnt + 1 - end - end - local take = {} - local take2 = {} - if need[1] == true and need[3] == true then - need[1] = nil - need[3] = nil - table.insert(take, full_boxes[1]) - table.insert(take2, sb_full_boxes[1]) - end - if need[2] == true and need[4] == true then - need[2] = nil - need[4] = nil - table.insert(take, full_boxes[2]) - table.insert(take2, sb_full_boxes[2]) - end - for k in pairs(need) do - table.insert(take, half_boxes[k]) - table.insert(take2, sb_half_boxes[k]) - end - local texture = def.textures[1] - if cnt == 1 then - texture = def.textures[1].."^"..def.textures[2] - end - minetest.register_node(":xpanes:"..name.."_"..i, { - drawtype = "nodebox", - tiles = {def.textures[3], def.textures[3], texture}, - paramtype = "light", - groups = def.groups, - drop = "xpanes:"..name, - sounds = def.sounds, - node_box = { - type = "fixed", - fixed = take - }, - selection_box = { - type = "fixed", - fixed = take2 - } - }) + minetest.register_alias("xpanes:" .. name .. "_" .. i, "xpanes:" .. name .. "_flat") end - for k, v in pairs(pane_def_fields) do - def[k] = def[k] or v - end + local flatgroups = table.copy(def.groups) + flatgroups.pane = 1 + minetest.register_node(":xpanes:" .. name .. "_flat", { + description = def.description, + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + sunlight_propagates = true, + inventory_image = def.inventory_image, + wield_image = def.wield_image, + paramtype2 = "facedir", + tiles = {def.textures[3], def.textures[3], def.textures[1]}, + groups = flatgroups, + drop = "xpanes:" .. name .. "_flat", + sounds = def.sounds, + node_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}}, + }, + selection_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}}, + }, + connect_sides = { "left", "right" }, + }) - def.on_construct = function(pos) - update_pane(pos, name) - end - - minetest.register_node(":xpanes:"..name, def) + local groups = table.copy(def.groups) + groups.pane = 1 + groups.not_in_creative_inventory = 1 + minetest.register_node(":xpanes:" .. name, { + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + sunlight_propagates = true, + description = def.description, + tiles = {def.textures[3], def.textures[3], def.textures[1]}, + groups = groups, + drop = "xpanes:" .. name .. "_flat", + sounds = def.sounds, + node_box = { + type = "connected", + fixed = {{-1/32, -1/2, -1/32, 1/32, 1/2, 1/32}}, + connect_front = {{-1/32, -1/2, -1/2, 1/32, 1/2, -1/32}}, + connect_left = {{-1/2, -1/2, -1/32, -1/32, 1/2, 1/32}}, + connect_back = {{-1/32, -1/2, 1/32, 1/32, 1/2, 1/2}}, + connect_right = {{1/32, -1/2, -1/32, 1/2, 1/2, 1/32}}, + }, + connects_to = {"group:pane", "group:stone", "group:glass", "group:wood", "group:tree"}, + }) minetest.register_craft({ - output = "xpanes:"..name.." 16", + output = "xpanes:" .. name .. "_flat 16", recipe = def.recipe }) end @@ -161,7 +151,7 @@ xpanes.register_pane("pane", { inventory_image = "default_glass.png", wield_image = "default_glass.png", sounds = default.node_sound_glass_defaults(), - groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1}, + groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3}, recipe = { {"default:glass", "default:glass", "default:glass"}, {"default:glass", "default:glass", "default:glass"} @@ -170,14 +160,25 @@ xpanes.register_pane("pane", { xpanes.register_pane("bar", { description = "Iron bar", - textures = {"xpanes_bar.png","xpanes_bar.png","xpanes_space.png"}, + textures = {"xpanes_bar.png","xpanes_bar.png","xpanes_bar_top.png"}, inventory_image = "xpanes_bar.png", wield_image = "xpanes_bar.png", - groups = {cracky=2, pane=1}, - sounds = default.node_sound_stone_defaults(), + groups = {cracky=2}, + sounds = default.node_sound_metal_defaults(), recipe = { {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} } }) +minetest.register_lbm({ + name = "xpanes:gen2", + nodenames = {"group:pane"}, + action = function(pos, node) + update_pane(pos) + for i = 0, 3 do + local dir = minetest.facedir_to_dir(i) + update_pane(vector.add(pos, dir)) + end + end +}) diff --git a/mods/xpanes/license.txt b/mods/xpanes/license.txt new file mode 100644 index 00000000..dff72274 --- /dev/null +++ b/mods/xpanes/license.txt @@ -0,0 +1,64 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 xyz +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2016 Auke Kok +Copyright (C) 2014-2016 Various Minetest developers and contributors + +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) 2014-2016 xyz +Copyright (C) 2013-2016 Gambit +Copyright (C) 2016 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/xpanes/textures/xpanes_bar.png b/mods/xpanes/textures/xpanes_bar.png index 4d17ceb8..3ea62a93 100644 Binary files a/mods/xpanes/textures/xpanes_bar.png and b/mods/xpanes/textures/xpanes_bar.png differ diff --git a/mods/xpanes/textures/xpanes_bar_top.png b/mods/xpanes/textures/xpanes_bar_top.png new file mode 100644 index 00000000..887518aa Binary files /dev/null and b/mods/xpanes/textures/xpanes_bar_top.png differ diff --git a/mods/xpanes/textures/xpanes_grey.png b/mods/xpanes/textures/xpanes_grey.png deleted file mode 100644 index e1c6f76f..00000000 Binary files a/mods/xpanes/textures/xpanes_grey.png and /dev/null differ diff --git a/mods/xpanes/textures/xpanes_white.png b/mods/xpanes/textures/xpanes_white.png index 777bd606..a2f4b636 100644 Binary files a/mods/xpanes/textures/xpanes_white.png and b/mods/xpanes/textures/xpanes_white.png differ diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 00000000..eeea0bfc --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,45 @@ +# This file contains settings of minetest_game that can be changed in +# minetest.conf + +# In creative mode players are able to dig all kind of blocks nearly +# instantly, and have access to unlimited resources. +# Some of the functionality is only available if this setting is present +# at startup. +creative_mode (Creative mode) bool false + +# Flammable nodes will be ignited by nearby igniters. Spreading fire may +# cause severe destruction. +# Spreading fire nodes will disappear when fire is disabled, but +# 'permanent_flame' nodes are unaffected. +enable_fire (Fire) bool true + +# Enable flame sound. +flame_sound (Flame sound) bool true + +# If enabled, steel tools, torches and cobblestone will be given to new +# players. +give_initial_stuff (Give initial items) bool false + +# If enabled, players respawn at the bed they last lay on instead of normal +# spawn. +# This setting is only read at startup. +enable_bed_respawn (Respawn at bed) bool true + +# If enabled, the night can be skipped if more than half of the players are +# in beds. +enable_bed_night_skip (Skip night when sleeping) bool true + +# When TNT explodes, it destroys nearby nodes and damages nearby players. +# This setting is disabled by default on servers. +enable_tnt (TNT) bool true + +# The radius in which nodes will be destroyed by a TNT explosion. +tnt_radius (TNT radius) int 3 0 + +# The time in seconds after which the bones of a dead player can be looted +# by everyone. +# Setting this to 0 will disable sharing of bones completely. +share_bones_time (Bone share time) int 1200 0 + +# Replaces old stairs with new ones. Only required for older worlds. +enable_stairs_replace_abm (Replace old stairs) bool false