X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Ftool.cpp;h=22e41d28e1d67a9bb2f1af83dc5724309df3846f;hb=6ccb5835ff55d85156be91473c598eca9d6cb9a6;hp=04f19749c9332c4c059b49d28b31a3817c70444a;hpb=6d0ea26c2d62c3774ff384cf1bfc2a3372b49a3b;p=dragonfireclient.git diff --git a/src/tool.cpp b/src/tool.cpp index 04f19749c..22e41d28e 100644 --- a/src/tool.cpp +++ b/src/tool.cpp @@ -18,146 +18,247 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "tool.h" -#include "itemdef.h" // For itemgroup_get() +#include "itemdef.h" +#include "itemgroup.h" #include "log.h" #include "inventory.h" +#include "exceptions.h" #include "util/serialize.h" #include "util/numeric.h" -void ToolCapabilities::serialize(std::ostream &os) const +void ToolGroupCap::toJson(Json::Value &object) const { - writeU8(os, 1); // version - writeF1000(os, full_punch_interval); + object["maxlevel"] = maxlevel; + object["uses"] = uses; + + Json::Value times_object; + for (auto time : times) + times_object[time.first] = time.second; + object["times"] = times_object; +} + +void ToolGroupCap::fromJson(const Json::Value &json) +{ + if (json.isObject()) { + if (json["maxlevel"].isInt()) + maxlevel = json["maxlevel"].asInt(); + if (json["uses"].isInt()) + uses = json["uses"].asInt(); + const Json::Value ×_object = json["times"]; + if (times_object.isArray()) { + Json::ArrayIndex size = times_object.size(); + for (Json::ArrayIndex i = 0; i < size; ++i) + if (times_object[i].isDouble()) + times[i] = times_object[i].asFloat(); + } + } +} + +void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const +{ + if (protocol_version >= 38) + writeU8(os, 5); + else + writeU8(os, 4); // proto == 37 + writeF32(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<uses); writeS16(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); + for (const auto &time : cap->times) { + writeS16(os, time.first); + writeF32(os, time.second); } } + + writeU32(os, damageGroups.size()); + + for (const auto &damageGroup : damageGroups) { + os << serializeString(damageGroup.first); + writeS16(os, damageGroup.second); + } + + if (protocol_version >= 38) + writeU16(os, rangelim(punch_attack_uses, 0, U16_MAX)); } void ToolCapabilities::deSerialize(std::istream &is) { int version = readU8(is); - if(version != 1) throw SerializationError( - "unsupported ToolCapabilities version"); - full_punch_interval = readF1000(is); + if (version < 4) + throw SerializationError("unsupported ToolCapabilities version"); + + full_punch_interval = readF32(is); max_drop_level = readS16(is); groupcaps.clear(); u32 groupcaps_size = readU32(is); - for(u32 i=0; i= 5) + punch_attack_uses = readU16(is); +} + +void ToolCapabilities::serializeJson(std::ostream &os) const +{ + Json::Value root; + root["full_punch_interval"] = full_punch_interval; + root["max_drop_level"] = max_drop_level; + root["punch_attack_uses"] = punch_attack_uses; + + Json::Value groupcaps_object; + for (const auto &groupcap : groupcaps) { + groupcap.second.toJson(groupcaps_object[groupcap.first]); + } + root["groupcaps"] = groupcaps_object; + + Json::Value damage_groups_object; + DamageGroup::const_iterator dgiter; + for (dgiter = damageGroups.begin(); dgiter != damageGroups.end(); ++dgiter) { + damage_groups_object[dgiter->first] = dgiter->second; + } + root["damage_groups"] = damage_groups_object; + + os << root; +} + +void ToolCapabilities::deserializeJson(std::istream &is) +{ + Json::Value root; + is >> root; + if (root.isObject()) { + if (root["full_punch_interval"].isDouble()) + full_punch_interval = root["full_punch_interval"].asFloat(); + if (root["max_drop_level"].isInt()) + max_drop_level = root["max_drop_level"].asInt(); + if (root["punch_attack_uses"].isInt()) + punch_attack_uses = root["punch_attack_uses"].asInt(); + + Json::Value &groupcaps_object = root["groupcaps"]; + if (groupcaps_object.isObject()) { + Json::ValueIterator gciter; + for (gciter = groupcaps_object.begin(); + gciter != groupcaps_object.end(); ++gciter) { + ToolGroupCap groupcap; + groupcap.fromJson(*gciter); + groupcaps[gciter.key().asString()] = groupcap; + } + } + + Json::Value &damage_groups_object = root["damage_groups"]; + if (damage_groups_object.isObject()) { + Json::ValueIterator dgiter; + for (dgiter = damage_groups_object.begin(); + dgiter != damage_groups_object.end(); ++dgiter) { + Json::Value &value = *dgiter; + if (value.isInt()) + damageGroups[dgiter.key().asString()] = + value.asInt(); + } + } + } } DigParams getDigParams(const ItemGroupList &groups, - const ToolCapabilities *tp, float time_from_last_punch) + const ToolCapabilities *tp) { - //infostream<<"getDigParams"<groupcaps.find("dig_immediate") == tp->groupcaps.cend()) { + switch (itemgroup_get(groups, "dig_immediate")) { + case 2: + return DigParams(true, 0.5, 0, "dig_immediate"); + case 3: + return DigParams(true, 0, 0, "dig_immediate"); + 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; - std::string result_main_group = ""; + std::string result_main_group; int level = itemgroup_get(groups, "level"); - //infostream<<"level="<::const_iterator - i = tp->groupcaps.begin(); i != tp->groupcaps.end(); i++){ - const std::string &name = i->first; - //infostream<<"group="<second; - int rating = itemgroup_get(groups, name); + for (const auto &groupcap : tp->groupcaps) { + const ToolGroupCap &cap = groupcap.second; + + int leveldiff = cap.maxlevel - level; + if (leveldiff < 0) + continue; + + const std::string &groupname = groupcap.first; float time = 0; + int rating = itemgroup_get(groups, groupname); bool time_exists = cap.getTime(rating, &time); - if(!result_diggable || time < result_time){ - if(cap.maxlevel >= level && time_exists){ - result_diggable = true; - int leveldiff = cap.maxlevel - level; - result_time = time / MYMAX(1, leveldiff); - if(cap.uses != 0) - result_wear = 1.0 / cap.uses / pow(3.0, (double)leveldiff); - else - result_wear = 0; - result_main_group = name; - } + if (!time_exists) + continue; + + if (leveldiff > 1) + time /= leveldiff; + if (!result_diggable || time < result_time) { + result_time = time; + result_diggable = true; + if (cap.uses != 0) + result_wear = 1.0 / cap.uses / pow(3.0, leveldiff); + else + result_wear = 0; + result_main_group = groupname; } } - //infostream<<"result_diggable="<name == "")) + if (do_hit && punchitem) { + if (itemgroup_get(armor_groups, "punch_operable") && + (toolcap == NULL || punchitem->name.empty())) do_hit = false; } - if(do_hit){ + + if (do_hit) { if(itemgroup_get(armor_groups, "immortal")) do_hit = false; } } - + PunchDamageResult result; if(do_hit) { @@ -187,10 +289,21 @@ PunchDamageResult getPunchDamage( result.did_punch = true; result.wear = hitparams.wear; result.damage = hitparams.hp; - result.main_group = hitparams.main_group; } return result; } +f32 getToolRange(const ItemDefinition &def_selected, const ItemDefinition &def_hand) +{ + float max_d = def_selected.range; + float max_d_hand = def_hand.range; + + if (max_d < 0 && max_d_hand >= 0) + max_d = max_d_hand; + else if (max_d < 0) + max_d = 4.0f; + + return max_d; +}