From 562ac3bce9fae076562bd2e92e7d330c296ac1b0 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Tue, 28 Feb 2012 19:45:23 +0200 Subject: [PATCH] Digging time groups WIP --- data/builtin.lua | 35 ++--- data/mods/default/init.lua | 310 +++++++++++++++---------------------- src/CMakeLists.txt | 2 +- src/clientserver.h | 4 +- src/content_sao.cpp | 47 +++--- src/game.cpp | 19 ++- src/inventory.h | 16 +- src/itemdef.cpp | 62 +++++--- src/itemdef.h | 19 ++- src/main.cpp | 1 - src/materials.cpp | 159 ------------------- src/materials.h | 137 ---------------- src/nodedef.cpp | 27 ++-- src/nodedef.h | 5 +- src/scriptapi.cpp | 251 +++++++++++++++++++----------- src/server.cpp | 1 - src/serverobject.cpp | 1 - src/serverremoteplayer.cpp | 27 ++-- src/test.cpp | 12 +- src/tool.cpp | 153 ++++++++++++++++++ src/tool.h | 111 +++++++++++++ 21 files changed, 695 insertions(+), 704 deletions(-) delete mode 100644 src/materials.cpp delete mode 100644 src/materials.h create mode 100644 src/tool.cpp create mode 100644 src/tool.h diff --git a/data/builtin.lua b/data/builtin.lua index eba5b429e..258704f63 100644 --- a/data/builtin.lua +++ b/data/builtin.lua @@ -327,9 +327,8 @@ function minetest.node_dig(pos, node, digger) 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) @@ -366,7 +365,7 @@ minetest.nodedef_default = { stack_max = 99, usable = false, liquids_pointable = false, - tool_digging_properties = nil, + tool_capabilities = nil, -- Interaction callbacks on_place = minetest.item_place, @@ -425,7 +424,7 @@ minetest.craftitemdef_default = { 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, @@ -443,7 +442,7 @@ minetest.tooldef_default = { 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, @@ -461,7 +460,7 @@ minetest.noneitemdef_default = { -- This is used for the hand and unknown items 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, @@ -643,7 +642,7 @@ function minetest.register_tool(name, tooldef) 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 @@ -655,7 +654,7 @@ function minetest.register_tool(name, tooldef) 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, @@ -711,18 +710,14 @@ minetest.register_item(":", { 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}, + } } }) diff --git a/data/mods/default/init.lua b/data/mods/default/init.lua index 7f63d9a7c..9750f610f 100644 --- a/data/mods/default/init.lua +++ b/data/mods/default/init.lua @@ -263,7 +263,7 @@ -- - 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, @@ -322,7 +322,7 @@ -- 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, @@ -371,14 +371,6 @@ -- 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 -- } @@ -455,209 +447,145 @@ default = {} 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} + } } }) @@ -1110,7 +1038,7 @@ minetest.register_node("default:stone", { 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, }) @@ -1119,7 +1047,7 @@ minetest.register_node("default:stone_with_coal", { 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', }) @@ -1127,7 +1055,7 @@ minetest.register_node("default:stone_with_iron", { 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', }) @@ -1135,7 +1063,7 @@ minetest.register_node("default:dirt_with_grass", { 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', }) @@ -1143,7 +1071,7 @@ minetest.register_node("default:dirt_with_grass_footsteps", { 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', }) @@ -1151,28 +1079,28 @@ minetest.register_node("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', }) @@ -1180,7 +1108,7 @@ minetest.register_node("default:clay", { 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', }) @@ -1188,7 +1116,7 @@ minetest.register_node("default:brick", { 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', }) @@ -1196,14 +1124,14 @@ minetest.register_node("default:tree", { 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", { @@ -1215,7 +1143,7 @@ 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", { @@ -1224,7 +1152,7 @@ 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 = { @@ -1246,7 +1174,7 @@ minetest.register_node("default:cactus", { 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", { @@ -1258,14 +1186,14 @@ 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", { @@ -1276,7 +1204,7 @@ 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", { @@ -1291,7 +1219,7 @@ 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", { @@ -1307,7 +1235,7 @@ minetest.register_node("default:rail", { type = "fixed", --fixed = }, - material = minetest.digprop_dirtlike(0.75), + groups = {bendy=2,snappy=1}, }) minetest.register_node("default:ladder", { @@ -1327,7 +1255,7 @@ minetest.register_node("default:ladder", { --wall_bottom = = --wall_side = = }, - material = minetest.digprop_woodlike(0.5), + groups = {snappy=2}, legacy_wallmounted = true, }) @@ -1335,14 +1263,14 @@ minetest.register_node("default:wood", { 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", { @@ -1371,6 +1299,7 @@ minetest.register_node("default:water_flowing", { {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", { @@ -1393,6 +1322,7 @@ 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", { @@ -1416,6 +1346,7 @@ 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", { @@ -1439,6 +1370,7 @@ 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", { @@ -1458,7 +1390,7 @@ 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, }) @@ -1479,7 +1411,7 @@ minetest.register_node("default:sign_wall", { --wall_bottom = --wall_side = }, - material = minetest.digprop_constanttime(0.5), + groups = {dig_immediate=2}, legacy_wallmounted = true, }) @@ -1489,7 +1421,7 @@ minetest.register_node("default:chest", { "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, }) @@ -1499,7 +1431,7 @@ minetest.register_node("default:chest_locked", { "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, }) @@ -1509,7 +1441,7 @@ minetest.register_node("default:furnace", { "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, }) @@ -1517,21 +1449,21 @@ minetest.register_node("default:cobble", { 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", { @@ -1540,7 +1472,7 @@ 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, }) @@ -1548,7 +1480,7 @@ minetest.register_node("default:nyancat_rainbow", { 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", { @@ -1560,7 +1492,7 @@ 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", { @@ -1572,7 +1504,7 @@ 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), }) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee02d66f0..860722712 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -116,7 +116,7 @@ set(common_SRCS serverobject.cpp noise.cpp porting.cpp - materials.cpp + tool.cpp defaultsettings.cpp mapnode.cpp voxel.cpp diff --git a/src/clientserver.h b/src/clientserver.h index acb4f8530..8badd177e 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -44,9 +44,11 @@ with this program; if not, write to the Free Software Foundation, Inc., 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 diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 02be64c64..cb4d81f9a 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #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 ServerActiveObject::m_types; @@ -723,24 +723,23 @@ void Oerkki1SAO::punch(ServerActiveObject *puncher, float time_from_last_punch) 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 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); } } @@ -1419,24 +1418,23 @@ void MobV2SAO::punch(ServerActiveObject *puncher, float time_from_last_punch) 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 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); } } @@ -1504,7 +1502,8 @@ void MobV2SAO::updateProperties() void MobV2SAO::doDamage(u16 d) { - infostream<<"MobV2 hp="<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) diff --git a/src/inventory.h b/src/inventory.h index fcac5f647..e27da15d5 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "debug.h" #include "itemdef.h" -struct ToolDiggingProperties; +struct ToolCapabilities; struct ItemStack { @@ -107,15 +107,15 @@ 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) diff --git a/src/itemdef.cpp b/src/itemdef.cpp index 22ca9f088..98232c6d5 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gamedef.h" #include "nodedef.h" -#include "materials.h" +#include "tool.h" #include "inventory.h" #ifndef SERVER #include "mapblock_mesh.h" @@ -64,11 +64,12 @@ ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def) 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) @@ -88,7 +89,7 @@ ItemDefinition::~ItemDefinition() 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; @@ -107,11 +108,12 @@ void ItemDefinition::reset() 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; @@ -125,7 +127,7 @@ void ItemDefinition::reset() void ItemDefinition::serialize(std::ostream &os) const { - writeU8(os, 0); // version + writeU8(os, 1); // version writeU8(os, type); os<serialize(tmp_os); - tool_digging_properties_s = tmp_os.str(); + tool_capabilities->serialize(tmp_os); + tool_capabilities_s = tmp_os.str(); + } + os<::const_iterator + i = groups.begin(); i != groups.end(); i++){ + os<first); + writeS16(os, i->second); } - os<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; iname = ""; 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; @@ -273,9 +287,9 @@ public: virtual void registerItem(const ItemDefinition &def) { infostream<<"ItemDefManager: registering \""< #include #include +#include class IGameDef; -struct ToolDiggingProperties; +struct ToolCapabilities; + +/* + Some helpers +*/ + +static inline int itemgroup_get(const std::map &groups, + const std::string &name) +{ + std::map::const_iterator i = groups.find(name); + if(i == groups.end()) + return 0; + return i->second; +} /* Base item definition @@ -63,7 +77,8 @@ struct ItemDefinition bool usable; bool liquids_pointable; // May be NULL. If non-NULL, deleted by destructor - ToolDiggingProperties *tool_digging_properties; + ToolCapabilities *tool_capabilities; + std::map groups; /* Cached stuff diff --git a/src/main.cpp b/src/main.cpp index 2875474f1..ec999c530 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -399,7 +399,6 @@ Doing currently: #include "filesys.h" #include "config.h" #include "guiMainMenu.h" -#include "materials.h" #include "game.h" #include "keycode.h" #include "tile.h" diff --git a/src/materials.cpp b/src/materials.cpp deleted file mode 100644 index c37b7c505..000000000 --- a/src/materials.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* -Minetest-c55 -Copyright (C) 2011 celeron55, Perttu Ahola - -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); -} - diff --git a/src/materials.h b/src/materials.h deleted file mode 100644 index 058b2ab85..000000000 --- a/src/materials.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -Minetest-c55 -Copyright (C) 2010-2011 celeron55, Perttu Ahola - -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 -#include - -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 - diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 0c2793a0e..7d0408eb7 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -118,6 +118,7 @@ void ContentFeatures::reset() in builtin.lua */ name = ""; + groups.clear(); drawtype = NDT_NORMAL; visual_scale = 1.0; for(u32 i=0; i<6; i++) @@ -144,18 +145,20 @@ void ContentFeatures::reset() 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<::const_iterator + i = groups.begin(); i != groups.end(); i++){ + os<first); + writeS16(os, i->second); + } writeU8(os, drawtype); writeF1000(os, visual_scale); writeU8(os, 6); @@ -188,7 +191,6 @@ void ContentFeatures::serialize(std::ostream &os) 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); } @@ -196,9 +198,16 @@ void ContentFeatures::serialize(std::ostream &os) 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 #include -#include +#include #include "mapnode.h" #ifndef SERVER #include "tile.h" #endif -#include "materials.h" // MaterialProperties class IItemDefManager; class ITextureSource; class IGameDef; @@ -149,6 +148,7 @@ struct ContentFeatures */ std::string name; // "" = undefined node + std::map groups; // Same as in itemdef // Visual definition enum NodeDrawType drawtype; @@ -194,7 +194,6 @@ struct ContentFeatures 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; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 8350c75f1..2ee727b3f 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -45,6 +45,7 @@ extern "C" { #include "mapblock.h" // For getNodeBlockPos #include "content_nodemeta.h" #include "utility.h" +#include "tool.h" static void stackDump(lua_State *L, std::ostream &o) { @@ -416,14 +417,6 @@ struct EnumString es_NodeBoxType[] = {0, NULL}, }; -struct EnumString es_Diggability[] = -{ - {DIGGABLE_NOT, "not"}, - {DIGGABLE_NORMAL, "normal"}, - {DIGGABLE_CONSTANT, "constant"}, - {0, NULL}, -}; - /* C struct <-> Lua table converter functions */ @@ -612,6 +605,7 @@ static core::aabbox3d read_aabbox3df32(lua_State *L, int index, f32 scale) return box; } +#if 0 /* MaterialProperties */ @@ -630,87 +624,156 @@ static MaterialProperties read_material_properties( getfloatfield(L, -1, "flammability", prop.flammability); return prop; } +#endif /* - ToolDiggingProperties + Groups +*/ +static void read_groups(lua_State *L, int index, + std::map &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::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::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); } /* @@ -778,20 +841,26 @@ static ItemDefinition read_item_definition(lua_State *L, int index) 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; } @@ -805,8 +874,14 @@ static ContentFeatures read_content_features(lua_State *L, int index) 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, @@ -958,12 +1033,6 @@ static ContentFeatures read_content_features(lua_State *L, int index) } 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 @@ -1215,16 +1284,16 @@ private: 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; } @@ -1386,7 +1455,7 @@ const luaL_reg LuaItemStack::methods[] = { 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), @@ -3513,28 +3582,30 @@ static int l_get_inventory(lua_State *L) 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 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 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; } @@ -3580,8 +3651,8 @@ static const struct luaL_Reg minetest_f [] = { {"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}, diff --git a/src/server.cpp b/src/server.cpp index 2facb1469..443a2a39b 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" #include "constants.h" #include "voxel.h" -#include "materials.h" #include "config.h" #include "servercommand.h" #include "filesys.h" diff --git a/src/serverobject.cpp b/src/serverobject.cpp index 2609e3015..4d7f19243 100644 --- a/src/serverobject.cpp +++ b/src/serverobject.cpp @@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverobject.h" #include #include "inventory.h" -#include "materials.h" ServerActiveObject::ServerActiveObject(ServerEnvironment *env, v3f pos): ActiveObject(0), diff --git a/src/serverremoteplayer.cpp b/src/serverremoteplayer.cpp index 728ffe026..8a81f1d2d 100644 --- a/src/serverremoteplayer.cpp +++ b/src/serverremoteplayer.cpp @@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gamedef.h" #include "inventory.h" #include "environment.h" -#include "materials.h" +#include "tool.h" ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env): Player(env->getGameDef()), @@ -181,35 +181,32 @@ void ServerRemotePlayer::punch(ServerActiveObject *puncher, 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 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 "<getDescription()<<", damage "<getDescription()<<", damage "<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); diff --git a/src/test.cpp b/src/test.cpp index 4226df544..45851a7e3 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -68,6 +68,7 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n 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" @@ -77,11 +78,6 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n 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); @@ -93,6 +89,7 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n 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" @@ -104,11 +101,6 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n 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); } diff --git a/src/tool.cpp b/src/tool.cpp new file mode 100644 index 000000000..3c61ad6e7 --- /dev/null +++ b/src/tool.cpp @@ -0,0 +1,153 @@ +/* +Minetest-c55 +Copyright (C) 2011 celeron55, Perttu Ahola + +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::const_iterator + i = groupcaps.begin(); i != groupcaps.end(); i++){ + const std::string *name = &i->first; + const ToolGroupCap *cap = &i->second; + os<maxwear); + writeF1000(os, cap->maxlevel); + writeU32(os, cap->times.size()); + for(std::map::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 &groups, + const ToolCapabilities *tp, float time_from_last_punch) +{ + //infostream<<"getDigParams"< +#include +#include + +struct ToolGroupCap +{ + std::map times; + float maxwear; + int maxlevel; + + ToolGroupCap(): + maxwear(0.05), + maxlevel(1) + {} + + bool getTime(int rating, float *time) const + { + std::map::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 groupcaps; + + ToolCapabilities( + float full_punch_interval_=3.0, + int max_drop_level_=1, + std::map groupcaps_ = + std::map() + ): + 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 &groups, + const ToolCapabilities *tp, float time_from_last_punch); + +DigParams getDigParams(const std::map &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 &groups, + const ToolCapabilities *tp, float time_from_last_punch); + +HitParams getHitParams(const std::map &groups, + const ToolCapabilities *tp); + +#endif +