Merge tag '0.4.15' into stable-0.4

0.4.15
This commit is contained in:
sfan5 2016-12-22 23:00:57 +01:00
commit 437860feff
236 changed files with 7044 additions and 2573 deletions

29
.gitignore vendored

@ -1,9 +1,22 @@
## Generic ignorable patterns and files
*~
.*.swp
*bak*
tags
*.vim
## Files related to minetest development cycle ## 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/*

17
.luacheckrc Normal file

@ -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

12
.travis.yml Normal file

@ -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

@ -12,22 +12,28 @@ Please note:
* [XYZ] refers to a section the Minetest API * [XYZ] refers to a section the Minetest API
* [#ABC] refers to a section in this document * [#ABC] refers to a section in this document
* [pos] refers to a position table `{x = -5, y = 0, z = 200}`
Bucket API Bucket API
---------- ----------
The bucket API allows registering new types of buckets for non-default liquids. The bucket API allows registering new types of buckets for non-default liquids.
bucket.register_liquid( bucket.register_liquid(
"default:lava_source", -- name of the source node "default:lava_source", -- name of the source node
"default:lava_flowing", -- name of the flowing 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: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) "bucket_lava.png", -- texture of the new bucket item (ignored if itemname == nil)
"Lava Bucket", -- text description of the bucket item "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 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 Doors API
--------- ---------
@ -177,6 +198,9 @@ The farming API allows you to easily register plants and hoes.
`farming.register_plant(name, Plant definition)` `farming.register_plant(name, Plant definition)`
* Register a new growing plant, see [#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 ### Hoe Definition
@ -213,6 +237,14 @@ New node def property:
* Called when fire attempts to remove a burning node. * Called when fire attempts to remove a burning node.
* `pos` Position of the 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 Give Initial Stuff API
---------------------- ----------------------
@ -244,6 +276,18 @@ Give Initial Stuff API
^ str is a comma separated list of initial stuff ^ str is a comma separated list of initial stuff
^ Adds items to the list of items to be given ^ 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 TNT API
---------- ----------
@ -272,9 +316,9 @@ TNT API
* `position` The center of explosion. * `position` The center of explosion.
* `definition` The TNT definion as passed to `tnt.register` * `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 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 * `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 * 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) 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 * 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 Stairs API
---------- ----------
@ -343,7 +505,7 @@ delivered with Minetest Game, to keep them compatible with other mods.
* Registers a stair. * Registers a stair.
* `subname`: Basically the material name (e.g. cobble) used for the stair name. Nodename pattern: "stairs:stair_subname" * `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] * `groups`: see [Known damage and digging time defining groups]
* `images`: see [Tile definition] * `images`: see [Tile definition]
* `description`: used for the description field in the stair's 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 ### 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] groups = {group = rating}, -- Uses the known node groups, see [Known damage and digging time defining groups]
sounds = SoundSpec, -- See [#Default sounds] sounds = SoundSpec, -- See [#Default sounds]
recipe = {{"","","","","","","","",""}}, -- Recipe field only 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_wood_defaults()`
* `default.node_sound_leaves_defaults()` * `default.node_sound_leaves_defaults()`
* `default.node_sound_glass_defaults()` * `default.node_sound_glass_defaults()`
* `default.node_sound_metal_defaults()`
Default constants Default constants
----------------- -----------------
@ -591,3 +754,83 @@ Trees
* `default.grow_new_snowy_pine_tree(pos)` * `default.grow_new_snowy_pine_tree(pos)`
* Grows a new design snowy pine tree at 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.

@ -5,6 +5,12 @@
# Whether creative mode (fast digging of all blocks, unlimited resources) should be enabled # Whether creative mode (fast digging of all blocks, unlimited resources) should be enabled
#creative_mode = false #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 # The time in seconds after which the bones of a dead player can be looted by everyone
# 0 to disable # 0 to disable
#share_bones_time = 1200 #share_bones_time = 1200
@ -14,9 +20,12 @@
# 0 to disable. By default it is "share_bones_time" divide by four. # 0 to disable. By default it is "share_bones_time" divide by four.
#share_bones_time_early = 300 #share_bones_time_early = 300
# Whether standard fire should be disabled ('basic flame' nodes will disappear) # Whether fire should be enabled. If disabled, 'basic flame' nodes will disappear.
# 'permanent flame' nodes will remain with either setting # 'permanent flame' nodes will remain with either setting.
#disable_fire = false #enable_fire = true
# Enable flame sound.
#flame_sound = true
# Whether the stuff in initial_stuff should be given to new players # Whether the stuff in initial_stuff should be given to new players
#give_initial_stuff = false #give_initial_stuff = false

@ -1,30 +1,26 @@
Minetest Game mod: beds 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 Authors of media (textures)
~~~~~ ---------------------------
This mod adds a bed to Minetest which allows to skip the night. To sleep rightclick the bed, if playing BlockMen (CC BY-SA 3.0)
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.
Another feature is a controled respawning. If you have slept in bed (not just lying in it) your respawn point This mod adds a bed to Minetest which allows to skip the night.
is set to the beds location and you will respawn there after death. To sleep, rightclick the bed. If playing in singleplayer mode the night gets skipped
You can disable the respawn at beds by setting "enable_bed_respawn = false" in minetest.conf immediately. If playing multiplayer you get shown how many other players are in bed too,
You can also disable the night skip feature by setting "enable_bed_night_skip = false" in minetest.conf or by using if all players are sleeping the night gets skipped. The night skip can be forced if more
the /set command ingame. than 50% of the players are lying in bed and use this option.
Another feature is a controlled respawning. If you have slept in bed (not just lying in
License of source code, textures: WTFPL it) your respawn point is set to the beds location and you will respawn there after
--------------------------------------- death.
(c) Copyright BlockMen (2014-2015) 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
This program is free software. It comes without any warranty, to minetest.conf or by using the /set command in-game.
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.

@ -16,7 +16,7 @@ local function destruct_bed(pos, n)
if reverse then if reverse then
reverse = not reverse reverse = not reverse
minetest.remove_node(other) minetest.remove_node(other)
nodeupdate(other) minetest.check_for_falling(other)
else else
reverse = not reverse reverse = not reverse
end end
@ -33,7 +33,7 @@ function beds.register_bed(name, def)
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false, is_ground_content = false,
stack_max = 1, 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(), sounds = default.node_sound_wood_defaults(),
node_box = { node_box = {
type = "fixed", type = "fixed",
@ -59,8 +59,8 @@ function beds.register_bed(name, def)
return itemstack return itemstack
end end
local def = minetest.registered_nodes[minetest.get_node(pos).name] local node_def = minetest.registered_nodes[minetest.get_node(pos).name]
if not def or not def.buildable_to then if not node_def or not node_def.buildable_to then
return itemstack return itemstack
end end
@ -91,8 +91,9 @@ function beds.register_bed(name, def)
destruct_bed(pos, 1) destruct_bed(pos, 1)
end, end,
on_rightclick = function(pos, node, clicker) on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
beds.on_rightclick(pos, clicker) beds.on_rightclick(pos, clicker)
return itemstack
end, end,
on_rotate = function(pos, node, user, mode, new_param2) on_rotate = function(pos, node, user, mode, new_param2)
@ -112,8 +113,8 @@ function beds.register_bed(name, def)
end end
local newp = vector.add(pos, minetest.facedir_to_dir(new_param2)) local newp = vector.add(pos, minetest.facedir_to_dir(new_param2))
local node3 = minetest.get_node_or_nil(newp) local node3 = minetest.get_node_or_nil(newp)
local def = node3 and minetest.registered_nodes[node3.name] local node_def = node3 and minetest.registered_nodes[node3.name]
if not def or not def.buildable_to then if not node_def or not node_def.buildable_to then
return false return false
end end
if minetest.is_protected(newp, user:get_player_name()) then if minetest.is_protected(newp, user:get_player_name()) then
@ -136,7 +137,7 @@ function beds.register_bed(name, def)
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false, is_ground_content = false,
pointable = 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(), sounds = default.node_sound_wood_defaults(),
drop = name .. "_bottom", drop = name .. "_bottom",
node_box = { node_box = {

@ -66,7 +66,7 @@ beds.register_bed("beds:bed", {
}, },
top = { top = {
"beds_bed_top_top.png^[transformR90", "beds_bed_top_top.png^[transformR90",
"default_wood.png", "default_wood.png",
"beds_bed_side_top_r.png", "beds_bed_side_top_r.png",
"beds_bed_side_top_r.png^[transformfx", "beds_bed_side_top_r.png^[transformfx",
"beds_bed_side_top.png", "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_bottom_red", "beds:bed_bottom")
minetest.register_alias("beds:bed_top_red", "beds:bed_top") 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,
})

@ -70,7 +70,7 @@ local function lay_down(player, pos, bed_pos, state, skip)
-- physics, eye_offset, etc -- physics, eye_offset, etc
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) 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 default.player_attached[name] = false
player:set_physics_override(1, 1, 1) player:set_physics_override(1, 1, 1)
hud_flags.wielditem = true hud_flags.wielditem = true
@ -85,7 +85,7 @@ local function lay_down(player, pos, bed_pos, state, skip)
-- physics, eye_offset, etc -- physics, eye_offset, etc
player:set_eye_offset({x = 0, y = -13, z = 0}, {x = 0, y = 0, z = 0}) player:set_eye_offset({x = 0, y = -13, z = 0}, {x = 0, y = 0, z = 0})
local yaw, param2 = get_look_yaw(bed_pos) 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 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} 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) player:set_physics_override(0, 0, 0)
@ -100,7 +100,7 @@ end
local function update_formspecs(finished) local function update_formspecs(finished)
local ges = #minetest.get_connected_players() local ges = #minetest.get_connected_players()
local form_n = "" local form_n
local is_majority = (ges / 2) < player_in_bed local is_majority = (ges / 2) < player_in_bed
if finished then if finished then
@ -130,7 +130,6 @@ end
function beds.skip_night() function beds.skip_night()
minetest.set_timeofday(0.23) minetest.set_timeofday(0.23)
beds.set_spawns()
end end
function beds.on_rightclick(pos, player) function beds.on_rightclick(pos, player)
@ -149,6 +148,7 @@ function beds.on_rightclick(pos, player)
-- move to bed -- move to bed
if not beds.player[name] then if not beds.player[name] then
lay_down(player, ppos, pos) lay_down(player, ppos, pos)
beds.set_spawns() -- save respawn positions when entering bed
else else
lay_down(player, nil, nil, false) lay_down(player, nil, nil, false)
end end
@ -173,23 +173,18 @@ end
-- Callbacks -- Callbacks
-- Only register respawn callback if respawn enabled
minetest.register_on_joinplayer(function(player) if enable_respawn then
beds.read_spawns() -- respawn player at bed if enabled and valid position is found
end) minetest.register_on_respawnplayer(function(player)
local name = player:get_player_name()
-- respawn player at bed if enabled and valid position is found local pos = beds.spawn[name]
minetest.register_on_respawnplayer(function(player) if pos then
if not enable_respawn then player:setpos(pos)
return false return true
end end
local name = player:get_player_name() end)
local pos = beds.spawn[name] or nil end
if pos then
player:setpos(pos)
return true
end
end)
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name() local name = player:get_player_name()

60
mods/beds/license.txt Normal file

@ -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/

@ -32,11 +32,11 @@ function beds.read_spawns()
beds.save_spawns() beds.save_spawns()
os.rename(file, file .. ".backup") os.rename(file, file .. ".backup")
file = org_file file = org_file
else
spawns = {}
end end
end end
beds.read_spawns()
function beds.save_spawns() function beds.save_spawns()
if not beds.spawn then if not beds.spawn then
return return

@ -1,16 +1,15 @@
Minetest Game mod: boats Minetest Game mod: boats
======================== ========================
by PilzAdam See license.txt for license information.
License of source code: Authors of source code
----------------------- ----------------------
WTFPL Originally by PilzAdam (MIT)
Various Minetest developers and contributors (MIT)
License of media (textures and sounds): Authors of media (textures and model)
--------------------------------------- -------------------------------------
WTFPL Textures: Zeg9 (CC BY-SA 3.0)
Model: thetoon and Zeg9 (CC BY-SA 3.0),
Authors of media files: modified by PavelS(SokolovPavel) (CC BY-SA 3.0),
----------------------- modified by sofar (CC BY-SA 3.0)
textures: Zeg9
model: thetoon and Zeg9, modified by PavelS(SokolovPavel)

@ -34,6 +34,8 @@ end
local boat = { local boat = {
physical = true, 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}, collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
visual = "mesh", visual = "mesh",
mesh = "boats_boat.obj", mesh = "boats_boat.obj",
@ -77,7 +79,7 @@ function boat.on_rightclick(self, clicker)
minetest.after(0.2, function() minetest.after(0.2, function()
default.player_set_animation(clicker, "sit" , 30) default.player_set_animation(clicker, "sit" , 30)
end) end)
self.object:setyaw(clicker:get_look_yaw() - math.pi / 2) clicker:set_look_horizontal(self.object:getyaw())
end end
end end
@ -107,18 +109,19 @@ function boat.on_punch(self, puncher)
end end
if not self.driver then if not self.driver then
self.removed = true 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 -- delay remove to ensure player is detached
minetest.after(0.1, function() minetest.after(0.1, function()
self.object:remove() self.object:remove()
end) 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
end end
@ -165,7 +168,7 @@ function boat.on_step(self, dtime)
local p = self.object:getpos() local p = self.object:getpos()
p.y = p.y - 0.5 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} local new_acce = {x = 0, y = 0, z = 0}
if not is_water(p) then if not is_water(p) then
local nodedef = minetest.registered_nodes[minetest.get_node(p).name] 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_image = "boats_wield.png",
wield_scale = {x = 2, y = 2, z = 1}, wield_scale = {x = 2, y = 2, z = 1},
liquids_pointable = true, liquids_pointable = true,
groups = {flammable = 2},
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then if pointed_thing.type ~= "node" then
return return itemstack
end end
if not is_water(pointed_thing.under) then if not is_water(pointed_thing.under) then
return return itemstack
end end
pointed_thing.under.y = pointed_thing.under.y + 0.5 pointed_thing.under.y = pointed_thing.under.y + 0.5
minetest.add_entity(pointed_thing.under, "boats:boat") boat = minetest.add_entity(pointed_thing.under, "boats:boat")
if not minetest.setting_getbool("creative_mode") then if boat then
itemstack:take_item() boat:setyaw(placer:get_look_horizontal())
if not minetest.setting_getbool("creative_mode") then
itemstack:take_item()
end
end end
return itemstack return itemstack
end, end,
@ -245,3 +252,9 @@ minetest.register_craft({
{"group:wood", "group:wood", "group:wood"}, {"group:wood", "group:wood", "group:wood"},
}, },
}) })
minetest.register_craft({
type = "fuel",
recipe = "boats:boat",
burntime = 20,
})

