diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/clientserver.h | 4 | ||||
-rw-r--r-- | src/content_sao.cpp | 47 | ||||
-rw-r--r-- | src/game.cpp | 19 | ||||
-rw-r--r-- | src/inventory.h | 16 | ||||
-rw-r--r-- | src/itemdef.cpp | 62 | ||||
-rw-r--r-- | src/itemdef.h | 19 | ||||
-rw-r--r-- | src/main.cpp | 1 | ||||
-rw-r--r-- | src/materials.cpp | 159 | ||||
-rw-r--r-- | src/materials.h | 137 | ||||
-rw-r--r-- | src/nodedef.cpp | 27 | ||||
-rw-r--r-- | src/nodedef.h | 5 | ||||
-rw-r--r-- | src/scriptapi.cpp | 251 | ||||
-rw-r--r-- | src/server.cpp | 1 | ||||
-rw-r--r-- | src/serverobject.cpp | 1 | ||||
-rw-r--r-- | src/serverremoteplayer.cpp | 27 | ||||
-rw-r--r-- | src/test.cpp | 12 | ||||
-rw-r--r-- | src/tool.cpp | 153 | ||||
-rw-r--r-- | src/tool.h | 111 |
19 files changed, 559 insertions, 495 deletions
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<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) { diff --git a/src/game.cpp b/src/game.cpp index 670148a44..3009112f3 100644 --- a/src/game.cpp +++ b/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) 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<<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); diff --git a/src/itemdef.h b/src/itemdef.h index 5a432591d..15734ff44 100644 --- a/src/itemdef.h +++ b/src/itemdef.h @@ -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 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 <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); -} - 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 <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 - 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<<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) diff --git a/src/nodedef.h b/src/nodedef.h index 9524385cf..5196e0233 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -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; 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<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}, 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 <fstream> #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<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); 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 <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); +} + diff --git a/src/tool.h b/src/tool.h new file mode 100644 index 000000000..cc2401a0d --- /dev/null +++ b/src/tool.h @@ -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 + |