bool readXMLString(xmlNodePtr node, const char* tag, std::string& value) { char* nodeValue = (char*)xmlGetProp(node, (xmlChar*)tag); if(!nodeValue) return false; if(!utf8ToLatin1(nodeValue, value)) value = nodeValue; xmlFree(nodeValue); return true; }
bool readXMLContentString(xmlNodePtr node, std::string& value) { char* nodeValue = (char*)xmlNodeGetContent(node); if(!nodeValue) return false; if(!utf8ToLatin1(nodeValue, value)) value = nodeValue; xmlFree(nodeValue); return true; }
std::string Item::getDescription(const ItemType& it, int32_t lookDistance, const Item* item /*= NULL*/, int32_t subType /*= -1*/, bool addArticle /*= true*/) { std::ostringstream s; s << getNameDescription(it, item, subType, addArticle); if (item) { subType = item->getSubType(); } if (it.isRune()) { if (!it.runeSpellName.empty()) { s << " (\"" << it.runeSpellName << "\")"; } if (it.runeLevel > 0 || it.runeMagLevel > 0) { int32_t tmpSubType = subType; if (item) { tmpSubType = item->getSubType(); } s << ". " << (it.stackable && tmpSubType > 1 ? "They" : "It") << " can only be used with"; if (it.runeLevel > 0) { s << " level " << it.runeLevel; } if (it.runeMagLevel > 0) { if (it.runeLevel > 0) { s << " and"; } s << " magic level " << it.runeMagLevel; } s << " or higher"; } } else if (it.weaponType != WEAPON_NONE) { if (it.weaponType == WEAPON_DIST && it.ammoType != AMMO_NONE) { s << " (Range:" << it.shootRange; if (it.attack != 0) { s << ", Atk " << std::showpos << it.attack << std::noshowpos; } if (it.hitChance != 0) { s << ", Hit% " << std::showpos << it.hitChance << std::noshowpos; } s << ")"; } else if (it.weaponType != WEAPON_AMMO) { bool begin = true; if (it.attack != 0) { begin = false; s << " (Atk:" << it.attack; if (it.abilities && it.abilities->elementType != COMBAT_NONE && it.abilities->elementDamage != 0) { s << " physical + " << it.abilities->elementDamage << " " << getCombatName(it.abilities->elementType); } } if (it.defense != 0 || it.extraDefense != 0) { if (begin) { begin = false; s << " ("; } else { s << ", "; } s << "Def:" << it.defense; if (it.extraDefense != 0 || (item && item->getExtraDefense() != 0)) { s << " " << std::showpos << it.extraDefense << std::noshowpos; } } if (it.abilities) { for (uint16_t i = SKILL_FIRST; i <= SKILL_LAST; i++) { if (!it.abilities->skills[i]) { continue; } if (begin) { begin = false; s << " ("; } else { s << ", "; } s << getSkillName(i) << " " << std::showpos << it.abilities->skills[i] << std::noshowpos; } if (it.abilities->stats[STAT_MAGICPOINTS]) { if (begin) { begin = false; s << " ("; } else { s << ", "; } s << "magic level " << std::showpos << it.abilities->stats[STAT_MAGICPOINTS] << std::noshowpos; } int32_t show = it.abilities->absorbPercent[COMBAT_FIRST]; for (uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_COUNT; ++i) { if (it.abilities->absorbPercent[i] == show) { continue; } show = 0; break; } if (!show) { bool tmp = true; for (uint32_t i = COMBAT_FIRST; i <= COMBAT_COUNT; i++) { if (!it.abilities->absorbPercent[i]) { continue; } if (tmp) { tmp = false; if (begin) { begin = false; s << " ("; } else { s << ", "; } s << "protection "; } else { s << ", "; } s << getCombatName(indexToCombatType(i)) << " " << std::showpos << it.abilities->absorbPercent[i] << std::noshowpos << "%"; } } else { if (begin) { begin = false; s << " ("; } else { s << ", "; } s << "protection all " << std::showpos << show << std::noshowpos << "%"; } if (it.abilities->speed) { if (begin) { begin = false; s << " ("; } else { s << ", "; } s << "speed " << std::showpos << (int32_t)(it.abilities->speed / 2) << std::noshowpos; } } if (!begin) { s << ")"; } } } else if (it.armor || (item && item->getArmor()) || it.showAttributes) { int32_t tmp = it.armor; if (item) { tmp = item->getArmor(); } bool begin = true; if (tmp != 0) { s << " (Arm:" << tmp; begin = false; } if (it.abilities) { for (uint16_t i = SKILL_FIRST; i <= SKILL_LAST; i++) { if (!it.abilities->skills[i]) { continue; } if (begin) { begin = false; s << " ("; } else { s << ", "; } s << getSkillName(i) << " " << std::showpos << it.abilities->skills[i] << std::noshowpos; } if (it.abilities->stats[STAT_MAGICPOINTS]) { if (begin) { begin = false; s << " ("; } else { s << ", "; } s << "magic level " << std::showpos << it.abilities->stats[STAT_MAGICPOINTS] << std::noshowpos; } int32_t show = it.abilities->absorbPercent[COMBAT_FIRST]; for (uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_COUNT; ++i) { if (it.abilities->absorbPercent[i] == show) { continue; } show = 0; break; } if (!show) { bool protectionBegin = true; for (uint32_t i = COMBAT_FIRST; i <= COMBAT_COUNT; i++) { if (!it.abilities->absorbPercent[i]) { continue; } if (protectionBegin) { protectionBegin = false; if (begin) { begin = false; s << " ("; } else { s << ", "; } s << "protection "; } else { s << ", "; } s << getCombatName(indexToCombatType(i)) << " " << std::showpos << it.abilities->absorbPercent[i] << std::noshowpos << "%"; } } else { if (begin) { begin = false; s << " ("; } else { s << ", "; } s << "protection all " << std::showpos << show << std::noshowpos << "%"; } if (it.abilities->speed) { if (begin) { begin = false; s << " ("; } else { s << ", "; } s << "speed " << std::showpos << (int32_t)(it.abilities->speed / 2) << std::noshowpos; } } if (!begin) { s << ")"; } } else if (it.isContainer()) { s << " (Vol:" << (int32_t)it.maxItems << ")"; } else { bool found = true; if (it.abilities) { if (it.abilities->speed > 0) { s << " (speed " << std::showpos << (it.abilities->speed / 2) << std::noshowpos << ")"; } else if (it.abilities && hasBitSet(CONDITION_DRUNK, it.abilities->conditionSuppressions)) { s << " (hard drinking)"; } else if (it.abilities->invisible) { s << " (invisibility)"; } else if (it.abilities->regeneration) { s << " (faster regeneration)"; } else if (it.abilities->manaShield) { s << " (mana shield)"; } else { found = false; } } else { found = false; } if (!found) { if (it.isKey()) { s << " (Key:" << (item ? (int32_t)item->getActionId() : 0) << ")"; } else if (it.isFluidContainer()) { if (subType > 0) { const std::string& itemName = items[subType].name; s << " of " << (itemName.length() ? itemName : "unknown"); } else { s << ". It is empty"; } } else if (it.isSplash()) { s << " of "; if (subType > 0 && items[subType].name.length()) { s << items[subType].name; } else { s << "unknown"; } } else if (it.allowDistRead && it.id != 7369 && it.id != 7370 && it.id != 7371) { s << "." << std::endl; if (lookDistance <= 4) { if (item && !item->getText().empty()) { if (item->getWriter().length()) { s << item->getWriter() << " wrote"; time_t date = item->getDate(); if (date > 0) { s << " on " << formatDateShort(date); } s << ": "; } else { s << "You read: "; } std::string outtext; if (utf8ToLatin1(item->getText().c_str(), outtext)) { s << outtext; } else { s << item->getText(); } } else { s << "Nothing is written on it"; } } else { s << "You are too far away to read it"; } } else if (it.levelDoor && item && item->getActionId() >= (int32_t)it.levelDoor) { s << " for level " << item->getActionId() - it.levelDoor; } } } if (it.showCharges) { s << " that has " << subType << " charge" << (subType != 1 ? "s" : "") << " left"; } if (it.showDuration) { if (item && item->hasAttribute(ATTR_ITEM_DURATION)) { int32_t duration = item->getDuration() / 1000; s << " that will expire in "; if (duration >= 86400) { uint16_t days = duration / 86400; uint16_t hours = (duration % 86400) / 3600; s << days << " day" << (days != 1 ? "s" : ""); if (hours > 0) { s << " and " << hours << " hour" << (hours != 1 ? "s" : ""); } } else if (duration >= 3600) { uint16_t hours = duration / 3600; uint16_t minutes = (duration % 3600) / 60; s << hours << " hour" << (hours != 1 ? "s" : ""); if (minutes > 0) { s << " and " << minutes << " minute" << (minutes != 1 ? "s" : ""); } } else if (duration >= 60) { uint16_t minutes = duration / 60; s << minutes << " minute" << (minutes != 1 ? "s" : ""); uint16_t seconds = duration % 60; if (seconds > 0) { s << " and " << seconds << " second" << (seconds != 1 ? "s" : ""); } } else { s << duration << " second" << (duration != 1 ? "s" : ""); } } else { s << " that is brand-new"; } } if (!it.allowDistRead || item->getText().empty() || (it.id >= 7369 && it.id <= 7371)) { s << "."; } if (it.wieldInfo != 0) { s << std::endl << "It can only be wielded properly by "; if (it.wieldInfo & WIELDINFO_PREMIUM) { s << "premium "; } if (it.wieldInfo & WIELDINFO_VOCREQ) { s << it.vocationString; } else { s << "players"; } if (it.wieldInfo & WIELDINFO_LEVEL) { s << " of level " << (int32_t)it.minReqLevel << " or higher"; } if (it.wieldInfo & WIELDINFO_MAGLV) { if (it.wieldInfo & WIELDINFO_LEVEL) { s << " and"; } else { s << " of"; } s << " magic level " << (int32_t)it.minReqMagicLevel << " or higher"; } s << "."; } if (lookDistance <= 1) { double weight = (item == NULL ? it.weight : item->getWeight()); if (weight > 0 && it.pickupable) { int32_t count = weight / it.weight; s << std::endl << getWeightDescription(it, weight, count); } } if (item && !item->getSpecialDescription().empty()) { s << std::endl << item->getSpecialDescription(); } else if (it.description.length() && lookDistance <= 1) { s << std::endl << it.description; } if (it.allowDistRead && it.id >= 7369 && it.id <= 7371 && !item->getText().empty()) { s << std::endl << item->getText(); } return s.str(); }