63
mods/boats/license.txt Normal file

@ -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/

@ -1,17 +1,12 @@
Minetest Game mod: bones Minetest Game mod: bones
======================== ========================
See license.txt for license information.
License of source code: Authors 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
---------------------- ----------------------
Bad_Command_ Originally by PilzAdam (MIT)
Various Minetest developers and contributors (MIT)
Authors of media (textures)
---------------------------
All textures: paramat (CC BY-SA 3.0)

@ -1,7 +1,5 @@
-- Minetest 0.4 mod: bones -- Minetest 0.4 mod: bones
-- See README.txt for licensing and other information. -- See README.txt for licensing and other information.
bones = {}
local function is_owner(pos, name) local function is_owner(pos, name)
local owner = minetest.get_meta(pos):get_string("owner") local owner = minetest.get_meta(pos):get_string("owner")
@ -11,7 +9,7 @@ local function is_owner(pos, name)
return false return false
end end
bones.bones_formspec = local bones_formspec =
"size[8,9]" .. "size[8,9]" ..
default.gui_bg .. default.gui_bg ..
default.gui_bg_img .. 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", { minetest.register_node("bones:bones", {
description = "Bones", description = "Bones",
tiles = { tiles = {
"bones_top.png", "bones_top.png^[transform2",
"bones_bottom.png", "bones_bottom.png",
"bones_side.png", "bones_side.png",
"bones_side.png", "bones_side.png",
@ -37,12 +35,9 @@ minetest.register_node("bones:bones", {
"bones_front.png" "bones_front.png"
}, },
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {dig_immediate=2}, groups = {dig_immediate = 2},
sounds = default.node_sound_dirt_defaults({ sounds = default.node_sound_gravel_defaults(),
footstep = {name="default_gravel_footstep", gain=0.5},
dug = {name="default_gravel_footstep", gain=1.0},
}),
can_dig = function(pos, player) can_dig = function(pos, player)
local inv = minetest.get_meta(pos):get_inventory() local inv = minetest.get_meta(pos):get_inventory()
local name = "" local name = ""
@ -51,46 +46,46 @@ minetest.register_node("bones:bones", {
end end
return is_owner(pos, name) and inv:is_empty("main") return is_owner(pos, name) and inv:is_empty("main")
end, end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) 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 if is_owner(pos, player:get_player_name()) then
return count return count
end end
return 0 return 0
end, end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player) allow_metadata_inventory_put = function(pos, listname, index, stack, player)
return 0 return 0
end, end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player) allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if is_owner(pos, player:get_player_name()) then if is_owner(pos, player:get_player_name()) then
return stack:get_count() return stack:get_count()
end end
return 0 return 0
end, end,
on_metadata_inventory_take = function(pos, listname, index, stack, player) on_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if meta:get_inventory():is_empty("main") then if meta:get_inventory():is_empty("main") then
minetest.remove_node(pos) minetest.remove_node(pos)
end end
end, end,
on_punch = function(pos, node, player) 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 return
end end
if(minetest.get_meta(pos):get_string("infotext") == "") then if minetest.get_meta(pos):get_string("infotext") == "" then
return return
end end
local inv = minetest.get_meta(pos):get_inventory() local inv = minetest.get_meta(pos):get_inventory()
local player_inv = player:get_inventory() local player_inv = player:get_inventory()
local has_space = true 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) local stk = inv:get_stack("main", i)
if player_inv:room_for_item("main", stk) then if player_inv:room_for_item("main", stk) then
inv:set_stack("main", i, nil) inv:set_stack("main", i, nil)
@ -100,7 +95,7 @@ minetest.register_node("bones:bones", {
break break
end end
end end
-- remove bones if player emptied them -- remove bones if player emptied them
if has_space then if has_space then
if player_inv:room_for_item("main", {name = "bones:bones"}) 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) minetest.remove_node(pos)
end end
end, end,
on_timer = function(pos, elapsed) on_timer = function(pos, elapsed)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local time = meta:get_int("time") + elapsed local time = meta:get_int("time") + elapsed
if time >= share_bones_time then 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", "") meta:set_string("owner", "")
else else
meta:set_int("time", time) 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_name = minetest.get_node(pos).name
local node_definition = minetest.registered_nodes[node_name] local node_definition = minetest.registered_nodes[node_name]
-- if the node is unknown, we let the protection mod decide -- if the node is unknown, we return false
-- 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 not node_definition then if not node_definition then
-- only replace nodes that are not protected return false
return not minetest.is_protected(pos, player:get_player_name())
end end
-- allow replacing air and liquids -- 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()) return node_definition.buildable_to and not minetest.is_protected(pos, player:get_player_name())
end 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) 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 return
end end
local player_inv = player:get_inventory() local player_inv = player:get_inventory()
if player_inv:is_empty("main") and if player_inv:is_empty("main") and
player_inv:is_empty("craft") then player_inv:is_empty("craft") then
return return
end end
local pos = player:getpos() local pos = vector.round(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 player_name = player:get_player_name() local player_name = player:get_player_name()
local player_inv = player:get_inventory()
if (not may_replace(pos, player)) then -- check if it's possible to place bones, if not find space near player
if (may_replace({x=pos.x, y=pos.y+1, z=pos.z}, player)) then if bones_mode == "bones" and not may_replace(pos, player) then
-- drop one node above if there's space local air = minetest.find_node_near(pos, 1, {"air"})
-- this should solve most cases of protection related deaths in which players dig straight down if air and not minetest.is_protected(air, player_name) then
-- yet keeps the bones reachable pos = air
pos.y = pos.y+1
else else
-- drop items instead of delete bones_mode = "drop"
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
end end
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 meta = minetest.get_meta(pos)
local inv = meta:get_inventory() 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")) 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) local stack = player_inv:get_stack("craft", i)
if inv:room_for_item("main", stack) then if inv:room_for_item("main", stack) then
inv:add_item("main", stack) inv:add_item("main", stack)
else else
--drop if no space left --drop if no space left
minetest.add_item(pos, stack) drop(pos, stack)
end end
end end
player_inv:set_list("main", {}) player_inv:set_list("main", {})
player_inv:set_list("craft", {}) player_inv:set_list("craft", {})
meta:set_string("formspec", bones.bones_formspec) meta:set_string("formspec", bones_formspec)
meta:set_string("owner", player_name) meta:set_string("owner", player_name)
if share_bones_time ~= 0 then 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 if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then
meta:set_int("time", 0) meta:set_int("time", 0)

58
mods/bones/license.txt Normal file

@ -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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 B

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

After

Width:  |  Height:  |  Size: 662 B

@ -1,26 +1,13 @@
Minetest Game mod: bucket Minetest Game mod: bucket
========================= =========================
See license.txt for license information.
License of source code: Authors of source code
----------------------- ----------------------
Copyright (C) 2011-2012 Kahrl <kahrl@gmx.net> Kahrl <kahrl@gmx.net> (LGPL 2.1)
Copyright (C) 2011-2012 celeron55, Perttu Ahola <celeron55@gmail.com> celeron55, Perttu Ahola <celeron55@gmail.com> (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 <celeron55@gmail.com>
Authors of media (textures)
---------------------------
ElementW (CC BY-SA 3.0)

@ -36,12 +36,17 @@ end
-- inventory_image = texture of the new bucket item (ignored if itemname == nil) -- inventory_image = texture of the new bucket item (ignored if itemname == nil)
-- name = text description of the bucket item -- name = text description of the bucket item
-- groups = (optional) groups of the bucket item, for example {water_bucket = 1} -- 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). -- 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] = { bucket.liquids[source] = {
source = source, source = source,
flowing = flowing, flowing = flowing,
itemname = itemname, itemname = itemname,
force_renew = force_renew,
} }
bucket.liquids[flowing] = bucket.liquids[source] bucket.liquids[flowing] = bucket.liquids[source]
@ -52,54 +57,53 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name
stack_max = 1, stack_max = 1,
liquids_pointable = true, liquids_pointable = true,
groups = groups, groups = groups,
on_place = function(itemstack, user, pointed_thing) on_place = function(itemstack, user, pointed_thing)
-- Must be pointing to node -- Must be pointing to node
if pointed_thing.type ~= "node" then if pointed_thing.type ~= "node" then
return return
end end
local node = minetest.get_node_or_nil(pointed_thing.under) local node = minetest.get_node_or_nil(pointed_thing.under)
local ndef local ndef = node and minetest.registered_nodes[node.name]
if node then
ndef = minetest.registered_nodes[node.name]
end
-- Call on_rightclick if the pointed node defines it -- Call on_rightclick if the pointed node defines it
if ndef and ndef.on_rightclick and if ndef and ndef.on_rightclick and
user and not user:get_player_control().sneak then user and not user:get_player_control().sneak then
return ndef.on_rightclick( return ndef.on_rightclick(
pointed_thing.under, pointed_thing.under,
node, user, node, user,
itemstack) or itemstack itemstack)
end end
local place_liquid = function(pos, node, source, flowing) local lpos
if check_protection(pos,
user and user:get_player_name() or "",
"place "..source) then
return
end
minetest.add_node(pos, {name=source})
end
-- Check if pointing to a buildable node -- Check if pointing to a buildable node
if ndef and ndef.buildable_to then if ndef and ndef.buildable_to then
-- buildable; replace the node -- buildable; replace the node
place_liquid(pointed_thing.under, node, lpos = pointed_thing.under
source, flowing)
else else
-- not buildable to; place the liquid above -- not buildable to; place the liquid above
-- check if the node above can be replaced -- 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 lpos = pointed_thing.above
place_liquid(pointed_thing.above, node = minetest.get_node_or_nil(lpos)
node, source, local above_ndef = node and minetest.registered_nodes[node.name]
flowing)
else if not above_ndef or not above_ndef.buildable_to then
-- do not remove the bucket with the liquid -- do not remove the bucket with the liquid
return return itemstack
end end
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
}) })
end end
@ -111,8 +115,11 @@ minetest.register_craftitem("bucket:bucket_empty", {
stack_max = 99, stack_max = 99,
liquids_pointable = true, liquids_pointable = true,
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
-- Must be pointing to node if pointed_thing.type == "object" then
if pointed_thing.type ~= "node" 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 return
end end
-- Check if pointing to a liquid source -- Check if pointing to a liquid source
@ -142,7 +149,7 @@ minetest.register_craftitem("bucket:bucket_empty", {
else else
local pos = user:getpos() local pos = user:getpos()
pos.y = math.floor(pos.y + 0.5) pos.y = math.floor(pos.y + 0.5)
core.add_item(pos, liquiddef.itemname) minetest.add_item(pos, liquiddef.itemname)
end end
-- set to return empty buckets minus 1 -- set to return empty buckets minus 1
@ -150,9 +157,24 @@ minetest.register_craftitem("bucket:bucket_empty", {
end 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) 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
end, end,
}) })
@ -172,7 +194,8 @@ bucket.register_liquid(
"bucket:bucket_river_water", "bucket:bucket_river_water",
"bucket_river_water.png", "bucket_river_water.png",
"River Water Bucket", "River Water Bucket",
{water_bucket = 1} {water_bucket = 1},
true
) )
bucket.register_liquid( bucket.register_liquid(

51
mods/bucket/license.txt Normal file

@ -0,0 +1,51 @@
License of source code
----------------------
GNU Lesser General Public License, version 2.1
Copyright (C) 2011-2016 Kahrl <kahrl@gmx.net>
Copyright (C) 2011-2016 celeron55, Perttu Ahola <celeron55@gmail.com>
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/

22
mods/carts/README.txt Normal file

@ -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

392
mods/carts/cart_entity.lua Normal file

@ -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"},
},
})

