mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Digging time groups WIP
This commit is contained in:
		@@ -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},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 = <default>
 | 
			
		||||
	},
 | 
			
		||||
	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 = = <default>
 | 
			
		||||
		--wall_side = = <default>
 | 
			
		||||
	},
 | 
			
		||||
	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 = <default>
 | 
			
		||||
		--wall_side = <default>
 | 
			
		||||
	},
 | 
			
		||||
	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),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -116,7 +116,7 @@ set(common_SRCS
 | 
			
		||||
	serverobject.cpp
 | 
			
		||||
	noise.cpp
 | 
			
		||||
	porting.cpp
 | 
			
		||||
	materials.cpp
 | 
			
		||||
	tool.cpp
 | 
			
		||||
	defaultsettings.cpp
 | 
			
		||||
	mapnode.cpp
 | 
			
		||||
	voxel.cpp
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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<u16, ServerActiveObject::Factory> 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<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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -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<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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1504,7 +1502,8 @@ void MobV2SAO::updateProperties()
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								src/game.cpp
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/game.cpp
									
									
									
									
									
								
							@@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#include "guiInventoryMenu.h"
 | 
			
		||||
#include "guiTextInputMenu.h"
 | 
			
		||||
#include "guiDeathScreen.h"
 | 
			
		||||
#include "materials.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "clouds.h"
 | 
			
		||||
#include "camera.h"
 | 
			
		||||
@@ -1935,21 +1935,26 @@ void the_game(
 | 
			
		||||
				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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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<<serializeString(name);
 | 
			
		||||
	os<<serializeString(description);
 | 
			
		||||
@@ -135,14 +137,19 @@ void ItemDefinition::serialize(std::ostream &os) const
 | 
			
		||||
	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)
 | 
			
		||||
@@ -152,7 +159,7 @@ 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);
 | 
			
		||||
@@ -163,12 +170,19 @@ void ItemDefinition::deSerialize(std::istream &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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -253,7 +267,7 @@ public:
 | 
			
		||||
		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;
 | 
			
		||||
@@ -273,9 +287,9 @@ public:
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,8 +25,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#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
 | 
			
		||||
@@ -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<std::string, int> groups;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		Cached stuff
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,159 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										137
									
								
								src/materials.h
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								src/materials.h
									
									
									
									
									
								
							@@ -1,137 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
@@ -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<<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);
 | 
			
		||||
@@ -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<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)
 | 
			
		||||
@@ -233,7 +242,6 @@ void ContentFeatures::deSerialize(std::istream &is)
 | 
			
		||||
	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);
 | 
			
		||||
}
 | 
			
		||||
@@ -412,9 +420,6 @@ public:
 | 
			
		||||
		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)
 | 
			
		||||
 
 | 
			
		||||
@@ -23,12 +23,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#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;
 | 
			
		||||
@@ -149,6 +148,7 @@ struct ContentFeatures
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	std::string name; // "" = undefined node
 | 
			
		||||
	std::map<std::string, int> 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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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<f32> 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<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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -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<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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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},
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#include "serverobject.h"
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include "inventory.h"
 | 
			
		||||
#include "materials.h"
 | 
			
		||||
 | 
			
		||||
ServerActiveObject::ServerActiveObject(ServerEnvironment *env, v3f pos):
 | 
			
		||||
	ActiveObject(0),
 | 
			
		||||
 
 | 
			
		||||
@@ -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<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);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								src/test.cpp
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										153
									
								
								src/tool.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								src/tool.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,153 @@
 | 
			
		||||
/*
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										111
									
								
								src/tool.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/tool.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
/*
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user