1
0
mirror of https://github.com/minetest/minetest_game.git synced 2025-06-28 20:56:02 +02:00

76 Commits

Author SHA1 Message Date
a9ac480dcd Set number of screwdriver uses to 200 2014-12-21 22:36:20 +01:00
1237bc3a4b Don't override param2 bits that are not used for rotation in screwdriver 2014-12-20 13:06:53 +01:00
854415fd33 Fix typo in furnace.lua 2014-12-13 12:52:47 +01:00
99cfe73bbf Give 4 obsidianbrick for 4 obsidian 2014-12-12 17:15:48 +01:00
697b39d40d Only allow rotating nodes that could be dug 2014-12-12 16:14:25 +01:00
2b7ca68805 Cleanup
* Remove unused variables
* Fix wearing out of screwdriver
* Move magic numbers into constants
* Scale down texture
2014-12-12 16:14:25 +01:00
bd24c15db4 Screwdriver rewrite 2014-12-12 16:14:24 +01:00
69614dc20d Pinetree (by sfan5, from mg mapgen) lua generation and sapling ABM. Add checks for ignore to other trees 2014-12-12 16:11:42 +01:00
75dfcdb1e7 Add 3D signs 2014-12-12 16:10:30 +01:00
c332081e81 Add white to the crack texture
This makes the crack stand out better on dark textures,
like obsidian and black wool.
2014-12-12 16:06:55 +01:00
608e51f16d Add obsidianbrick
use Zeg9`s texture
2014-12-12 16:04:27 +01:00
b0fb180e4d Use an overlay over default_dirt.png for soil 2014-12-07 19:46:23 +01:00
2ebd6b3839 Correct node definitons for pine saplings and pine needles 2014-12-07 11:57:37 +01:00
5a06de184c Rewrite furnace
* Move furnace related code into furnace.lua
* Move duplicated code into functions
* Rewrite ABM:
	* Easier to follow strcuture (no returns in the middle)
	* No unnecessary calls to get_craft_result
	* Split logic and "visual feedback" (a bit)
	* Fewer calls to meta:set and meta:get
	* Better feedback on the current state of the furnace
2014-12-06 21:18:02 +01:00
957f94534b Remove remains of finite liquids from bucket mod
This reverts commit 79856c914d.
2014-12-06 20:58:03 +01:00
4ec4672f01 Remove remains of weather 2014-12-06 20:58:03 +01:00
954d64afdc Add a minetest.conf.example with all available settings 2014-12-06 20:56:52 +01:00
ef0eb4d435 Move doc for dyes to game_api.txt 2014-12-06 20:54:53 +01:00
11a7b88434 Fix visibility of global/local dye tables 2014-12-06 20:54:02 +01:00
9ec33f34f1 Set param2 to 1 if player places leaves 2014-12-06 20:36:20 +01:00
2c2edfad04 Move leafdecay doc to game_api.txt 2014-12-06 20:36:20 +01:00
22dd46dcc6 Dont dry out soil if unloaded blocks are nearby 2014-12-06 11:54:56 +01:00
20f938e44a Allow the group book to be placed into bookshelfs 2014-12-06 11:46:04 +01:00
fd34872de8 Fix possible stacking of books in bookshelf
Original author: @MT-Modder
2014-12-06 11:43:07 +01:00
31edc5a9ff Add all saplings to group sapling 2014-12-03 17:26:01 +01:00
19bdcb26f6 Add missing groups to pine sapling 2014-12-03 17:26:01 +01:00
5b7db48372 Fix various fire sound bugs 2014-12-03 16:59:36 +01:00
128f0adb24 Fix some undeclared global variables 2014-11-30 18:02:33 +01:00
6fb072e5ff Pine tree, pine needles, pine sapling and pinewood nodes, including textures by Splizard and Cisoun 2014-11-30 17:47:02 +01:00
8007c142de Added the new door textures 2014-11-30 17:34:35 +01:00
e707ba3cf1 Fix leaked globals. 2014-11-29 18:03:18 +01:00
6680a51988 New ladder texture 2014-11-23 11:54:40 +01:00
3bf3249d71 Fix leaking globals in flowers and default mapgen.lua
Signed-off-by: Craig Robbins <kde.psych@gmail.com>
2014-11-22 00:24:49 +10:00
e71b71c1a9 Default and flowers: only run on-generated functions in mgv6. Remove indev ore definitions 2014-11-16 19:38:04 +01:00
a90338d40d New flower textures 2014-11-08 23:45:18 +01:00
929559fe85 Revert "Fix fire blocking sunlight"
This reverts commit dcce6e9795.
2014-11-08 23:25:40 +01:00
c41762d211 New grass(plant) and leaves textures 2014-11-08 22:54:00 +01:00
f06d4b8547 Vessels: new textures 2014-11-08 17:39:52 +01:00
dcce6e9795 Fix fire blocking sunlight 2014-11-04 16:17:56 -05:00
d57cb0a110 Boats mod improve y motion. Smaller collision box. Reverse turn with negative velocity only. Smooth turning. Enable underwater higher acceleration 2014-10-29 10:54:39 +00:00
ba8cbbcdbd Add new ore blocks textures 2014-10-05 08:49:55 +02:00
56cc4191ca Tweak some textures, new chest texture 2014-10-03 11:29:17 +02:00
6532978a58 Add improved grass textures by @Philipbenr (slightly modified), fixes #323 2014-10-03 11:29:10 +02:00
349a63ed14 Allow only boat driver to be detached from boat (fixes #276) 2014-10-03 03:20:31 +02:00
7f44a49d99 Use new optional framed glasslike drawtype 2014-10-02 11:51:47 +02:00
5047540db2 Make new textures fit existing style 2014-09-27 20:33:17 +02:00
9dfaab7f20 Some new textures (natural beauty texturepack) 2014-09-27 20:10:58 +02:00
8fe62ea7f6 Use new firelike drawtype 2014-09-21 22:25:00 +02:00
c4969665e7 Fix dye stuff, fixes #243 2014-09-16 19:40:50 +02:00
9670c27161 Clean up treegen code 2014-09-16 18:38:11 +02:00
c32957f942 Enable dungeons by default 2014-09-16 18:26:32 +02:00
c95cd8414b Fix xpanes API 2014-09-16 17:11:54 +02:00
cc2573acdf Remove API from player.lua
It's now in game_api.txt
2014-09-16 17:07:43 +02:00
44dc611088 Fix farming unloaded node crash 2014-09-06 20:36:40 -04:00
49a8ddc822 Make sand and some leaves sounds quieter 2014-08-22 11:52:51 +02:00
11c04e984d Localize player_attached 2014-08-21 16:49:30 +02:00
ef1f66a64e Fix some farming stuff 2014-08-21 16:48:48 +02:00
a1aee9a68f Fix door hardness detection for open/close sounds 2014-08-07 13:47:01 +02:00
Jat
5dbc738dbd Add API doors : Sound for door open and close. 2014-08-07 12:42:37 +02:00
5b5aa493b5 Fix boat flying up and some tweaks 2014-08-07 12:27:40 +02:00
6967232619 Fix TNT init for undefined enable_tnt setting 2014-07-25 23:29:44 -04:00
263b6f2fdf Show filled buckets in creative inventory 2014-07-24 13:41:17 +02:00
0ca4520cc2 Rewrite TNT 2014-07-22 12:05:40 -04:00
ea3fcdd077 Pair door with door of any type
Mirror the setup of a door placed next to any door, not just next to
a door of the same type.  This is particularly useful where there are
multiple door types that have the same appearance, but one wants the
doors of a pair to have different behaviour in some other respect.
2014-07-22 13:41:32 +02:00
820e48badc Make open trapdoor climbable
When a trapdoor is mounted upside down, to make its top surface flush
with the floor above when closed, it is necessary to have some way to
climb through the trapdoor node when it's open.  Making it climbable
like a ladder satisfies this need.  It is somewhat realistic, as a real
trapdoor can have a ladder segment mounted on one face.  When the trapdoor
is mounted in its default orientation, making the bottom surface flush
with the ceiling below when closed, the climbability when open is not
strictly necessary, but is still a convenience.
2014-07-22 13:04:45 +02:00
c39b9b29de Improve message about screwdriver control
The message to "hold shift" makes an unwarranted assumption about the
user's keybindings.  Messages from the server should refer to a key's
game function, rather than its extragame identity.
2014-07-22 13:04:20 +02:00
a8ad9bfc9d Consistently use group:stick in tool recipes
The left-handed recipes for axes were using default:stick instead of
the group:stick used by all other tool recipes.
2014-07-22 13:03:45 +02:00
d4c24a30e9 Retain sign text when editing is aborted by <esc> 2014-07-22 13:00:20 +02:00
c8845e8d44 Fix desert_sand_soil dropping itself, and changed the descriptions 2014-07-22 12:56:20 +02:00
5175897cdc Alias string to cotton
Cotton plants used to drop strings, now they drop farming:cotton. Some mods (namely, throwing) still use farming:string, therefore we need farming:string to be equal farming:cotton.
2014-07-13 20:04:14 +02:00
c521cb06bf Better ingot textures 2014-07-13 19:37:01 +02:00
3180bdfe6c Add protection to TNT (by @tenplus1) 2014-07-13 19:24:57 +02:00
c993e14084 Add spaces around operators in boat mod code, fix a problem with boat staticdata, fix a crash that can occur with boat going over unknown nodes. 2014-07-09 09:47:51 +02:00
955f3cf310 Fix crafting recipe for iron bars 2014-07-08 19:10:55 +02:00
814c17631d Fix jump-stacking 2014-07-08 16:50:06 +02:00
ca7f6bb97a Convert spaces to tabs and add unknown node checks to xpanes 2014-07-06 21:49:47 -04:00
101 changed files with 1688 additions and 1584 deletions

View File

@ -46,6 +46,8 @@ The doors mod allows modders to register custom doors.
node_box_top = regular nodebox, see [Node boxes], OPTIONAL,
selection_box_bottom = regular nodebox, see [Node boxes], OPTIONAL,
selection_box_top = regular nodebox, see [Node boxes], OPTIONAL,
sound_open_door = sound play for open door, OPTIONAL,
sound_close_door = sound play for close door, OPTIONAL,
only_placer_can_open = true/false,
^ If true, only placer can open the door (locked for others)
}
@ -118,7 +120,7 @@ Xpanes API
Creates panes that automatically connect to each other
xpanes.register_pane(subname, def)
-> subname: used for nodename. Result: "xpanes:subname_{1..16}"
-> subname: used for nodename. Result: "xpanes:subname" and "xpanes:subname_{2..15}"
-> def: See [#Pane definition]
#Pane definition
@ -132,10 +134,6 @@ xpanes.register_pane(subname, def)
^ See [#Default sounds]
recipe = {{"","","","","","","","",""}},
^ Recipe field only
on_construct = function(pos)
update_pane(pos, "pane")
end,
^ Required to handle rotation correctly
}
Default sounds
@ -197,3 +195,83 @@ Model Definition
-- ...
},
}
Leafdecay
---------
To enable leaf decay for a node, add it to the "leafdecay" group.
The rating of the group determines how far from a node in the group "tree"
the node can be without decaying.
If param2 of the node is ~= 0, the node will always be preserved. Thus, if
the player places a node of that kind, you will want to set param2=1 or so.
The function default.after_place_leaves can be set as after_place_node of a node
to set param2 to 1 if the player places the node (should not be used for nodes
that use param2 otherwise (e.g. facedir)).
If the node is in the leafdecay_drop group then it will always be dropped as an
item.
Dyes
----
To make recipes that will work with any dye ever made by anybody, define
them based on groups. You can select any group of groups, based on your need for
amount of colors.
#Color groups
-------------
Base color groups:
- basecolor_white
- basecolor_grey
- basecolor_black
- basecolor_red
- basecolor_yellow
- basecolor_green
- basecolor_cyan
- basecolor_blue
- basecolor_magenta
Extended color groups (* = equal to a base color):
* excolor_white
- excolor_lightgrey
* excolor_grey
- excolor_darkgrey
* excolor_black
* excolor_red
- excolor_orange
* excolor_yellow
- excolor_lime
* excolor_green
- excolor_aqua
* excolor_cyan
- excolor_sky_blue
* excolor_blue
- excolor_violet
* excolor_magenta
- excolor_red_violet
The whole unifieddyes palette as groups:
- unicolor_<excolor>
For the following, no white/grey/black is allowed:
- unicolor_medium_<excolor>
- unicolor_dark_<excolor>
- unicolor_light_<excolor>
- unicolor_<excolor>_s50
- unicolor_medium_<excolor>_s50
- unicolor_dark_<excolor>_s50
Example of one shapeless recipe using a color group:
minetest.register_craft({
type = "shapeless",
output = '<mod>:item_yellow',
recipe = {'<mod>:item_no_color', 'group:basecolor_yellow'},
})
#Color lists
------------
dye.basecolors
^ Array containing the names of available base colors
dye.excolors
^ Array containing the names of the available extended colors

View File

@ -1,6 +1,6 @@
mg_flags = dungeons
mgv6_spflags = biomeblend, jungles
movement_liquid_sink = 25
movement_speed_jump = 6.2
movement_liquid_fluidity = 0.8
movement_liquid_fluidity_smooth = 2

24
minetest.conf.example Normal file
View File

@ -0,0 +1,24 @@
# This file contains settings of minetest_game that can be changed in
# minetest.conf
#
# By default, all the settings are commented and not functional.
# Uncomment settings by removing the preceding #.
# Whether creative mode (fast digging of all blocks, unlimited resources) should be enabled
#creative_mode = false
# The time in seconds after which the bones of a dead player can be looted by everyone
# 0 to disable
#share_bones_time = 1200
# Whether fire should be disabled (all fire nodes will instantly disappear)
#disable_fire = false
# Whether steel tools, torches and cobblestone should be given to new players
#give_initial_stuff = false
# Whether the TNT mod should be enabled
#enable_tnt = <true in singleplayer, false in multiplayer>
# The radius of a TNT explosion
#tnt_radius = 3

View File

@ -32,7 +32,7 @@ end
local boat = {
physical = true,
collisionbox = {-0.6,-0.4,-0.6, 0.6,0.3,0.6},
collisionbox = {-0.5, -0.4, -0.5, 0.5, 0.3, 0.5},
visual = "mesh",
mesh = "boat.x",
textures = {"default_wood.png"},
@ -72,17 +72,20 @@ function boat.on_activate(self, staticdata, dtime_s)
self.last_v = self.v
end
function boat.get_staticdata()
return tostring(v)
function boat.get_staticdata(self)
return tostring(self.v)
end
function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, direction)
if not puncher or not puncher:is_player() or self.removed then
return
end
if self.driver and puncher == self.driver then
self.driver = nil
puncher:set_detach()
default.player_attached[puncher:get_player_name()] = false
end
if not self.driver then
self.removed = true
-- delay remove to ensure player is detached
minetest.after(0.1, function()
@ -92,6 +95,7 @@ function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, d
puncher:get_inventory():add_item("main", "boats:boat")
end
end
end
function boat.on_step(self, dtime)
self.v = get_v(self.object:getvelocity()) * get_sign(self.v)
@ -100,27 +104,26 @@ function boat.on_step(self, dtime)
local yaw = self.object:getyaw()
if ctrl.up then
self.v = self.v + 0.1
end
if ctrl.down then
self.v = self.v-0.08
elseif ctrl.down then
self.v = self.v - 0.1
end
if ctrl.left then
if ctrl.down then
self.object:setyaw(yaw-math.pi/120-dtime*math.pi/120)
if self.v < 0 then
self.object:setyaw(yaw - (1 + dtime) * 0.03)
else
self.object:setyaw(yaw+math.pi/120+dtime*math.pi/120)
self.object:setyaw(yaw + (1 + dtime) * 0.03)
end
end
if ctrl.right then
if ctrl.down then
self.object:setyaw(yaw+math.pi/120+dtime*math.pi/120)
elseif ctrl.right then
if self.v < 0 then
self.object:setyaw(yaw + (1 + dtime) * 0.03)
else
self.object:setyaw(yaw-math.pi/120-dtime*math.pi/120)
self.object:setyaw(yaw - (1 + dtime) * 0.03)
end
end
end
local velo = self.object:getvelocity()
if self.v == 0 and velo.x == 0 and velo.z == 0 then
if self.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
self.object:setpos(self.object:getpos())
return
end
local s = get_sign(self.v)
@ -139,23 +142,28 @@ function boat.on_step(self, dtime)
local new_velo = {x = 0, y = 0, z = 0}
local new_acce = {x = 0, y = 0, z = 0}
if not is_water(p) then
if minetest.registered_nodes[minetest.env:get_node(p).name].walkable then
local nodedef = minetest.registered_nodes[minetest.get_node(p).name]
if (not nodedef) or nodedef.walkable then
self.v = 0
new_acce = {x = 0, y = 1, z = 0}
else
new_acce = {x = 0, y = -9.8, z = 0}
end
new_acce = {x=0, y=-10, z=0}
new_velo = get_velocity(self.v, self.object:getyaw(), self.object:getvelocity().y)
self.object:setpos(self.object:getpos())
else
p.y = p.y + 1
if is_water(p) then
new_acce = {x=0, y=3, z=0}
local y = self.object:getvelocity().y
if y > 2 then
y = 2
end
if y < 0 then
self.object:setacceleration({x=0, y=10, z=0})
if y >= 4.5 then
y = 4.5
elseif y < 0 then
new_acce = {x = 0, y = 20, z = 0}
else
new_acce = {x = 0, y = 5, z = 0}
end
new_velo = get_velocity(self.v, self.object:getyaw(), y)
self.object:setpos(self.object:getpos())
else
new_acce = {x = 0, y = 0, z = 0}
if math.abs(self.object:getvelocity().y) < 1 then
@ -165,6 +173,7 @@ function boat.on_step(self, dtime)
new_velo = get_velocity(self.v, self.object:getyaw(), 0)
else
new_velo = get_velocity(self.v, self.object:getyaw(), self.object:getvelocity().y)
self.object:setpos(self.object:getpos())
end
end
end
@ -174,7 +183,6 @@ end
minetest.register_entity("boats:boat", boat)
minetest.register_craftitem("boats:boat", {
description = "Boat",
inventory_image = "boat_inventory.png",
@ -206,3 +214,4 @@ minetest.register_craft({
{"group:wood", "group:wood", "group:wood"},
},
})

View File

@ -1,8 +1,6 @@
-- Minetest 0.4 mod: bucket
-- See README.txt for licensing and other information.
local LIQUID_MAX = 8 --The number of water levels when liquid_finite is enabled
minetest.register_alias("bucket", "bucket:bucket_empty")
minetest.register_alias("bucket_water", "bucket:bucket_water")
minetest.register_alias("bucket_lava", "bucket:bucket_lava")
@ -51,7 +49,6 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name
inventory_image = inventory_image,
stack_max = 1,
liquids_pointable = true,
groups = {not_in_creative_inventory=1},
on_place = function(itemstack, user, pointed_thing)
-- Must be pointing to node
if pointed_thing.type ~= "node" then
@ -72,40 +69,20 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name
itemstack) or itemstack
end
local place_liquid = function(pos, node, source, flowing, fullness)
local place_liquid = function(pos, node, source, flowing)
if check_protection(pos,
user and user:get_player_name() or "",
"place "..source) then
return
end
if math.floor(fullness/128) == 1 or
not minetest.setting_getbool("liquid_finite") then
minetest.add_node(pos, {name=source,
param2=fullness})
return
elseif node.name == flowing then
fullness = fullness + node.param2
elseif node.name == source then
fullness = LIQUID_MAX
end
if fullness >= LIQUID_MAX then
minetest.add_node(pos, {name=source,
param2=LIQUID_MAX})
else
minetest.add_node(pos, {name=flowing,
param2=fullness})
end
minetest.add_node(pos, {name=source})
end
-- Check if pointing to a buildable node
local fullness = tonumber(itemstack:get_metadata())
if not fullness then fullness = LIQUID_MAX end
if ndef and ndef.buildable_to then
-- buildable; replace the node
place_liquid(pointed_thing.under, node,
source, flowing, fullness)
source, flowing)
else
-- not buildable to; place the liquid above
-- check if the node above can be replaced
@ -113,7 +90,7 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name
if node and minetest.registered_nodes[node.name].buildable_to then
place_liquid(pointed_thing.above,
node, source,
flowing, fullness)
flowing)
else
-- do not remove the bucket with the liquid
return
@ -136,12 +113,10 @@ minetest.register_craftitem("bucket:bucket_empty", {
return
end
-- Check if pointing to a liquid source
node = minetest.get_node(pointed_thing.under)
liquiddef = bucket.liquids[node.name]
local node = minetest.get_node(pointed_thing.under)
local liquiddef = bucket.liquids[node.name]
if liquiddef ~= nil and liquiddef.itemname ~= nil and
(node.name == liquiddef.source or
(node.name == liquiddef.flowing and
minetest.setting_getbool("liquid_finite"))) then
node.name == liquiddef.source then
if check_protection(pointed_thing.under,
user:get_player_name(),
"take ".. node.name) then
@ -150,11 +125,7 @@ minetest.register_craftitem("bucket:bucket_empty", {
minetest.add_node(pointed_thing.under, {name="air"})
if node.name == liquiddef.source then
node.param2 = LIQUID_MAX
end
return ItemStack({name = liquiddef.itemname,
metadata = tostring(node.param2)})
return ItemStack(liquiddef.itemname)
end
end,
})

View File

@ -23,13 +23,6 @@ Everything not listed in here:
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
Cisoun's WTFPL texture pack:
default_chest_front.png
default_chest_lock.png
default_chest_side.png
default_chest_top.png
default_dirt.png
default_grass.png
default_grass_side.png
default_jungletree.png
default_jungletree_top.png
default_lava.png
@ -41,6 +34,9 @@ Cisoun's WTFPL texture pack:
default_tree_top.png
default_water.png
Cisoun's conifers mod (WTFPL):
default_pine_needles.png
Originating from G4JC's Almost MC Texture Pack:
default_torch.png
default_torch_on_ceiling.png
@ -73,6 +69,7 @@ Calinou (CC BY-SA):
default_papyrus.png
default_copper_lump.png
default_mineral_copper.png
default_glass_detail.png
MirceaKitsune (WTFPL):
character.x
@ -86,7 +83,6 @@ PilzAdam (WTFPL):
default_junglewood.png
default_obsidian_glass.png
default_obsidian_shard.png
default_mossycobble.png
default_gold_lump.png
default_mineral_gold.png
default_snowball.png
@ -101,6 +97,7 @@ Splizard (CC BY-SA 3.0):
default_snow.png
default_snow_side.png
default_ice.png
default_pine_sapling.png
Zeg9 (CC BY-SA 3.0):
default_coal_block.png
@ -111,6 +108,9 @@ Zeg9 (CC BY-SA 3.0):
paramat (CC BY-SA 3.0):
wieldhand.png, based on character.png by Jordach (CC BY-SA 3.0)
default_pinetree.png
default_pinetree_top.png
default_pinewood.png
brunob.santos (CC BY-SA 4.0):
default_desert_cobble.png
@ -118,7 +118,6 @@ brunob.santos (CC BY-SA 4.0):
BlockMen (CC BY-SA 3.0):
default_stone_brick.png
default_wood.png
default_cobble.png
default_clay_brick.png
default_tool_steelsword.png
default_bronze_ingot.png
@ -132,10 +131,25 @@ BlockMen (CC BY-SA 3.0):
default_book.png
default_paper.png
default_stick.png
default_chest_front.png
default_chest_lock.png
default_chest_side.png
default_chest_top.png
bubble.png
heart.png
gui_*.png
Neuromancer (CC BY-SA 2.0):
default_cobble.png, based on texture by Brane praefect
default_mossycobble.png, based on texture by Brane praefect
Neuromancer (CC BY-SA 3.0):
default_dirt.png
default_furnace_*.png
Philipbenr (CC BY-SA 3.0):
default_grass.png
default_grass_side.png
Glass breaking sounds (CC BY 3.0):
1: http://www.freesound.org/people/cmusounddesign/sounds/71947/
2: http://www.freesound.org/people/Tomlija/sounds/97669/

View File

@ -14,6 +14,13 @@ minetest.register_craft({
}
})
minetest.register_craft({
output = 'default:pinewood 4',
recipe = {
{'default:pinetree'},
}
})
minetest.register_craft({
output = 'default:stick 4',
recipe = {
@ -212,8 +219,8 @@ minetest.register_craft({
output = 'default:axe_wood',
recipe = {
{'group:wood', 'group:wood'},
{'default:stick', 'group:wood'},
{'default:stick',''},
{'group:stick', 'group:wood'},
{'group:stick',''},
}
})
@ -221,8 +228,8 @@ minetest.register_craft({
output = 'default:axe_stone',
recipe = {
{'group:stone', 'group:stone'},
{'default:stick', 'group:stone'},
{'default:stick', ''},
{'group:stick', 'group:stone'},
{'group:stick', ''},
}
})
@ -230,8 +237,8 @@ minetest.register_craft({
output = 'default:axe_steel',
recipe = {
{'default:steel_ingot', 'default:steel_ingot'},
{'default:stick', 'default:steel_ingot'},
{'default:stick', ''},
{'group:stick', 'default:steel_ingot'},
{'group:stick', ''},
}
})
@ -239,8 +246,8 @@ minetest.register_craft({
output = 'default:axe_bronze',
recipe = {
{'default:bronze_ingot', 'default:bronze_ingot'},
{'default:stick', 'default:bronze_ingot'},
{'default:stick', ''},
{'group:stick', 'default:bronze_ingot'},
{'group:stick', ''},
}
})
@ -248,8 +255,8 @@ minetest.register_craft({
output = 'default:axe_mese',
recipe = {
{'default:mese_crystal', 'default:mese_crystal'},
{'default:stick', 'default:mese_crystal'},
{'default:stick', ''},
{'group:stick', 'default:mese_crystal'},
{'group:stick', ''},
}
})
@ -257,8 +264,8 @@ minetest.register_craft({
output = 'default:axe_diamond',
recipe = {
{'default:diamond', 'default:diamond'},
{'default:stick', 'default:diamond'},
{'default:stick', ''},
{'group:stick', 'default:diamond'},
{'group:stick', ''},
}
})
@ -573,6 +580,14 @@ minetest.register_craft({
}
})
minetest.register_craft({
output = 'default:obsidianbrick 4',
recipe = {
{'default:obsidian', 'default:obsidian'},
{'default:obsidian', 'default:obsidian'}
}
})
minetest.register_craft({
output = 'default:stonebrick 4',
recipe = {
@ -800,3 +815,10 @@ minetest.register_craft({
recipe = "default:grass_1",
burntime = 2,
})
minetest.register_craft({
type = "fuel",
recipe = "default:pine_sapling",
burntime = 10,
})

View File

@ -14,11 +14,13 @@ minetest.register_craftitem("default:paper", {
minetest.register_craftitem("default:book", {
description = "Book",
inventory_image = "default_book.png",
groups = {book=1},
})
minetest.register_craftitem("default:coal_lump", {
description = "Coal Lump",
inventory_image = "default_coal_lump.png",
groups = {coal = 1}
})
minetest.register_craftitem("default:iron_lump", {

View File

@ -40,9 +40,9 @@ end
function default.node_sound_sand_defaults(table)
table = table or {}
table.footstep = table.footstep or
{name="default_sand_footstep", gain=0.5}
{name="default_sand_footstep", gain=0.2}
table.dug = table.dug or
{name="default_sand_footstep", gain=1.0}
{name="default_sand_footstep", gain=0.4}
table.place = table.place or
{name="default_place_node", gain=1.0}
default.node_sound_defaults(table)
@ -64,7 +64,7 @@ function default.node_sound_leaves_defaults(table)
table.footstep = table.footstep or
{name="default_grass_footstep", gain=0.35}
table.dug = table.dug or
{name="default_grass_footstep", gain=0.85}
{name="default_grass_footstep", gain=0.7}
table.dig = table.dig or
{name="default_dig_crumbly", gain=0.4}
table.place = table.place or
@ -127,56 +127,6 @@ end
minetest.register_on_punchnode(on_punchnode)
--
-- Grow trees
--
minetest.register_abm({
nodenames = {"default:sapling"},
interval = 10,
chance = 50,
action = function(pos, node)
local nu = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name
local is_soil = minetest.get_item_group(nu, "soil")
if is_soil == 0 then
return
end
minetest.log("action", "A sapling grows into a tree at "..minetest.pos_to_string(pos))
local vm = minetest.get_voxel_manip()
local minp, maxp = vm:read_from_map({x=pos.x-16, y=pos.y, z=pos.z-16}, {x=pos.x+16, y=pos.y+16, z=pos.z+16})
local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
local data = vm:get_data()
default.grow_tree(data, a, pos, math.random(1, 4) == 1, math.random(1,100000))
vm:set_data(data)
vm:write_to_map(data)
vm:update_map()
end
})
minetest.register_abm({
nodenames = {"default:junglesapling"},
interval = 10,
chance = 50,
action = function(pos, node)
local nu = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name
local is_soil = minetest.get_item_group(nu, "soil")
if is_soil == 0 then
return
end
minetest.log("action", "A jungle sapling grows into a tree at "..minetest.pos_to_string(pos))
local vm = minetest.get_voxel_manip()
local minp, maxp = vm:read_from_map({x=pos.x-16, y=pos.y-1, z=pos.z-16}, {x=pos.x+16, y=pos.y+16, z=pos.z+16})
local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
local data = vm:get_data()
default.grow_jungletree(data, a, pos, math.random(1,100000))
vm:set_data(data)
vm:write_to_map(data)
vm:update_map()
end
})
--
-- Lavacooling
--
@ -283,17 +233,6 @@ end
-- Leafdecay
--
-- To enable leaf decay for a node, add it to the "leafdecay" group.
--
-- The rating of the group determines how far from a node in the group "tree"
-- the node can be without decaying.
--
-- If param2 of the node is ~= 0, the node will always be preserved. Thus, if
-- the player places a node of that kind, you will want to set param2=1 or so.
--
-- If the node is in the leafdecay_drop group then the it will always be dropped
-- as an item
default.leafdecay_trunk_cache = {}
default.leafdecay_enable_cache = true
-- Spread the load of finding trunks
@ -305,6 +244,12 @@ minetest.register_globalstep(function(dtime)
math.floor(dtime * finds_per_second)
end)
default.after_place_leaves = function(pos, placer, itemstack, pointed_thing)
local node = minetest.get_node(pos)
node.param2 = 1
minetest.set_node(pos, node)
end
minetest.register_abm({
nodenames = {"group:leafdecay"},
neighbors = {"air", "group:liquid"},
@ -359,7 +304,7 @@ minetest.register_abm({
end
if not do_preserve then
-- Drop stuff other than the node itself
itemstacks = minetest.get_node_drops(n0.name)
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

283
mods/default/furnace.lua Normal file
View File

@ -0,0 +1,283 @@
--
-- Formspecs
--
local function active_formspec(fuel_percent, item_percent)
local formspec =
"size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[current_name;src;2.75,0.5;1,1;]"..
"list[current_name;fuel;2.75,2.5;1,1;]"..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
(100-fuel_percent)..":default_furnace_fire_fg.png]"..
"image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:"..
(item_percent)..":gui_furnace_arrow_fg.png^[transformR270]"..
"list[current_name;dst;4.75,0.96;2,2;]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
default.get_hotbar_bg(0, 4.25)
return formspec
end
local inactive_formspec =
"size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[current_name;src;2.75,0.5;1,1;]"..
"list[current_name;fuel;2.75,2.5;1,1;]"..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png]"..
"image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
"list[current_name;dst;4.75,0.96;2,2;]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
default.get_hotbar_bg(0, 4.25)
--
-- Node callback functions that are the same for active and inactive furnace
--
local function can_dig(pos, player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("fuel") and inv:is_empty("dst") and inv:is_empty("src")
end
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "fuel" then
if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext", "Furnace is empty")
end
return stack:get_count()
else
return 0
end
elseif listname == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
--
-- Node definitions
--
minetest.register_node("default:furnace", {
description = "Furnace",
tiles = {
"default_furnace_top.png", "default_furnace_bottom.png",
"default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_front.png"
},
paramtype2 = "facedir",
groups = {cracky=2},
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
can_dig = can_dig,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
})
minetest.register_node("default:furnace_active", {
description = "Furnace",
tiles = {
"default_furnace_top.png", "default_furnace_bottom.png",
"default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png",
{
image = "default_furnace_front_active.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1.5
},
}
},
paramtype2 = "facedir",
light_source = 8,
drop = "default:furnace",
groups = {cracky=2, not_in_creative_inventory=1},
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
can_dig = can_dig,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
})
--
-- ABM
--
local function swap_node(pos, name)
local node = minetest.get_node(pos)
if node.name == name then
return
end
node.name = name
minetest.swap_node(pos, node)
end
minetest.register_abm({
nodenames = {"default:furnace", "default:furnace_active"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
--
-- Inizialize metadata
--
local meta = minetest.get_meta(pos)
local fuel_time = meta:get_float("fuel_time") or 0
local src_time = meta:get_float("src_time") or 0
local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
--
-- Inizialize inventory
--
local inv = meta:get_inventory()
for listname, size in pairs({
src = 1,
fuel = 1,
dst = 4,
}) do
if inv:get_size(listname) ~= size then
inv:set_size(listname, size)
end
end
local srclist = inv:get_list("src")
local fuellist = inv:get_list("fuel")
local dstlist = inv:get_list("dst")
--
-- Cooking
--
-- Check if we have cookable content
local cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
local cookable = true
if cooked.time == 0 then
cookable = false
end
-- Check if we have enough fuel to burn
if fuel_time < fuel_totaltime then
-- The furnace is currently active and has enough fuel
fuel_time = fuel_time + 1
-- If there is a cookable item then check if it is ready yet
if cookable then
src_time = src_time + 1
if src_time >= cooked.time then
-- Place result in dst list if possible
if inv:room_for_item("dst", cooked.item) then
inv:add_item("dst", cooked.item)
inv:set_stack("src", 1, aftercooked.items[1])
src_time = 0
end
end
end
else
-- Furnace ran out of fuel
if cookable then
-- We need to get new fuel
local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
if fuel.time == 0 then
-- No valid fuel in fuel list
fuel_totaltime = 0
fuel_time = 0
src_time = 0
else
-- Take fuel from fuel list
inv:set_stack("fuel", 1, afterfuel.items[1])
fuel_totaltime = fuel.time
fuel_time = 0
end
else
-- We don't need to get new fuel since there is no cookable item
fuel_totaltime = 0
fuel_time = 0
src_time = 0
end
end
--
-- Update formspec, infotext and node
--
local formspec = inactive_formspec
local item_state = ""
local item_percent = 0
if cookable then
item_percent = math.floor(src_time / cooked.time * 100)
item_state = item_percent .. "%"
else
if srclist[1]:is_empty() then
item_state = "Empty"
else
item_state = "Not cookable"
end
end
local fuel_state = "Empty"
local active = "inactive "
if fuel_time <= fuel_totaltime and fuel_totaltime ~= 0 then
active = "active "
local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
fuel_state = fuel_percent .. "%"
formspec = active_formspec(fuel_percent, item_percent)
swap_node(pos, "default:furnace_active")
else
if not fuellist[1]:is_empty() then
fuel_state = "0%"
end
swap_node(pos, "default:furnace")
end
local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")"
--
-- Set meta values
--
meta:set_float("fuel_totaltime", fuel_totaltime)
meta:set_float("fuel_time", fuel_time)
meta:set_float("src_time", src_time)
meta:set_string("formspec", formspec)
meta:set_string("infotext", infotext)
end,
})

View File

@ -38,6 +38,7 @@ default.gui_suvival_form = "size[8,8.5]"..
-- Load files
dofile(minetest.get_modpath("default").."/functions.lua")
dofile(minetest.get_modpath("default").."/nodes.lua")
dofile(minetest.get_modpath("default").."/furnace.lua")
dofile(minetest.get_modpath("default").."/tools.lua")
dofile(minetest.get_modpath("default").."/craftitems.lua")
dofile(minetest.get_modpath("default").."/crafting.lua")

View File

@ -207,69 +207,6 @@ minetest.register_ore({
flags = "absheight",
})
if minetest.setting_get("mg_name") == "indev" then
-- Floatlands and high mountains springs
minetest.register_ore({
ore_type = "scatter",
ore = "default:water_source",
ore_param2 = 128,
wherein = "default:stone",
clust_scarcity = 40*40*40,
clust_num_ores = 8,
clust_size = 3,
height_min = 100,
height_max = 31000,
})
minetest.register_ore({
ore_type = "scatter",
ore = "default:lava_source",
ore_param2 = 128,
wherein = "default:stone",
clust_scarcity = 50*50*50,
clust_num_ores = 5,
clust_size = 2,
height_min = 10000,
height_max = 31000,
})
minetest.register_ore({
ore_type = "scatter",
ore = "default:sand",
wherein = "default:stone",
clust_scarcity = 20*20*20,
clust_num_ores = 5*5*3,
clust_size = 5,
height_min = 500,
height_max = 31000,
})
-- Underground springs
minetest.register_ore({
ore_type = "scatter",
ore = "default:water_source",
ore_param2 = 128,
wherein = "default:stone",
clust_scarcity = 25*25*25,
clust_num_ores = 8,
clust_size = 3,
height_min = -10000,
height_max = -10,
})
minetest.register_ore({
ore_type = "scatter",
ore = "default:lava_source",
ore_param2 = 128,
wherein = "default:stone",
clust_scarcity = 35*35*35,
clust_num_ores = 5,
clust_size = 2,
height_min = -31000,
height_max = -100,
})
end
minetest.register_ore({
ore_type = "scatter",
ore = "default:clay",
@ -323,6 +260,12 @@ function default.generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume
--print("generate_ore done")
end
--
-- Mgv6 papyrus, cactus, long grasses
--
function default.mgv6_ongen(minp, maxp, seed)
function default.make_papyrus(pos, size)
for y=0,size-1 do
local p = {x=pos.x, y=pos.y+y, z=pos.z}
@ -349,55 +292,6 @@ function default.make_cactus(pos, size)
end
end
-- facedir: 0/1/2/3 (head node facedir value)
-- length: length of rainbow tail
function default.make_nyancat(pos, facedir, length)
local tailvec = {x=0, y=0, z=0}
if facedir == 0 then
tailvec.z = 1
elseif facedir == 1 then
tailvec.x = 1
elseif facedir == 2 then
tailvec.z = -1
elseif facedir == 3 then
tailvec.x = -1
else
--print("default.make_nyancat(): Invalid facedir: "+dump(facedir))
facedir = 0
tailvec.z = 1
end
local p = {x=pos.x, y=pos.y, z=pos.z}
minetest.set_node(p, {name="default:nyancat", param2=facedir})
for i=1,length do
p.x = p.x + tailvec.x
p.z = p.z + tailvec.z
minetest.set_node(p, {name="default:nyancat_rainbow", param2=facedir})
end
end
function generate_nyancats(seed, minp, maxp)
local height_min = -31000
local height_max = -32
if maxp.y < height_min or minp.y > height_max then
return
end
local y_min = math.max(minp.y, height_min)
local y_max = math.min(maxp.y, height_max)
local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
local pr = PseudoRandom(seed + 9324342)
local max_num_nyancats = math.floor(volume / (16*16*16))
for i=1,max_num_nyancats do
if pr:next(0, 1000) == 0 then
local x0 = pr:next(minp.x, maxp.x)
local y0 = pr:next(minp.y, maxp.y)
local z0 = pr:next(minp.z, maxp.z)
local p0 = {x=x0, y=y0, z=z0}
default.make_nyancat(p0, pr:next(0,3), pr:next(3,15))
end
end
end
minetest.register_on_generated(function(minp, maxp, seed)
if maxp.y >= 2 and minp.y <= 0 then
-- Generate papyrus
local perlin1 = minetest.get_perlin(354, 3, 0.7, 100)
@ -506,8 +400,68 @@ minetest.register_on_generated(function(minp, maxp, seed)
end
end
end
end
-- Generate nyan cats
generate_nyancats(seed, minp, maxp)
--
-- Detect mapgen and register suitable on-generated function
--
minetest.register_on_mapgen_init(function(mg_params)
if mg_params.mgname == "v6" then
minetest.register_on_generated(default.mgv6_ongen)
end
end)
--
-- Generate nyan cats in all mapgens
--
-- facedir: 0/1/2/3 (head node facedir value)
-- length: length of rainbow tail
function default.make_nyancat(pos, facedir, length)
local tailvec = {x=0, y=0, z=0}
if facedir == 0 then
tailvec.z = 1
elseif facedir == 1 then
tailvec.x = 1
elseif facedir == 2 then
tailvec.z = -1
elseif facedir == 3 then
tailvec.x = -1
else
--print("default.make_nyancat(): Invalid facedir: "+dump(facedir))
facedir = 0
tailvec.z = 1
end
local p = {x=pos.x, y=pos.y, z=pos.z}
minetest.set_node(p, {name="default:nyancat", param2=facedir})
for i=1,length do
p.x = p.x + tailvec.x
p.z = p.z + tailvec.z
minetest.set_node(p, {name="default:nyancat_rainbow", param2=facedir})
end
end
function default.generate_nyancats(minp, maxp, seed)
local height_min = -31000
local height_max = -32
if maxp.y < height_min or minp.y > height_max then
return
end
local y_min = math.max(minp.y, height_min)
local y_max = math.min(maxp.y, height_max)
local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
local pr = PseudoRandom(seed + 9324342)
local max_num_nyancats = math.floor(volume / (16*16*16))
for i=1,max_num_nyancats do
if pr:next(0, 1000) == 0 then
local x0 = pr:next(minp.x, maxp.x)
local y0 = pr:next(minp.y, maxp.y)
local z0 = pr:next(minp.z, maxp.z)
local p0 = {x=x0, y=y0, z=z0}
default.make_nyancat(p0, pr:next(0,3), pr:next(3,15))
end
end
end
minetest.register_on_generated(default.generate_nyancats)

View File

@ -114,7 +114,7 @@ minetest.register_node("default:dirt_with_snow", {
description = "Dirt with Snow",
tiles = {"default_snow.png", "default_dirt.png", "default_dirt.png^default_snow_side.png"},
is_ground_content = true,
groups = {crumbly=3},
groups = {crumbly=3,soil=1},
drop = 'default:dirt',
sounds = default.node_sound_dirt_defaults({
footstep = {name="default_snow_footstep", gain=0.25},
@ -277,6 +277,7 @@ minetest.register_node("default:jungleleaves", {
}
},
sounds = default.node_sound_leaves_defaults(),
after_place_node = default.after_place_leaves,
})
minetest.register_node("default:junglesapling", {
@ -292,7 +293,7 @@ minetest.register_node("default:junglesapling", {
type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
},
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1,sapling=1},
sounds = default.node_sound_leaves_defaults(),
})
@ -341,6 +342,7 @@ minetest.register_node("default:leaves", {
}
},
sounds = default.node_sound_leaves_defaults(),
after_place_node = default.after_place_leaves,
})
minetest.register_node("default:cactus", {
@ -393,22 +395,24 @@ minetest.register_node("default:bookshelf", {
groups = {choppy=3,oddly_breakable_by_hand=2,flammable=3},
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", default.bookshelf_formspec)
local inv = meta:get_inventory()
inv:set_size("books", 8*2)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("books")
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.env:get_meta(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local to_stack = inv:get_stack(listname, index)
if listname == "books" then
if stack:get_name() == "default:book" then
if minetest.get_item_group(stack:get_name(), "book") ~= 0
and to_stack:is_empty() then
return 1
else
return 0
@ -417,7 +421,7 @@ minetest.register_node("default:bookshelf", {
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.env:get_meta(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
local to_stack = inv:get_stack(to_list, to_index)
@ -446,8 +450,8 @@ minetest.register_node("default:bookshelf", {
minetest.register_node("default:glass", {
description = "Glass",
drawtype = "glasslike",
tiles = {"default_glass.png"},
drawtype = "glasslike_framed_optional",
tiles = {"default_glass.png", "default_glass_detail.png"},
inventory_image = minetest.inventorycube("default_glass.png"),
paramtype = "light",
sunlight_propagates = true,
@ -556,9 +560,8 @@ minetest.register_node("default:water_flowing", {
liquid_alternative_flowing = "default:water_flowing",
liquid_alternative_source = "default:water_source",
liquid_viscosity = WATER_VISC,
freezemelt = "default:snow",
post_effect_color = {a=64, r=100, g=100, b=200},
groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1, freezes=1, melt_around=1},
groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1},
})
minetest.register_node("default:water_source", {
@ -588,9 +591,8 @@ minetest.register_node("default:water_source", {
liquid_alternative_flowing = "default:water_flowing",
liquid_alternative_source = "default:water_source",
liquid_viscosity = WATER_VISC,
freezemelt = "default:ice",
post_effect_color = {a=64, r=100, g=100, b=200},
groups = {water=3, liquid=3, puts_out_fire=1, freezes=1},
groups = {water=3, liquid=3, puts_out_fire=1},
})
minetest.register_node("default:lava_flowing", {
@ -685,15 +687,15 @@ minetest.register_node("default:torch", {
wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
},
groups = {choppy=2,dig_immediate=3,flammable=1,attached_node=1,hot=2},
groups = {choppy=2,dig_immediate=3,flammable=1,attached_node=1},
legacy_wallmounted = true,
sounds = default.node_sound_defaults(),
})
minetest.register_node("default:sign_wall", {
description = "Sign",
drawtype = "signlike",
tiles = {"default_sign_wall.png"},
drawtype = "nodebox",
tiles = {"default_sign.png"},
inventory_image = "default_sign_wall.png",
wield_image = "default_sign_wall.png",
paramtype = "light",
@ -701,11 +703,11 @@ minetest.register_node("default:sign_wall", {
sunlight_propagates = true,
is_ground_content = false,
walkable = false,
selection_box = {
node_box = {
type = "wallmounted",
--wall_top = <default>
--wall_bottom = <default>
--wall_side = <default>
wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125},
wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125},
wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375},
},
groups = {choppy=2,dig_immediate=2,attached_node=1},
legacy_wallmounted = true,
@ -723,7 +725,7 @@ minetest.register_node("default:sign_wall", {
return
end
local meta = minetest.get_meta(pos)
fields.text = fields.text or ""
if not fields.text then return end
minetest.log("action", (sender:get_player_name() or "").." wrote \""..fields.text..
"\" to sign at "..minetest.pos_to_string(pos))
meta:set_string("text", fields.text)
@ -866,335 +868,6 @@ minetest.register_node("default:chest_locked", {
end,
})
function default.furnace_active(pos, percent, item_percent)
local formspec =
"size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[current_name;src;2.75,0.5;1,1;]"..
"list[current_name;fuel;2.75,2.5;1,1;]"..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
(100-percent)..":default_furnace_fire_fg.png]"..
"image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:"..
(item_percent*100)..":gui_furnace_arrow_fg.png^[transformR270]"..
"list[current_name;dst;4.75,0.96;2,2;]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
default.get_hotbar_bg(0,4.25)
return formspec
end
function default.get_furnace_active_formspec(pos, percent)
local meta = minetest.get_meta(pos)local inv = meta:get_inventory()
local srclist = inv:get_list("src")
local cooked = nil
local aftercooked = nil
if srclist then
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
end
local item_percent = 0
if cooked then
item_percent = meta:get_float("src_time")/cooked.time
end
return default.furnace_active(pos, percent, item_percent)
end
default.furnace_inactive_formspec =
"size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[current_name;src;2.75,0.5;1,1;]"..
"list[current_name;fuel;2.75,2.5;1,1;]"..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png]"..
"image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
"list[current_name;dst;4.75,0.96;2,2;]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
default.get_hotbar_bg(0,4.25)
minetest.register_node("default:furnace", {
description = "Furnace",
tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
paramtype2 = "facedir",
groups = {cracky=2},
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", default.furnace_inactive_formspec)
meta:set_string("infotext", "Furnace")
local inv = meta:get_inventory()
inv:set_size("fuel", 1)
inv:set_size("src", 1)
inv:set_size("dst", 4)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("fuel") then
return false
elseif not inv:is_empty("dst") then
return false
elseif not inv:is_empty("src") then
return false
end
return true
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext","Furnace is empty")
end
return stack:get_count()
else
return 0
end
elseif listname == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
if to_list == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext","Furnace is empty")
end
return count
else
return 0
end
elseif to_list == "src" then
return count
elseif to_list == "dst" then
return 0
end
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end,
})
minetest.register_node("default:furnace_active", {
description = "Furnace",
tiles = {
"default_furnace_top.png",
"default_furnace_bottom.png",
"default_furnace_side.png",
"default_furnace_side.png",
"default_furnace_side.png",
{
image = "default_furnace_front_active.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1.5
},
}
},
paramtype2 = "facedir",
light_source = 8,
drop = "default:furnace",
groups = {cracky=2, not_in_creative_inventory=1,hot=1},
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", default.furnace_inactive_formspec)
meta:set_string("infotext", "Furnace");
local inv = meta:get_inventory()
inv:set_size("fuel", 1)
inv:set_size("src", 1)
inv:set_size("dst", 4)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("fuel") then
return false
elseif not inv:is_empty("dst") then
return false
elseif not inv:is_empty("src") then
return false
end
return true
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext","Furnace is empty")
end
return stack:get_count()
else
return 0
end
elseif listname == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
if to_list == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext","Furnace is empty")
end
return count
else
return 0
end
elseif to_list == "src" then
return count
elseif to_list == "dst" then
return 0
end
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end,
})
local function swap_node(pos,name)
local node = minetest.get_node(pos)
if node.name == name then
return
end
node.name = name
minetest.swap_node(pos,node)
end
minetest.register_abm({
nodenames = {"default:furnace","default:furnace_active"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
for i, name in ipairs({
"fuel_totaltime",
"fuel_time",
"src_totaltime",
"src_time"
}) do
if meta:get_string(name) == "" then
meta:set_float(name, 0.0)
end
end
local inv = meta:get_inventory()
local srclist = inv:get_list("src")
local cooked = nil
local aftercooked
if srclist then
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
end
local was_active = false
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
was_active = true
meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
meta:set_float("src_time", meta:get_float("src_time") + 1)
if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
-- check if there's room for output in "dst" list
if inv:room_for_item("dst",cooked.item) then
-- Put result in "dst" list
inv:add_item("dst", cooked.item)
-- take stuff from "src" list
inv:set_stack("src", 1, aftercooked.items[1])
else
--print("Could not insert '"..cooked.item:to_string().."'")
end
meta:set_string("src_time", 0)
end
end
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
local percent = math.floor(meta:get_float("fuel_time") /
meta:get_float("fuel_totaltime") * 100)
meta:set_string("infotext","Furnace active: "..percent.."%")
swap_node(pos,"default:furnace_active")
meta:set_string("formspec",default.get_furnace_active_formspec(pos, percent))
return
end
local fuel = nil
local afterfuel
local cooked = nil
local fuellist = inv:get_list("fuel")
local srclist = inv:get_list("src")
if srclist then
cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
end
if fuellist then
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
end
if not fuel or fuel.time <= 0 then
meta:set_string("infotext","Furnace out of fuel")
swap_node(pos,"default:furnace")
meta:set_string("formspec", default.furnace_inactive_formspec)
return
end
if cooked.item:is_empty() then
if was_active then
meta:set_string("infotext","Furnace is empty")
swap_node(pos,"default:furnace")
meta:set_string("formspec", default.furnace_inactive_formspec)
end
return
end
meta:set_string("fuel_totaltime", fuel.time)
meta:set_string("fuel_time", 0)
inv:set_stack("fuel", 1, afterfuel.items[1])
end,
})
minetest.register_node("default:cobble", {
description = "Cobblestone",
tiles = {"default_cobble.png"},
@ -1295,6 +968,13 @@ minetest.register_node("default:obsidian", {
groups = {cracky=1,level=2},
})
minetest.register_node("default:obsidianbrick", {
description = "Obsidian Brick",
tiles = {"default_obsidian_brick.png"},
sounds = default.node_sound_stone_defaults(),
groups = {cracky=1,level=2},
})
minetest.register_node("default:nyancat", {
description = "Nyan Cat",
tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
@ -1330,7 +1010,7 @@ minetest.register_node("default:sapling", {
type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
},
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1,sapling=1},
sounds = default.node_sound_leaves_defaults(),
})
@ -1431,8 +1111,7 @@ minetest.register_node("default:ice", {
tiles = {"default_ice.png"},
is_ground_content = true,
paramtype = "light",
freezemelt = "default:water_source",
groups = {cracky=3, melts=1},
groups = {cracky=3},
sounds = default.node_sound_glass_defaults(),
})
@ -1444,16 +1123,14 @@ minetest.register_node("default:snow", {
is_ground_content = true,
paramtype = "light",
buildable_to = true,
leveled = 7,
drawtype = "nodebox",
freezemelt = "default:water_flowing",
node_box = {
type = "leveled",
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, -0.5+2/16, 0.5},
},
},
groups = {crumbly=3,falling_node=1, melts=1, float=1},
groups = {crumbly=3,falling_node=1},
sounds = default.node_sound_dirt_defaults({
footstep = {name="default_snow_footstep", gain=0.25},
dug = {name="default_snow_footstep", gain=0.75},
@ -1471,10 +1148,73 @@ minetest.register_node("default:snowblock", {
description = "Snow Block",
tiles = {"default_snow.png"},
is_ground_content = true,
freezemelt = "default:water_source",
groups = {crumbly=3, melts=1},
groups = {crumbly=3},
sounds = default.node_sound_dirt_defaults({
footstep = {name="default_snow_footstep", gain=0.25},
dug = {name="default_snow_footstep", gain=0.75},
}),
})
minetest.register_node("default:pine_needles",{
description = "Pine Needles",
drawtype = "allfaces_optional",
visual_scale = 1.3,
tiles = {"default_pine_needles.png"},
waving = 1,
paramtype = "light",
is_ground_content = false,
groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
drop = {
max_items = 1,
items = {
{
-- player will get sapling with 1/20 chance
items = {"default:pine_sapling"},
rarity = 20,
},
{
-- player will get leaves only if he get no saplings,
-- this is because max_items is 1
items = {"default:pine_needles"},
}
}
},
sounds = default.node_sound_leaves_defaults(),
after_place_node = default.after_place_leaves,
})
minetest.register_node("default:pine_sapling", {
description = "Pine Sapling",
drawtype = "plantlike",
visual_scale = 1.0,
tiles = {"default_pine_sapling.png"},
inventory_image = "default_pine_sapling.png",
wield_image = "default_pine_sapling.png",
paramtype = "light",
walkable = false,
is_ground_content = true,
selection_box = {
type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
},
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1,sapling=1},
sounds = default.node_sound_leaves_defaults(),
})
minetest.register_node("default:pinetree", {
description = "Pine Tree",
tiles = {"default_pinetree_top.png", "default_pinetree_top.png", "default_pinetree.png"},
paramtype2 = "facedir",
is_ground_content = false,
groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
sounds = default.node_sound_wood_defaults(),
on_place = minetest.rotate_node
})
minetest.register_node("default:pinewood", {
description = "Pinewood Planks",
tiles = {"default_pinewood.png"},
groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
sounds = default.node_sound_wood_defaults(),
})

View File

@ -1,55 +1,6 @@
-- Minetest 0.4 mod: player
-- See README.txt for licensing and other information.
--[[
API
---
default.player_register_model(name, def)
^ Register a new model to be used by players.
^ <name> is the model filename such as "character.x", "foo.b3d", etc.
^ See Model Definition below for format of <def>.
default.registered_player_models[name]
^ See Model Definition below for format.
default.player_set_model(player, model_name)
^ <player> is a PlayerRef.
^ <model_name> is a model registered with player_register_model.
default.player_set_animation(player, anim_name [, speed])
^ <player> is a PlayerRef.
^ <anim_name> is the name of the animation.
^ <speed> is in frames per second. If nil, default from the model is used
default.player_set_textures(player, textures)
^ <player> is a PlayerRef.
^ <textures> is an array of textures
^ If <textures> is nil, the default textures from the model def are used
default.player_get_animation(player)
^ <player> is a PlayerRef.
^ Returns a table containing fields "model", "textures" and "animation".
^ Any of the fields of the returned table may be nil.
Model Definition
----------------
model_def = {
animation_speed = 30, -- Default animation speed, in FPS.
textures = {"character.png", }, -- Default array of textures.
visual_size = {x=1, y=1,}, -- Used to scale the model.
animations = {
-- <anim_name> = { x=<start_frame>, y=<end_frame>, },
foo = { x= 0, y=19, },
bar = { x=20, y=39, },
-- ...
},
}
]]
-- Player animation blending
-- Note: This is currently broken due to a bug in Irrlicht, leave at 0
local animation_blend = 0
@ -162,6 +113,7 @@ end)
-- Localize for better performance.
local player_set_animation = default.player_set_animation
local player_attached = default.player_attached
-- Check each player and apply animations
minetest.register_globalstep(function(dtime)
@ -169,7 +121,7 @@ minetest.register_globalstep(function(dtime)
local name = player:get_player_name()
local model_name = player_model[name]
local model = model_name and models[model_name]
if model and not default.player_attached[name] then
if model and not player_attached[name] then
local controls = player:get_player_control()
local walking = false
local animation_speed_mod = model.animation_speed or 30

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 B

After

Width:  |  Height:  |  Size: 568 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 B

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 B

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 780 B

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 638 B

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 627 B

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 B

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 B

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 835 B

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 693 B

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 B

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 771 B

After

Width:  |  Height:  |  Size: 827 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 470 B

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

After

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 689 B

After

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 368 B

View File

@ -1,150 +1,344 @@
--
-- Grow trees
--
local random = math.random
local function can_grow(pos)
local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
if not node_under then
return false
end
local name_under = node_under.name
local is_soil = minetest.get_item_group(name_under, "soil")
if is_soil == 0 then
return false
end
return true
end
-- Sapling ABMs
minetest.register_abm({
nodenames = {"default:sapling"},
interval = 10,
chance = 50,
action = function(pos, node)
if not can_grow(pos) then
return
end
minetest.log("action", "A sapling grows into a tree at "..
minetest.pos_to_string(pos))
default.grow_tree(pos, random(1, 4) == 1)
end
})
minetest.register_abm({
nodenames = {"default:junglesapling"},
interval = 11,
chance = 50,
action = function(pos, node)
if not can_grow(pos) then
return
end
minetest.log("action", "A jungle sapling grows into a tree at "..
minetest.pos_to_string(pos))
default.grow_jungletree(pos)
end
})
minetest.register_abm({
nodenames = {"default:pine_sapling"},
interval = 12,
chance = 50,
action = function(pos, node)
if not can_grow(pos) then
return
end
minetest.log("action", "A pine sapling grows into a tree at "..
minetest.pos_to_string(pos))
default.grow_pinetree(pos)
end
})
-- Appletree, jungletree function
local function add_trunk_and_leaves(data, a, pos, tree_cid, leaves_cid,
height, size, iters, is_apple_tree)
local x, y, z = pos.x, pos.y, pos.z
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local c_tree = minetest.get_content_id("default:tree")
local c_leaves = minetest.get_content_id("default:leaves")
local c_apple = minetest.get_content_id("default:apple")
function default.grow_tree(data, a, pos, is_apple_tree, seed)
-- Trunk
for y_dist = 0, height - 1 do
local vi = a:index(x, y + y_dist, z)
local node_id = data[vi]
if y_dist == 0 or node_id == c_air or node_id == c_ignore
or node_id == leaves_cid then
data[vi] = tree_cid
end
end
-- Force leaves near the trunk
for z_dist = -1, 1 do
for y_dist = -size, 1 do
local vi = a:index(x - 1, y + height + y_dist, z + z_dist)
for x_dist = -1, 1 do
if data[vi] == c_air or data[vi] == c_ignore then
if is_apple_tree and random(1, 8) == 1 then
data[vi] = c_apple
else
data[vi] = leaves_cid
end
end
vi = vi + 1
end
end
end
-- Randomly add leaves in 2x2x2 clusters.
for i = 1, iters do
local clust_x = x + random(-size, size - 1)
local clust_y = y + height + random(-size, 0)
local clust_z = z + random(-size, size - 1)
for xi = 0, 1 do
for yi = 0, 1 do
for zi = 0, 1 do
local vi = a:index(clust_x + xi, clust_y + yi, clust_z + zi)
if data[vi] == c_air or data[vi] == c_ignore then
if is_apple_tree and random(1, 8) == 1 then
data[vi] = c_apple
else
data[vi] = leaves_cid
end
end
end
end
end
end
end
-- Appletree
function default.grow_tree(pos, is_apple_tree, bad)
--[[
NOTE: Tree-placing code is currently duplicated in the engine
and in games that have saplings; both are deprecated but not
replaced yet
]]--
local pr = PseudoRandom(seed)
local th = pr:next(4, 5)
--]]
if bad then
error("Deprecated use of default.grow_tree")
end
local x, y, z = pos.x, pos.y, pos.z
for yy = y, y+th-1 do
local vi = a:index(x, yy, z)
if a:contains(x, yy, z) and (data[vi] == c_air or yy == y) then
data[vi] = c_tree
end
end
y = y+th-1 -- (x, y, z) is now last piece of trunk
local leaves_a = VoxelArea:new{MinEdge={x=-2, y=-1, z=-2}, MaxEdge={x=2, y=2, z=2}}
local leaves_buffer = {}
local height = random(4, 5)
local c_tree = minetest.get_content_id("default:tree")
local c_leaves = minetest.get_content_id("default:leaves")
-- Force leaves near the trunk
local d = 1
for xi = -d, d do
for yi = -d, d do
for zi = -d, d do
leaves_buffer[leaves_a:index(xi, yi, zi)] = true
end
end
local vm = minetest.get_voxel_manip()
local minp, maxp = vm:read_from_map(
{x = pos.x - 2, y = pos.y, z = pos.z - 2},
{x = pos.x + 2, y = pos.y + height + 1, z = pos.z + 2}
)
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
local data = vm:get_data()
add_trunk_and_leaves(data, a, pos, c_tree, c_leaves, height, 2, 8, is_apple_tree)
vm:set_data(data)
vm:write_to_map()
vm:update_map()
end
-- Add leaves randomly
for iii = 1, 8 do
local d = 1
local xx = pr:next(leaves_a.MinEdge.x, leaves_a.MaxEdge.x - d)
local yy = pr:next(leaves_a.MinEdge.y, leaves_a.MaxEdge.y - d)
local zz = pr:next(leaves_a.MinEdge.z, leaves_a.MaxEdge.z - d)
-- Jungletree
for xi = 0, d do
for yi = 0, d do
for zi = 0, d do
leaves_buffer[leaves_a:index(xx+xi, yy+yi, zz+zi)] = true
end
end
end
end
-- Add the leaves
for xi = leaves_a.MinEdge.x, leaves_a.MaxEdge.x do
for yi = leaves_a.MinEdge.y, leaves_a.MaxEdge.y do
for zi = leaves_a.MinEdge.z, leaves_a.MaxEdge.z do
if a:contains(x+xi, y+yi, z+zi) then
local vi = a:index(x+xi, y+yi, z+zi)
if data[vi] == c_air or data[vi] == c_ignore then
if leaves_buffer[leaves_a:index(xi, yi, zi)] then
if is_apple_tree and pr:next(1, 100) <= 10 then
data[vi] = c_apple
else
data[vi] = c_leaves
end
end
end
end
end
end
end
function default.grow_jungletree(pos, bad)
--[[
NOTE: Jungletree-placing code is currently duplicated in the engine
and in games that have saplings; both are deprecated but not
replaced yet
--]]
if bad then
error("Deprecated use of default.grow_jungletree")
end
local x, y, z = pos.x, pos.y, pos.z
local height = random(8, 12)
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local c_jungletree = minetest.get_content_id("default:jungletree")
local c_jungleleaves = minetest.get_content_id("default:jungleleaves")
function default.grow_jungletree(data, a, pos, seed)
--[[
NOTE: Tree-placing code is currently duplicated in the engine
and in games that have saplings; both are deprecated but not
replaced yet
]]--
local pr = PseudoRandom(seed)
local x, y, z = pos.x, pos.y, pos.z
for xi = -1, 1 do
for zi = -1, 1 do
if pr:next(1, 3) >= 2 then
local vi1 = a:index(x+xi, y, z+zi)
local vi2 = a:index(x+xi, y-1, z+zi)
if a:contains(x+xi, y-1, z+zi) and data[vi2] == c_air then
data[vi2] = c_jungletree
elseif a:contains(x+xi, y, z+zi) and data[vi1] == c_air then
data[vi1] = c_jungletree
local vm = minetest.get_voxel_manip()
local minp, maxp = vm:read_from_map(
{x = pos.x - 3, y = pos.y - 1, z = pos.z - 3},
{x = pos.x + 3, y = pos.y + height + 1, z = pos.z + 3}
)
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
local data = vm:get_data()
add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves, height, 3, 30, false)
-- Roots
for z_dist = -1, 1 do
local vi_1 = a:index(x - 1, y - 1, z + z_dist)
local vi_2 = a:index(x - 1, y, z + z_dist)
for x_dist = -1, 1 do
if random(1, 3) >= 2 then
if data[vi_1] == c_air or data[vi_1] == c_ignore then
data[vi_1] = c_jungletree
elseif data[vi_2] == c_air or data[vi_2] == c_ignore then
data[vi_2] = c_jungletree
end
end
vi_1 = vi_1 + 1
vi_2 = vi_2 + 1
end
end
local th = pr:next(8, 12)
for yy = y, y+th-1 do
local vi = a:index(x, yy, z)
if a:contains(x, yy, z) and (data[vi] == c_air or yy == y) then
data[vi] = c_jungletree
vm:set_data(data)
vm:write_to_map()
vm:update_map()
end
end
y = y+th-1 -- (x, y, z) is now last piece of trunk
local leaves_a = VoxelArea:new{MinEdge={x=-3, y=-2, z=-3}, MaxEdge={x=3, y=2, z=3}}
local leaves_buffer = {}
-- Force leaves near the trunk
local d = 1
for xi = -d, d do
for yi = -d, d do
for zi = -d, d do
leaves_buffer[leaves_a:index(xi, yi, zi)] = true
end
-- Pinetree from mg mapgen mod, design by sfan5, pointy top added by paramat
local function add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles)
if data[vi] == c_air or data[vi] == c_ignore or data[vi] == c_snow then
data[vi] = c_pine_needles
end
end
-- Add leaves randomly
for iii = 1, 30 do
local d = 1
local xx = pr:next(leaves_a.MinEdge.x, leaves_a.MaxEdge.x - d)
local yy = pr:next(leaves_a.MinEdge.y, leaves_a.MaxEdge.y - d)
local zz = pr:next(leaves_a.MinEdge.z, leaves_a.MaxEdge.z - d)
for xi = 0, d do
for yi = 0, d do
for zi = 0, d do
leaves_buffer[leaves_a:index(xx+xi, yy+yi, zz+zi)] = true
end
end
end
end
-- Add the leaves
for xi = leaves_a.MinEdge.x, leaves_a.MaxEdge.x do
for yi = leaves_a.MinEdge.y, leaves_a.MaxEdge.y do
for zi = leaves_a.MinEdge.z, leaves_a.MaxEdge.z do
if a:contains(x+xi, y+yi, z+zi) then
local vi = a:index(x+xi, y+yi, z+zi)
local function add_snow(data, vi, c_air, c_ignore, c_snow)
if data[vi] == c_air or data[vi] == c_ignore then
if leaves_buffer[leaves_a:index(xi, yi, zi)] then
data[vi] = c_jungleleaves
data[vi] = c_snow
end
end
function default.grow_pinetree(pos)
local x, y, z = pos.x, pos.y, pos.z
local maxy = y + random(9, 13) -- Trunk top
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local c_pinetree = minetest.get_content_id("default:pinetree")
local c_pine_needles = minetest.get_content_id("default:pine_needles")
local c_snow = minetest.get_content_id("default:snow")
local c_snowblock = minetest.get_content_id("default:snowblock")
local c_dirtsnow = minetest.get_content_id("default:dirt_with_snow")
local vm = minetest.get_voxel_manip()
local minp, maxp = vm:read_from_map(
{x = x - 3, y = y - 1, z = z - 3},
{x = x + 3, y = maxy + 3, z = z + 3}
)
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
local data = vm:get_data()
-- Scan for snow nodes near sapling
local snow = false
for yy = y - 1, y + 1 do
for zz = z - 1, z + 1 do
local vi = a:index(x - 1, yy, zz)
for xx = x - 1, x + 1 do
local nodid = data[vi]
if nodid == c_snow
or nodid == c_snowblock
or nodid == c_dirtsnow then
snow = true
end
vi = vi + 1
end
end
end
-- Upper branches layer
local dev = 3
for yy = maxy - 1, maxy + 1 do
for zz = z - dev, z + dev do
local vi = a:index(x - dev, yy, zz)
local via = a:index(x - dev, yy + 1, zz)
for xx = x - dev, x + dev do
if random() < 0.95 - dev * 0.05 then
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
c_pine_needles)
if snow then
add_snow(data, via, c_air, c_ignore, c_snow)
end
end
vi = vi + 1
via = via + 1
end
end
dev = dev - 1
end
-- Centre top nodes
add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow,
c_pine_needles)
add_pine_needles(data, a:index(x, maxy + 2, z), c_air, c_ignore, c_snow,
c_pine_needles) -- Paramat added a pointy top node
if snow then
add_snow(data, a:index(x, maxy + 3, z), c_air, c_ignore, c_snow)
end
-- Lower branches layer
local my = 0
for i = 1, 20 do -- Random 2x2 squares of needles
local xi = x + random(-3, 2)
local yy = maxy + random(-6, -5)
local zi = z + random(-3, 2)
if yy > my then
my = yy
end
for zz = zi, zi+1 do
local vi = a:index(xi, yy, zz)
local via = a:index(xi, yy + 1, zz)
for xx = xi, xi + 1 do
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
c_pine_needles)
if snow then
add_snow(data, via, c_air, c_ignore, c_snow)
end
vi = vi + 1
via = via + 1
end
end
end
local dev = 2
for yy = my + 1, my + 2 do
for zz = z - dev, z + dev do
local vi = a:index(x - dev, yy, zz)
local via = a:index(x - dev, yy + 1, zz)
for xx = x - dev, x + dev do
if random() < 0.95 - dev * 0.05 then
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
c_pine_needles)
if snow then
add_snow(data, via, c_air, c_ignore, c_snow)
end
end
vi = vi + 1
via = via + 1
end
end
dev = dev - 1
end
-- Trunk
for yy = y, maxy do
local vi = a:index(x, yy, z)
data[vi] = c_pinetree
end
vm:set_data(data)
vm:write_to_map()
vm:update_map()
end

View File

@ -16,17 +16,6 @@ doors = {}
-- only_placer_can_open: if true only the player who placed the door can
-- open it
local function is_right(pos)
local r1 = minetest.get_node({x=pos.x-1, y=pos.y, z=pos.z})
local r2 = minetest.get_node({x=pos.x, y=pos.y, z=pos.z-1})
if string.find(r1.name, "door_") or string.find(r2.name, "door_") then
if string.find(r1.name, "_1") or string.find(r2.name, "_1") then
return true
else
return false
end
end
end
function doors.register_door(name, def)
def.groups.not_in_creative_inventory = 1
@ -46,6 +35,14 @@ function doors.register_door(name, def)
def.selection_box_top = box
end
if not def.sound_close_door then
def.sound_close_door = "door_close"
end
if not def.sound_open_door then
def.sound_open_door = "door_open"
end
minetest.register_craftitem(name, {
description = def.description,
inventory_image = def.inventory_image,
@ -90,12 +87,14 @@ function doors.register_door(name, def)
elseif p2 == 3 then
pt3.z = pt3.z-1
end
if not string.find(minetest.get_node(pt3).name, name.."_b_") then
if minetest.get_item_group(minetest.get_node(pt3).name, "door") == 0 then
minetest.set_node(pt, {name=name.."_b_1", param2=p2})
minetest.set_node(pt2, {name=name.."_t_1", param2=p2})
else
minetest.set_node(pt, {name=name.."_b_2", param2=p2})
minetest.set_node(pt2, {name=name.."_t_2", param2=p2})
minetest.get_meta(pt):set_int("right", 1)
minetest.get_meta(pt2):set_int("right", 1)
end
if def.only_placer_can_open then
@ -138,17 +137,17 @@ function doors.register_door(name, def)
pos.y = pos.y-dir
minetest.swap_node(pos, {name=replace, param2=p2})
local snd_1 = "_close"
local snd_2 = "_open"
local snd_1 = def.sound_close_door
local snd_2 = def.sound_open_door
if params[1] == 3 then
snd_1 = "_open"
snd_2 = "_close"
snd_1 = def.sound_open_door
snd_2 = def.sound_close_door
end
if is_right(pos) then
minetest.sound_play("door"..snd_1, {pos = pos, gain = 0.3, max_hear_distance = 10})
if minetest.get_meta(pos):get_int("right") ~= 0 then
minetest.sound_play(snd_1, {pos = pos, gain = 0.3, max_hear_distance = 10})
else
minetest.sound_play("door"..snd_2, {pos = pos, gain = 0.3, max_hear_distance = 10})
minetest.sound_play(snd_2, {pos = pos, gain = 0.3, max_hear_distance = 10})
end
end
@ -381,7 +380,6 @@ local function punch(pos)
local me = minetest.get_node(pos)
local tmp_node
local tmp_node2
oben = {x=pos.x, y=pos.y+1, z=pos.z}
if state == 1 then
state = 0
minetest.sound_play("door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
@ -429,6 +427,7 @@ minetest.register_node("doors:trapdoor_open", {
pointable = true,
stack_max = 0,
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=2,door=1},
climbable = true,
sounds = default.node_sound_wood_defaults(),
drop = "doors:trapdoor",
node_box = {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 B

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

After

Width:  |  Height:  |  Size: 539 B

View File

@ -1,63 +1,10 @@
-- minetest/dye/init.lua
-- To make recipes that will work with any dye ever made by anybody, define
-- them based on groups.
-- You can select any group of groups, based on your need for amount of colors.
-- basecolor: 9, excolor: 17, unicolor: 89
--
-- Example of one shapeless recipe using a color group:
-- Note: As this uses basecolor_*, you'd need 9 of these.
-- minetest.register_craft({
-- type = "shapeless",
-- output = '<mod>:item_yellow',
-- recipe = {'<mod>:item_no_color', 'group:basecolor_yellow'},
-- })
-- Other mods can use these for looping through available colors
local dye = {}
dye = {}
dye.basecolors = {"white", "grey", "black", "red", "yellow", "green", "cyan", "blue", "magenta"}
dye.excolors = {"white", "lightgrey", "grey", "darkgrey", "black", "red", "orange", "yellow", "lime", "green", "aqua", "cyan", "sky_blue", "blue", "violet", "magenta", "red_violet"}
-- Base color groups:
-- - basecolor_white
-- - basecolor_grey
-- - basecolor_black
-- - basecolor_red
-- - basecolor_yellow
-- - basecolor_green
-- - basecolor_cyan
-- - basecolor_blue
-- - basecolor_magenta
-- Extended color groups (* = equal to a base color):
-- * excolor_white
-- - excolor_lightgrey
-- * excolor_grey
-- - excolor_darkgrey
-- * excolor_black
-- * excolor_red
-- - excolor_orange
-- * excolor_yellow
-- - excolor_lime
-- * excolor_green
-- - excolor_aqua
-- * excolor_cyan
-- - excolor_sky_blue
-- * excolor_blue
-- - excolor_violet
-- * excolor_magenta
-- - excolor_red_violet
-- The whole unifieddyes palette as groups:
-- - unicolor_<excolor>
-- For the following, no white/grey/black is allowed:
-- - unicolor_medium_<excolor>
-- - unicolor_dark_<excolor>
-- - unicolor_light_<excolor>
-- - unicolor_<excolor>_s50
-- - unicolor_medium_<excolor>_s50
-- - unicolor_dark_<excolor>_s50
-- Local stuff
local dyelocal = {}
@ -73,7 +20,7 @@ dyelocal.dyes = {
{"dark_green", "Dark green dye",{dye=1, basecolor_green=1, excolor_green=1, unicolor_dark_green=1}},
{"green", "Green dye", {dye=1, basecolor_green=1, excolor_green=1, unicolor_green=1}},
{"yellow", "Yellow dye", {dye=1, basecolor_yellow=1, excolor_yellow=1, unicolor_yellow=1}},
{"brown", "Brown dye", {dye=1, basecolor_yellow=1, excolor_orange=1, unicolor_dark_orange=1}},
{"brown", "Brown dye", {dye=1, basecolor_brown=1, excolor_orange=1, unicolor_dark_orange=1}},
{"orange", "Orange dye", {dye=1, basecolor_orange=1, excolor_orange=1, unicolor_orange=1}},
{"red", "Red dye", {dye=1, basecolor_red=1, excolor_red=1, unicolor_red=1}},
{"magenta", "Magenta dye", {dye=1, basecolor_magenta=1, excolor_red_violet=1,unicolor_red_violet=1}},
@ -98,6 +45,12 @@ for _, row in ipairs(dyelocal.dyes) do
recipe = {"group:flower,color_"..name},
})
end
-- manually add coal->black dye
minetest.register_craft({
type = "shapeless",
output = "dye:black 4",
recipe = {"group:coal"},
})
-- Mix recipes
-- Just mix everything to everything somehow sanely
@ -132,8 +85,3 @@ for one,results in pairs(dyelocal.mixes) do
})
end
end
-- Hide dyelocal
dyelocal = nil
-- EOF

View File

@ -44,7 +44,10 @@ farming.hoe_on_use = function(itemstack, user, pointed_thing, uses)
pos = pt.under,
gain = 0.5,
})
if not minetest.setting_getbool("creative_mode") then
itemstack:add_wear(65535/(uses-1))
end
return itemstack
end
@ -135,25 +138,27 @@ end
farming.register_plant = function(name, def)
local mname = name:split(":")[1]
local pname = name:split(":")[2]
-- Check def table
if def.description == nil then
if not def.description then
def.description = "Seed"
end
if def.inventory_image == nil then
if not def.inventory_image then
def.inventory_image = "unknown_item.png"
end
if def.steps == nil then
if not def.steps then
return nil
end
if def.minlight == nil then
if not def.minlight then
def.minlight = 1
end
if def.maxlight == nil then
if not def.maxlight then
def.maxlight = 14
end
if not def.fertility then
def.fertility = {}
end
-- Register seed
local g = {seed = 1, snappy = 3, attached_node = 1}
for k, v in pairs(def.fertility) do
@ -179,40 +184,13 @@ farming.register_plant = function(name, def)
return farming.place_seed(itemstack, placer, pointed_thing, mname .. ":seed_" .. pname)
end
})
-- Seed -> plant
minetest.register_abm({
nodenames = {"group:seed"},
neighbors = {"group:soil"},
interval = 90,
chance = 2,
action = function(pos, node)
local seedferts = minetest.registered_nodes[node.name].fertility
local soilferts = {}
-- Collect fertilities of soil
for k, v in pairs(minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}).name].groups) do
if k == "grassland" or k == "desert" then
soilferts[k] = k
end
end
-- Cannot grow if no fertility match found
local fertmatch = false
for k, v in pairs(seedferts) do
if soilferts[v] ~= nil then
fertmatch = true
break
end
end
if fertmatch == true and minetest.get_item_group(minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}).name, "wet") ~= 0 then
minetest.set_node(pos, {name = node.name:gsub("seed_", "") .. "_1"})
end
end
})
-- Register harvest
minetest.register_craftitem(":" .. mname .. ":" .. pname, {
description = pname:gsub("^%l", string.upper),
inventory_image = mname .. "_" .. pname .. ".png",
})
-- Register growing steps
for i=1,def.steps do
local drop = {
@ -242,15 +220,38 @@ farming.register_plant = function(name, def)
sounds = default.node_sound_leaves_defaults(),
})
end
-- Growing ABM
minetest.register_abm({
nodenames = {"group:" .. pname},
nodenames = {"group:" .. pname, "group:seed"},
neighbors = {"group:soil"},
interval = 90,
chance = 2,
action = function(pos, node)
local plant_height = minetest.get_item_group(node.name, pname)
-- return if already full grown
if minetest.get_item_group(node.name, pname) == def.steps then
if plant_height == def.steps then
return
end
local node_def = minetest.registered_items[node.name] or nil
-- grow seed
if minetest.get_item_group(node.name, "seed") and node_def.fertility then
local can_grow = false
local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
if not soil_node then
return
end
for _, v in pairs(node_def.fertility) do
if minetest.get_item_group(soil_node.name, v) ~= 0 then
can_grow = true
end
end
if can_grow then
minetest.set_node(pos, {name = node.name:gsub("seed_", "") .. "_1"})
end
return
end
@ -263,18 +264,17 @@ farming.register_plant = function(name, def)
pos.y = pos.y + 1
-- check light
if not minetest.get_node_light(pos) then
return
end
if minetest.get_node_light(pos) < def.minlight or minetest.get_node_light(pos) > def.maxlight then
local ll = minetest.get_node_light(pos)
if not ll or ll < def.minlight or ll > def.maxlight then
return
end
-- grow
local height = minetest.get_item_group(node.name, pname) + 1
minetest.set_node(pos, {name = mname .. ":" .. pname .. "_" .. height})
minetest.set_node(pos, {name = mname .. ":" .. pname .. "_" .. plant_height + 1})
end
})
-- Return
local r = {
seed = mname .. ":seed_" .. pname,

View File

@ -50,10 +50,7 @@ farming.register_plant("farming:cotton", {
fertility = {"grassland", "desert"}
})
minetest.register_craftitem("farming:string", {
description = "String",
inventory_image = "farming_cotton.png",
})
minetest.register_alias("farming:string", "farming:cotton")
minetest.register_craft({
output = "wool:white",

View File

@ -18,10 +18,10 @@ minetest.override_item("default:dirt_with_grass", {
minetest.register_node("farming:soil", {
description = "Soil",
tiles = {"farming_soil.png", "default_dirt.png"},
tiles = {"default_dirt.png^farming_soil.png", "default_dirt.png"},
drop = "default:dirt",
is_ground_content = true,
groups = {crumbly=3, not_in_creative_inventory=1, soil=2, grassland = 1},
groups = {crumbly=3, not_in_creative_inventory=1, soil=2, grassland = 1, field = 1},
sounds = default.node_sound_dirt_defaults(),
soil = {
base = "default:dirt",
@ -32,10 +32,10 @@ minetest.register_node("farming:soil", {
minetest.register_node("farming:soil_wet", {
description = "Wet Soil",
tiles = {"farming_soil_wet.png", "farming_soil_wet_side.png"},
tiles = {"default_dirt.png^farming_soil_wet.png", "default_dirt.png^farming_soil_wet_side.png"},
drop = "default:dirt",
is_ground_content = true,
groups = {crumbly=3, not_in_creative_inventory=1, soil=3, wet = 1, grassland = 1},
groups = {crumbly=3, not_in_creative_inventory=1, soil=3, wet = 1, grassland = 1, field = 1},
sounds = default.node_sound_dirt_defaults(),
soil = {
base = "default:dirt",
@ -53,10 +53,11 @@ minetest.override_item("default:desert_sand", {
}
})
minetest.register_node("farming:desert_sand_soil", {
description = "Desert Sand",
description = "Desert Sand Soil",
drop = "default:desert_sand",
tiles = {"farming_desert_sand_soil.png", "default_desert_sand.png"},
is_ground_content = true,
groups = {crumbly=3, not_in_creative_inventory = 1, falling_node=1, sand=1, soil = 2, desert = 1},
groups = {crumbly=3, not_in_creative_inventory = 1, falling_node=1, sand=1, soil = 2, desert = 1, field = 1},
sounds = default.node_sound_sand_defaults(),
soil = {
base = "default:desert_sand",
@ -66,11 +67,11 @@ minetest.register_node("farming:desert_sand_soil", {
})
minetest.register_node("farming:desert_sand_soil_wet", {
description = "Desert Sand",
description = "Wet Desert Sand Soil",
drop = "default:desert_sand",
tiles = {"farming_desert_sand_soil_wet.png", "farming_desert_sand_soil_wet_side.png"},
is_ground_content = true,
groups = {crumbly=3, falling_node=1, sand=1, not_in_creative_inventory=1, soil=3, wet = 1, desert = 1},
groups = {crumbly=3, falling_node=1, sand=1, not_in_creative_inventory=1, soil=3, wet = 1, desert = 1, field = 1},
sounds = default.node_sound_sand_defaults(),
soil = {
base = "default:desert_sand",
@ -80,39 +81,52 @@ minetest.register_node("farming:desert_sand_soil_wet", {
})
minetest.register_abm({
nodenames = {"group:soil", "group:wet"},
interval = 5,
chance = 10,
nodenames = {"group:field"},
interval = 15,
chance = 4,
action = function(pos, node)
pos.y = pos.y+1
local nn = minetest.get_node(pos).name
node = minetest.registered_nodes[node.name]
pos.y = pos.y-1
if node.soil == nil or node.soil.wet == nil or node.soil.base == nil or node.soil.dry == nil then
local n_def = minetest.registered_nodes[node.name] or nil
local wet = n_def.soil.wet or nil
local base = n_def.soil.base or nil
local dry = n_def.soil.dry or nil
if not n_def or not n_def.soil or not wet or not base or not dry then
return
end
if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].walkable and minetest.get_item_group(nn, "plant") == 0 and node.name ~= node.soil.base then
minetest.set_node(pos, {name = node.soil.base})
pos.y = pos.y + 1
local nn = minetest.get_node_or_nil(pos)
if not nn or not nn.name then
return
end
local nn_def = minetest.registered_nodes[nn.name] or nil
pos.y = pos.y - 1
if nn_def and nn_def.walkable and minetest.get_item_group(nn.name, "plant") == 0 then
minetest.set_node(pos, {name = base})
return
end
-- check if there is water nearby
local wet_lvl = minetest.get_item_group(node.name, "wet")
if minetest.find_node_near(pos, 3, {"group:water"}) then
-- if it is dry soil and not base node, turn it into wet soil
if node.name ~= node.soil.base and minetest.get_item_group(node.name, "wet") == 0 then
minetest.set_node(pos, {name = node.soil.wet})
if wet_lvl == 0 then
minetest.set_node(pos, {name = wet})
end
else
-- only turn back if there are no unloaded blocks (and therefore
-- possible water sources) nearby
if not minetest.find_node_near(pos, 3, {"ignore"}) then
-- turn it back into base if it is already dry
if minetest.get_item_group(node.name, "wet") == 0 then
if wet_lvl == 0 then
-- only turn it back if there is no plant/seed on top of it
if minetest.get_item_group(nn, "plant") == 0 and minetest.get_item_group(nn, "seed") == 0 then
minetest.set_node(pos, {name = node.soil.base})
if minetest.get_item_group(nn.name, "plant") == 0 and minetest.get_item_group(nn.name, "seed") == 0 then
minetest.set_node(pos, {name = base})
end
-- if its wet turn it back into dry soil
elseif minetest.get_item_group(node.name, "wet") == 1 then
minetest.set_node(pos, {name = node.soil.dry})
elseif wet_lvl == 1 then
minetest.set_node(pos, {name = dry})
end
end
end
end,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 713 B

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 659 B

After

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 109 B

View File

@ -1,30 +1,31 @@
-- minetest/fire/init.lua
fire = {}
minetest.register_node("fire:basic_flame", {
description = "Fire",
drawtype = "plantlike",
drawtype = "firelike",
tiles = {{
name="fire_basic_flame_animated.png",
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1},
}},
inventory_image = "fire_basic_flame.png",
light_source = 14,
groups = {igniter=2,dig_immediate=3,hot=3},
groups = {igniter=2,dig_immediate=3},
drop = '',
walkable = false,
buildable_to = true,
damage_per_second = 4,
after_place_node = function(pos, placer)
fire.on_flame_add_at(pos)
on_construct = function(pos)
minetest.after(0, fire.on_flame_add_at, pos)
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
fire.on_flame_remove_at(pos)
on_destruct = function(pos)
minetest.after(0, fire.on_flame_remove_at, pos)
end,
})
fire = {}
fire.D = 6
-- key: position hash of low corner of area
-- value: {handle=sound handle, name=sound name}
@ -81,12 +82,10 @@ function fire.update_sounds_around(pos)
end
function fire.on_flame_add_at(pos)
--print("flame added at "..minetest.pos_to_string(pos))
fire.update_sounds_around(pos)
end
function fire.on_flame_remove_at(pos)
--print("flame removed at "..minetest.pos_to_string(pos))
fire.update_sounds_around(pos)
end
@ -117,7 +116,6 @@ minetest.register_abm({
local p = fire.find_pos_for_flame_around(p0)
if p then
minetest.set_node(p, {name="fire:basic_flame"})
fire.on_flame_add_at(p)
end
end,
})
@ -143,7 +141,6 @@ minetest.register_abm({
local p2 = fire.find_pos_for_flame_around(p)
if p2 then
minetest.set_node(p2, {name="fire:basic_flame"})
fire.on_flame_add_at(p2)
end
end
end,
@ -158,7 +155,6 @@ minetest.register_abm({
-- If there is water or stuff like that around flame, remove flame
if fire.flame_should_extinguish(p0) then
minetest.remove_node(p0)
fire.on_flame_remove_at(p0)
return
end
-- Make the following things rarer
@ -168,7 +164,6 @@ minetest.register_abm({
-- If there are no flammable nodes around flame, remove flame
if not minetest.find_node_near(p0, 1, {"group:flammable"}) then
minetest.remove_node(p0)
fire.on_flame_remove_at(p0)
return
end
if math.random(1,4) == 1 then
@ -185,7 +180,6 @@ minetest.register_abm({
else
-- remove flame
minetest.remove_node(p0)
fire.on_flame_remove_at(p0)
end
end,
})

View File

@ -1,6 +1,9 @@
-- Minetest 0.4 mod: default
-- See README.txt for licensing and other information.
-- Namespace for functions
flowers = {}
-- Map Generation
dofile(minetest.get_modpath("flowers").."/mapgen.lua")
@ -26,7 +29,7 @@ minetest.register_node("flowers:dandelion_white", {
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = { -0.15, -0.5, -0.15, 0.15, 0.2, 0.15 },
fixed = { -0.5, -0.5, -0.5, 0.5, -0.2, 0.5 },
},
})
@ -80,7 +83,7 @@ minetest.register_node("flowers:rose", {
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = { -0.15, -0.5, -0.15, 0.15, 0.2, 0.15 },
fixed = { -0.15, -0.5, -0.15, 0.15, 0.3, 0.15 },
},
})
@ -116,7 +119,7 @@ minetest.register_node("flowers:viola", {
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = { -0.15, -0.5, -0.15, 0.15, 0.2, 0.15 },
fixed = { -0.5, -0.5, -0.5, 0.5, -0.2, 0.5 },
},
})

View File

@ -1,4 +1,4 @@
minetest.register_on_generated(function(minp, maxp, seed)
function flowers.mgv6ongen(minp, maxp, seed)
if maxp.y >= 2 and minp.y <= 0 then
-- Generate flowers
local perlin1 = minetest.get_perlin(436, 3, 0.6, 100)
@ -59,4 +59,12 @@ minetest.register_on_generated(function(minp, maxp, seed)
end
end
end
end
-- Enable in mapgen v6 only
minetest.register_on_mapgen_init(function(mg_params)
if mg_params.mgname == "v6" then
minetest.register_on_generated(flowers.mgv6ongen)
end
end)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 B

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

After

Width:  |  Height:  |  Size: 291 B

View File

@ -1,52 +1,3 @@
local mode_text = {
{"Change rotation, Don't change axisdir."},
{"Keep choosen face in front then rotate it."},
{"Change axis dir, Reset rotation."},
{"Bring top in front then rotate it."},
}
local opposite_faces = {
[0] = 5,
[1] = 2,
[2] = 1,
[3] = 4,
[4] = 3,
[5] = 0,
}
local function screwdriver_setmode(user,itemstack)
local player_name = user:get_player_name()
local item = itemstack:to_table()
local mode = tonumber(itemstack:get_metadata())
if not mode then
minetest.chat_send_player(player_name, "Hold shift and use to change screwdriwer modes.")
mode = 0
end
mode = mode + 1
if mode == 5 then
mode = 1
end
minetest.chat_send_player(player_name, "Screwdriver mode : "..mode.." - "..mode_text[mode][1] )
itemstack:set_name("screwdriver:screwdriver"..mode)
itemstack:set_metadata(mode)
return itemstack
end
local function get_node_face(pointed_thing)
local ax, ay, az = pointed_thing.above.x, pointed_thing.above.y, pointed_thing.above.z
local ux, uy, uz = pointed_thing.under.x, pointed_thing.under.y, pointed_thing.under.z
if ay > uy then return 0 -- Top
elseif az > uz then return 1 -- Z+ side
elseif az < uz then return 2 -- Z- side
elseif ax > ux then return 3 -- X+ side
elseif ax < ux then return 4 -- X- side
elseif ay < uy then return 5 -- Bottom
else
error("pointed_thing.above and under are the same!")
end
end
local function nextrange(x, max)
x = x + 1
if x > max then
@ -55,21 +6,23 @@ local function nextrange(x, max)
return x
end
local function screwdriver_handler(itemstack, user, pointed_thing)
local ROTATE_FACE = 1
local ROTATE_AXIS = 2
local USES = 200
-- Handles rotation
local function screwdriver_handler(itemstack, user, pointed_thing, mode)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
local keys = user:get_player_control()
local player_name = user:get_player_name()
local mode = tonumber(itemstack:get_metadata())
if not mode or keys["sneak"] == true then
return screwdriver_setmode(user, itemstack)
end
if minetest.is_protected(pos, user:get_player_name()) then
minetest.record_protection_violation(pos, user:get_player_name())
return
end
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
if not ndef or not ndef.paramtype2 == "facedir" or
@ -78,54 +31,47 @@ local function screwdriver_handler(itemstack, user, pointed_thing)
node.param2 == nil then
return
end
-- Get ready to set the param2
local n = node.param2
local axisdir = math.floor(n / 4)
local rotation = n - axisdir * 4
if mode == 1 then
n = axisdir * 4 + nextrange(rotation, 3)
elseif mode == 2 then
-- If you are pointing at the axisdir face or the
-- opposite one then you can just rotate the node.
-- Otherwise change the axisdir, avoiding the facing
-- and opposite axes.
local face = get_node_face(pointed_thing)
if axisdir == face or axisdir == opposite_faces[face] then
n = axisdir * 4 + nextrange(rotation, 3)
else
axisdir = nextrange(axisdir, 5)
-- This is repeated because switching from the face
-- can move to to the opposite and vice-versa
if axisdir == face or axisdir == opposite_faces[face] then
axisdir = nextrange(axisdir, 5)
if ndef.can_dig and not ndef.can_dig(pos, user) then
return
end
if axisdir == face or axisdir == opposite_faces[face] then
axisdir = nextrange(axisdir, 5)
-- Set param2
local rotationPart = node.param2 % 32 -- get first 4 bits
local preservePart = node.param2 - rotationPart
local axisdir = math.floor(rotationPart / 4)
local rotation = rotationPart - axisdir * 4
if mode == ROTATE_FACE then
rotationPart = axisdir * 4 + nextrange(rotation, 3)
elseif mode == ROTATE_AXIS then
rotationPart = nextrange(axisdir, 5) * 4
end
n = axisdir * 4
end
elseif mode == 3 then
n = nextrange(axisdir, 5) * 4
elseif mode == 4 then
local face = get_node_face(pointed_thing)
if axisdir == face then
n = axisdir * 4 + nextrange(rotation, 3)
else
n = face * 4
end
end
--print (dump(axisdir..", "..rotation))
node.param2 = n
node.param2 = preservePart + rotationPart
minetest.swap_node(pos, node)
local item_wear = tonumber(itemstack:get_wear())
item_wear = item_wear + 327
if item_wear > 65535 then
itemstack:clear()
if not minetest.setting_getbool("creative_mode") then
itemstack:add_wear(65535 / (USES - 1))
end
return itemstack
end
itemstack:set_wear(item_wear)
-- Screwdriver
minetest.register_tool("screwdriver:screwdriver", {
description = "Screwdriver (left-click rotates face, right-click rotates axis)",
inventory_image = "screwdriver.png",
on_use = function(itemstack, user, pointed_thing)
screwdriver_handler(itemstack, user, pointed_thing, ROTATE_FACE)
return itemstack
end
end,
on_place = function(itemstack, user, pointed_thing)
screwdriver_handler(itemstack, user, pointed_thing, ROTATE_AXIS)
return itemstack
end,
})
minetest.register_craft({
output = "screwdriver:screwdriver",
@ -135,25 +81,7 @@ minetest.register_craft({
}
})
minetest.register_tool("screwdriver:screwdriver", {
description = "Screwdriver",
inventory_image = "screwdriver.png",
on_use = function(itemstack, user, pointed_thing)
screwdriver_handler(itemstack, user, pointed_thing)
return itemstack
end,
})
for i = 1, 4 do
minetest.register_tool("screwdriver:screwdriver"..i, {
description = "Screwdriver in Mode "..i,
inventory_image = "screwdriver.png^tool_mode"..i..".png",
wield_image = "screwdriver.png",
groups = {not_in_creative_inventory=1},
on_use = function(itemstack, user, pointed_thing)
screwdriver_handler(itemstack, user, pointed_thing)
return itemstack
end,
})
end
minetest.register_alias("screwdriver:screwdriver1", "screwdriver:screwdriver")
minetest.register_alias("screwdriver:screwdriver2", "screwdriver:screwdriver")
minetest.register_alias("screwdriver:screwdriver3", "screwdriver:screwdriver")
minetest.register_alias("screwdriver:screwdriver4", "screwdriver:screwdriver")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 769 B

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 B

View File

@ -30,7 +30,7 @@ minetest.register_chatcommand("home", {
description = "Teleport you to your home point",
privs = {home=true},
func = function(name)
local player = minetest.env:get_player_by_name(name)
local player = minetest.get_player_by_name(name)
if player == nil then
-- just a check to prevent the server crashing
return false
@ -48,7 +48,7 @@ minetest.register_chatcommand("sethome", {
description = "Set your home point",
privs = {home=true},
func = function(name)
local player = minetest.env:get_player_by_name(name)
local player = minetest.get_player_by_name(name)
local pos = player:getpos()
homepos[player:get_player_name()] = pos
minetest.chat_send_player(name, "Home set!")

View File

@ -288,3 +288,11 @@ stairs.register_stair_and_slab("stonebrick", "default:stonebrick",
"Stone Brick Stair",
"Stone Brick Slab",
default.node_sound_stone_defaults())
stairs.register_stair_and_slab("pinewood", "default:pinewood",
{snappy=2,choppy=2,oddly_breakable_by_hand=2,flammable=3},
{"default_pinewood.png"},
"Pinewood Stair",
"Pinewood Slab",
default.node_sound_wood_defaults())

View File

@ -1,19 +1,10 @@
=== TNT-MOD for MINETEST-C55 ===
by PilzAdam
=== TNT mod for Minetest ===
by PilzAdam and ShadowNinja
Introduction:
This mod adds TNT to Minetest. TNT is a tool to help the player
in mining.
How to install:
Unzip the archive an place it in minetest-base-directory/mods/minetest/
if you have a windows client or a linux run-in-place client. If you have
a linux system-wide instalation place it in ~/.minetest/mods/minetest/.
If you want to install this mod only in one world create the folder
worldmods/ in your worlddirectory.
For further information or help see:
http://wiki.minetest.com/wiki/Installing_Mods
How to use the mod:
Craft gunpowder by placing coal and gravel in the crafting area. The
gunpowder can be used to craft TNT or as fuze for TNT. To craft TNT

View File

@ -1,2 +1,3 @@
default
fire

View File

@ -1,193 +1,222 @@
-- Default to enabled in singleplayer and disabled in multiplayer
local singleplayer = minetest.is_singleplayer()
local setting = minetest.setting_getbool("enable_tnt")
if (not singleplayer and setting ~= true) or
(singleplayer and setting == false) then
return
end
-- loss probabilities array (one in X will be lost)
local loss_prob = {}
loss_prob["default:cobble"] = 3
loss_prob["default:dirt"] = 4
local radius_max = tonumber(minetest.setting_get("tnt_radius_max") or 25)
local radius = tonumber(minetest.setting_get("tnt_radius") or 3)
local eject_drops = function(pos, stack)
local obj = minetest.add_item(pos, stack)
if obj == nil then
return
-- Fill a list with data for content IDs, after all nodes are registered
local cid_data = {}
minetest.after(0, function()
for name, def in pairs(minetest.registered_nodes) do
cid_data[minetest.get_content_id(name)] = {
name = name,
drops = def.drops,
flammable = def.groups.flammable,
}
end
end)
local function rand_pos(center, pos, radius)
pos.x = center.x + math.random(-radius, radius)
pos.z = center.z + math.random(-radius, radius)
end
local function eject_drops(drops, pos, radius)
local drop_pos = vector.new(pos)
for _, item in pairs(drops) do
local count = item:get_count()
local max = item:get_stack_max()
if count > max then
item:set_count(max)
end
while count > 0 do
if count < max then
item:set_count(count)
end
rand_pos(pos, drop_pos, radius)
local obj = minetest.add_item(drop_pos, item)
if obj then
obj:get_luaentity().collect = true
obj:setacceleration({x=0, y=-10, z=0})
obj:setvelocity({x=math.random(0,6)-3, y=10, z=math.random(0,6)-3})
obj:setvelocity({x=math.random(-3, 3), y=10,
z=math.random(-3, 3)})
end
count = count - max
end
end
end
local add_drop = function(drops, pos, item)
if loss_prob[item] ~= nil then
if math.random(1,loss_prob[item]) == 1 then
local function add_drop(drops, item)
item = ItemStack(item)
local name = item:get_name()
if loss_prob[name] ~= nil and math.random(1, loss_prob[name]) == 1 then
return
end
end
if drops[item] == nil then
drops[item] = ItemStack(item)
local drop = drops[name]
if drop == nil then
drops[name] = item
else
drops[item]:add_item(item)
end
if drops[item]:get_free_space() == 0 then
stack = drops[item]
eject_drops(pos, stack)
drops[item] = nil
drop:set_count(drop:get_count() + item:get_count())
end
end
local destroy = function(drops, pos, last, fast)
local nodename = minetest.get_node(pos).name
if nodename ~= "air" then
minetest.remove_node(pos, (fast and 1 or 0))
if last then
nodeupdate(pos)
end
if minetest.registered_nodes[nodename].groups.flammable ~= nil then
minetest.set_node(pos, {name="fire:basic_flame"}, (fast and 2 or 0))
local fire_node = {name="fire:basic_flame"}
local function destroy(drops, pos, cid)
if minetest.is_protected(pos, "") then
return
end
local drop = minetest.get_node_drops(nodename, "")
for _,item in ipairs(drop) do
if type(item) == "string" then
add_drop(drops, pos, item)
local def = cid_data[cid]
if def and def.flammable then
minetest.set_node(pos, fire_node)
else
for i=1,item:get_count() do
add_drop(drops, pos, item:get_name())
end
minetest.remove_node(pos)
if def then
local node_drops = minetest.get_node_drops(def.name, "")
for _, item in ipairs(node_drops) do
add_drop(drops, item)
end
end
end
end
boom = function(pos, time)
minetest.after(time, function(pos)
if minetest.get_node(pos).name ~= "tnt:tnt_burning" then
return
local function calc_velocity(pos1, pos2, old_vel, power)
local vel = vector.direction(pos1, pos2)
vel = vector.normalize(vel)
vel = vector.multiply(vel, power)
-- Divide by distance
local dist = vector.distance(pos1, pos2)
dist = math.max(dist, 1)
vel = vector.divide(vel, dist)
-- Add old velocity
vel = vector.add(vel, old_vel)
return vel
end
local function entity_physics(pos, radius)
-- Make the damage radius larger than the destruction radius
radius = radius * 2
local objs = minetest.get_objects_inside_radius(pos, radius)
for _, obj in pairs(objs) do
local obj_pos = obj:getpos()
local obj_vel = obj:getvelocity()
local dist = math.max(1, vector.distance(pos, obj_pos))
if obj_vel ~= nil then
obj:setvelocity(calc_velocity(pos, obj_pos,
obj_vel, radius * 10))
end
local damage = (4 / dist) * radius
obj:set_hp(obj:get_hp() - damage)
end
end
local function add_effects(pos, radius)
minetest.add_particlespawner({
amount = 128,
time = 1,
minpos = vector.subtract(pos, radius / 2),
maxpos = vector.add(pos, radius / 2),
minvel = {x=-20, y=-20, z=-20},
maxvel = {x=20, y=20, z=20},
minacc = vector.new(),
maxacc = vector.new(),
minexptime = 1,
maxexptime = 3,
minsize = 8,
maxsize = 16,
texture = "tnt_smoke.png",
})
end
local function burn(pos)
local name = minetest.get_node(pos).name
if name == "tnt:tnt" then
minetest.sound_play("tnt_ignite", {pos=pos})
minetest.set_node(pos, {name="tnt:tnt_burning"})
minetest.get_node_timer(pos):start(1)
elseif name == "tnt:gunpowder" then
minetest.sound_play("tnt_gunpowder_burning", {pos=pos, gain=2})
minetest.set_node(pos, {name="tnt:gunpowder_burning"})
minetest.get_node_timer(pos):start(1)
end
end
local function explode(pos, radius)
local pos = vector.round(pos)
local vm = VoxelManip()
local pr = PseudoRandom(os.time())
local p1 = vector.subtract(pos, radius)
local p2 = vector.add(pos, radius)
local minp, maxp = vm:read_from_map(p1, p2)
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
local data = vm:get_data()
local drops = {}
local p = {}
local c_air = minetest.get_content_id("air")
local c_tnt = minetest.get_content_id("tnt:tnt")
local c_tnt_burning = minetest.get_content_id("tnt:tnt_burning")
local c_gunpowder = minetest.get_content_id("tnt:gunpowder")
local c_gunpowder_burning = minetest.get_content_id("tnt:gunpowder_burning")
local c_boom = minetest.get_content_id("tnt:boom")
local c_fire = minetest.get_content_id("fire:basic_flame")
for z = -radius, radius do
for y = -radius, radius do
local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z)
for x = -radius, radius do
if (x * x) + (y * y) + (z * z) <=
(radius * radius) + pr:next(-radius, radius) then
local cid = data[vi]
p.x = pos.x + x
p.y = pos.y + y
p.z = pos.z + z
if cid == c_tnt or cid == c_gunpowder then
burn(p)
elseif cid ~= c_tnt_burning and
cid ~= c_gunpowder_burning and
cid ~= c_air and
cid ~= c_fire and
cid ~= c_boom then
destroy(drops, p, cid)
end
end
vi = vi + 1
end
end
end
return drops
end
local function boom(pos)
minetest.sound_play("tnt_explode", {pos=pos, gain=1.5, max_hear_distance=2*64})
minetest.set_node(pos, {name="tnt:boom"})
minetest.after(0.5, function(pos)
minetest.remove_node(pos)
end, {x=pos.x, y=pos.y, z=pos.z})
minetest.get_node_timer(pos):start(0.5)
local radius = 2
local drops = {}
local list = {}
local dr = 0
local tnts = 1
local destroyed = 0
while dr<radius do
dr=dr+1
for dx=-dr,dr,dr*2 do
for dy=-dr,dr,1 do
for dz=-dr,dr,1 do
table.insert(list, {x=dx, y=dy, z=dz})
end
end
end
for dy=-dr,dr,dr*2 do
for dx=-dr+1,dr-1,1 do
for dz=-dr,dr,1 do
table.insert(list, {x=dx, y=dy, z=dz})
end
end
end
for dz=-dr,dr,dr*2 do
for dx=-dr+1,dr-1,1 do
for dy=-dr+1,dr-1,1 do
table.insert(list, {x=dx, y=dy, z=dz})
end
end
end
for _,p in ipairs(list) do
local np = {x=pos.x+p.x, y=pos.y+p.y, z=pos.z+p.z}
local node = minetest.get_node(np)
if node.name == "air" then
elseif node.name == "tnt:tnt" or node.name == "tnt:tnt_burning" then
if radius < radius_max then
if radius <= 5 then
radius = radius + 1
elseif radius <= 10 then
radius = radius + 0.5
else
radius = radius + 0.3
end
minetest.remove_node(np, 2)
tnts = tnts + 1
else
minetest.set_node(np, {name="tnt:tnt_burning"})
boom(np, 1)
end
elseif node.name == "fire:basic_flame"
--or string.find(node.name, "default:water_")
--or string.find(node.name, "default:lava_")
or node.name == "tnt:boom"
then
else
if math.abs(p.x)<2 and math.abs(p.y)<2 and math.abs(p.z)<2 then
destroy(drops, np, dr == radius, radius > 7)
destroyed = destroyed + 1
else
if math.random(1,5) <= 4 then
destroy(drops, np, dr == radius, radius > 7)
destroyed = destroyed + 1
end
end
end
end
end
local objects = minetest.get_objects_inside_radius(pos, radius*2)
for _,obj in ipairs(objects) do
--if obj:is_player() or (obj:get_luaentity() and obj:get_luaentity().name ~= "__builtin:item") then
local p = obj:getpos()
local v = obj:getvelocity()
local vec = {x=p.x-pos.x, y=p.y-pos.y, z=p.z-pos.z}
local dist = (vec.x^2+vec.y^2+vec.z^2)^0.5
local damage = ((radius*20)/dist)
--print("DMG dist="..dist.." damage="..damage)
if obj:is_player() or (obj:get_luaentity() and obj:get_luaentity().name ~= "__builtin:item") then
obj:punch(obj, 1.0, {
full_punch_interval=1.0,
damage_groups={fleshy=damage},
}, vec)
end
if v ~= nil then
--obj:setvelocity({x=(p.x - pos.x) + (radius / 4) + v.x, y=(p.y - pos.y) + (radius / 2) + v.y, z=(p.z - pos.z) + (radius / 4) + v.z})
obj:setvelocity({x=(p.x - pos.x) + (radius / 2) + v.x, y=(p.y - pos.y) + radius + v.y, z=(p.z - pos.z) + (radius / 2) + v.z})
end
--end
end
print("TNT exploded=" .. tnts .. " radius=" .. radius .. " destroyed="..destroyed)
for _,stack in pairs(drops) do
eject_drops(pos, stack)
end
local radiusp = radius+1
minetest.add_particlespawner(
100, --amount
0.1, --time
{x=pos.x-radiusp, y=pos.y-radiusp, z=pos.z-radiusp}, --minpos
{x=pos.x+radiusp, y=pos.y+radiusp, z=pos.z+radiusp}, --maxpos
{x=-0, y=-0, z=-0}, --minvel
{x=0, y=0, z=0}, --maxvel
{x=-0.5,y=5,z=-0.5}, --minacc
{x=0.5,y=5,z=0.5}, --maxacc
0.1, --minexptime
1, --maxexptime
8, --minsize
15, --maxsize
false, --collisiondetection
"tnt_smoke.png" --texture
)
end, pos)
local drops = explode(pos, radius)
entity_physics(pos, radius)
eject_drops(drops, pos, radius)
add_effects(pos, radius)
end
minetest.register_node("tnt:tnt", {
@ -195,30 +224,32 @@ minetest.register_node("tnt:tnt", {
tiles = {"tnt_top.png", "tnt_bottom.png", "tnt_side.png"},
groups = {dig_immediate=2, mesecon=2},
sounds = default.node_sound_wood_defaults(),
on_punch = function(pos, node, puncher)
if puncher:get_wielded_item():get_name() == "default:torch" then
minetest.sound_play("tnt_ignite", {pos=pos})
minetest.set_node(pos, {name="tnt:tnt_burning"})
boom(pos, 4)
minetest.get_node_timer(pos):start(4)
end
end,
mesecons = {
effector = {
action_on = function(pos, node)
minetest.set_node(pos, {name="tnt:tnt_burning"})
boom(pos, 0)
end
},
},
mesecons = {effector = {action_on = boom}},
})
minetest.register_node("tnt:tnt_burning", {
tiles = {{name="tnt_top_burning_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1}}, "tnt_bottom.png", "tnt_side.png"},
tiles = {
{
name = "tnt_top_burning_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1,
}
},
"tnt_bottom.png", "tnt_side.png"},
light_source = 5,
drop = "",
sounds = default.node_sound_wood_defaults(),
on_timer = boom,
})
minetest.register_node("tnt:boom", {
@ -228,53 +259,10 @@ minetest.register_node("tnt:boom", {
walkable = false,
drop = "",
groups = {dig_immediate=3},
})
burn = function(pos)
if minetest.get_node(pos).name == "tnt:tnt" then
minetest.sound_play("tnt_ignite", {pos=pos})
minetest.set_node(pos, {name="tnt:tnt_burning"})
boom(pos, 1)
return
end
if minetest.get_node(pos).name ~= "tnt:gunpowder" then
return
end
minetest.sound_play("tnt_gunpowder_burning", {pos=pos, gain=2})
minetest.set_node(pos, {name="tnt:gunpowder_burning"})
minetest.after(1, function(pos)
if minetest.get_node(pos).name ~= "tnt:gunpowder_burning" then
return
end
minetest.after(0.5, function(pos)
on_timer = function(pos, elapsed)
minetest.remove_node(pos)
end, {x=pos.x, y=pos.y, z=pos.z})
for dx=-1,1 do
for dz=-1,1 do
for dy=-1,1 do
pos.x = pos.x+dx
pos.y = pos.y+dy
pos.z = pos.z+dz
if not (math.abs(dx) == 1 and math.abs(dz) == 1) then
if dy == 0 then
burn({x=pos.x, y=pos.y, z=pos.z})
else
if math.abs(dx) == 1 or math.abs(dz) == 1 then
burn({x=pos.x, y=pos.y, z=pos.z})
end
end
end
pos.x = pos.x-dx
pos.y = pos.y-dy
pos.z = pos.z-dz
end
end
end
end, pos)
end
end,
})
minetest.register_node("tnt:gunpowder", {
description = "Gun Powder",
@ -305,7 +293,15 @@ minetest.register_node("tnt:gunpowder_burning", {
sunlight_propagates = true,
walkable = false,
light_source = 5,
tiles = {{name="tnt_gunpowder_burning_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1}}},
tiles = {{
name = "tnt_gunpowder_burning_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1,
}
}},
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
@ -313,21 +309,30 @@ minetest.register_node("tnt:gunpowder_burning", {
drop = "",
groups = {dig_immediate=2,attached_node=1},
sounds = default.node_sound_leaves_defaults(),
on_timer = function(pos, elapsed)
for dx = -1, 1 do
for dz = -1, 1 do
for dy = -1, 1 do
if not (dx == 0 and dz == 0) then
burn({
x = pos.x + dx,
y = pos.y + dy,
z = pos.z + dz,
})
end
end
end
end
minetest.remove_node(pos)
end
})
minetest.register_abm({
nodenames = {"tnt:tnt", "tnt:gunpowder"},
neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"},
interval = 2,
chance = 10,
action = function(pos, node)
if node.name == "tnt:tnt" then
minetest.set_node(pos, {name="tnt:tnt_burning"})
boom({x=pos.x, y=pos.y, z=pos.z}, 0)
else
burn(pos)
end
end
interval = 1,
chance = 1,
action = burn,
})
minetest.register_craft({
@ -346,5 +351,6 @@ minetest.register_craft({
})
if minetest.setting_get("log_mods") then
minetest.log("action", "tnt loaded")
minetest.debug("[TNT] Loaded!")
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 B

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 B

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 425 B

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