1
mods/carts/depends.txt Normal file

@ -0,0 +1 @@
default

221
mods/carts/functions.lua Normal file

@ -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

20
mods/carts/init.lua Normal file

@ -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")

54
mods/carts/license.txt Normal file

@ -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

Binary file not shown.

Binary file not shown.

59
mods/carts/rails.lua Normal file

@ -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"},
}
})

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

@ -1,23 +1,12 @@
Minetest Game mod: creative Minetest Game mod: creative
=========================== ===========================
See license.txt for license information.
Implements creative mode. Authors of source code
----------------------
Switch on by using the "creative_mode" setting. Originally by Perttu Ahola (celeron55) <celeron55@gmail.com> (MIT)
Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com> (MIT)
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) <celeron55@gmail.com>
Copyright (C) 2016 Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com>
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.
Author of media (textures)
--------------------------
Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com> (CC BY-SA 3.0)

@ -1 +1,2 @@
default default
sfinv

@ -1,225 +1,14 @@
-- minetest/creative/init.lua dofile(minetest.get_modpath("creative") .. "/inventory.lua")
creative = {} if minetest.setting_getbool("creative_mode") then
local player_inventory = {} -- Dig time is modified according to difference (leveldiff) between tool
local creative_mode = minetest.setting_getbool("creative_mode") -- 'maxlevel' and node 'level'. Digtime is divided by the larger of
-- leveldiff and 1.
-- Create detached creative inventory after loading all mods -- To speed up digging in creative, hand 'maxlevel' and 'digtime' have been
creative.init_creative_inventory = function(player) -- increased such that nodes of differing levels have an insignificant
local player_name = player:get_player_name() -- effect on digtime.
player_inventory[player_name] = {} local digtime = 42
player_inventory[player_name].size = 0 local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256}
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}
minetest.register_item(":", { minetest.register_item(":", {
type = "none", type = "none",

180
mods/creative/inventory.lua Normal file

@ -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

60
mods/creative/license.txt Normal file

@ -0,0 +1,60 @@
License of source code
----------------------
The MIT License (MIT)
Copyright (C) 2012-2016 Perttu Ahola (celeron55) <celeron55@gmail.com>
Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com>
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) <jeanpatrick.guerrero@gmail.com>
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/

@ -1,28 +1,18 @@
Minetest Game mod: default Minetest Game mod: default
========================== ==========================
See license.txt for license information.
License of source code: Authors of source code
----------------------- ----------------------
Copyright (C) 2011-2012 celeron55, Perttu Ahola <celeron55@gmail.com> Originally by celeron55, Perttu Ahola <celeron55@gmail.com> (LGPL 2.1)
Various Minetest developers and contributors (LGPL 2.1)
This program is free software; you can redistribute it and/or modify Authors of media (textures, models and sounds)
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
-----------------------
Everything not listed in here: Everything not listed in here:
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com> celeron55, Perttu Ahola <celeron55@gmail.com> (CC BY-SA 3.0)
Cisoun's WTFPL texture pack: Cisoun's texture pack (CC BY-SA 3.0):
default_jungletree.png default_jungletree.png
default_lava.png default_lava.png
default_leaves.png default_leaves.png
@ -32,61 +22,57 @@ Cisoun's WTFPL texture pack:
default_tree_top.png default_tree_top.png
default_water.png default_water.png
Cisoun's conifers mod (WTFPL): Cisoun's conifers mod (CC BY-SA 3.0):
default_pine_needles.png 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.png
default_torch_on_ceiling.png default_torch_on_ceiling.png
default_torch_on_floor.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_animated.png
default_torch_on_ceiling_animated.png default_torch_on_ceiling_animated.png
default_torch_on_floor_animated.png default_torch_on_floor_animated.png
default_torch_on_floor.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_source_animated.png
default_water_flowing_animated.png default_water_flowing_animated.png
VanessaE (WTFPL): VanessaE (CC BY-SA 3.0):
default_nc_back.png
default_nc_front.png
default_nc_rb.png
default_nc_side.png
default_desert_sand.png default_desert_sand.png
default_desert_stone.png default_desert_stone.png
default_sand.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_brick.png
default_papyrus.png default_papyrus.png
default_mineral_copper.png default_mineral_copper.png
default_glass_detail.png default_glass_detail.png
MirceaKitsune (WTFPL): MirceaKitsune (CC BY-SA 3.0):
character.x character.x
Jordach (CC BY-SA 3.0): Jordach (CC BY-SA 3.0):
character.png character.png
PilzAdam (WTFPL): PilzAdam (CC BY-SA 3.0):
default_jungleleaves.png default_jungleleaves.png
default_junglesapling.png default_junglesapling.png
default_obsidian_glass.png default_obsidian_glass.png
default_obsidian_shard.png default_obsidian_shard.png
default_mineral_gold.png default_mineral_gold.png
default_snowball.png
jojoa1997 (WTFPL): jojoa1997 (CC BY-SA 3.0):
default_obsidian.png default_obsidian.png
InfinityProject (WTFPL): InfinityProject (CC BY-SA 3.0):
default_mineral_diamond.png default_mineral_diamond.png
Splizard (CC BY-SA 3.0): Splizard (CC BY-SA 3.0):
default_snow.png
default_pine_sapling.png default_pine_sapling.png
Zeg9 (CC BY-SA 3.0): Zeg9 (CC BY-SA 3.0):
@ -102,16 +88,23 @@ paramat (CC BY-SA 3.0):
default_pinetree_top.png default_pinetree_top.png
default_pinewood.png default_pinewood.png
default_acacia_leaves.png default_acacia_leaves.png
default_acacia_leaves_simple.png
default_acacia_sapling.png default_acacia_sapling.png
default_acacia_tree.png default_acacia_tree.png
default_acacia_tree_top.png default_acacia_tree_top.png
default_acacia_wood.png default_acacia_wood.png
default_acacia_bush_stem.png
default_bush_stem.png
default_junglewood.png default_junglewood.png
default_jungletree_top.png default_jungletree_top.png
default_sandstone_brick.png default_sandstone_brick.png
default_obsidian_brick.png default_obsidian_brick.png
default_stone_brick.png default_stone_brick.png
default_desert_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.png
default_river_water_source_animated.png default_river_water_source_animated.png
default_river_water_flowing_animated.png default_river_water_flowing_animated.png
@ -120,7 +113,8 @@ paramat (CC BY-SA 3.0):
default_dry_grass_*.png default_dry_grass_*.png
default_grass.png default_grass.png
default_grass_side.png default_grass_side.png
default_snow_side.png default_mese_block.png
default_silver_sand.png
brunob.santos (CC BY-SA 4.0): brunob.santos (CC BY-SA 4.0):
default_desert_cobble.png default_desert_cobble.png
@ -146,6 +140,9 @@ BlockMen (CC BY-SA 3.0):
bubble.png bubble.png
gui_*.png gui_*.png
Wuzzy (CC BY-SA 3.0):
default_bookshelf_slot.png (based on default_book.png)
sofar (CC BY-SA 3.0): sofar (CC BY-SA 3.0):
default_book_written.png, based on default_book.png default_book_written.png, based on default_book.png
default_aspen_sapling default_aspen_sapling
@ -153,18 +150,17 @@ sofar (CC BY-SA 3.0):
default_aspen_tree default_aspen_tree
default_aspen_tree_top, derived from default_pine_tree_top (by paramat) default_aspen_tree_top, derived from default_pine_tree_top (by paramat)
default_aspen_wood, derived from default_pine_wood (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 default_gravel.png -- Derived from Gambit's PixelBOX texture pack light gravel
Neuromancer (CC BY-SA 2.0): Neuromancer (CC BY-SA 2.0):
default_cobble.png, based on texture by Brane praefect default_cobble.png, based on texture by Brane praefect
default_mossycobble.png, based on texture by Brane praefect default_mossycobble.png, based on texture by Brane praefect
Neuromancer (CC BY-SA 3.0): Neuromancer (CC BY-SA 3.0):
default_dirt.png default_dirt.png
default_furnace_*.png default_furnace_*.png
Gambit (WTFPL): Gambit (CC BY-SA 3.0):
default_bronze_ingot.png default_bronze_ingot.png
default_copper_ingot.png default_copper_ingot.png
default_copper_lump.png default_copper_lump.png
@ -178,19 +174,37 @@ Gambit (WTFPL):
default_ladder_steel.png default_ladder_steel.png
default_sign_wall_wood.png default_sign_wall_wood.png
default_flint.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 default_ice.png
KevDoy (CC BY-SA 3.0) KevDoy (CC BY-SA 3.0)
heart.png 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): Glass breaking sounds (CC BY 3.0):
1: http://www.freesound.org/people/cmusounddesign/sounds/71947/ 1: http://www.freesound.org/people/cmusounddesign/sounds/71947/
2: http://www.freesound.org/people/Tomlija/sounds/97669/ 2: http://www.freesound.org/people/Tomlija/sounds/97669/
3: http://www.freesound.org/people/lsprice/sounds/88808/ 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_choppy.ogg
default_dig_cracky.ogg default_dig_cracky.ogg
default_dig_crumbly.1.ogg default_dig_crumbly.1.ogg
@ -224,3 +238,27 @@ Mito551 (sounds) (CC BY-SA):
default_dirt_footstep.1.ogg default_dirt_footstep.1.ogg
default_dirt_footstep.2.ogg default_dirt_footstep.2.ogg
default_glass_footstep.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

@ -22,7 +22,7 @@ minetest.register_alias("papyrus", "default:papyrus")
minetest.register_alias("bookshelf", "default:bookshelf") minetest.register_alias("bookshelf", "default:bookshelf")
minetest.register_alias("glass", "default:glass") minetest.register_alias("glass", "default:glass")
minetest.register_alias("wooden_fence", "default:fence_wood") 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("ladder", "default:ladder_wood")
minetest.register_alias("wood", "default:wood") minetest.register_alias("wood", "default:wood")
minetest.register_alias("mese", "default:mese") 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("cobble", "default:cobble")
minetest.register_alias("mossycobble", "default:mossycobble") minetest.register_alias("mossycobble", "default:mossycobble")
minetest.register_alias("steelblock", "default:steelblock") 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("sapling", "default:sapling")
minetest.register_alias("apple", "default:apple") 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:ladder", "default:ladder_wood")
minetest.register_alias("default:sign_wall", "default:sign_wall_wood") minetest.register_alias("default:sign_wall", "default:sign_wall_wood")

@ -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({ minetest.register_craft({
output = 'default:stick 4', output = 'default:stick 4',
recipe = { recipe = {
@ -339,11 +353,9 @@ minetest.register_craft({
}) })
minetest.register_craft({ minetest.register_craft({
output = 'default:rail 24', output = 'default:skeleton_key',
recipe = { recipe = {
{'default:steel_ingot', '', 'default:steel_ingot'}, {'default:gold_ingot'},
{'default:steel_ingot', 'group:stick', 'default:steel_ingot'},
{'default:steel_ingot', '', 'default:steel_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({ minetest.register_craft({
output = 'default:furnace', output = 'default:furnace',
recipe = { 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({ minetest.register_craft({
output = 'default:clay', output = 'default:clay',
recipe = { 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({ minetest.register_craft({
output = 'default:meselamp 1', output = 'default:meselamp 1',
recipe = { 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({ minetest.register_craft({
output = 'default:stonebrick 4', output = 'default:stonebrick 4',
recipe = { 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({ minetest.register_craft({
output = 'default:desert_stonebrick 4', output = 'default:desert_stonebrick 4',
recipe = { 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({ minetest.register_craft({
output = 'default:snowblock', output = 'default:snowblock',
recipe = { recipe = {
@ -725,16 +788,185 @@ minetest.register_craft({
recipe = "default:clay_lump", 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 -- Fuels
-- --
-- Support use of group:tree
minetest.register_craft({ minetest.register_craft({
type = "fuel", type = "fuel",
recipe = "group:tree", recipe = "group:tree",
burntime = 30, 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({ minetest.register_craft({
type = "fuel", type = "fuel",
recipe = "default:junglegrass", recipe = "default:junglegrass",
@ -765,46 +997,10 @@ minetest.register_craft({
burntime = 30, 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({ minetest.register_craft({
type = "fuel", type = "fuel",
recipe = "default:ladder_wood", recipe = "default:ladder_wood",
burntime = 5, burntime = 2,
})
minetest.register_craft({
type = "fuel",
recipe = "group:wood",
burntime = 7,
}) })
minetest.register_craft({ minetest.register_craft({
@ -837,24 +1033,6 @@ minetest.register_craft({
burntime = 30, 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({ minetest.register_craft({
type = "fuel", type = "fuel",
recipe = "default:apple", recipe = "default:apple",
@ -885,3 +1063,57 @@ minetest.register_craft({
burntime = 2, 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,
})

@ -3,19 +3,20 @@
minetest.register_craftitem("default:stick", { minetest.register_craftitem("default:stick", {
description = "Stick", description = "Stick",
inventory_image = "default_stick.png", inventory_image = "default_stick.png",
groups = {stick = 1}, groups = {stick = 1, flammable = 2},
}) })
minetest.register_craftitem("default:paper", { minetest.register_craftitem("default:paper", {
description = "Paper", description = "Paper",
inventory_image = "default_paper.png", inventory_image = "default_paper.png",
groups = {flammable = 3},
}) })
local lpp = 14 -- Lines per book's page local lpp = 14 -- Lines per book's page
local function book_on_use(itemstack, user) local function book_on_use(itemstack, user)
local player_name = user:get_player_name() local player_name = user:get_player_name()
local data = minetest.deserialize(itemstack:get_metadata()) 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, {}, "" local page, page_max, lines, string = 1, 1, {}, ""
if data then if data then
@ -38,6 +39,7 @@ local function book_on_use(itemstack, user)
end end
end end
local formspec
if owner == player_name then if owner == player_name then
formspec = "size[8,8]" .. default.gui_bg .. formspec = "size[8,8]" .. default.gui_bg ..
default.gui_bg_img .. 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 elseif fields.book_next or fields.book_prev then
local data = minetest.deserialize(stack:get_metadata()) 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 if fields.book_next then
data.page = data.page + 1 data.page = data.page + 1
@ -129,14 +133,14 @@ end)
minetest.register_craftitem("default:book", { minetest.register_craftitem("default:book", {
description = "Book", description = "Book",
inventory_image = "default_book.png", inventory_image = "default_book.png",
groups = {book = 1}, groups = {book = 1, flammable = 3},
on_use = book_on_use, on_use = book_on_use,
}) })
minetest.register_craftitem("default:book_written", { minetest.register_craftitem("default:book_written", {
description = "Book With Text", description = "Book With Text",
inventory_image = "default_book_written.png", 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, stack_max = 1,
on_use = book_on_use, on_use = book_on_use,
}) })
@ -152,7 +156,6 @@ minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv
return return
end end
local copy = ItemStack("default:book_written")
local original local original
local index local index
for i = 1, player:get_inventory():get_size("craft") do for i = 1, player:get_inventory():get_size("craft") do
@ -174,7 +177,7 @@ end)
minetest.register_craftitem("default:coal_lump", { minetest.register_craftitem("default:coal_lump", {
description = "Coal Lump", description = "Coal Lump",
inventory_image = "default_coal_lump.png", inventory_image = "default_coal_lump.png",
groups = {coal = 1} groups = {coal = 1, flammable = 1}
}) })
minetest.register_craftitem("default:iron_lump", { minetest.register_craftitem("default:iron_lump", {

@ -18,7 +18,7 @@ end
function default.node_sound_stone_defaults(table) function default.node_sound_stone_defaults(table)
table = table or {} table = table or {}
table.footstep = table.footstep 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 table.dug = table.dug or
{name = "default_hard_footstep", gain = 1.0} {name = "default_hard_footstep", gain = 1.0}
default.node_sound_defaults(table) default.node_sound_defaults(table)
@ -28,9 +28,9 @@ end
function default.node_sound_dirt_defaults(table) function default.node_sound_dirt_defaults(table)
table = table or {} table = table or {}
table.footstep = table.footstep 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 table.dug = table.dug or
{name = "default_dirt_footstep", gain = 1.5} {name = "default_dirt_footstep", gain = 1.0}
table.place = table.place or table.place = table.place or
{name = "default_place_node", gain = 1.0} {name = "default_place_node", gain = 1.0}
default.node_sound_defaults(table) default.node_sound_defaults(table)
@ -52,7 +52,7 @@ end
function default.node_sound_gravel_defaults(table) function default.node_sound_gravel_defaults(table)
table = table or {} table = table or {}
table.footstep = table.footstep 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 table.dug = table.dug or
{name = "default_gravel_footstep", gain = 1.0} {name = "default_gravel_footstep", gain = 1.0}
table.place = table.place or table.place = table.place or
@ -64,7 +64,7 @@ end
function default.node_sound_wood_defaults(table) function default.node_sound_wood_defaults(table)
table = table or {} table = table or {}
table.footstep = table.footstep 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 table.dug = table.dug or
{name = "default_wood_footstep", gain = 1.0} {name = "default_wood_footstep", gain = 1.0}
default.node_sound_defaults(table) default.node_sound_defaults(table)
@ -74,7 +74,7 @@ end
function default.node_sound_leaves_defaults(table) function default.node_sound_leaves_defaults(table)
table = table or {} table = table or {}
table.footstep = table.footstep 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 table.dug = table.dug or
{name = "default_grass_footstep", gain = 0.7} {name = "default_grass_footstep", gain = 0.7}
table.dig = table.dig or table.dig = table.dig or
@ -88,6 +88,8 @@ end
function default.node_sound_glass_defaults(table) function default.node_sound_glass_defaults(table)
table = table or {} table = table or {}
table.footstep = table.footstep 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} {name = "default_glass_footstep", gain = 0.5}
table.dug = table.dug or table.dug = table.dug or
{name = "default_break_glass", gain = 1.0} {name = "default_break_glass", gain = 1.0}
@ -95,6 +97,27 @@ function default.node_sound_glass_defaults(table)
return table return table
end 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 -- Lavacooling
@ -111,8 +134,9 @@ default.cool_lava = function(pos, node)
end end
minetest.register_abm({ minetest.register_abm({
label = "Lava cooling",
nodenames = {"default:lava_source", "default:lava_flowing"}, nodenames = {"default:lava_source", "default:lava_flowing"},
neighbors = {"group:water"}, neighbors = {"group:cools_lava", "group:water"},
interval = 1, interval = 1,
chance = 1, chance = 1,
catch_up = false, catch_up = false,
@ -125,6 +149,7 @@ minetest.register_abm({
-- --
-- optimized helper to put all items in an inventory into a drops list -- optimized helper to put all items in an inventory into a drops list
-- --
function default.get_inventory_drops(pos, inventory, drops) function default.get_inventory_drops(pos, inventory, drops)
local inv = minetest.get_meta(pos):get_inventory() local inv = minetest.get_meta(pos):get_inventory()
local n = #drops local n = #drops
@ -189,6 +214,7 @@ function default.grow_papyrus(pos, node)
end end
minetest.register_abm({ minetest.register_abm({
label = "Grow cactus",
nodenames = {"default:cactus"}, nodenames = {"default:cactus"},
neighbors = {"group:sand"}, neighbors = {"group:sand"},
interval = 12, interval = 12,
@ -199,6 +225,7 @@ minetest.register_abm({
}) })
minetest.register_abm({ minetest.register_abm({
label = "Grow papyrus",
nodenames = {"default:papyrus"}, nodenames = {"default:papyrus"},
neighbors = {"default:dirt", "default:dirt_with_grass"}, neighbors = {"default:dirt", "default:dirt_with_grass"},
interval = 14, interval = 14,
@ -226,6 +253,7 @@ end
-- --
-- Fence registration helper -- Fence registration helper
-- --
function default.register_fence(name, def) function default.register_fence(name, def)
minetest.register_craft({ minetest.register_craft({
output = name .. " 4", output = name .. " 4",
@ -283,16 +311,7 @@ end
-- Leafdecay -- Leafdecay
-- --
default.leafdecay_trunk_cache = {} -- Prevent decay of placed leaves
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)
default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) default.after_place_leaves = function(pos, placer, itemstack, pointed_thing)
if placer and not placer:get_player_control().sneak then 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
end end
minetest.register_abm({ -- Leafdecay ABM
nodenames = {"group:leafdecay"},
neighbors = {"air", "group:liquid"},
-- A low interval and a high inverse chance spreads the load
interval = 2,
chance = 5,
action = function(p0, node, _, _) minetest.register_abm({
--print("leafdecay ABM at "..p0.x..", "..p0.y..", "..p0.z..")") label = "Leaf decay",
local do_preserve = false nodenames = {"group:leafdecay"},
local d = minetest.registered_nodes[node.name].groups.leafdecay neighbors = {"air"},
if not d or d == 0 then interval = 2,
--print("not groups.leafdecay") chance = 10,
catch_up = false,
action = function(pos, node, _, _)
-- Check if leaf is placed
if node.param2 ~= 0 then
return return
end end
local n0 = minetest.get_node(p0)
if n0.param2 ~= 0 then local rad = minetest.registered_nodes[node.name].groups.leafdecay
--print("param2 ~= 0") -- 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 return
end end
local p0_hash = nil -- Drop stuff
if default.leafdecay_enable_cache then local itemstacks = minetest.get_node_drops(node.name)
p0_hash = minetest.hash_node_position(p0) for _, itemname in ipairs(itemstacks) do
local trunkp = default.leafdecay_trunk_cache[p0_hash] if itemname ~= node.name or
if trunkp then minetest.get_item_group(node.name, "leafdecay_drop") ~= 0 then
local n = minetest.get_node(trunkp) local p_drop = {
local reg = minetest.registered_nodes[n.name] x = pos.x - 0.5 + math.random(),
-- Assume ignore is a trunk, to make the thing y = pos.y - 0.5 + math.random(),
-- work at the border of the active area z = pos.z - 0.5 + math.random(),
if n.name == "ignore" or (reg and reg.groups.tree and }
reg.groups.tree ~= 0) then minetest.add_item(p_drop, itemname)
--print("cached trunk still exists")
return
end
--print("cached trunk is invalid")
-- Cache is invalid
table.remove(default.leafdecay_trunk_cache, p0_hash)
end end
end end
if default.leafdecay_trunk_find_allow_accumulator <= 0 then -- Remove node
return minetest.remove_node(pos)
end minetest.check_for_falling(pos)
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
end end
}) })
@ -384,49 +368,39 @@ minetest.register_abm({
-- --
minetest.register_abm({ minetest.register_abm({
label = "Grass spread",
nodenames = {"default:dirt"}, nodenames = {"default:dirt"},
neighbors = { neighbors = {
"default:dirt_with_grass", "air",
"default:dirt_with_dry_grass",
"default:dirt_with_snow",
"group:grass", "group:grass",
"group:dry_grass", "group:dry_grass",
"default:snow", "default:snow",
}, },
interval = 6, interval = 6,
chance = 67, chance = 50,
catch_up = false, catch_up = false,
action = function(pos, node) 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} local above = {x = pos.x, y = pos.y + 1, z = pos.z}
if (minetest.get_node_light(above) or 0) < 13 then if (minetest.get_node_light(above) or 0) < 13 then
return return
end end
-- Look for likely neighbors. -- Look for spreading dirt-type neighbours
local p2 = minetest.find_node_near(pos, 1, {"default:dirt_with_grass", local p2 = minetest.find_node_near(pos, 1, "group:spreading_dirt_type")
"default:dirt_with_dry_grass", "default:dirt_with_snow"})
if p2 then if p2 then
-- But the node needs to be under air in this case. local n3 = minetest.get_node(p2)
local n2 = minetest.get_node(above) minetest.set_node(pos, {name = n3.name})
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
return return
end end
local name = n2.name -- Else, any seeding nodes on top?
-- Snow check is cheapest, so comes first. local name = minetest.get_node(above).name
-- Snow check is cheapest, so comes first
if name == "default:snow" then if name == "default:snow" then
minetest.set_node(pos, {name = "default:dirt_with_snow"}) 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 elseif minetest.get_item_group(name, "grass") ~= 0 then
minetest.set_node(pos, {name = "default:dirt_with_grass"}) minetest.set_node(pos, {name = "default:dirt_with_grass"})
elseif minetest.get_item_group(name, "dry_grass") ~= 0 then elseif minetest.get_item_group(name, "dry_grass") ~= 0 then
@ -435,16 +409,14 @@ minetest.register_abm({
end end
}) })
-- --
-- Grass and dry grass removed in darkness -- Grass and dry grass removed in darkness
-- --
minetest.register_abm({ minetest.register_abm({
nodenames = { label = "Grass covered",
"default:dirt_with_grass", nodenames = {"group:spreading_dirt_type"},
"default:dirt_with_dry_grass",
"default:dirt_with_snow",
},
interval = 8, interval = 8,
chance = 50, chance = 50,
catch_up = false, catch_up = false,
@ -466,12 +438,77 @@ minetest.register_abm({
-- --
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"}, neighbors = {"group:water"},
interval = 16, interval = 16,
chance = 200, chance = 200,
catch_up = false, catch_up = false,
action = function(pos, node) 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 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,
})

@ -4,7 +4,7 @@
-- --
local function active_formspec(fuel_percent, item_percent) local function active_formspec(fuel_percent, item_percent)
local formspec = local formspec =
"size[8,8.5]".. "size[8,8.5]"..
default.gui_bg.. default.gui_bg..
default.gui_bg_img.. default.gui_bg_img..
@ -22,6 +22,8 @@ local function active_formspec(fuel_percent, item_percent)
"listring[current_player;main]".. "listring[current_player;main]"..
"listring[current_name;src]".. "listring[current_name;src]"..
"listring[current_player;main]".. "listring[current_player;main]"..
"listring[current_name;fuel]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25) default.get_hotbar_bg(0, 4.25)
return formspec return formspec
end end
@ -42,6 +44,8 @@ local inactive_formspec =
"listring[current_player;main]".. "listring[current_player;main]"..
"listring[current_name;src]".. "listring[current_name;src]"..
"listring[current_player;main]".. "listring[current_player;main]"..
"listring[current_name;fuel]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25) 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 fuel_totaltime = meta:get_float("fuel_totaltime") or 0
local inv = meta:get_inventory() local inv = meta:get_inventory()
local srclist = inv:get_list("src") local srclist, fuellist
local fuellist = inv:get_list("fuel")
local dstlist = inv:get_list("dst")
-- local cookable, cooked
-- Cooking local fuel
--
-- Check if we have cookable content local update = true
local cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) while update do
local cookable = true update = false
if cooked.time == 0 then srclist = inv:get_list("src")
cookable = false fuellist = inv:get_list("fuel")
end
-- Check if we have enough fuel to burn --
if fuel_time < fuel_totaltime then -- Cooking
-- The furnace is currently active and has enough fuel --
fuel_time = fuel_time + 1
-- If there is a cookable item then check if it is ready yet -- Check if we have cookable content
if cookable then local aftercooked
src_time = src_time + 1 cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
if src_time >= cooked.time then cookable = cooked.time ~= 0
-- Place result in dst list if possible
if inv:room_for_item("dst", cooked.item) then -- Check if we have enough fuel to burn
inv:add_item("dst", cooked.item) if fuel_time < fuel_totaltime then
inv:set_stack("src", 1, aftercooked.items[1]) -- The furnace is currently active and has enough fuel
src_time = 0 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 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 else
-- We don't need to get new fuel since there is no cookable item -- Furnace ran out of fuel
fuel_totaltime = 0 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 fuel_time = 0
src_time = 0
end 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 end
-- --
-- Update formspec, infotext and node -- Update formspec, infotext and node
-- --
local formspec = inactive_formspec local formspec = inactive_formspec
local item_state = "" local item_state
local item_percent = 0 local item_percent = 0
if cookable then if cookable then
item_percent = math.floor(src_time / cooked.time * 100) 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 else
if srclist[1]:is_empty() then if srclist[1]:is_empty() then
item_state = "Empty" item_state = "Empty"
@ -189,7 +212,7 @@ local function furnace_node_timer(pos, elapsed)
local active = "inactive " local active = "inactive "
local result = false local result = false
if fuel_time <= fuel_totaltime and fuel_totaltime ~= 0 then if fuel_totaltime ~= 0 then
active = "active " active = "active "
local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100) local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
fuel_state = fuel_percent .. "%" fuel_state = fuel_percent .. "%"
@ -203,8 +226,7 @@ local function furnace_node_timer(pos, elapsed)
end end
swap_node(pos, "default:furnace") swap_node(pos, "default:furnace")
-- stop timer on the inactive furnace -- stop timer on the inactive furnace
local timer = minetest.get_node_timer(pos) minetest.get_node_timer(pos):stop()
timer:stop()
end end
local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")" local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")"
@ -252,13 +274,11 @@ minetest.register_node("default:furnace", {
end, end,
on_metadata_inventory_move = function(pos) on_metadata_inventory_move = function(pos)
local timer = minetest.get_node_timer(pos) minetest.get_node_timer(pos):start(1.0)
timer:start(1.0)
end, end,
on_metadata_inventory_put = function(pos) on_metadata_inventory_put = function(pos)
-- start timer function, it will sort out whether furnace can burn or not. -- start timer function, it will sort out whether furnace can burn or not.
local timer = minetest.get_node_timer(pos) minetest.get_node_timer(pos):start(1.0)
timer:start(1.0)
end, end,
on_blast = function(pos) on_blast = function(pos)
local drops = {} local drops = {}

@ -35,14 +35,18 @@ default.gui_survival_form = "size[8,8.5]"..
default.get_hotbar_bg(0,4.25) default.get_hotbar_bg(0,4.25)
-- Load files -- Load files
dofile(minetest.get_modpath("default").."/functions.lua") local default_path = minetest.get_modpath("default")
dofile(minetest.get_modpath("default").."/nodes.lua")
dofile(minetest.get_modpath("default").."/furnace.lua") dofile(default_path.."/functions.lua")
dofile(minetest.get_modpath("default").."/tools.lua") dofile(default_path.."/trees.lua")
dofile(minetest.get_modpath("default").."/craftitems.lua") dofile(default_path.."/nodes.lua")
dofile(minetest.get_modpath("default").."/crafting.lua") dofile(default_path.."/furnace.lua")
dofile(minetest.get_modpath("default").."/mapgen.lua") dofile(default_path.."/torch.lua")
dofile(minetest.get_modpath("default").."/player.lua") dofile(default_path.."/tools.lua")
dofile(minetest.get_modpath("default").."/trees.lua") dofile(default_path.."/item_entity.lua")
dofile(minetest.get_modpath("default").."/aliases.lua") dofile(default_path.."/craftitems.lua")
dofile(minetest.get_modpath("default").."/legacy.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")

@ -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)

@ -1,6 +1,6 @@
-- mods/default/legacy.lua -- 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! -- 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) -- (More specifically, the client and the C++ code doesn't get the group)
function default.register_falling_node(nodename, texture) function default.register_falling_node(nodename, texture)

174
mods/default/license.txt Normal file

@ -0,0 +1,174 @@
License of source code
----------------------
GNU Lesser General Public License, version 2.1
Copyright (C) 2011-2016 celeron55, Perttu Ahola <celeron55@gmail.com>
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 <celeron55@gmail.com>
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/

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

@ -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

@ -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

@ -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

File diff suppressed because it is too large Load Diff

@ -25,7 +25,6 @@ default.player_register_model("character.b3d", {
walk = { x=168, y=187, }, walk = { x=168, y=187, },
mine = { x=189, y=198, }, mine = { x=189, y=198, },
walk_mine = { x=200, y=219, }, walk_mine = { x=200, y=219, },
-- Extra animations (not currently used by the game).
sit = { x= 81, y=160, }, 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_attached[player:get_player_name()] = false
default.player_set_model(player, "character.b3d") 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) player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30)
-- set GUI -- set GUI
if not minetest.setting_getbool("creative_mode") then if not minetest.setting_getbool("creative_mode") then
player:set_inventory_formspec(default.gui_survival_form) player:set_inventory_formspec(default.gui_survival_form)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More