local drops = minetest.get_node_drops(node.name, wielded:get_name())
-- Wear out tool
- mp = def.material
- tp = wielded:get_tool_digging_properties()
- dp = minetest.get_digging_properties(mp, tp)
+ tp = wielded:get_tool_capabilities()
+ dp = minetest.get_dig_params(def.groups, tp)
wielded:add_wear(dp.wear)
digger:set_wielded_item(wielded)
stack_max = 99,
usable = false,
liquids_pointable = false,
- tool_digging_properties = nil,
+ tool_capabilities = nil,
-- Interaction callbacks
on_place = minetest.item_place,
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
liquids_pointable = false,
- tool_digging_properties = nil,
+ tool_capabilities = nil,
-- Interaction callbacks
on_place = minetest.item_place,
wield_scale = {x=1,y=1,z=1},
stack_max = 1,
liquids_pointable = false,
- tool_digging_properties = nil,
+ tool_capabilities = nil,
-- Interaction callbacks
on_place = minetest.item_place,
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
liquids_pointable = false,
- tool_digging_properties = nil,
+ tool_capabilities = nil,
-- Interaction callbacks
on_place = nil,
if tooldef.inventory_image == nil and tooldef.image ~= nil then
tooldef.inventory_image = tooldef.image
end
- if tooldef.tool_digging_properties == nil and
+ if tooldef.tool_capabilities == nil and
(tooldef.full_punch_interval ~= nil or
tooldef.basetime ~= nil or
tooldef.dt_weight ~= nil or
tooldef.dd_crackiness ~= nil or
tooldef.dd_crumbliness ~= nil or
tooldef.dd_cuttability ~= nil) then
- tooldef.tool_digging_properties = {
+ tooldef.tool_capabilities = {
full_punch_interval = tooldef.full_punch_interval,
basetime = tooldef.basetime,
dt_weight = tooldef.dt_weight,
type = "none",
wield_image = "wieldhand.png",
wield_scale = {x=1,y=1,z=2.5},
- tool_digging_properties = {
+ tool_capabilities = {
full_punch_interval = 2.0,
- basetime = 0.5,
- dt_weight = 1,
- dt_crackiness = 0,
- dt_crumbliness = -1,
- dt_cuttability = 0,
- basedurability = 50,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ max_drop_level = 0,
+ groupcaps = {
+ fleshy = {times={[2]=2.00, [3]=1.00}, maxwear=0, maxlevel=1},
+ crumbly = {times={[3]=0.70}, maxwear=0, maxlevel=1},
+ snappy = {times={[3]=0.70}, maxwear=0, maxlevel=1},
+ }
}
})
-- - get_free_space(): returns get_stack_max() - get_count()
-- - is_known(): returns true if the item name refers to a defined item type
-- - get_definition(): returns the item definition table
--- - get_tool_digging_properties(): returns the digging properties of the item,
+-- - get_tool_capabilities(): returns the digging properties of the item,
-- ^ or those of the hand if none are defined for this item type
-- - add_wear(amount): increases wear by amount if the item is a tool
-- - add_item(item): put some item or stack onto this stack,
-- wield_scale = {x=1,y=1,z=1},
-- stack_max = 99,
-- liquids_pointable = false,
--- tool_digging_properties = {
+-- tool_capabilities = {
-- full_punch_interval = 1.0,
-- basetime = 1.0,
-- dt_weight = 0.5,
-- light_source = 0,
-- damage_per_second = 0,
-- selection_box = {type="regular"},
--- material = {
--- diggablity = "normal",
--- weight = 0,
--- crackiness = 0,
--- crumbliness = 0,
--- cuttability = 0,
--- flammability = 0,
--- },
-- legacy_facedir_simple = false, -- Support maps made in and before January 2012
-- legacy_wallmounted = false, -- Support maps made in and before January 2012
-- }
minetest.register_tool("default:pick_wood", {
description = "Wooden Pickaxe",
inventory_image = "default_tool_woodpick.png",
- tool_digging_properties = {
- basetime = 2.0,
- dt_weight = 0,
- dt_crackiness = -0.5,
- dt_crumbliness = 2,
- dt_cuttability = 0,
- basedurability = 30,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[2]=1.50, [3]=0.80}, maxwear=0.1, maxlevel=1}
+ }
},
})
minetest.register_tool("default:pick_stone", {
description = "Stone Pickaxe",
inventory_image = "default_tool_stonepick.png",
- tool_digging_properties = {
- basetime = 1.5,
- dt_weight = 0,
- dt_crackiness = -0.5,
- dt_crumbliness = 2,
- dt_cuttability = 0,
- basedurability = 100,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[1]=1.50, [2]=0.80, [3]=0.60}, maxwear=0.05, maxlevel=1}
+ }
},
})
minetest.register_tool("default:pick_steel", {
description = "Steel Pickaxe",
inventory_image = "default_tool_steelpick.png",
- tool_digging_properties = {
- basetime = 1.0,
- dt_weight = 0,
- dt_crackiness = -0.5,
- dt_crumbliness = 2,
- dt_cuttability = 0,
- basedurability = 333,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ cracky={times={[1]=1.00, [2]=0.60, [3]=0.40}, maxwear=0.1, maxlevel=2}
+ }
},
})
minetest.register_tool("default:pick_mese", {
description = "Mese Pickaxe",
inventory_image = "default_tool_mesepick.png",
- tool_digging_properties = {
- basetime = 0,
- dt_weight = 0,
- dt_crackiness = 0,
- dt_crumbliness = 0,
- dt_cuttability = 0,
- basedurability = 1337,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=3,
+ groupcaps={
+ cracky={times={[1]=0.2, [2]=0.2, [3]=0.2}, maxwear=0.05, maxlevel=3},
+ crumbly={times={[1]=0.2, [2]=0.2, [3]=0.2}, maxwear=0.05, maxlevel=3},
+ snappy={times={[1]=0.2, [2]=0.2, [3]=0.2}, maxwear=0.05, maxlevel=3}
+ }
},
})
minetest.register_tool("default:shovel_wood", {
description = "Wooden Shovel",
inventory_image = "default_tool_woodshovel.png",
- tool_digging_properties = {
- basetime = 2.0,
- dt_weight = 0.5,
- dt_crackiness = 2,
- dt_crumbliness = -1.5,
- dt_cuttability = 0.3,
- basedurability = 30,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ crumbly={times={[1]=1.50, [2]=0.80, [3]=0.50}, maxwear=0.1, maxlevel=1}
+ }
},
})
minetest.register_tool("default:shovel_stone", {
description = "Stone Shovel",
inventory_image = "default_tool_stoneshovel.png",
- tool_digging_properties = {
- basetime = 1.5,
- dt_weight = 0.5,
- dt_crackiness = 2,
- dt_crumbliness = -1.5,
- dt_cuttability = 0.1,
- basedurability = 100,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ crumbly={times={[1]=0.80, [2]=0.50, [3]=0.30}, maxwear=0.05, maxlevel=1}
+ }
},
})
minetest.register_tool("default:shovel_steel", {
description = "Steel Shovel",
inventory_image = "default_tool_steelshovel.png",
- tool_digging_properties = {
- basetime = 1.0,
- dt_weight = 0.5,
- dt_crackiness = 2,
- dt_crumbliness = -1.5,
- dt_cuttability = 0.0,
- basedurability = 330,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ crumbly={times={[1]=0.50, [2]=0.35, [3]=0.30}, maxwear=0.1, maxlevel=2}
+ }
},
})
minetest.register_tool("default:axe_wood", {
description = "Wooden Axe",
inventory_image = "default_tool_woodaxe.png",
- tool_digging_properties = {
- basetime = 2.0,
- dt_weight = 0.5,
- dt_crackiness = -0.2,
- dt_crumbliness = 1,
- dt_cuttability = -0.5,
- basedurability = 30,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ choppy={times={[2]=1.50, [3]=0.80}, maxwear=0.1, maxlevel=1},
+ fleshy={times={[2]=1.50, [3]=0.80}, maxwear=0.1, maxlevel=1}
+ }
},
})
minetest.register_tool("default:axe_stone", {
description = "Stone Axe",
inventory_image = "default_tool_stoneaxe.png",
- tool_digging_properties = {
- basetime = 1.5,
- dt_weight = 0.5,
- dt_crackiness = -0.2,
- dt_crumbliness = 1,
- dt_cuttability = -0.5,
- basedurability = 100,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ choppy={times={[1]=1.50, [2]=1.00, [3]=0.60}, maxwear=0.05, maxlevel=1},
+ fleshy={times={[2]=1.30, [3]=0.70}, maxwear=0.05, maxlevel=1}
+ }
},
})
minetest.register_tool("default:axe_steel", {
description = "Steel Axe",
inventory_image = "default_tool_steelaxe.png",
- tool_digging_properties = {
- basetime = 1.0,
- dt_weight = 0.5,
- dt_crackiness = -0.2,
- dt_crumbliness = 1,
- dt_cuttability = -0.5,
- basedurability = 330,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ choppy={times={[1]=1.00, [2]=0.80, [3]=0.50}, maxwear=0.1, maxlevel=2},
+ fleshy={times={[2]=1.10, [3]=0.60}, maxwear=0.03, maxlevel=1}
+ }
},
})
minetest.register_tool("default:sword_wood", {
description = "Wooden Sword",
inventory_image = "default_tool_woodsword.png",
- tool_digging_properties = {
- basetime = 3.0,
- dt_weight = 3,
- dt_crackiness = 0,
- dt_crumbliness = 1,
- dt_cuttability = -1,
- basedurability = 30,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ full_punch_interval = 2.0,
+ max_drop_level=0,
+ groupcaps={
+ fleshy={times={[2]=1.10, [3]=0.60}, maxwear=0.1, maxlevel=1},
+ snappy={times={[2]=1.00, [3]=0.50}, maxwear=0.1, maxlevel=1},
+ choppy={times={[3]=1.00}, maxwear=0.05, maxlevel=0}
+ }
}
})
minetest.register_tool("default:sword_stone", {
description = "Stone Sword",
inventory_image = "default_tool_stonesword.png",
- tool_digging_properties = {
- basetime = 2.5,
- dt_weight = 3,
- dt_crackiness = 0,
- dt_crumbliness = 1,
- dt_cuttability = -1,
- basedurability = 100,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ full_punch_interval = 2.0,
+ max_drop_level=0,
+ groupcaps={
+ fleshy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
+ snappy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
+ choppy={times={[3]=0.90}, maxwear=0.05, maxlevel=0}
+ }
}
})
minetest.register_tool("default:sword_steel", {
description = "Steel Sword",
inventory_image = "default_tool_steelsword.png",
- tool_digging_properties = {
- basetime = 2.0,
- dt_weight = 3,
- dt_crackiness = 0,
- dt_crumbliness = 1,
- dt_cuttability = -1,
- basedurability = 330,
- dd_weight = 0,
- dd_crackiness = 0,
- dd_crumbliness = 0,
- dd_cuttability = 0,
+ tool_capabilities = {
+ full_punch_interval = 2.0,
+ max_drop_level=1,
+ groupcaps={
+ fleshy={times={[1]=1.00, [2]=0.40, [3]=0.20}, maxwear=0.1, maxlevel=2},
+ snappy={times={[2]=0.70, [3]=0.30}, maxwear=0.03, maxlevel=1},
+ choppy={times={[3]=0.70}, maxwear=0.03, maxlevel=0}
+ }
}
})
description = "Stone",
tile_images = {"default_stone.png"},
is_ground_content = true,
- material = minetest.digprop_stonelike(1.0),
+ groups = {cracky=3},
drop = 'default:cobble',
legacy_mineral = true,
})
description = "Stone with coal",
tile_images = {"default_stone.png^default_mineral_coal.png"},
is_ground_content = true,
- material = minetest.digprop_stonelike(1.0),
+ groups = {cracky=3},
drop = 'default:coal_lump',
})
description = "Stone with iron",
tile_images = {"default_stone.png^default_mineral_iron.png"},
is_ground_content = true,
- material = minetest.digprop_stonelike(1.0),
+ groups = {cracky=3},
drop = 'default:iron_lump',
})
description = "Dirt with grass",
tile_images = {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
is_ground_content = true,
- material = minetest.digprop_dirtlike(1.0),
+ groups = {crumbly=3},
drop = 'default:dirt',
})
description = "Dirt with grass and footsteps",
tile_images = {"default_grass_footsteps.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
is_ground_content = true,
- material = minetest.digprop_dirtlike(1.0),
+ groups = {crumbly=3},
drop = 'default:dirt',
})
description = "Dirt",
tile_images = {"default_dirt.png"},
is_ground_content = true,
- material = minetest.digprop_dirtlike(1.0),
+ groups = {crumbly=3},
})
minetest.register_node("default:sand", {
description = "Sand",
tile_images = {"default_sand.png"},
is_ground_content = true,
- material = minetest.digprop_dirtlike(1.0),
+ groups = {crumbly=3},
})
minetest.register_node("default:gravel", {
description = "Gravel",
tile_images = {"default_gravel.png"},
is_ground_content = true,
- material = minetest.digprop_gravellike(1.0),
+ groups = {crumbly=2},
})
minetest.register_node("default:sandstone", {
description = "Sandstone",
tile_images = {"default_sandstone.png"},
is_ground_content = true,
- material = minetest.digprop_dirtlike(1.0), -- FIXME should this be stonelike?
+ groups = {crumbly=2,cracky=2},
drop = 'default:sand',
})
description = "Clay",
tile_images = {"default_clay.png"},
is_ground_content = true,
- material = minetest.digprop_dirtlike(1.0),
+ groups = {crumbly=3},
drop = 'default:clay_lump 4',
})
description = "Brick",
tile_images = {"default_brick.png"},
is_ground_content = true,
- material = minetest.digprop_stonelike(1.0),
+ groups = {cracky=3},
drop = 'default:clay_brick 4',
})
description = "Tree",
tile_images = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
is_ground_content = true,
- material = minetest.digprop_woodlike(1.0),
+ groups = {snappy=2},
})
minetest.register_node("default:jungletree", {
description = "Jungle Tree",
tile_images = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
is_ground_content = true,
- material = minetest.digprop_woodlike(1.0),
+ groups = {snappy=2},
})
minetest.register_node("default:junglegrass", {
wield_image = "default_junglegrass.png",
paramtype = "light",
walkable = false,
- material = minetest.digprop_leaveslike(1.0),
+ groups = {snappy=3},
})
minetest.register_node("default:leaves", {
visual_scale = 1.3,
tile_images = {"default_leaves.png"},
paramtype = "light",
- material = minetest.digprop_leaveslike(1.0),
+ groups = {snappy=3},
drop = {
max_items = 1,
items = {
description = "Cactus",
tile_images = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
is_ground_content = true,
- material = minetest.digprop_woodlike(0.75),
+ groups = {snappy=2},
})
minetest.register_node("default:papyrus", {
paramtype = "light",
is_ground_content = true,
walkable = false,
- material = minetest.digprop_leaveslike(0.5),
+ groups = {snappy=3},
})
minetest.register_node("default:bookshelf", {
description = "Bookshelf",
tile_images = {"default_wood.png", "default_wood.png", "default_bookshelf.png"},
is_ground_content = true,
- material = minetest.digprop_woodlike(0.75),
+ groups = {snappy=2},
})
minetest.register_node("default:glass", {
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
- material = minetest.digprop_glasslike(1.0),
+ groups = {snappy=2,cracky=3},
})
minetest.register_node("default:fence_wood", {
type = "fixed",
fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
},
- material = minetest.digprop_woodlike(0.75),
+ groups = {snappy=2},
})
minetest.register_node("default:rail", {
type = "fixed",
--fixed = <default>
},
- material = minetest.digprop_dirtlike(0.75),
+ groups = {bendy=2,snappy=1},
})
minetest.register_node("default:ladder", {
--wall_bottom = = <default>
--wall_side = = <default>
},
- material = minetest.digprop_woodlike(0.5),
+ groups = {snappy=2},
legacy_wallmounted = true,
})
description = "Wood",
tile_images = {"default_wood.png"},
is_ground_content = true,
- material = minetest.digprop_woodlike(0.75),
+ groups = {snappy=2},
})
minetest.register_node("default:mese", {
description = "Mese",
tile_images = {"default_mese.png"},
is_ground_content = true,
- material = minetest.digprop_stonelike(0.5),
+ groups = {cracky=1},
})
minetest.register_node("default:cloud", {
{image="default_water.png", backface_culling=false},
{image="default_water.png", backface_culling=true},
},
+ groups = {water=3, liquid=3},
})
minetest.register_node("default:water_source", {
-- New-style water source material (mostly unused)
{image="default_water.png", backface_culling=false},
},
+ groups = {water=3, liquid=3},
})
minetest.register_node("default:lava_flowing", {
{image="default_lava.png", backface_culling=false},
{image="default_lava.png", backface_culling=true},
},
+ groups = {lava=3, liquid=2, hot=3},
})
minetest.register_node("default:lava_source", {
-- New-style lava source material (mostly unused)
{image="default_lava.png", backface_culling=false},
},
+ groups = {lava=3, liquid=2, hot=3},
})
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},
},
- material = minetest.digprop_constanttime(0.0),
+ groups = {dig_immediate=1},
legacy_wallmounted = true,
})
--wall_bottom = <default>
--wall_side = <default>
},
- material = minetest.digprop_constanttime(0.5),
+ groups = {dig_immediate=2},
legacy_wallmounted = true,
})
"default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
paramtype2 = "facedir",
metadata_name = "chest",
- material = minetest.digprop_woodlike(1.0),
+ groups = {snappy=2},
legacy_facedir_simple = true,
})
"default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
paramtype2 = "facedir",
metadata_name = "locked_chest",
- material = minetest.digprop_woodlike(1.0),
+ groups = {snappy=2},
legacy_facedir_simple = true,
})
"default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
paramtype2 = "facedir",
metadata_name = "furnace",
- material = minetest.digprop_stonelike(3.0),
+ groups = {cracky=2},
legacy_facedir_simple = true,
})
description = "Cobble",
tile_images = {"default_cobble.png"},
is_ground_content = true,
- material = minetest.digprop_stonelike(0.9),
+ groups = {cracky=3},
})
minetest.register_node("default:mossycobble", {
description = "Mossy Cobble",
tile_images = {"default_mossycobble.png"},
is_ground_content = true,
- material = minetest.digprop_stonelike(0.8),
+ groups = {cracky=3},
})
minetest.register_node("default:steelblock", {
description = "Steel Block",
tile_images = {"default_steel_block.png"},
is_ground_content = true,
- material = minetest.digprop_stonelike(5.0),
+ groups = {snappy=1,bendy=2},
})
minetest.register_node("default:nyancat", {
"default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
inventory_image = "default_nc_front.png",
paramtype2 = "facedir",
- material = minetest.digprop_stonelike(3.0),
+ groups = {cracky=2},
legacy_facedir_simple = true,
})
description = "Nyancat Rainbow",
tile_images = {"default_nc_rb.png"},
inventory_image = "default_nc_rb.png",
- material = minetest.digprop_stonelike(3.0),
+ groups = {cracky=2},
})
minetest.register_node("default:sapling", {
wield_image = "default_sapling.png",
paramtype = "light",
walkable = false,
- material = minetest.digprop_constanttime(0.0),
+ groups = {dig_immediate=1},
})
minetest.register_node("default:apple", {
paramtype = "light",
sunlight_propagates = true,
walkable = false,
- material = minetest.digprop_constanttime(0.0),
+ groups = {dig_immediate=1},
on_use = minetest.item_eat(4),
})
serverobject.cpp
noise.cpp
porting.cpp
- materials.cpp
+ tool.cpp
defaultsettings.cpp
mapnode.cpp
voxel.cpp
Obsolete TOCLIENT_TOOLDEF
Obsolete TOCLIENT_CRAFTITEMDEF
Compress the contents of TOCLIENT_ITEMDEF and TOCLIENT_NODEDEF
+ PROTOCOL_VERSION 8:
+ Digging based on item groups
*/
-#define PROTOCOL_VERSION 7
+#define PROTOCOL_VERSION 8
#define PROTOCOL_ID 0x4f457403
#include "main.h" // For g_profiler
#include "profiler.h"
#include "serialization.h" // For compressZlib
-#include "materials.h" // For MaterialProperties and ToolDiggingProperties
+#include "tool.h" // For ToolCapabilities
#include "gamedef.h"
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
v3f dir = (getBasePosition() - puncher->getBasePosition()).normalize();
m_speed_f += dir*12*BS;
- // "Material" properties of an oerkki
- MaterialProperties mp;
- mp.diggability = DIGGABLE_NORMAL;
- mp.crackiness = -1.0;
- mp.cuttability = 1.0;
+ // "Material" groups of the object
+ std::map<std::string, int> groups;
+ groups["snappy"] = 1;
+ groups["choppy"] = 1;
+ groups["fleshy"] = 3;
IItemDefManager *idef = m_env->getGameDef()->idef();
- ItemStack punchitem = puncher->getWieldedItem();
- ToolDiggingProperties tp =
- punchitem.getToolDiggingProperties(idef);
+ ItemStack punchitem = puncher->getWieldedItem();
+ ToolCapabilities tp = punchitem.getToolCapabilities(idef);
- HittingProperties hitprop = getHittingProperties(&mp, &tp,
+ HitParams hit_params = getHitParams(groups, &tp,
time_from_last_punch);
- doDamage(hitprop.hp);
+ doDamage(hit_params.hp);
if(g_settings->getBool("creative_mode") == false)
{
- punchitem.addWear(hitprop.wear, idef);
+ punchitem.addWear(hit_params.wear, idef);
puncher->setWieldedItem(punchitem);
}
}
sendPosition();
- // "Material" properties of the MobV2
- MaterialProperties mp;
- mp.diggability = DIGGABLE_NORMAL;
- mp.crackiness = -1.0;
- mp.cuttability = 1.0;
+ // "Material" groups of the object
+ std::map<std::string, int> groups;
+ groups["snappy"] = 1;
+ groups["choppy"] = 1;
+ groups["fleshy"] = 3;
IItemDefManager *idef = m_env->getGameDef()->idef();
- ItemStack punchitem = puncher->getWieldedItem();
- ToolDiggingProperties tp =
- punchitem.getToolDiggingProperties(idef);
+ ItemStack punchitem = puncher->getWieldedItem();
+ ToolCapabilities tp = punchitem.getToolCapabilities(idef);
- HittingProperties hitprop = getHittingProperties(&mp, &tp,
+ HitParams hit_params = getHitParams(groups, &tp,
time_from_last_punch);
- doDamage(hitprop.hp);
+ doDamage(hit_params.hp);
if(g_settings->getBool("creative_mode") == false)
{
- punchitem.addWear(hitprop.wear, idef);
+ punchitem.addWear(hit_params.wear, idef);
puncher->setWieldedItem(punchitem);
}
}
void MobV2SAO::doDamage(u16 d)
{
- infostream<<"MobV2 hp="<<m_hp<<" damage="<<d<<std::endl;
+ if(d > 0)
+ actionstream<<"MobV2 ("<<m_hp<<"hp) takes "<<d<<"hp of damage"<<std::endl;
if(d < m_hp)
{
#include "guiInventoryMenu.h"
#include "guiTextInputMenu.h"
#include "guiDeathScreen.h"
-#include "materials.h"
+#include "tool.h"
#include "config.h"
#include "clouds.h"
#include "camera.h"
MapNode n = client.getNode(nodepos);
// Get digging properties for material and tool
- MaterialProperties mp = nodedef->get(n.getContent()).material;
- ToolDiggingProperties tp =
- playeritem.getToolDiggingProperties(itemdef);
- DiggingProperties prop = getDiggingProperties(&mp, &tp);
+ ToolCapabilities tp = playeritem.getToolCapabilities(itemdef);
+ DigParams params = getDigParams(nodedef->get(n).groups, &tp);
+ // If can't dig, try hand
+ if(!params.diggable){
+ const ItemDefinition &hand = itemdef->get("");
+ const ToolCapabilities *tp = hand.tool_capabilities;
+ if(tp)
+ params = getDigParams(nodedef->get(n).groups, tp);
+ }
float dig_time_complete = 0.0;
- if(prop.diggable == false)
+ if(params.diggable == false)
{
// I guess nobody will wait for this long
dig_time_complete = 10000000.0;
}
else
{
- dig_time_complete = prop.time;
+ dig_time_complete = params.time;
}
if(dig_time_complete >= 0.001)
#include "debug.h"
#include "itemdef.h"
-struct ToolDiggingProperties;
+struct ToolCapabilities;
struct ItemStack
{
}
// Get tool digging properties, or those of the hand if not a tool
- const ToolDiggingProperties& getToolDiggingProperties(
+ const ToolCapabilities& getToolCapabilities(
IItemDefManager *itemdef) const
{
- ToolDiggingProperties *prop;
- prop = itemdef->get(name).tool_digging_properties;
- if(prop == NULL)
- prop = itemdef->get("").tool_digging_properties;
- assert(prop != NULL);
- return *prop;
+ ToolCapabilities *cap;
+ cap = itemdef->get(name).tool_capabilities;
+ if(cap == NULL)
+ cap = itemdef->get("").tool_capabilities;
+ assert(cap != NULL);
+ return *cap;
}
// Wear out (only tools)
#include "gamedef.h"
#include "nodedef.h"
-#include "materials.h"
+#include "tool.h"
#include "inventory.h"
#ifndef SERVER
#include "mapblock_mesh.h"
stack_max = def.stack_max;
usable = def.usable;
liquids_pointable = def.liquids_pointable;
- if(def.tool_digging_properties)
+ if(def.tool_capabilities)
{
- tool_digging_properties = new ToolDiggingProperties(
- *def.tool_digging_properties);
+ tool_capabilities = new ToolCapabilities(
+ *def.tool_capabilities);
}
+ groups = def.groups;
#ifndef SERVER
inventory_texture = def.inventory_texture;
if(def.wield_mesh)
void ItemDefinition::resetInitial()
{
// Initialize pointers to NULL so reset() does not delete undefined pointers
- tool_digging_properties = NULL;
+ tool_capabilities = NULL;
#ifndef SERVER
inventory_texture = NULL;
wield_mesh = NULL;
stack_max = 99;
usable = false;
liquids_pointable = false;
- if(tool_digging_properties)
+ if(tool_capabilities)
{
- delete tool_digging_properties;
- tool_digging_properties = NULL;
+ delete tool_capabilities;
+ tool_capabilities = NULL;
}
+ groups.clear();
#ifndef SERVER
inventory_texture = NULL;
void ItemDefinition::serialize(std::ostream &os) const
{
- writeU8(os, 0); // version
+ writeU8(os, 1); // version
writeU8(os, type);
os<<serializeString(name);
os<<serializeString(description);
writeS16(os, stack_max);
writeU8(os, usable);
writeU8(os, liquids_pointable);
- std::string tool_digging_properties_s = "";
- if(tool_digging_properties)
- {
+ std::string tool_capabilities_s = "";
+ if(tool_capabilities){
std::ostringstream tmp_os(std::ios::binary);
- tool_digging_properties->serialize(tmp_os);
- tool_digging_properties_s = tmp_os.str();
+ tool_capabilities->serialize(tmp_os);
+ tool_capabilities_s = tmp_os.str();
+ }
+ os<<serializeString(tool_capabilities_s);
+ writeU16(os, groups.size());
+ for(std::map<std::string, int>::const_iterator
+ i = groups.begin(); i != groups.end(); i++){
+ os<<serializeString(i->first);
+ writeS16(os, i->second);
}
- os<<serializeString(tool_digging_properties_s);
}
void ItemDefinition::deSerialize(std::istream &is)
// Deserialize
int version = readU8(is);
- if(version != 0)
+ if(version != 1)
throw SerializationError("unsupported ItemDefinition version");
type = (enum ItemType)readU8(is);
name = deSerializeString(is);
stack_max = readS16(is);
usable = readU8(is);
liquids_pointable = readU8(is);
- std::string tool_digging_properties_s = deSerializeString(is);
- if(!tool_digging_properties_s.empty())
+ std::string tool_capabilities_s = deSerializeString(is);
+ if(!tool_capabilities_s.empty())
{
- std::istringstream tmp_is(tool_digging_properties_s, std::ios::binary);
- tool_digging_properties = new ToolDiggingProperties;
- tool_digging_properties->deSerialize(tmp_is);
+ std::istringstream tmp_is(tool_capabilities_s, std::ios::binary);
+ tool_capabilities = new ToolCapabilities;
+ tool_capabilities->deSerialize(tmp_is);
+ }
+ groups.clear();
+ u32 groups_size = readU16(is);
+ for(u32 i=0; i<groups_size; i++){
+ std::string name = deSerializeString(is);
+ int value = readS16(is);
+ groups[name] = value;
}
}
ItemDefinition* hand_def = new ItemDefinition;
hand_def->name = "";
hand_def->wield_image = "wieldhand.png";
- hand_def->tool_digging_properties = new ToolDiggingProperties;
+ hand_def->tool_capabilities = new ToolCapabilities;
m_item_definitions.insert(std::make_pair("", hand_def));
ItemDefinition* unknown_def = new ItemDefinition;
virtual void registerItem(const ItemDefinition &def)
{
infostream<<"ItemDefManager: registering \""<<def.name<<"\""<<std::endl;
- // Ensure that the "" item (the hand) always has ToolDiggingProperties
+ // Ensure that the "" item (the hand) always has ToolCapabilities
if(def.name == "")
- assert(def.tool_digging_properties != NULL);
+ assert(def.tool_capabilities != NULL);
m_item_definitions[def.name] = new ItemDefinition(def);
#include <string>
#include <iostream>
#include <set>
+#include <map>
class IGameDef;
-struct ToolDiggingProperties;
+struct ToolCapabilities;
+
+/*
+ Some helpers
+*/
+
+static inline int itemgroup_get(const std::map<std::string, int> &groups,
+ const std::string &name)
+{
+ std::map<std::string, int>::const_iterator i = groups.find(name);
+ if(i == groups.end())
+ return 0;
+ return i->second;
+}
/*
Base item definition
bool usable;
bool liquids_pointable;
// May be NULL. If non-NULL, deleted by destructor
- ToolDiggingProperties *tool_digging_properties;
+ ToolCapabilities *tool_capabilities;
+ std::map<std::string, int> groups;
/*
Cached stuff
#include "filesys.h"
#include "config.h"
#include "guiMainMenu.h"
-#include "materials.h"
#include "game.h"
#include "keycode.h"
#include "tile.h"
+++ /dev/null
-/*
-Minetest-c55
-Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "materials.h"
-#include "utility.h"
-
-void MaterialProperties::serialize(std::ostream &os)
-{
- writeU8(os, 0); // version
- writeU8(os, diggability);
- writeF1000(os, constant_time);
- writeF1000(os, weight);
- writeF1000(os, crackiness);
- writeF1000(os, crumbliness);
- writeF1000(os, cuttability);
- writeF1000(os, flammability);
-}
-
-void MaterialProperties::deSerialize(std::istream &is)
-{
- int version = readU8(is);
- if(version != 0)
- throw SerializationError("unsupported MaterialProperties version");
- diggability = (enum Diggability)readU8(is);
- constant_time = readF1000(is);
- weight = readF1000(is);
- crackiness = readF1000(is);
- crumbliness = readF1000(is);
- cuttability = readF1000(is);
- flammability = readF1000(is);
-}
-
-ToolDiggingProperties::ToolDiggingProperties(float full_punch_interval_,
- float a, float b, float c, float d, float e,
- float f, float g, float h, float i, float j):
- full_punch_interval(full_punch_interval_),
- basetime(a),
- dt_weight(b),
- dt_crackiness(c),
- dt_crumbliness(d),
- dt_cuttability(e),
- basedurability(f),
- dd_weight(g),
- dd_crackiness(h),
- dd_crumbliness(i),
- dd_cuttability(j)
-{}
-
-void ToolDiggingProperties::serialize(std::ostream &os)
-{
- writeU8(os, 0); // version
- writeF1000(os, full_punch_interval);
- writeF1000(os, basetime);
- writeF1000(os, dt_weight);
- writeF1000(os, dt_crackiness);
- writeF1000(os, dt_crumbliness);
- writeF1000(os, dt_cuttability);
- writeF1000(os, basedurability);
- writeF1000(os, dd_weight);
- writeF1000(os, dd_crackiness);
- writeF1000(os, dd_crumbliness);
- writeF1000(os, dd_cuttability);
-}
-
-void ToolDiggingProperties::deSerialize(std::istream &is)
-{
- int version = readU8(is);
- if(version != 0) throw SerializationError(
- "unsupported ToolDiggingProperties version");
- full_punch_interval = readF1000(is);
- basetime = readF1000(is);
- dt_weight = readF1000(is);
- dt_crackiness = readF1000(is);
- dt_crumbliness = readF1000(is);
- dt_cuttability = readF1000(is);
- basedurability = readF1000(is);
- dd_weight = readF1000(is);
- dd_crackiness = readF1000(is);
- dd_crumbliness = readF1000(is);
- dd_cuttability = readF1000(is);
-}
-
-DiggingProperties getDiggingProperties(const MaterialProperties *mp,
- const ToolDiggingProperties *tp, float time_from_last_punch)
-{
- if(mp->diggability == DIGGABLE_NOT)
- return DiggingProperties(false, 0, 0);
- if(mp->diggability == DIGGABLE_CONSTANT)
- return DiggingProperties(true, mp->constant_time, 0);
-
- float time = tp->basetime;
- time += tp->dt_weight * mp->weight;
- time += tp->dt_crackiness * mp->crackiness;
- time += tp->dt_crumbliness * mp->crumbliness;
- time += tp->dt_cuttability * mp->cuttability;
- if(time < 0.2)
- time = 0.2;
-
- float durability = tp->basedurability;
- durability += tp->dd_weight * mp->weight;
- durability += tp->dd_crackiness * mp->crackiness;
- durability += tp->dd_crumbliness * mp->crumbliness;
- durability += tp->dd_cuttability * mp->cuttability;
- if(durability < 1)
- durability = 1;
-
- if(time_from_last_punch < tp->full_punch_interval){
- float f = time_from_last_punch / tp->full_punch_interval;
- time /= f;
- durability /= f;
- }
-
- float wear = 1.0 / durability;
- u16 wear_i = 65535.*wear;
- return DiggingProperties(true, time, wear_i);
-}
-
-DiggingProperties getDiggingProperties(const MaterialProperties *mp,
- const ToolDiggingProperties *tp)
-{
- return getDiggingProperties(mp, tp, 1000000);
-}
-
-HittingProperties getHittingProperties(const MaterialProperties *mp,
- const ToolDiggingProperties *tp, float time_from_last_punch)
-{
- DiggingProperties digprop = getDiggingProperties(mp, tp,
- time_from_last_punch);
-
- // If digging time would be 1 second, 2 hearts go in 1 second.
- s16 hp = 2.0 * 2.0 / digprop.time;
- // Wear is the same as for digging a single node
- s16 wear = (float)digprop.wear;
-
- return HittingProperties(hp, wear);
-}
-
-HittingProperties getHittingProperties(const MaterialProperties *mp,
- const ToolDiggingProperties *tp)
-{
- return getHittingProperties(mp, tp, 1000000);
-}
-
+++ /dev/null
-/*
-Minetest-c55
-Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef MATERIALS_HEADER
-#define MATERIALS_HEADER
-
-/*
- Material properties
-*/
-
-#include "common_irrlicht.h"
-#include <string>
-#include <iostream>
-
-enum Diggability
-{
- DIGGABLE_NOT,
- DIGGABLE_NORMAL,
- DIGGABLE_CONSTANT
-};
-
-struct MaterialProperties
-{
- // Values can be anything. 0 is normal.
-
- enum Diggability diggability;
-
- // Constant time for DIGGABLE_CONSTANT
- float constant_time;
-
- // Weight; the amount of stuff in the block. Not realistic.
- float weight;
- // Rock; wood a bit.
- // A Pickaxe manages high crackiness well.
- float crackiness;
- // Sand is extremely crumble; dirt is quite crumble.
- // A shovel is good for crumbly stuff. Pickaxe is horrible.
- float crumbliness;
- // An axe is best for cuttable heavy stuff.
- // Sword is best for cuttable light stuff.
- float cuttability;
- // If high, ignites easily
- float flammability;
-
- MaterialProperties():
- diggability(DIGGABLE_NOT),
- constant_time(0.5),
- weight(0),
- crackiness(0),
- crumbliness(0),
- cuttability(0),
- flammability(0)
- {}
-
- void serialize(std::ostream &os);
- void deSerialize(std::istream &is);
-};
-
-struct ToolDiggingProperties
-{
- // time = basetime + sum(feature here * feature in MaterialProperties)
- float full_punch_interval;
- float basetime;
- float dt_weight;
- float dt_crackiness;
- float dt_crumbliness;
- float dt_cuttability;
- float basedurability;
- float dd_weight;
- float dd_crackiness;
- float dd_crumbliness;
- float dd_cuttability;
-
- ToolDiggingProperties(float full_punch_interval_=2.0,
- float a=0.75, float b=0, float c=0, float d=0, float e=0,
- float f=50, float g=0, float h=0, float i=0, float j=0);
-
- void serialize(std::ostream &os);
- void deSerialize(std::istream &is);
-};
-
-struct DiggingProperties
-{
- bool diggable;
- // Digging time in seconds
- float time;
- // Caused wear
- u16 wear;
-
- DiggingProperties(bool a_diggable=false, float a_time=0, u16 a_wear=0):
- diggable(a_diggable),
- time(a_time),
- wear(a_wear)
- {}
-};
-
-DiggingProperties getDiggingProperties(const MaterialProperties *mp,
- const ToolDiggingProperties *tp, float time_from_last_punch);
-
-DiggingProperties getDiggingProperties(const MaterialProperties *mp,
- const ToolDiggingProperties *tp);
-
-struct HittingProperties
-{
- s16 hp;
- s16 wear;
-
- HittingProperties(s16 hp_=0, s16 wear_=0):
- hp(hp_),
- wear(wear_)
- {}
-};
-
-HittingProperties getHittingProperties(const MaterialProperties *mp,
- const ToolDiggingProperties *tp, float time_from_last_punch);
-
-HittingProperties getHittingProperties(const MaterialProperties *mp,
- const ToolDiggingProperties *tp);
-
-#endif
-
in builtin.lua
*/
name = "";
+ groups.clear();
drawtype = NDT_NORMAL;
visual_scale = 1.0;
for(u32 i=0; i<6; i++)
light_source = 0;
damage_per_second = 0;
selection_box = NodeBox();
- material = MaterialProperties();
- // Make unknown blocks diggable
- material.diggability = DIGGABLE_CONSTANT;
- material.constant_time = 0.5;
legacy_facedir_simple = false;
legacy_wallmounted = false;
}
void ContentFeatures::serialize(std::ostream &os)
{
- writeU8(os, 1); // version
+ writeU8(os, 2); // version
os<<serializeString(name);
+ writeU16(os, groups.size());
+ for(std::map<std::string, int>::const_iterator
+ i = groups.begin(); i != groups.end(); i++){
+ os<<serializeString(i->first);
+ writeS16(os, i->second);
+ }
writeU8(os, drawtype);
writeF1000(os, visual_scale);
writeU8(os, 6);
writeU8(os, light_source);
writeU32(os, damage_per_second);
selection_box.serialize(os);
- material.serialize(os);
writeU8(os, legacy_facedir_simple);
writeU8(os, legacy_wallmounted);
}
void ContentFeatures::deSerialize(std::istream &is)
{
int version = readU8(is);
- if(version != 1)
+ if(version != 2)
throw SerializationError("unsupported ContentFeatures version");
name = deSerializeString(is);
+ groups.clear();
+ u32 groups_size = readU16(is);
+ for(u32 i=0; i<groups_size; i++){
+ std::string name = deSerializeString(is);
+ int value = readS16(is);
+ groups[name] = value;
+ }
drawtype = (enum NodeDrawType)readU8(is);
visual_scale = readF1000(is);
if(readU8(is) != 6)
light_source = readU8(is);
damage_per_second = readU32(is);
selection_box.deSerialize(is);
- material.deSerialize(is);
legacy_facedir_simple = readU8(is);
legacy_wallmounted = readU8(is);
}
assert(name != "");
ContentFeatures f;
f.name = name;
- // Make unknown blocks diggable
- f.material.diggability = DIGGABLE_CONSTANT;
- f.material.constant_time = 0.5;
return set(name, f);
}
virtual void updateAliases(IItemDefManager *idef)
#include "common_irrlicht.h"
#include <string>
#include <iostream>
-#include <set>
+#include <map>
#include "mapnode.h"
#ifndef SERVER
#include "tile.h"
#endif
-#include "materials.h" // MaterialProperties
class IItemDefManager;
class ITextureSource;
class IGameDef;
*/
std::string name; // "" = undefined node
+ std::map<std::string, int> groups; // Same as in itemdef
// Visual definition
enum NodeDrawType drawtype;
u8 light_source;
u32 damage_per_second;
NodeBox selection_box;
- MaterialProperties material;
// Compatibility with old maps
// Set to true if paramtype used to be 'facedir_simple'
bool legacy_facedir_simple;
#include "mapblock.h" // For getNodeBlockPos
#include "content_nodemeta.h"
#include "utility.h"
+#include "tool.h"
static void stackDump(lua_State *L, std::ostream &o)
{
{0, NULL},
};
-struct EnumString es_Diggability[] =
-{
- {DIGGABLE_NOT, "not"},
- {DIGGABLE_NORMAL, "normal"},
- {DIGGABLE_CONSTANT, "constant"},
- {0, NULL},
-};
-
/*
C struct <-> Lua table converter functions
*/
return box;
}
+#if 0
/*
MaterialProperties
*/
getfloatfield(L, -1, "flammability", prop.flammability);
return prop;
}
+#endif
/*
- ToolDiggingProperties
+ Groups
+*/
+static void read_groups(lua_State *L, int index,
+ std::map<std::string, int> &result)
+{
+ result.clear();
+ lua_pushnil(L);
+ if(index < 0)
+ index -= 1;
+ while(lua_next(L, index) != 0){
+ // key at index -2 and value at index -1
+ std::string name = luaL_checkstring(L, -2);
+ int rating = luaL_checkinteger(L, -1);
+ result[name] = rating;
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+}
+
+/*
+ ToolCapabilities
*/
-static ToolDiggingProperties read_tool_digging_properties(
+static ToolCapabilities read_tool_capabilities(
lua_State *L, int table)
{
- ToolDiggingProperties prop;
- getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
- getfloatfield(L, table, "basetime", prop.basetime);
- getfloatfield(L, table, "dt_weight", prop.dt_weight);
- getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
- getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
- getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
- getfloatfield(L, table, "basedurability", prop.basedurability);
- getfloatfield(L, table, "dd_weight", prop.dd_weight);
- getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
- getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
- getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
- return prop;
+ ToolCapabilities toolcap;
+ getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
+ getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
+ lua_getfield(L, table, "groupcaps");
+ if(lua_istable(L, -1)){
+ int table_groupcaps = lua_gettop(L);
+ lua_pushnil(L);
+ while(lua_next(L, table_groupcaps) != 0){
+ // key at index -2 and value at index -1
+ std::string groupname = luaL_checkstring(L, -2);
+ if(lua_istable(L, -1)){
+ int table_groupcap = lua_gettop(L);
+ // This will be created
+ ToolGroupCap groupcap;
+ // Read simple parameters
+ getfloatfield(L, table_groupcap, "maxwear", groupcap.maxwear);
+ getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel);
+ // Read "times" table
+ lua_getfield(L, table_groupcap, "times");
+ if(lua_istable(L, -1)){
+ int table_times = lua_gettop(L);
+ lua_pushnil(L);
+ while(lua_next(L, table_times) != 0){
+ // key at index -2 and value at index -1
+ int rating = luaL_checkinteger(L, -2);
+ float time = luaL_checknumber(L, -1);
+ groupcap.times[rating] = time;
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ // Insert groupcap into toolcap
+ toolcap.groupcaps[groupname] = groupcap;
+ }
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ return toolcap;
}
-static void set_tool_digging_properties(lua_State *L, int table,
- const ToolDiggingProperties &prop)
+static void set_tool_capabilities(lua_State *L, int table,
+ const ToolCapabilities &toolcap)
{
- setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
- setfloatfield(L, table, "basetime", prop.basetime);
- setfloatfield(L, table, "dt_weight", prop.dt_weight);
- setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
- setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
- setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
- setfloatfield(L, table, "basedurability", prop.basedurability);
- setfloatfield(L, table, "dd_weight", prop.dd_weight);
- setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
- setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
- setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
+ setfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
+ setintfield(L, table, "max_drop_level", toolcap.max_drop_level);
+ // Create groupcaps table
+ lua_newtable(L);
+ // For each groupcap
+ for(std::map<std::string, ToolGroupCap>::const_iterator
+ i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){
+ // Create groupcap table
+ lua_newtable(L);
+ const std::string &name = i->first;
+ const ToolGroupCap &groupcap = i->second;
+ // Create subtable "times"
+ lua_newtable(L);
+ for(std::map<int, float>::const_iterator
+ i = groupcap.times.begin(); i != groupcap.times.end(); i++){
+ int rating = i->first;
+ float time = i->second;
+ lua_pushinteger(L, rating);
+ lua_pushnumber(L, time);
+ lua_settable(L, -3);
+ }
+ // Set subtable "times"
+ lua_setfield(L, -2, "times");
+ // Set simple parameters
+ setfloatfield(L, -1, "maxwear", groupcap.maxwear);
+ setintfield(L, -1, "maxlevel", groupcap.maxlevel);
+ // Insert groupcap table into groupcaps table
+ lua_setfield(L, -2, name.c_str());
+ }
+ // Set groupcaps table
+ lua_setfield(L, -2, "groupcaps");
}
-static void push_tool_digging_properties(lua_State *L,
- const ToolDiggingProperties &prop)
+static void push_tool_capabilities(lua_State *L,
+ const ToolCapabilities &prop)
{
lua_newtable(L);
- set_tool_digging_properties(L, -1, prop);
+ set_tool_capabilities(L, -1, prop);
}
/*
- DiggingProperties
+ DigParams
*/
-static void set_digging_properties(lua_State *L, int table,
- const DiggingProperties &prop)
+static void set_dig_params(lua_State *L, int table,
+ const DigParams ¶ms)
{
- setboolfield(L, table, "diggable", prop.diggable);
- setfloatfield(L, table, "time", prop.time);
- setintfield(L, table, "wear", prop.wear);
+ setboolfield(L, table, "diggable", params.diggable);
+ setfloatfield(L, table, "time", params.time);
+ setintfield(L, table, "wear", params.wear);
}
-static void push_digging_properties(lua_State *L,
- const DiggingProperties &prop)
+static void push_dig_params(lua_State *L,
+ const DigParams ¶ms)
{
lua_newtable(L);
- set_digging_properties(L, -1, prop);
+ set_dig_params(L, -1, params);
}
/*
- HittingProperties
+ HitParams
*/
-static void set_hitting_properties(lua_State *L, int table,
- const HittingProperties &prop)
+static void set_hit_params(lua_State *L, int table,
+ const HitParams ¶ms)
{
- setintfield(L, table, "hp", prop.hp);
- setintfield(L, table, "wear", prop.wear);
+ setintfield(L, table, "hp", params.hp);
+ setintfield(L, table, "wear", params.wear);
}
-static void push_hitting_properties(lua_State *L,
- const HittingProperties &prop)
+static void push_hit_params(lua_State *L,
+ const HitParams ¶ms)
{
lua_newtable(L);
- set_hitting_properties(L, -1, prop);
+ set_hit_params(L, -1, params);
}
/*
getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
- lua_getfield(L, index, "tool_digging_properties");
+ warn_if_field_exists(L, index, "tool_digging_properties",
+ "deprecated: use tool_capabilities");
+
+ lua_getfield(L, index, "tool_capabilities");
if(lua_istable(L, -1)){
- def.tool_digging_properties = new ToolDiggingProperties(
- read_tool_digging_properties(L, -1));
+ def.tool_capabilities = new ToolCapabilities(
+ read_tool_capabilities(L, -1));
}
- lua_pop(L, 1);
- // If name is "" (hand), ensure there are ToolDiggingProperties
+ // If name is "" (hand), ensure there are ToolCapabilities
// because it will be looked up there whenever any other item has
- // no ToolDiggingProperties
- if(def.name == "" && def.tool_digging_properties == NULL){
- def.tool_digging_properties = new ToolDiggingProperties();
+ // no ToolCapabilities
+ if(def.name == "" && def.tool_capabilities == NULL){
+ def.tool_capabilities = new ToolCapabilities();
}
+ lua_getfield(L, index, "groups");
+ read_groups(L, -1, def.groups);
+ lua_pop(L, 1);
+
return def;
}
index = lua_gettop(L) + 1 + index;
ContentFeatures f;
+ /* Name */
getstringfield(L, index, "name", f.name);
+ /* Groups */
+ lua_getfield(L, index, "groups");
+ read_groups(L, -1, f.groups);
+ lua_pop(L, 1);
+
/* Visual definition */
f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType,
}
lua_pop(L, 1);
- lua_getfield(L, index, "material");
- if(lua_istable(L, -1)){
- f.material = read_material_properties(L, -1);
- }
- lua_pop(L, 1);
-
// Set to true if paramtype used to be 'facedir_simple'
getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
// Set to true if wall_mounted used to be set to true
return 1;
}
- // get_tool_digging_properties(self) -> table
+ // get_tool_capabilities(self) -> table
// Returns the effective tool digging properties.
// Returns those of the hand ("") if this item has none associated.
- static int l_get_tool_digging_properties(lua_State *L)
+ static int l_get_tool_capabilities(lua_State *L)
{
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
- const ToolDiggingProperties &prop =
- item.getToolDiggingProperties(get_server(L)->idef());
- push_tool_digging_properties(L, prop);
+ const ToolCapabilities &prop =
+ item.getToolCapabilities(get_server(L)->idef());
+ push_tool_capabilities(L, prop);
return 1;
}
method(LuaItemStack, get_free_space),
method(LuaItemStack, is_known),
method(LuaItemStack, get_definition),
- method(LuaItemStack, get_tool_digging_properties),
+ method(LuaItemStack, get_tool_capabilities),
method(LuaItemStack, add_wear),
method(LuaItemStack, add_item),
method(LuaItemStack, item_fits),
return 1;
}
-// get_digging_properties(material_properties, tool_digging_properties[, time_from_last_punch])
-static int l_get_digging_properties(lua_State *L)
+// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
+static int l_get_dig_params(lua_State *L)
{
- MaterialProperties mp = read_material_properties(L, 1);
- ToolDiggingProperties tp = read_tool_digging_properties(L, 2);
+ std::map<std::string, int> groups;
+ read_groups(L, 1, groups);
+ ToolCapabilities tp = read_tool_capabilities(L, 2);
if(lua_isnoneornil(L, 3))
- push_digging_properties(L, getDiggingProperties(&mp, &tp));
+ push_dig_params(L, getDigParams(groups, &tp));
else
- push_digging_properties(L, getDiggingProperties(&mp, &tp,
+ push_dig_params(L, getDigParams(groups, &tp,
luaL_checknumber(L, 3)));
return 1;
}
-// get_hitting_properties(material_properties, tool_digging_properties[, time_from_last_punch])
-static int l_get_hitting_properties(lua_State *L)
+// get_hit_params(groups, tool_capabilities[, time_from_last_punch])
+static int l_get_hit_params(lua_State *L)
{
- MaterialProperties mp = read_material_properties(L, 1);
- ToolDiggingProperties tp = read_tool_digging_properties(L, 2);
+ std::map<std::string, int> groups;
+ read_groups(L, 1, groups);
+ ToolCapabilities tp = read_tool_capabilities(L, 2);
if(lua_isnoneornil(L, 3))
- push_hitting_properties(L, getHittingProperties(&mp, &tp));
+ push_hit_params(L, getHitParams(groups, &tp));
else
- push_hitting_properties(L, getHittingProperties(&mp, &tp,
+ push_hit_params(L, getHitParams(groups, &tp,
luaL_checknumber(L, 3)));
return 1;
}
{"chat_send_player", l_chat_send_player},
{"get_player_privs", l_get_player_privs},
{"get_inventory", l_get_inventory},
- {"get_digging_properties", l_get_digging_properties},
- {"get_hitting_properties", l_get_hitting_properties},
+ {"get_dig_params", l_get_dig_params},
+ {"get_hit_params", l_get_hit_params},
{"get_current_modname", l_get_current_modname},
{"get_modpath", l_get_modpath},
{"get_worldpath", l_get_worldpath},
#include "main.h"
#include "constants.h"
#include "voxel.h"
-#include "materials.h"
#include "config.h"
#include "servercommand.h"
#include "filesys.h"
#include "serverobject.h"
#include <fstream>
#include "inventory.h"
-#include "materials.h"
ServerActiveObject::ServerActiveObject(ServerEnvironment *env, v3f pos):
ActiveObject(0),
#include "gamedef.h"
#include "inventory.h"
#include "environment.h"
-#include "materials.h"
+#include "tool.h"
ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
Player(env->getGameDef()),
return;
}
- // "Material" properties of a player
- MaterialProperties mp;
- mp.diggability = DIGGABLE_NORMAL;
- mp.crackiness = -0.5;
- mp.cuttability = 0.5;
+ // "Material" groups of the player
+ std::map<std::string, int> groups;
+ groups["snappy"] = 1;
+ groups["choppy"] = 2;
IItemDefManager *idef = m_env->getGameDef()->idef();
ItemStack punchitem = puncher->getWieldedItem();
- ToolDiggingProperties tp =
- punchitem.getToolDiggingProperties(idef);
+ ToolCapabilities tp = punchitem.getToolCapabilities(idef);
- HittingProperties hitprop = getHittingProperties(&mp, &tp,
- time_from_last_punch);
+ HitParams hitparams = getHitParams(groups, &tp, time_from_last_punch);
actionstream<<"Player "<<getName()<<" punched by "
- <<puncher->getDescription()<<", damage "<<hitprop.hp
+ <<puncher->getDescription()<<", damage "<<hitparams.hp
<<" HP"<<std::endl;
- setHP(getHP() - hitprop.hp);
- punchitem.addWear(hitprop.wear, idef);
+ setHP(getHP() - hitparams.hp);
+ punchitem.addWear(hitparams.wear, idef);
puncher->setWieldedItem(punchitem);
- if(hitprop.hp != 0)
+ if(hitparams.hp != 0)
{
std::ostringstream os(std::ios::binary);
// command (1 = punched)
writeU8(os, 1);
// damage
- writeS16(os, hitprop.hp);
+ writeS16(os, hitparams.hp);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
m_messages_out.push_back(aom);
itemdef.type = ITEM_NODE;
itemdef.name = "default:stone";
itemdef.description = "Stone";
+ itemdef.groups["cracky"] = 3;
itemdef.inventory_image = "[inventorycube"
"{default_stone.png"
"{default_stone.png"
for(int i = 0; i < 6; i++)
f.tname_tiles[i] = "default_stone.png";
f.is_ground_content = true;
- f.material.diggability = DIGGABLE_NORMAL;
- f.material.weight = 5.0;
- f.material.crackiness = 1.0;
- f.material.crumbliness = -0.1;
- f.material.cuttability = -0.2;
idef->registerItem(itemdef);
ndef->set(i, f);
itemdef.type = ITEM_NODE;
itemdef.name = "default:dirt_with_grass";
itemdef.description = "Dirt with grass";
+ itemdef.groups["crumbly"] = 3;
itemdef.inventory_image = "[inventorycube"
"{default_grass.png"
"{default_dirt.png&default_grass_side.png"
for(int i = 2; i < 6; i++)
f.tname_tiles[i] = "default_dirt.png^default_grass_side.png";
f.is_ground_content = true;
- f.material.diggability = DIGGABLE_NORMAL;
- f.material.weight = 1.2;
- f.material.crackiness = 0.0;
- f.material.crumbliness = 1.2;
- f.material.cuttability = -0.4;
idef->registerItem(itemdef);
ndef->set(i, f);
}
--- /dev/null
+/*
+Minetest-c55
+Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "tool.h"
+#include "utility.h"
+#include "itemdef.h" // For itemgroup_get()
+#include "log.h"
+
+void ToolCapabilities::serialize(std::ostream &os) const
+{
+ writeU8(os, 0); // version
+ writeF1000(os, full_punch_interval);
+ writeS16(os, max_drop_level);
+ writeU32(os, groupcaps.size());
+ for(std::map<std::string, ToolGroupCap>::const_iterator
+ i = groupcaps.begin(); i != groupcaps.end(); i++){
+ const std::string *name = &i->first;
+ const ToolGroupCap *cap = &i->second;
+ os<<serializeString(*name);
+ writeF1000(os, cap->maxwear);
+ writeF1000(os, cap->maxlevel);
+ writeU32(os, cap->times.size());
+ for(std::map<int, float>::const_iterator
+ i = cap->times.begin(); i != cap->times.end(); i++){
+ writeS16(os, i->first);
+ writeF1000(os, i->second);
+ }
+ }
+}
+
+void ToolCapabilities::deSerialize(std::istream &is)
+{
+ int version = readU8(is);
+ if(version != 0) throw SerializationError(
+ "unsupported ToolCapabilities version");
+ full_punch_interval = readF1000(is);
+ max_drop_level = readS16(is);
+ groupcaps.clear();
+ u32 groupcaps_size = readU32(is);
+ for(u32 i=0; i<groupcaps_size; i++){
+ std::string name = deSerializeString(is);
+ ToolGroupCap cap;
+ cap.maxwear = readF1000(is);
+ cap.maxlevel = readF1000(is);
+ u32 times_size = readU32(is);
+ for(u32 i=0; i<times_size; i++){
+ int level = readS16(is);
+ float time = readF1000(is);
+ cap.times[level] = time;
+ }
+ groupcaps[name] = cap;
+ }
+}
+
+DigParams getDigParams(const std::map<std::string, int> &groups,
+ const ToolCapabilities *tp, float time_from_last_punch)
+{
+ //infostream<<"getDigParams"<<std::endl;
+ /* Check group dig_immediate */
+ switch(itemgroup_get(groups, "dig_immediate")){
+ case 1:
+ //infostream<<"dig_immediate=1"<<std::endl;
+ return DigParams(true, 0.0, 0);
+ case 2:
+ //infostream<<"dig_immediate=2"<<std::endl;
+ return DigParams(true, 1.0, 0);
+ default:
+ break;
+ }
+
+ // Values to be returned (with a bit of conversion)
+ bool result_diggable = false;
+ float result_time = 0.0;
+ float result_wear = 0.0;
+
+ int level = itemgroup_get(groups, "level");
+ //infostream<<"level="<<level<<std::endl;
+ for(std::map<std::string, ToolGroupCap>::const_iterator
+ i = tp->groupcaps.begin(); i != tp->groupcaps.end(); i++){
+ const std::string &name = i->first;
+ //infostream<<"group="<<name<<std::endl;
+ const ToolGroupCap &cap = i->second;
+ int rating = itemgroup_get(groups, name);
+ float time = 0;
+ bool time_exists = cap.getTime(rating, &time);
+ if(!result_diggable || time < result_time){
+ if(cap.maxlevel > level && time_exists){
+ result_diggable = true;
+ result_time = time;
+ int leveldiff = cap.maxlevel - level;
+ result_wear = cap.maxwear / pow(4.0, (double)leveldiff);
+ }
+ }
+ }
+ //infostream<<"result_diggable="<<result_diggable<<std::endl;
+ //infostream<<"result_time="<<result_time<<std::endl;
+ //infostream<<"result_wear="<<result_wear<<std::endl;
+
+ if(time_from_last_punch < tp->full_punch_interval){
+ float f = time_from_last_punch / tp->full_punch_interval;
+ //infostream<<"f="<<f<<std::endl;
+ result_time /= f;
+ result_wear /= f;
+ }
+
+ u16 wear_i = 65535.*result_wear;
+ return DigParams(result_diggable, result_time, wear_i);
+}
+
+DigParams getDigParams(const std::map<std::string, int> &groups,
+ const ToolCapabilities *tp)
+{
+ return getDigParams(groups, tp, 1000000);
+}
+
+HitParams getHitParams(const std::map<std::string, int> &groups,
+ const ToolCapabilities *tp, float time_from_last_punch)
+{
+ DigParams digprop = getDigParams(groups, tp,
+ time_from_last_punch);
+
+ // If digging time would be 1 second, 8 half-hearts go in 1 second.
+ s16 hp = 0;
+ if(digprop.diggable)
+ hp = 8.0 / digprop.time;
+ // Wear is the same as for digging a single node
+ s16 wear = (float)digprop.wear;
+
+ return HitParams(hp, wear);
+}
+
+HitParams getHitParams(const std::map<std::string, int> &groups,
+ const ToolCapabilities *tp)
+{
+ return getHitParams(groups, tp, 1000000);
+}
+
--- /dev/null
+/*
+Minetest-c55
+Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef TOOL_HEADER
+#define TOOL_HEADER
+
+#include "common_irrlicht.h"
+#include <string>
+#include <iostream>
+#include <map>
+
+struct ToolGroupCap
+{
+ std::map<int, float> times;
+ float maxwear;
+ int maxlevel;
+
+ ToolGroupCap():
+ maxwear(0.05),
+ maxlevel(1)
+ {}
+
+ bool getTime(int rating, float *time) const
+ {
+ std::map<int, float>::const_iterator i = times.find(rating);
+ if(i == times.end()){
+ *time = 0;
+ return false;
+ }
+ *time = i->second;
+ return true;
+ }
+};
+
+struct ToolCapabilities
+{
+ float full_punch_interval;
+ int max_drop_level;
+ std::map<std::string, ToolGroupCap> groupcaps;
+
+ ToolCapabilities(
+ float full_punch_interval_=3.0,
+ int max_drop_level_=1,
+ std::map<std::string, ToolGroupCap> groupcaps_ =
+ std::map<std::string, ToolGroupCap>()
+ ):
+ full_punch_interval(full_punch_interval_),
+ max_drop_level(max_drop_level_),
+ groupcaps(groupcaps_)
+ {}
+
+ void serialize(std::ostream &os) const;
+ void deSerialize(std::istream &is);
+};
+
+struct DigParams
+{
+ bool diggable;
+ // Digging time in seconds
+ float time;
+ // Caused wear
+ u16 wear;
+
+ DigParams(bool a_diggable=false, float a_time=0, u16 a_wear=0):
+ diggable(a_diggable),
+ time(a_time),
+ wear(a_wear)
+ {}
+};
+
+DigParams getDigParams(const std::map<std::string, int> &groups,
+ const ToolCapabilities *tp, float time_from_last_punch);
+
+DigParams getDigParams(const std::map<std::string, int> &groups,
+ const ToolCapabilities *tp);
+
+struct HitParams
+{
+ s16 hp;
+ s16 wear;
+
+ HitParams(s16 hp_=0, s16 wear_=0):
+ hp(hp_),
+ wear(wear_)
+ {}
+};
+
+HitParams getHitParams(const std::map<std::string, int> &groups,
+ const ToolCapabilities *tp, float time_from_last_punch);
+
+HitParams getHitParams(const std::map<std::string, int> &groups,
+ const ToolCapabilities *tp);
+
+#endif
+