From 562ac3bce9fae076562bd2e92e7d330c296ac1b0 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Tue, 28 Feb 2012 19:45:23 +0200 Subject: Digging time groups WIP --- src/CMakeLists.txt | 2 +- src/clientserver.h | 4 +- src/content_sao.cpp | 47 +++++---- src/game.cpp | 19 ++-- src/inventory.h | 16 +-- src/itemdef.cpp | 62 ++++++----- src/itemdef.h | 19 +++- src/main.cpp | 1 - src/materials.cpp | 159 ---------------------------- src/materials.h | 137 ------------------------- src/nodedef.cpp | 27 +++-- src/nodedef.h | 5 +- src/scriptapi.cpp | 251 +++++++++++++++++++++++++++++---------------- src/server.cpp | 1 - src/serverobject.cpp | 1 - src/serverremoteplayer.cpp | 27 +++-- src/test.cpp | 12 +-- src/tool.cpp | 153 +++++++++++++++++++++++++++ src/tool.h | 111 ++++++++++++++++++++ 19 files changed, 559 insertions(+), 495 deletions(-) delete mode 100644 src/materials.cpp delete mode 100644 src/materials.h create mode 100644 src/tool.cpp create mode 100644 src/tool.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee02d66f0..860722712 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -116,7 +116,7 @@ set(common_SRCS serverobject.cpp noise.cpp porting.cpp - materials.cpp + tool.cpp defaultsettings.cpp mapnode.cpp voxel.cpp diff --git a/src/clientserver.h b/src/clientserver.h index acb4f8530..8badd177e 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -44,9 +44,11 @@ with this program; if not, write to the Free Software Foundation, Inc., Obsolete TOCLIENT_TOOLDEF Obsolete TOCLIENT_CRAFTITEMDEF Compress the contents of TOCLIENT_ITEMDEF and TOCLIENT_NODEDEF + PROTOCOL_VERSION 8: + Digging based on item groups */ -#define PROTOCOL_VERSION 7 +#define PROTOCOL_VERSION 8 #define PROTOCOL_ID 0x4f457403 diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 02be64c64..cb4d81f9a 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" // For g_profiler #include "profiler.h" #include "serialization.h" // For compressZlib -#include "materials.h" // For MaterialProperties and ToolDiggingProperties +#include "tool.h" // For ToolCapabilities #include "gamedef.h" core::map ServerActiveObject::m_types; @@ -723,24 +723,23 @@ void Oerkki1SAO::punch(ServerActiveObject *puncher, float time_from_last_punch) v3f dir = (getBasePosition() - puncher->getBasePosition()).normalize(); m_speed_f += dir*12*BS; - // "Material" properties of an oerkki - MaterialProperties mp; - mp.diggability = DIGGABLE_NORMAL; - mp.crackiness = -1.0; - mp.cuttability = 1.0; + // "Material" groups of the object + std::map groups; + groups["snappy"] = 1; + groups["choppy"] = 1; + groups["fleshy"] = 3; IItemDefManager *idef = m_env->getGameDef()->idef(); - ItemStack punchitem = puncher->getWieldedItem(); - ToolDiggingProperties tp = - punchitem.getToolDiggingProperties(idef); + ItemStack punchitem = puncher->getWieldedItem(); + ToolCapabilities tp = punchitem.getToolCapabilities(idef); - HittingProperties hitprop = getHittingProperties(&mp, &tp, + HitParams hit_params = getHitParams(groups, &tp, time_from_last_punch); - doDamage(hitprop.hp); + doDamage(hit_params.hp); if(g_settings->getBool("creative_mode") == false) { - punchitem.addWear(hitprop.wear, idef); + punchitem.addWear(hit_params.wear, idef); puncher->setWieldedItem(punchitem); } } @@ -1419,24 +1418,23 @@ void MobV2SAO::punch(ServerActiveObject *puncher, float time_from_last_punch) sendPosition(); - // "Material" properties of the MobV2 - MaterialProperties mp; - mp.diggability = DIGGABLE_NORMAL; - mp.crackiness = -1.0; - mp.cuttability = 1.0; + // "Material" groups of the object + std::map groups; + groups["snappy"] = 1; + groups["choppy"] = 1; + groups["fleshy"] = 3; IItemDefManager *idef = m_env->getGameDef()->idef(); - ItemStack punchitem = puncher->getWieldedItem(); - ToolDiggingProperties tp = - punchitem.getToolDiggingProperties(idef); + ItemStack punchitem = puncher->getWieldedItem(); + ToolCapabilities tp = punchitem.getToolCapabilities(idef); - HittingProperties hitprop = getHittingProperties(&mp, &tp, + HitParams hit_params = getHitParams(groups, &tp, time_from_last_punch); - doDamage(hitprop.hp); + doDamage(hit_params.hp); if(g_settings->getBool("creative_mode") == false) { - punchitem.addWear(hitprop.wear, idef); + punchitem.addWear(hit_params.wear, idef); puncher->setWieldedItem(punchitem); } } @@ -1504,7 +1502,8 @@ void MobV2SAO::updateProperties() void MobV2SAO::doDamage(u16 d) { - infostream<<"MobV2 hp="<get(n.getContent()).material; - ToolDiggingProperties tp = - playeritem.getToolDiggingProperties(itemdef); - DiggingProperties prop = getDiggingProperties(&mp, &tp); + ToolCapabilities tp = playeritem.getToolCapabilities(itemdef); + DigParams params = getDigParams(nodedef->get(n).groups, &tp); + // If can't dig, try hand + if(!params.diggable){ + const ItemDefinition &hand = itemdef->get(""); + const ToolCapabilities *tp = hand.tool_capabilities; + if(tp) + params = getDigParams(nodedef->get(n).groups, tp); + } float dig_time_complete = 0.0; - if(prop.diggable == false) + if(params.diggable == false) { // I guess nobody will wait for this long dig_time_complete = 10000000.0; } else { - dig_time_complete = prop.time; + dig_time_complete = params.time; } if(dig_time_complete >= 0.001) diff --git a/src/inventory.h b/src/inventory.h index fcac5f647..e27da15d5 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "debug.h" #include "itemdef.h" -struct ToolDiggingProperties; +struct ToolCapabilities; struct ItemStack { @@ -107,15 +107,15 @@ struct ItemStack } // Get tool digging properties, or those of the hand if not a tool - const ToolDiggingProperties& getToolDiggingProperties( + const ToolCapabilities& getToolCapabilities( IItemDefManager *itemdef) const { - ToolDiggingProperties *prop; - prop = itemdef->get(name).tool_digging_properties; - if(prop == NULL) - prop = itemdef->get("").tool_digging_properties; - assert(prop != NULL); - return *prop; + ToolCapabilities *cap; + cap = itemdef->get(name).tool_capabilities; + if(cap == NULL) + cap = itemdef->get("").tool_capabilities; + assert(cap != NULL); + return *cap; } // Wear out (only tools) diff --git a/src/itemdef.cpp b/src/itemdef.cpp index 22ca9f088..98232c6d5 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gamedef.h" #include "nodedef.h" -#include "materials.h" +#include "tool.h" #include "inventory.h" #ifndef SERVER #include "mapblock_mesh.h" @@ -64,11 +64,12 @@ ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def) stack_max = def.stack_max; usable = def.usable; liquids_pointable = def.liquids_pointable; - if(def.tool_digging_properties) + if(def.tool_capabilities) { - tool_digging_properties = new ToolDiggingProperties( - *def.tool_digging_properties); + tool_capabilities = new ToolCapabilities( + *def.tool_capabilities); } + groups = def.groups; #ifndef SERVER inventory_texture = def.inventory_texture; if(def.wield_mesh) @@ -88,7 +89,7 @@ ItemDefinition::~ItemDefinition() void ItemDefinition::resetInitial() { // Initialize pointers to NULL so reset() does not delete undefined pointers - tool_digging_properties = NULL; + tool_capabilities = NULL; #ifndef SERVER inventory_texture = NULL; wield_mesh = NULL; @@ -107,11 +108,12 @@ void ItemDefinition::reset() stack_max = 99; usable = false; liquids_pointable = false; - if(tool_digging_properties) + if(tool_capabilities) { - delete tool_digging_properties; - tool_digging_properties = NULL; + delete tool_capabilities; + tool_capabilities = NULL; } + groups.clear(); #ifndef SERVER inventory_texture = NULL; @@ -125,7 +127,7 @@ void ItemDefinition::reset() void ItemDefinition::serialize(std::ostream &os) const { - writeU8(os, 0); // version + writeU8(os, 1); // version writeU8(os, type); os<serialize(tmp_os); - tool_digging_properties_s = tmp_os.str(); + tool_capabilities->serialize(tmp_os); + tool_capabilities_s = tmp_os.str(); + } + os<::const_iterator + i = groups.begin(); i != groups.end(); i++){ + os<first); + writeS16(os, i->second); } - os<deSerialize(tmp_is); + std::istringstream tmp_is(tool_capabilities_s, std::ios::binary); + tool_capabilities = new ToolCapabilities; + tool_capabilities->deSerialize(tmp_is); + } + groups.clear(); + u32 groups_size = readU16(is); + for(u32 i=0; iname = ""; hand_def->wield_image = "wieldhand.png"; - hand_def->tool_digging_properties = new ToolDiggingProperties; + hand_def->tool_capabilities = new ToolCapabilities; m_item_definitions.insert(std::make_pair("", hand_def)); ItemDefinition* unknown_def = new ItemDefinition; @@ -273,9 +287,9 @@ public: virtual void registerItem(const ItemDefinition &def) { infostream<<"ItemDefManager: registering \""< #include #include +#include class IGameDef; -struct ToolDiggingProperties; +struct ToolCapabilities; + +/* + Some helpers +*/ + +static inline int itemgroup_get(const std::map &groups, + const std::string &name) +{ + std::map::const_iterator i = groups.find(name); + if(i == groups.end()) + return 0; + return i->second; +} /* Base item definition @@ -63,7 +77,8 @@ struct ItemDefinition bool usable; bool liquids_pointable; // May be NULL. If non-NULL, deleted by destructor - ToolDiggingProperties *tool_digging_properties; + ToolCapabilities *tool_capabilities; + std::map groups; /* Cached stuff diff --git a/src/main.cpp b/src/main.cpp index 2875474f1..ec999c530 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -399,7 +399,6 @@ Doing currently: #include "filesys.h" #include "config.h" #include "guiMainMenu.h" -#include "materials.h" #include "game.h" #include "keycode.h" #include "tile.h" diff --git a/src/materials.cpp b/src/materials.cpp deleted file mode 100644 index c37b7c505..000000000 --- a/src/materials.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* -Minetest-c55 -Copyright (C) 2011 celeron55, Perttu Ahola - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "materials.h" -#include "utility.h" - -void MaterialProperties::serialize(std::ostream &os) -{ - writeU8(os, 0); // version - writeU8(os, diggability); - writeF1000(os, constant_time); - writeF1000(os, weight); - writeF1000(os, crackiness); - writeF1000(os, crumbliness); - writeF1000(os, cuttability); - writeF1000(os, flammability); -} - -void MaterialProperties::deSerialize(std::istream &is) -{ - int version = readU8(is); - if(version != 0) - throw SerializationError("unsupported MaterialProperties version"); - diggability = (enum Diggability)readU8(is); - constant_time = readF1000(is); - weight = readF1000(is); - crackiness = readF1000(is); - crumbliness = readF1000(is); - cuttability = readF1000(is); - flammability = readF1000(is); -} - -ToolDiggingProperties::ToolDiggingProperties(float full_punch_interval_, - float a, float b, float c, float d, float e, - float f, float g, float h, float i, float j): - full_punch_interval(full_punch_interval_), - basetime(a), - dt_weight(b), - dt_crackiness(c), - dt_crumbliness(d), - dt_cuttability(e), - basedurability(f), - dd_weight(g), - dd_crackiness(h), - dd_crumbliness(i), - dd_cuttability(j) -{} - -void ToolDiggingProperties::serialize(std::ostream &os) -{ - writeU8(os, 0); // version - writeF1000(os, full_punch_interval); - writeF1000(os, basetime); - writeF1000(os, dt_weight); - writeF1000(os, dt_crackiness); - writeF1000(os, dt_crumbliness); - writeF1000(os, dt_cuttability); - writeF1000(os, basedurability); - writeF1000(os, dd_weight); - writeF1000(os, dd_crackiness); - writeF1000(os, dd_crumbliness); - writeF1000(os, dd_cuttability); -} - -void ToolDiggingProperties::deSerialize(std::istream &is) -{ - int version = readU8(is); - if(version != 0) throw SerializationError( - "unsupported ToolDiggingProperties version"); - full_punch_interval = readF1000(is); - basetime = readF1000(is); - dt_weight = readF1000(is); - dt_crackiness = readF1000(is); - dt_crumbliness = readF1000(is); - dt_cuttability = readF1000(is); - basedurability = readF1000(is); - dd_weight = readF1000(is); - dd_crackiness = readF1000(is); - dd_crumbliness = readF1000(is); - dd_cuttability = readF1000(is); -} - -DiggingProperties getDiggingProperties(const MaterialProperties *mp, - const ToolDiggingProperties *tp, float time_from_last_punch) -{ - if(mp->diggability == DIGGABLE_NOT) - return DiggingProperties(false, 0, 0); - if(mp->diggability == DIGGABLE_CONSTANT) - return DiggingProperties(true, mp->constant_time, 0); - - float time = tp->basetime; - time += tp->dt_weight * mp->weight; - time += tp->dt_crackiness * mp->crackiness; - time += tp->dt_crumbliness * mp->crumbliness; - time += tp->dt_cuttability * mp->cuttability; - if(time < 0.2) - time = 0.2; - - float durability = tp->basedurability; - durability += tp->dd_weight * mp->weight; - durability += tp->dd_crackiness * mp->crackiness; - durability += tp->dd_crumbliness * mp->crumbliness; - durability += tp->dd_cuttability * mp->cuttability; - if(durability < 1) - durability = 1; - - if(time_from_last_punch < tp->full_punch_interval){ - float f = time_from_last_punch / tp->full_punch_interval; - time /= f; - durability /= f; - } - - float wear = 1.0 / durability; - u16 wear_i = 65535.*wear; - return DiggingProperties(true, time, wear_i); -} - -DiggingProperties getDiggingProperties(const MaterialProperties *mp, - const ToolDiggingProperties *tp) -{ - return getDiggingProperties(mp, tp, 1000000); -} - -HittingProperties getHittingProperties(const MaterialProperties *mp, - const ToolDiggingProperties *tp, float time_from_last_punch) -{ - DiggingProperties digprop = getDiggingProperties(mp, tp, - time_from_last_punch); - - // If digging time would be 1 second, 2 hearts go in 1 second. - s16 hp = 2.0 * 2.0 / digprop.time; - // Wear is the same as for digging a single node - s16 wear = (float)digprop.wear; - - return HittingProperties(hp, wear); -} - -HittingProperties getHittingProperties(const MaterialProperties *mp, - const ToolDiggingProperties *tp) -{ - return getHittingProperties(mp, tp, 1000000); -} - diff --git a/src/materials.h b/src/materials.h deleted file mode 100644 index 058b2ab85..000000000 --- a/src/materials.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -Minetest-c55 -Copyright (C) 2010-2011 celeron55, Perttu Ahola - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef MATERIALS_HEADER -#define MATERIALS_HEADER - -/* - Material properties -*/ - -#include "common_irrlicht.h" -#include -#include - -enum Diggability -{ - DIGGABLE_NOT, - DIGGABLE_NORMAL, - DIGGABLE_CONSTANT -}; - -struct MaterialProperties -{ - // Values can be anything. 0 is normal. - - enum Diggability diggability; - - // Constant time for DIGGABLE_CONSTANT - float constant_time; - - // Weight; the amount of stuff in the block. Not realistic. - float weight; - // Rock; wood a bit. - // A Pickaxe manages high crackiness well. - float crackiness; - // Sand is extremely crumble; dirt is quite crumble. - // A shovel is good for crumbly stuff. Pickaxe is horrible. - float crumbliness; - // An axe is best for cuttable heavy stuff. - // Sword is best for cuttable light stuff. - float cuttability; - // If high, ignites easily - float flammability; - - MaterialProperties(): - diggability(DIGGABLE_NOT), - constant_time(0.5), - weight(0), - crackiness(0), - crumbliness(0), - cuttability(0), - flammability(0) - {} - - void serialize(std::ostream &os); - void deSerialize(std::istream &is); -}; - -struct ToolDiggingProperties -{ - // time = basetime + sum(feature here * feature in MaterialProperties) - float full_punch_interval; - float basetime; - float dt_weight; - float dt_crackiness; - float dt_crumbliness; - float dt_cuttability; - float basedurability; - float dd_weight; - float dd_crackiness; - float dd_crumbliness; - float dd_cuttability; - - ToolDiggingProperties(float full_punch_interval_=2.0, - float a=0.75, float b=0, float c=0, float d=0, float e=0, - float f=50, float g=0, float h=0, float i=0, float j=0); - - void serialize(std::ostream &os); - void deSerialize(std::istream &is); -}; - -struct DiggingProperties -{ - bool diggable; - // Digging time in seconds - float time; - // Caused wear - u16 wear; - - DiggingProperties(bool a_diggable=false, float a_time=0, u16 a_wear=0): - diggable(a_diggable), - time(a_time), - wear(a_wear) - {} -}; - -DiggingProperties getDiggingProperties(const MaterialProperties *mp, - const ToolDiggingProperties *tp, float time_from_last_punch); - -DiggingProperties getDiggingProperties(const MaterialProperties *mp, - const ToolDiggingProperties *tp); - -struct HittingProperties -{ - s16 hp; - s16 wear; - - HittingProperties(s16 hp_=0, s16 wear_=0): - hp(hp_), - wear(wear_) - {} -}; - -HittingProperties getHittingProperties(const MaterialProperties *mp, - const ToolDiggingProperties *tp, float time_from_last_punch); - -HittingProperties getHittingProperties(const MaterialProperties *mp, - const ToolDiggingProperties *tp); - -#endif - diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 0c2793a0e..7d0408eb7 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -118,6 +118,7 @@ void ContentFeatures::reset() in builtin.lua */ name = ""; + groups.clear(); drawtype = NDT_NORMAL; visual_scale = 1.0; for(u32 i=0; i<6; i++) @@ -144,18 +145,20 @@ void ContentFeatures::reset() light_source = 0; damage_per_second = 0; selection_box = NodeBox(); - material = MaterialProperties(); - // Make unknown blocks diggable - material.diggability = DIGGABLE_CONSTANT; - material.constant_time = 0.5; legacy_facedir_simple = false; legacy_wallmounted = false; } void ContentFeatures::serialize(std::ostream &os) { - writeU8(os, 1); // version + writeU8(os, 2); // version os<::const_iterator + i = groups.begin(); i != groups.end(); i++){ + os<first); + writeS16(os, i->second); + } writeU8(os, drawtype); writeF1000(os, visual_scale); writeU8(os, 6); @@ -188,7 +191,6 @@ void ContentFeatures::serialize(std::ostream &os) writeU8(os, light_source); writeU32(os, damage_per_second); selection_box.serialize(os); - material.serialize(os); writeU8(os, legacy_facedir_simple); writeU8(os, legacy_wallmounted); } @@ -196,9 +198,16 @@ void ContentFeatures::serialize(std::ostream &os) void ContentFeatures::deSerialize(std::istream &is) { int version = readU8(is); - if(version != 1) + if(version != 2) throw SerializationError("unsupported ContentFeatures version"); name = deSerializeString(is); + groups.clear(); + u32 groups_size = readU16(is); + for(u32 i=0; i #include -#include +#include #include "mapnode.h" #ifndef SERVER #include "tile.h" #endif -#include "materials.h" // MaterialProperties class IItemDefManager; class ITextureSource; class IGameDef; @@ -149,6 +148,7 @@ struct ContentFeatures */ std::string name; // "" = undefined node + std::map groups; // Same as in itemdef // Visual definition enum NodeDrawType drawtype; @@ -194,7 +194,6 @@ struct ContentFeatures u8 light_source; u32 damage_per_second; NodeBox selection_box; - MaterialProperties material; // Compatibility with old maps // Set to true if paramtype used to be 'facedir_simple' bool legacy_facedir_simple; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 8350c75f1..2ee727b3f 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -45,6 +45,7 @@ extern "C" { #include "mapblock.h" // For getNodeBlockPos #include "content_nodemeta.h" #include "utility.h" +#include "tool.h" static void stackDump(lua_State *L, std::ostream &o) { @@ -416,14 +417,6 @@ struct EnumString es_NodeBoxType[] = {0, NULL}, }; -struct EnumString es_Diggability[] = -{ - {DIGGABLE_NOT, "not"}, - {DIGGABLE_NORMAL, "normal"}, - {DIGGABLE_CONSTANT, "constant"}, - {0, NULL}, -}; - /* C struct <-> Lua table converter functions */ @@ -612,6 +605,7 @@ static core::aabbox3d read_aabbox3df32(lua_State *L, int index, f32 scale) return box; } +#if 0 /* MaterialProperties */ @@ -630,87 +624,156 @@ static MaterialProperties read_material_properties( getfloatfield(L, -1, "flammability", prop.flammability); return prop; } +#endif /* - ToolDiggingProperties + Groups +*/ +static void read_groups(lua_State *L, int index, + std::map &result) +{ + result.clear(); + lua_pushnil(L); + if(index < 0) + index -= 1; + while(lua_next(L, index) != 0){ + // key at index -2 and value at index -1 + std::string name = luaL_checkstring(L, -2); + int rating = luaL_checkinteger(L, -1); + result[name] = rating; + // removes value, keeps key for next iteration + lua_pop(L, 1); + } +} + +/* + ToolCapabilities */ -static ToolDiggingProperties read_tool_digging_properties( +static ToolCapabilities read_tool_capabilities( lua_State *L, int table) { - ToolDiggingProperties prop; - getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval); - getfloatfield(L, table, "basetime", prop.basetime); - getfloatfield(L, table, "dt_weight", prop.dt_weight); - getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness); - getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness); - getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability); - getfloatfield(L, table, "basedurability", prop.basedurability); - getfloatfield(L, table, "dd_weight", prop.dd_weight); - getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness); - getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness); - getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability); - return prop; + ToolCapabilities toolcap; + getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval); + getintfield(L, table, "max_drop_level", toolcap.max_drop_level); + lua_getfield(L, table, "groupcaps"); + if(lua_istable(L, -1)){ + int table_groupcaps = lua_gettop(L); + lua_pushnil(L); + while(lua_next(L, table_groupcaps) != 0){ + // key at index -2 and value at index -1 + std::string groupname = luaL_checkstring(L, -2); + if(lua_istable(L, -1)){ + int table_groupcap = lua_gettop(L); + // This will be created + ToolGroupCap groupcap; + // Read simple parameters + getfloatfield(L, table_groupcap, "maxwear", groupcap.maxwear); + getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel); + // Read "times" table + lua_getfield(L, table_groupcap, "times"); + if(lua_istable(L, -1)){ + int table_times = lua_gettop(L); + lua_pushnil(L); + while(lua_next(L, table_times) != 0){ + // key at index -2 and value at index -1 + int rating = luaL_checkinteger(L, -2); + float time = luaL_checknumber(L, -1); + groupcap.times[rating] = time; + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } + lua_pop(L, 1); + // Insert groupcap into toolcap + toolcap.groupcaps[groupname] = groupcap; + } + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } + lua_pop(L, 1); + return toolcap; } -static void set_tool_digging_properties(lua_State *L, int table, - const ToolDiggingProperties &prop) +static void set_tool_capabilities(lua_State *L, int table, + const ToolCapabilities &toolcap) { - setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval); - setfloatfield(L, table, "basetime", prop.basetime); - setfloatfield(L, table, "dt_weight", prop.dt_weight); - setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness); - setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness); - setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability); - setfloatfield(L, table, "basedurability", prop.basedurability); - setfloatfield(L, table, "dd_weight", prop.dd_weight); - setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness); - setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness); - setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability); + setfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval); + setintfield(L, table, "max_drop_level", toolcap.max_drop_level); + // Create groupcaps table + lua_newtable(L); + // For each groupcap + for(std::map::const_iterator + i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){ + // Create groupcap table + lua_newtable(L); + const std::string &name = i->first; + const ToolGroupCap &groupcap = i->second; + // Create subtable "times" + lua_newtable(L); + for(std::map::const_iterator + i = groupcap.times.begin(); i != groupcap.times.end(); i++){ + int rating = i->first; + float time = i->second; + lua_pushinteger(L, rating); + lua_pushnumber(L, time); + lua_settable(L, -3); + } + // Set subtable "times" + lua_setfield(L, -2, "times"); + // Set simple parameters + setfloatfield(L, -1, "maxwear", groupcap.maxwear); + setintfield(L, -1, "maxlevel", groupcap.maxlevel); + // Insert groupcap table into groupcaps table + lua_setfield(L, -2, name.c_str()); + } + // Set groupcaps table + lua_setfield(L, -2, "groupcaps"); } -static void push_tool_digging_properties(lua_State *L, - const ToolDiggingProperties &prop) +static void push_tool_capabilities(lua_State *L, + const ToolCapabilities &prop) { lua_newtable(L); - set_tool_digging_properties(L, -1, prop); + set_tool_capabilities(L, -1, prop); } /* - DiggingProperties + DigParams */ -static void set_digging_properties(lua_State *L, int table, - const DiggingProperties &prop) +static void set_dig_params(lua_State *L, int table, + const DigParams ¶ms) { - setboolfield(L, table, "diggable", prop.diggable); - setfloatfield(L, table, "time", prop.time); - setintfield(L, table, "wear", prop.wear); + setboolfield(L, table, "diggable", params.diggable); + setfloatfield(L, table, "time", params.time); + setintfield(L, table, "wear", params.wear); } -static void push_digging_properties(lua_State *L, - const DiggingProperties &prop) +static void push_dig_params(lua_State *L, + const DigParams ¶ms) { lua_newtable(L); - set_digging_properties(L, -1, prop); + set_dig_params(L, -1, params); } /* - HittingProperties + HitParams */ -static void set_hitting_properties(lua_State *L, int table, - const HittingProperties &prop) +static void set_hit_params(lua_State *L, int table, + const HitParams ¶ms) { - setintfield(L, table, "hp", prop.hp); - setintfield(L, table, "wear", prop.wear); + setintfield(L, table, "hp", params.hp); + setintfield(L, table, "wear", params.wear); } -static void push_hitting_properties(lua_State *L, - const HittingProperties &prop) +static void push_hit_params(lua_State *L, + const HitParams ¶ms) { lua_newtable(L); - set_hitting_properties(L, -1, prop); + set_hit_params(L, -1, params); } /* @@ -778,20 +841,26 @@ static ItemDefinition read_item_definition(lua_State *L, int index) getboolfield(L, index, "liquids_pointable", def.liquids_pointable); - lua_getfield(L, index, "tool_digging_properties"); + warn_if_field_exists(L, index, "tool_digging_properties", + "deprecated: use tool_capabilities"); + + lua_getfield(L, index, "tool_capabilities"); if(lua_istable(L, -1)){ - def.tool_digging_properties = new ToolDiggingProperties( - read_tool_digging_properties(L, -1)); + def.tool_capabilities = new ToolCapabilities( + read_tool_capabilities(L, -1)); } - lua_pop(L, 1); - // If name is "" (hand), ensure there are ToolDiggingProperties + // If name is "" (hand), ensure there are ToolCapabilities // because it will be looked up there whenever any other item has - // no ToolDiggingProperties - if(def.name == "" && def.tool_digging_properties == NULL){ - def.tool_digging_properties = new ToolDiggingProperties(); + // no ToolCapabilities + if(def.name == "" && def.tool_capabilities == NULL){ + def.tool_capabilities = new ToolCapabilities(); } + lua_getfield(L, index, "groups"); + read_groups(L, -1, def.groups); + lua_pop(L, 1); + return def; } @@ -805,8 +874,14 @@ static ContentFeatures read_content_features(lua_State *L, int index) index = lua_gettop(L) + 1 + index; ContentFeatures f; + /* Name */ getstringfield(L, index, "name", f.name); + /* Groups */ + lua_getfield(L, index, "groups"); + read_groups(L, -1, f.groups); + lua_pop(L, 1); + /* Visual definition */ f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType, @@ -958,12 +1033,6 @@ static ContentFeatures read_content_features(lua_State *L, int index) } lua_pop(L, 1); - lua_getfield(L, index, "material"); - if(lua_istable(L, -1)){ - f.material = read_material_properties(L, -1); - } - lua_pop(L, 1); - // Set to true if paramtype used to be 'facedir_simple' getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple); // Set to true if wall_mounted used to be set to true @@ -1215,16 +1284,16 @@ private: return 1; } - // get_tool_digging_properties(self) -> table + // get_tool_capabilities(self) -> table // Returns the effective tool digging properties. // Returns those of the hand ("") if this item has none associated. - static int l_get_tool_digging_properties(lua_State *L) + static int l_get_tool_capabilities(lua_State *L) { LuaItemStack *o = checkobject(L, 1); ItemStack &item = o->m_stack; - const ToolDiggingProperties &prop = - item.getToolDiggingProperties(get_server(L)->idef()); - push_tool_digging_properties(L, prop); + const ToolCapabilities &prop = + item.getToolCapabilities(get_server(L)->idef()); + push_tool_capabilities(L, prop); return 1; } @@ -1386,7 +1455,7 @@ const luaL_reg LuaItemStack::methods[] = { method(LuaItemStack, get_free_space), method(LuaItemStack, is_known), method(LuaItemStack, get_definition), - method(LuaItemStack, get_tool_digging_properties), + method(LuaItemStack, get_tool_capabilities), method(LuaItemStack, add_wear), method(LuaItemStack, add_item), method(LuaItemStack, item_fits), @@ -3513,28 +3582,30 @@ static int l_get_inventory(lua_State *L) return 1; } -// get_digging_properties(material_properties, tool_digging_properties[, time_from_last_punch]) -static int l_get_digging_properties(lua_State *L) +// get_dig_params(groups, tool_capabilities[, time_from_last_punch]) +static int l_get_dig_params(lua_State *L) { - MaterialProperties mp = read_material_properties(L, 1); - ToolDiggingProperties tp = read_tool_digging_properties(L, 2); + std::map groups; + read_groups(L, 1, groups); + ToolCapabilities tp = read_tool_capabilities(L, 2); if(lua_isnoneornil(L, 3)) - push_digging_properties(L, getDiggingProperties(&mp, &tp)); + push_dig_params(L, getDigParams(groups, &tp)); else - push_digging_properties(L, getDiggingProperties(&mp, &tp, + push_dig_params(L, getDigParams(groups, &tp, luaL_checknumber(L, 3))); return 1; } -// get_hitting_properties(material_properties, tool_digging_properties[, time_from_last_punch]) -static int l_get_hitting_properties(lua_State *L) +// get_hit_params(groups, tool_capabilities[, time_from_last_punch]) +static int l_get_hit_params(lua_State *L) { - MaterialProperties mp = read_material_properties(L, 1); - ToolDiggingProperties tp = read_tool_digging_properties(L, 2); + std::map groups; + read_groups(L, 1, groups); + ToolCapabilities tp = read_tool_capabilities(L, 2); if(lua_isnoneornil(L, 3)) - push_hitting_properties(L, getHittingProperties(&mp, &tp)); + push_hit_params(L, getHitParams(groups, &tp)); else - push_hitting_properties(L, getHittingProperties(&mp, &tp, + push_hit_params(L, getHitParams(groups, &tp, luaL_checknumber(L, 3))); return 1; } @@ -3580,8 +3651,8 @@ static const struct luaL_Reg minetest_f [] = { {"chat_send_player", l_chat_send_player}, {"get_player_privs", l_get_player_privs}, {"get_inventory", l_get_inventory}, - {"get_digging_properties", l_get_digging_properties}, - {"get_hitting_properties", l_get_hitting_properties}, + {"get_dig_params", l_get_dig_params}, + {"get_hit_params", l_get_hit_params}, {"get_current_modname", l_get_current_modname}, {"get_modpath", l_get_modpath}, {"get_worldpath", l_get_worldpath}, diff --git a/src/server.cpp b/src/server.cpp index 2facb1469..443a2a39b 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" #include "constants.h" #include "voxel.h" -#include "materials.h" #include "config.h" #include "servercommand.h" #include "filesys.h" diff --git a/src/serverobject.cpp b/src/serverobject.cpp index 2609e3015..4d7f19243 100644 --- a/src/serverobject.cpp +++ b/src/serverobject.cpp @@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverobject.h" #include #include "inventory.h" -#include "materials.h" ServerActiveObject::ServerActiveObject(ServerEnvironment *env, v3f pos): ActiveObject(0), diff --git a/src/serverremoteplayer.cpp b/src/serverremoteplayer.cpp index 728ffe026..8a81f1d2d 100644 --- a/src/serverremoteplayer.cpp +++ b/src/serverremoteplayer.cpp @@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gamedef.h" #include "inventory.h" #include "environment.h" -#include "materials.h" +#include "tool.h" ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env): Player(env->getGameDef()), @@ -181,35 +181,32 @@ void ServerRemotePlayer::punch(ServerActiveObject *puncher, return; } - // "Material" properties of a player - MaterialProperties mp; - mp.diggability = DIGGABLE_NORMAL; - mp.crackiness = -0.5; - mp.cuttability = 0.5; + // "Material" groups of the player + std::map groups; + groups["snappy"] = 1; + groups["choppy"] = 2; IItemDefManager *idef = m_env->getGameDef()->idef(); ItemStack punchitem = puncher->getWieldedItem(); - ToolDiggingProperties tp = - punchitem.getToolDiggingProperties(idef); + ToolCapabilities tp = punchitem.getToolCapabilities(idef); - HittingProperties hitprop = getHittingProperties(&mp, &tp, - time_from_last_punch); + HitParams hitparams = getHitParams(groups, &tp, time_from_last_punch); actionstream<<"Player "<getDescription()<<", damage "<getDescription()<<", damage "<setWieldedItem(punchitem); - if(hitprop.hp != 0) + if(hitparams.hp != 0) { std::ostringstream os(std::ios::binary); // command (1 = punched) writeU8(os, 1); // damage - writeS16(os, hitprop.hp); + writeS16(os, hitparams.hp); // create message and add to list ActiveObjectMessage aom(getId(), false, os.str()); m_messages_out.push_back(aom); diff --git a/src/test.cpp b/src/test.cpp index 4226df544..45851a7e3 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -68,6 +68,7 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n itemdef.type = ITEM_NODE; itemdef.name = "default:stone"; itemdef.description = "Stone"; + itemdef.groups["cracky"] = 3; itemdef.inventory_image = "[inventorycube" "{default_stone.png" "{default_stone.png" @@ -77,11 +78,6 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n for(int i = 0; i < 6; i++) f.tname_tiles[i] = "default_stone.png"; f.is_ground_content = true; - f.material.diggability = DIGGABLE_NORMAL; - f.material.weight = 5.0; - f.material.crackiness = 1.0; - f.material.crumbliness = -0.1; - f.material.cuttability = -0.2; idef->registerItem(itemdef); ndef->set(i, f); @@ -93,6 +89,7 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n itemdef.type = ITEM_NODE; itemdef.name = "default:dirt_with_grass"; itemdef.description = "Dirt with grass"; + itemdef.groups["crumbly"] = 3; itemdef.inventory_image = "[inventorycube" "{default_grass.png" "{default_dirt.png&default_grass_side.png" @@ -104,11 +101,6 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n for(int i = 2; i < 6; i++) f.tname_tiles[i] = "default_dirt.png^default_grass_side.png"; f.is_ground_content = true; - f.material.diggability = DIGGABLE_NORMAL; - f.material.weight = 1.2; - f.material.crackiness = 0.0; - f.material.crumbliness = 1.2; - f.material.cuttability = -0.4; idef->registerItem(itemdef); ndef->set(i, f); } diff --git a/src/tool.cpp b/src/tool.cpp new file mode 100644 index 000000000..3c61ad6e7 --- /dev/null +++ b/src/tool.cpp @@ -0,0 +1,153 @@ +/* +Minetest-c55 +Copyright (C) 2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "tool.h" +#include "utility.h" +#include "itemdef.h" // For itemgroup_get() +#include "log.h" + +void ToolCapabilities::serialize(std::ostream &os) const +{ + writeU8(os, 0); // version + writeF1000(os, full_punch_interval); + writeS16(os, max_drop_level); + writeU32(os, groupcaps.size()); + for(std::map::const_iterator + i = groupcaps.begin(); i != groupcaps.end(); i++){ + const std::string *name = &i->first; + const ToolGroupCap *cap = &i->second; + os<maxwear); + writeF1000(os, cap->maxlevel); + writeU32(os, cap->times.size()); + for(std::map::const_iterator + i = cap->times.begin(); i != cap->times.end(); i++){ + writeS16(os, i->first); + writeF1000(os, i->second); + } + } +} + +void ToolCapabilities::deSerialize(std::istream &is) +{ + int version = readU8(is); + if(version != 0) throw SerializationError( + "unsupported ToolCapabilities version"); + full_punch_interval = readF1000(is); + max_drop_level = readS16(is); + groupcaps.clear(); + u32 groupcaps_size = readU32(is); + for(u32 i=0; i &groups, + const ToolCapabilities *tp, float time_from_last_punch) +{ + //infostream<<"getDigParams"< +#include +#include + +struct ToolGroupCap +{ + std::map times; + float maxwear; + int maxlevel; + + ToolGroupCap(): + maxwear(0.05), + maxlevel(1) + {} + + bool getTime(int rating, float *time) const + { + std::map::const_iterator i = times.find(rating); + if(i == times.end()){ + *time = 0; + return false; + } + *time = i->second; + return true; + } +}; + +struct ToolCapabilities +{ + float full_punch_interval; + int max_drop_level; + std::map groupcaps; + + ToolCapabilities( + float full_punch_interval_=3.0, + int max_drop_level_=1, + std::map groupcaps_ = + std::map() + ): + full_punch_interval(full_punch_interval_), + max_drop_level(max_drop_level_), + groupcaps(groupcaps_) + {} + + void serialize(std::ostream &os) const; + void deSerialize(std::istream &is); +}; + +struct DigParams +{ + bool diggable; + // Digging time in seconds + float time; + // Caused wear + u16 wear; + + DigParams(bool a_diggable=false, float a_time=0, u16 a_wear=0): + diggable(a_diggable), + time(a_time), + wear(a_wear) + {} +}; + +DigParams getDigParams(const std::map &groups, + const ToolCapabilities *tp, float time_from_last_punch); + +DigParams getDigParams(const std::map &groups, + const ToolCapabilities *tp); + +struct HitParams +{ + s16 hp; + s16 wear; + + HitParams(s16 hp_=0, s16 wear_=0): + hp(hp_), + wear(wear_) + {} +}; + +HitParams getHitParams(const std::map &groups, + const ToolCapabilities *tp, float time_from_last_punch); + +HitParams getHitParams(const std::map &groups, + const ToolCapabilities *tp); + +#endif + -- cgit v1.2.3