LCOV - code coverage report
Current view: top level - src - tool.cpp (source / functions) Hit Total Coverage
Test: report Lines: 26 114 22.8 %
Date: 2015-07-11 18:23:49 Functions: 3 9 33.3 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : #include "tool.h"
      21             : #include "itemgroup.h"
      22             : #include "log.h"
      23             : #include "inventory.h"
      24             : #include "exceptions.h"
      25             : #include "util/serialize.h"
      26             : #include "util/numeric.h"
      27             : 
      28           0 : void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const
      29             : {
      30           0 :         if(protocol_version <= 17)
      31           0 :                 writeU8(os, 1); // version
      32             :         else
      33           0 :                 writeU8(os, 2); // version
      34           0 :         writeF1000(os, full_punch_interval);
      35           0 :         writeS16(os, max_drop_level);
      36           0 :         writeU32(os, groupcaps.size());
      37           0 :         for(std::map<std::string, ToolGroupCap>::const_iterator
      38           0 :                         i = groupcaps.begin(); i != groupcaps.end(); i++){
      39           0 :                 const std::string *name = &i->first;
      40           0 :                 const ToolGroupCap *cap = &i->second;
      41           0 :                 os<<serializeString(*name);
      42           0 :                 writeS16(os, cap->uses);
      43           0 :                 writeS16(os, cap->maxlevel);
      44           0 :                 writeU32(os, cap->times.size());
      45           0 :                 for(std::map<int, float>::const_iterator
      46           0 :                                 i = cap->times.begin(); i != cap->times.end(); i++){
      47           0 :                         writeS16(os, i->first);
      48           0 :                         writeF1000(os, i->second);
      49             :                 }
      50             :         }
      51           0 :         if(protocol_version > 17){
      52           0 :                 writeU32(os, damageGroups.size());
      53           0 :                 for(std::map<std::string, s16>::const_iterator
      54           0 :                                 i = damageGroups.begin(); i != damageGroups.end(); i++){
      55           0 :                         os<<serializeString(i->first);
      56           0 :                         writeS16(os, i->second);
      57             :                 }
      58             :         }
      59           0 : }
      60             : 
      61          42 : void ToolCapabilities::deSerialize(std::istream &is)
      62             : {
      63          42 :         int version = readU8(is);
      64          42 :         if(version != 1 && version != 2) throw SerializationError(
      65           0 :                         "unsupported ToolCapabilities version");
      66          42 :         full_punch_interval = readF1000(is);
      67          42 :         max_drop_level = readS16(is);
      68          42 :         groupcaps.clear();
      69          42 :         u32 groupcaps_size = readU32(is);
      70          95 :         for(u32 i=0; i<groupcaps_size; i++){
      71         106 :                 std::string name = deSerializeString(is);
      72         106 :                 ToolGroupCap cap;
      73          53 :                 cap.uses = readS16(is);
      74          53 :                 cap.maxlevel = readS16(is);
      75          53 :                 u32 times_size = readU32(is);
      76         178 :                 for(u32 i=0; i<times_size; i++){
      77         125 :                         int level = readS16(is);
      78         125 :                         float time = readF1000(is);
      79         125 :                         cap.times[level] = time;
      80             :                 }
      81          53 :                 groupcaps[name] = cap;
      82             :         }
      83          42 :         if(version == 2)
      84             :         {
      85          42 :                 u32 damage_groups_size = readU32(is);
      86          76 :                 for(u32 i=0; i<damage_groups_size; i++){
      87          68 :                         std::string name = deSerializeString(is);
      88          34 :                         s16 rating = readS16(is);
      89          34 :                         damageGroups[name] = rating;
      90             :                 }
      91             :         }
      92          42 : }
      93             : 
      94           0 : DigParams getDigParams(const ItemGroupList &groups,
      95             :                 const ToolCapabilities *tp, float time_from_last_punch)
      96             : {
      97             :         //infostream<<"getDigParams"<<std::endl;
      98             :         /* Check group dig_immediate */
      99           0 :         switch(itemgroup_get(groups, "dig_immediate")){
     100             :         case 2:
     101             :                 //infostream<<"dig_immediate=2"<<std::endl;
     102           0 :                 return DigParams(true, 0.5, 0, "dig_immediate");
     103             :         case 3:
     104             :                 //infostream<<"dig_immediate=3"<<std::endl;
     105           0 :                 return DigParams(true, 0.0, 0, "dig_immediate");
     106             :         default:
     107           0 :                 break;
     108             :         }
     109             :         
     110             :         // Values to be returned (with a bit of conversion)
     111           0 :         bool result_diggable = false;
     112           0 :         float result_time = 0.0;
     113           0 :         float result_wear = 0.0;
     114           0 :         std::string result_main_group = "";
     115             : 
     116           0 :         int level = itemgroup_get(groups, "level");
     117             :         //infostream<<"level="<<level<<std::endl;
     118           0 :         for(std::map<std::string, ToolGroupCap>::const_iterator
     119           0 :                         i = tp->groupcaps.begin(); i != tp->groupcaps.end(); i++){
     120           0 :                 const std::string &name = i->first;
     121             :                 //infostream<<"group="<<name<<std::endl;
     122           0 :                 const ToolGroupCap &cap = i->second;
     123           0 :                 int rating = itemgroup_get(groups, name);
     124           0 :                 float time = 0;
     125           0 :                 bool time_exists = cap.getTime(rating, &time);
     126           0 :                 if(!result_diggable || time < result_time){
     127           0 :                         if(cap.maxlevel >= level && time_exists){
     128           0 :                                 result_diggable = true;
     129           0 :                                 int leveldiff = cap.maxlevel - level;
     130           0 :                                 result_time = time / MYMAX(1, leveldiff);
     131           0 :                                 if(cap.uses != 0)
     132           0 :                                         result_wear = 1.0 / cap.uses / pow(3.0, (double)leveldiff);
     133             :                                 else
     134           0 :                                         result_wear = 0;
     135           0 :                                 result_main_group = name;
     136             :                         }
     137             :                 }
     138             :         }
     139             :         //infostream<<"result_diggable="<<result_diggable<<std::endl;
     140             :         //infostream<<"result_time="<<result_time<<std::endl;
     141             :         //infostream<<"result_wear="<<result_wear<<std::endl;
     142             : 
     143           0 :         if(time_from_last_punch < tp->full_punch_interval){
     144           0 :                 float f = time_from_last_punch / tp->full_punch_interval;
     145             :                 //infostream<<"f="<<f<<std::endl;
     146           0 :                 result_time /= f;
     147           0 :                 result_wear /= f;
     148             :         }
     149             : 
     150           0 :         u16 wear_i = 65535.*result_wear;
     151           0 :         return DigParams(result_diggable, result_time, wear_i, result_main_group);
     152             : }
     153             : 
     154           0 : DigParams getDigParams(const ItemGroupList &groups,
     155             :                 const ToolCapabilities *tp)
     156             : {
     157           0 :         return getDigParams(groups, tp, 1000000);
     158             : }
     159             : 
     160           0 : HitParams getHitParams(const ItemGroupList &armor_groups,
     161             :                 const ToolCapabilities *tp, float time_from_last_punch)
     162             : {
     163           0 :         s16 damage = 0;
     164           0 :         float full_punch_interval = tp->full_punch_interval;
     165             : 
     166           0 :         for(std::map<std::string, s16>::const_iterator
     167           0 :                         i = tp->damageGroups.begin(); i != tp->damageGroups.end(); i++){
     168           0 :                 s16 armor = itemgroup_get(armor_groups, i->first);
     169           0 :                 damage += i->second * rangelim(time_from_last_punch / full_punch_interval, 0.0, 1.0)
     170           0 :                                 * armor / 100.0;
     171             :         }
     172             : 
     173           0 :         return HitParams(damage, 0);
     174             : }
     175             : 
     176           0 : HitParams getHitParams(const ItemGroupList &armor_groups,
     177             :                 const ToolCapabilities *tp)
     178             : {
     179           0 :         return getHitParams(armor_groups, tp, 1000000);
     180             : }
     181             : 
     182           0 : PunchDamageResult getPunchDamage(
     183             :                 const ItemGroupList &armor_groups,
     184             :                 const ToolCapabilities *toolcap,
     185             :                 const ItemStack *punchitem,
     186             :                 float time_from_last_punch
     187             : ){
     188           0 :         bool do_hit = true;
     189             :         {
     190           0 :                 if(do_hit && punchitem){
     191           0 :                         if(itemgroup_get(armor_groups, "punch_operable") &&
     192           0 :                                         (toolcap == NULL || punchitem->name == ""))
     193           0 :                                 do_hit = false;
     194             :                 }
     195           0 :                 if(do_hit){
     196           0 :                         if(itemgroup_get(armor_groups, "immortal"))
     197           0 :                                 do_hit = false;
     198             :                 }
     199             :         }
     200             :         
     201           0 :         PunchDamageResult result;
     202           0 :         if(do_hit)
     203             :         {
     204             :                 HitParams hitparams = getHitParams(armor_groups, toolcap,
     205           0 :                                 time_from_last_punch);
     206           0 :                 result.did_punch = true;
     207           0 :                 result.wear = hitparams.wear;
     208           0 :                 result.damage = hitparams.hp;
     209             :         }
     210             : 
     211           0 :         return result;
     212           3 : }
     213             : 
     214             : 

Generated by: LCOV version 1.11