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(); }
std::string Item::getDescription(const ItemType& it, int32_t lookDistance, const Item* item/* = NULL*/, int32_t subType/* = -1*/, bool addArticle/* = true*/) { std::stringstream s; s << getNameDescription(it, item, subType, addArticle); if(item) subType = item->getSubType(); bool dot = true; if(it.isRune()) { if(!it.runeSpellName.empty()) s << "(\"" << it.runeSpellName << "\")"; if(it.runeLevel > 0 || it.runeMagLevel > 0 || (it.vocationString != "" && it.wieldInfo == 0)) { s << "." << std::endl << "It can only be used"; if(it.vocationString != "" && it.wieldInfo == 0) s << " by " << it.vocationString; bool begin = true; if(g_config.getBool(ConfigManager::USE_RUNE_REQUIREMENTS) && it.runeLevel > 0) { begin = false; s << " with level " << it.runeLevel; } if(g_config.getBool(ConfigManager::USE_RUNE_REQUIREMENTS) && it.runeMagLevel > 0) { begin = false; s << " " << (begin ? "with" : "and") << " magic level " << it.runeMagLevel; } if(g_config.getBool(ConfigManager::USE_RUNE_REQUIREMENTS) && !begin) s << " or higher"; } } else if(it.weaponType != WEAPON_NONE) { bool begin = true; if(it.weaponType == WEAPON_DIST && it.ammoType != AMMO_NONE) { begin = false; s << " (Range:" << int32_t(item ? item->getShootRange() : it.shootRange); if(it.attack || it.extraAttack || (item && (item->getAttack() || item->getExtraAttack()))) { s << ", Atk " << std::showpos << int32_t(item ? item->getAttack() : it.attack); if(it.extraAttack || (item && item->getExtraAttack())) s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos; } if(it.hitChance != -1 || (item && item->getHitChance() != -1)) s << ", Hit% " << std::showpos << (item ? item->getHitChance() : it.hitChance) << std::noshowpos; if(it.attackSpeed || (item && item->getAttackSpeed())) s << ", AS: " << (item ? item->getAttackSpeed() : it.attackSpeed); } else if(it.weaponType != WEAPON_AMMO && it.weaponType != WEAPON_WAND) { if(it.attack || it.extraAttack || (item && (item->getAttack() || item->getExtraAttack()))) { begin = false; s << " (Atk:"; if(it.hasAbilities() && it.abilities->elementType != COMBAT_NONE) { s << std::max((int32_t)0, int32_t((item ? item->getAttack() : it.attack) - it.abilities->elementDamage)); if(it.extraAttack || (item && item->getExtraAttack())) s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos; s << " physical + " << it.abilities->elementDamage << " " << getCombatName(it.abilities->elementType); } else { s << int32_t(item ? item->getAttack() : it.attack); if(it.extraAttack || (item && item->getExtraAttack())) s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos; } } if(it.defense || it.extraDefense || (item && (item->getDefense() || item->getExtraDefense()))) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "Def:" << int32_t(item ? item->getDefense() : it.defense); if(it.extraDefense || (item && item->getExtraDefense())) s << " " << std::showpos << int32_t(item ? item->getExtraDefense() : it.extraDefense) << std::noshowpos; } } if(it.attackSpeed || (item && item->getAttackSpeed())) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "AS: " << (item ? item->getAttackSpeed() : it.attackSpeed); } if(it.hasAbilities()) { 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 << (int32_t)it.abilities->skills[i] << std::noshowpos; } if(it.abilities->stats[STAT_MAGICLEVEL]) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "magic level " << std::showpos << (int32_t)it.abilities->stats[STAT_MAGICLEVEL] << std::noshowpos; } int32_t show = it.abilities->absorb[COMBAT_ALL]; if(!show) { bool tmp = true; for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1) { if(!it.abilities->absorb[i]) continue; if(tmp) { tmp = false; if(begin) { begin = false; s << " ("; } else s << ", "; s << "protection "; } else s << ", "; s << getCombatName((CombatType_t)i) << " " << std::showpos << it.abilities->absorb[i] << std::noshowpos << "%"; } } else { if(begin) { begin = false; s << " ("; } else s << ", "; s << "protection all " << std::showpos << show << std::noshowpos << "%"; } show = it.abilities->fieldAbsorb[COMBAT_ALL]; if(!show) { bool tmp = true; for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1) { if(!it.abilities->fieldAbsorb[i]) continue; if(tmp) { tmp = false; if(begin) { begin = false; s << " ("; } else s << ", "; s << "protection "; } else s << ", "; s << getCombatName((CombatType_t)i) << " field " << std::showpos << it.abilities->absorb[i] << std::noshowpos << "%"; } } else { if(begin) { begin = false; s << " ("; } else s << ", "; s << "protection all fields " << std::showpos << show << std::noshowpos << "%"; } show = it.abilities->reflect[REFLECT_CHANCE][COMBAT_ALL]; if(!show) { bool tmp = true; for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1) { if(!it.abilities->reflect[REFLECT_CHANCE][i] || !it.abilities->reflect[REFLECT_PERCENT][i]) continue; if(tmp) { tmp = false; if(begin) { begin = false; s << " ("; } else s << ", "; s << "reflect: "; } else s << ", "; s << it.abilities->reflect[REFLECT_CHANCE][i] << "% for "; if(it.abilities->reflect[REFLECT_PERCENT][i] > 99) s << "whole"; else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 75) s << "huge"; else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 50) s << "medium"; else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 25) s << "small"; else s << "tiny"; s << getCombatName((CombatType_t)i); } if(!tmp) s << " damage"; } else { if(begin) { begin = false; s << " ("; } else s << ", "; int32_t tmp = it.abilities->reflect[REFLECT_PERCENT][COMBAT_ALL]; s << "reflect: " << show << "% for "; if(tmp) { if(tmp > 99) s << "whole"; else if(tmp >= 75) s << "huge"; else if(tmp >= 50) s << "medium"; else if(tmp >= 25) s << "small"; else s << "tiny"; } else s << "mixed"; s << " damage"; } if(it.abilities->speed) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "speed " << std::showpos << (int32_t)(it.abilities->speed / 2) << std::noshowpos; } if(it.abilities->invisible) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "invisibility"; } if(it.abilities->regeneration) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "faster regeneration"; } if(it.abilities->manaShield) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "mana shield"; } if(hasBitSet(CONDITION_DRUNK, it.abilities->conditionSuppressions)) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "hard drinking"; } } if(it.dualWield || (item && item->isDualWield())) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "dual wielding"; } 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) { s << " (Arm:" << tmp; begin = false; } if(it.hasAbilities()) { 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 << (int32_t)it.abilities->skills[i] << std::noshowpos; } if(it.abilities->stats[STAT_MAGICLEVEL]) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "magic level " << std::showpos << (int32_t)it.abilities->stats[STAT_MAGICLEVEL] << std::noshowpos; } int32_t show = it.abilities->absorb[COMBAT_ALL]; if(!show) { bool tmp = true; for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1) { if(!it.abilities->absorb[i]) continue; if(tmp) { tmp = false; if(begin) { begin = false; s << " ("; } else s << ", "; s << "protection "; } else s << ", "; s << getCombatName((CombatType_t)i) << " " << std::showpos << it.abilities->absorb[i] << std::noshowpos << "%"; } } else { if(begin) { begin = false; s << " ("; } else s << ", "; s << "protection all " << std::showpos << show << std::noshowpos << "%"; } show = it.abilities->reflect[REFLECT_CHANCE][COMBAT_ALL]; if(!show) { bool tmp = true; for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1) { if(!it.abilities->reflect[REFLECT_CHANCE][i] || !it.abilities->reflect[REFLECT_PERCENT][i]) continue; if(tmp) { tmp = false; if(begin) { begin = false; s << " ("; } else s << ", "; s << "reflect: "; } else s << ", "; s << it.abilities->reflect[REFLECT_CHANCE][i] << "% for "; if(it.abilities->reflect[REFLECT_PERCENT][i] > 99) s << "whole"; else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 75) s << "huge"; else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 50) s << "medium"; else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 25) s << "small"; else s << "tiny"; s << getCombatName((CombatType_t)i); } if(!tmp) s << " damage"; } else { if(begin) { begin = false; s << " ("; } else s << ", "; int32_t tmp = it.abilities->reflect[REFLECT_PERCENT][COMBAT_ALL]; s << "reflect: " << show << "% for "; if(tmp) { if(tmp > 99) s << "whole"; else if(tmp >= 75) s << "huge"; else if(tmp >= 50) s << "medium"; else if(tmp >= 25) s << "small"; else s << "tiny"; } else s << "mixed"; s << " damage"; } if(it.abilities->speed) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "speed " << std::showpos << (int32_t)(it.abilities->speed / 2) << std::noshowpos; } if(it.abilities->invisible) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "invisibility"; } if(it.abilities->regeneration) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "faster regeneration"; } if(it.abilities->manaShield) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "mana shield"; } if(hasBitSet(CONDITION_DRUNK, it.abilities->conditionSuppressions)) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "hard drinking"; } if(!begin) s << ")"; } } else if(it.isContainer()) s << " (Vol:" << (int32_t)it.maxItems << ")"; else if(it.isKey()) s << " (Key:" << (item ? (int32_t)item->getActionId() : 0) << ")"; else if(it.isFluidContainer()) { if(subType > 0) s << " of " << (items[subType].name.length() ? items[subType].name : "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) { s << "." << std::endl; if(item && !item->getText().empty()) { if(lookDistance <= 4) { if(!item->getWriter().empty()) { s << item->getWriter() << " wrote"; time_t date = item->getDate(); if(date > 0) s << " on " << formatDate(date); s << ": "; } else s << "You read: "; std::string text = item->getText(); s << text; char end = *text.rbegin(); if(end == '?' || end == '!' || end == '.') dot = false; } else s << "You are too far away to read it"; } else s << "Nothing is written on it"; } else if(it.levelDoor && item && item->getActionId() >= (int32_t)it.levelDoor && item->getActionId() <= ((int32_t)it.levelDoor + g_config.getNumber(ConfigManager::MAXIMUM_DOOR_LEVEL))) 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->hasIntegerAttribute("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(hours > 0) s << " and " << minutes << " minute" << (minutes > 1 ? "s" : ""); } else if(duration >= 60) { uint16_t minutes = duration / 60; uint16_t seconds = duration % 60; s << minutes << " minute" << (minutes > 1 ? "s" : ""); if(seconds > 0) s << " and " << seconds << " second" << (seconds > 1 ? "s" : ""); } else s << duration << " second" << (duration > 1 ? "s" : ""); } else s << " that is brand-new"; } if(dot) s << "."; if(it.wieldInfo) { 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 && it.pickupable) { std::string tmp; if(!item) tmp = getWeightDescription(it.weight, it.stackable && it.showCount, subType); else tmp = item->getWeightDescription(); if(!tmp.empty()) s << std::endl << tmp; } if(item && !item->getSpecialDescription().empty()) s << std::endl << item->getSpecialDescription(); else if(!it.description.empty() && lookDistance <= 1) s << std::endl << it.description; std::string str = s.str(); if(str.find("|PLAYERNAME|") != std::string::npos) { std::string tmp = "You"; if(item) { if(const Player* player = item->getHoldingPlayer()) tmp = player->getName(); } replaceString(str, "|PLAYERNAME|", tmp); } if(str.find("|TIME|") != std::string::npos || str.find("|DATE|") != std::string::npos || str.find( "|DAY|") != std::string::npos || str.find("|MONTH|") != std::string::npos || str.find( "|YEAR|") != std::string::npos || str.find("|HOUR|") != std::string::npos || str.find( "|MINUTES|") != std::string::npos || str.find("|SECONDS|") != std::string::npos || str.find("|WEEKDAY|") != std::string::npos || str.find("|YEARDAY|") != std::string::npos) { time_t now = time(NULL); tm* ts = localtime(&now); std::stringstream ss; ss << ts->tm_sec; replaceString(str, "|SECONDS|", ss.str()); ss.str(""); ss << ts->tm_min; replaceString(str, "|MINUTES|", ss.str()); ss.str(""); ss << ts->tm_hour; replaceString(str, "|HOUR|", ss.str()); ss.str(""); ss << ts->tm_mday; replaceString(str, "|DAY|", ss.str()); ss.str(""); ss << (ts->tm_mon + 1); replaceString(str, "|MONTH|", ss.str()); ss.str(""); ss << (ts->tm_year + 1900); replaceString(str, "|YEAR|", ss.str()); ss.str(""); ss << ts->tm_wday; replaceString(str, "|WEEKDAY|", ss.str()); ss.str(""); ss << ts->tm_yday; replaceString(str, "|YEARDAY|", ss.str()); ss.str(""); ss << ts->tm_hour << ":" << ts->tm_min << ":" << ts->tm_sec; replaceString(str, "|TIME|", ss.str()); ss.str(""); replaceString(str, "|DATE|", formatDateEx(now)); } return str; }
std::string Item::getDescription(const ItemType& it, int32_t lookDistance, const Item* item/* = NULL*/, int32_t subType/* = -1*/, bool addArticle/* = true*/) { std::stringstream s; s << getNameDescription(it, item, subType, addArticle); if(item) subType = item->getSubType(); bool dot = true; if(it.isRune()) { s << "("; if(!it.runeSpellName.empty()) s << "\"" << it.runeSpellName << "\", "; s << "Charges:" << subType << ")"; if(it.runeLevel > 0 || it.runeMagLevel > 0 || (it.vocationString != "" && it.wieldInfo == 0)) { s << "." << std::endl << "It can only be used"; if(it.vocationString != "" && it.wieldInfo == 0) s << " by " << it.vocationString; bool begin = true; if(it.runeLevel > 0) { begin = false; s << " with level " << it.runeLevel; } if(it.runeMagLevel > 0) { begin = false; s << " " << (begin ? "with" : "and") << " magic level " << it.runeMagLevel; } if(!begin) s << " or higher"; } } else if(it.weaponType != WEAPON_NONE) { bool begin = true; if(it.weaponType == WEAPON_DIST && it.ammoType != AMMO_NONE) { begin = false; s << " (Range:" << int32_t(item ? item->getShootRange() : it.shootRange); if(it.attack || it.extraAttack || (item && (item->getAttack() || item->getExtraAttack()))) { s << ", Atk " << std::showpos << int32_t(item ? item->getAttack() : it.attack); if(it.extraAttack || (item && item->getExtraAttack())) s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos; } if(it.hitChance != -1 || (item && item->getHitChance() != -1)) s << ", Hit% " << std::showpos << (item ? item->getHitChance() : it.hitChance) << std::noshowpos; } else if(it.weaponType != WEAPON_AMMO && it.weaponType != WEAPON_WAND) { if(it.attack || it.extraAttack || (item && (item->getAttack() || item->getExtraAttack()))) { begin = false; s << " (Atk:"; if(it.abilities.elementType != COMBAT_NONE && it.decayTo < 1) { s << std::max((int32_t)0, int32_t((item ? item->getAttack() : it.attack) - it.abilities.elementDamage)); if(it.extraAttack || (item && item->getExtraAttack())) s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos; s << " physical + " << it.abilities.elementDamage << " " << getCombatName(it.abilities.elementType); } else { s << int32_t(item ? item->getAttack() : it.attack); if(it.extraAttack || (item && item->getExtraAttack())) s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos; } } if(it.defense || it.extraDefense || (item && (item->getDefense() || item->getExtraDefense()))) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "Def:" << int32_t(item ? item->getDefense() : it.defense); if(it.extraDefense || (item && item->getExtraDefense())) s << " " << std::showpos << int32_t(item ? item->getExtraDefense() : it.extraDefense) << std::noshowpos; } } 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 << (int32_t)it.abilities.skills[i] << std::noshowpos; } if(it.abilities.stats[STAT_MAGICLEVEL]) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "magic level " << std::showpos << (int32_t)it.abilities.stats[STAT_MAGICLEVEL] << std::noshowpos; } int32_t show = it.abilities.absorb[COMBAT_FIRST]; for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i++) { if(it.abilities.absorb[i] == show) continue; show = 0; break; } // TODO: update to the latest (from below) if(!show) { bool tmp = true; for(uint32_t i = COMBAT_FIRST; i <= COMBAT_LAST; i++) { if(!it.abilities.absorb[i]) continue; if(tmp) { if(begin) { begin = false; s << " ("; } else s << ", "; tmp = false; s << "protection "; } else s << ", "; s << getCombatName((CombatType_t)i) << " " << std::showpos << it.abilities.absorb[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(it.dualWield || (item && item->isDualWield())) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "dual wielding"; } 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) { s << " (Arm:" << tmp; begin = false; } 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 << (int32_t)it.abilities.skills[i] << std::noshowpos; } if(it.abilities.stats[STAT_MAGICLEVEL]) { if(begin) { begin = false; s << " ("; } else s << ", "; s << "magic level " << std::showpos << (int32_t)it.abilities.stats[STAT_MAGICLEVEL] << std::noshowpos; } // TODO: we should find some better way of completing this int32_t show = it.abilities.absorb[COMBAT_FIRST]; for(int32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i++) { if(it.abilities.absorb[i] == show) continue; show = 0; break; } if(!show) { bool tmp = true; for(int32_t i = COMBAT_FIRST; i <= COMBAT_LAST; i++) { if(!it.abilities.absorb[i]) continue; if(tmp) { tmp = false; if(begin) { begin = false; s << " ("; } else s << ", "; s << "protection "; } else s << ", "; s << getCombatName((CombatType_t)i) << " " << std::showpos << it.abilities.absorb[i] << std::noshowpos << "%"; } } else { if(begin) { begin = false; s << " ("; } else s << ", "; s << "protection all " << std::showpos << show << std::noshowpos << "%"; } // TODO: same case as absorbs... show = it.abilities.reflect[REFLECT_CHANCE][COMBAT_FIRST]; for(int32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i++) { if(it.abilities.reflect[REFLECT_CHANCE][i] == show) continue; show = 0; break; } if(!show) { bool tmp = true; for(int32_t i = COMBAT_FIRST; i <= COMBAT_LAST; i++) { if(!it.abilities.reflect[REFLECT_CHANCE][i] || !it.abilities.reflect[REFLECT_PERCENT][i]) continue; if(tmp) { tmp = false; if(begin) { begin = false; s << " ("; } else s << ", "; s << "reflect: "; } else s << ", "; s << it.abilities.reflect[REFLECT_CHANCE][i] << "% for "; if(it.abilities.reflect[REFLECT_PERCENT][i] > 99) s << "whole"; else if(it.abilities.reflect[REFLECT_PERCENT][i] >= 75) s << "huge"; else if(it.abilities.reflect[REFLECT_PERCENT][i] >= 50) s << "medium"; else if(it.abilities.reflect[REFLECT_PERCENT][i] >= 25) s << "small"; else s << "tiny"; s << getCombatName((CombatType_t)i); } if(!tmp) s << " damage"; } else { if(begin) { begin = false; s << " ("; } else s << ", "; int32_t tmp = it.abilities.reflect[REFLECT_PERCENT][COMBAT_FIRST]; for(int32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i++) { if(it.abilities.reflect[REFLECT_PERCENT][i] == tmp) continue; tmp = 0; break; } s << "reflect: " << show << "% for "; if(tmp) { if(tmp > 99) s << "whole"; else if(tmp >= 75) s << "huge"; else if(tmp >= 50) s << "medium"; else if(tmp >= 25) s << "small"; else s << "tiny"; } else s << "mixed"; s << " damage"; } 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 if(it.isKey()) s << " (Key:" << (item ? (int32_t)item->getActionId() : 0) << ")"; else if(it.isFluidContainer()) { if(subType > 0) s << " of " << (items[subType].name.length() ? items[subType].name : "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) { s << std::endl; if(item && !item->getText().empty()) { if(lookDistance <= 4) { if(!item->getWriter().empty()) { s << item->getWriter() << " wrote"; time_t date = item->getDate(); if(date > 0) s << " on " << formatDate(date); s << ": "; } else s << "You read: "; std::string text = item->getText(); s << text; if(!text.empty()) { char end = *text.rbegin(); if(end == '?' || end == '!' || end == '.') dot = false; } } else s << "You are too far away to read it"; } else s << "Nothing is written on it"; } else if(it.levelDoor && item && item->getActionId() >= (int32_t)it.levelDoor && item->getActionId() <= ((int32_t)it.levelDoor + g_config.getNumber(ConfigManager::MAXIMUM_DOOR_LEVEL))) 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->hasIntegerAttribute("duration")) { int32_t duration = item->getDuration() / 1000; s << " that has energy for "; if(duration >= 120) s << duration / 60 << " minutes left"; else if(duration > 60) s << "1 minute left"; else s << " less than a minute left"; } else s << " that is brand-new"; } if(dot) s << "."; if(it.wieldInfo) { 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 && it.pickupable) { std::string tmp; if(!item) tmp = getWeightDescription(it.weight, it.stackable, subType); else tmp = item->getWeightDescription(); if(!tmp.empty()) s << std::endl << tmp; } if(it.abilities.elementType != COMBAT_NONE && it.decayTo > 0) { s << std::endl << "It is temporarily enchanted with " << getCombatName(it.abilities.elementType) << " ("; s << std::max((int32_t)0, int32_t((item ? item->getAttack() : it.attack) - it.abilities.elementDamage)); if(it.extraAttack || (item && item->getExtraAttack())) s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos; s << " physical + " << it.abilities.elementDamage << " " << getCombatName(it.abilities.elementType) << " damage)."; } std::string str; if(item && !item->getSpecialDescription().empty()) str = item->getSpecialDescription(); else if(!it.description.empty() && lookDistance <= 1) str = it.description; if(str.empty()) return s.str(); if(str.find("|PLAYERNAME|") != std::string::npos) { std::string tmp = "You"; if(item) { if(const Player* player = item->getHoldingPlayer()) tmp = player->getName(); } replaceString(str, "|PLAYERNAME|", tmp); } if(str.find("|TIME|") != std::string::npos || str.find("|DATE|") != std::string::npos || str.find( "|DAY|") != std::string::npos || str.find("|MONTH|") != std::string::npos || str.find( "|YEAR|") != std::string::npos || str.find("|HOUR|") != std::string::npos || str.find( "|MINUTES|") != std::string::npos || str.find("|SECONDS|") != std::string::npos || str.find("|WEEKDAY|") != std::string::npos || str.find("|YEARDAY|") != std::string::npos) { time_t now = time(NULL); tm* ts = localtime(&now); std::stringstream ss; ss << ts->tm_sec; replaceString(str, "|SECONDS|", ss.str()); ss.str(""); ss << ts->tm_min; replaceString(str, "|MINUTES|", ss.str()); ss.str(""); ss << ts->tm_hour; replaceString(str, "|HOUR|", ss.str()); ss.str(""); ss << ts->tm_mday; replaceString(str, "|DAY|", ss.str()); ss.str(""); ss << (ts->tm_mon + 1); replaceString(str, "|MONTH|", ss.str()); ss.str(""); ss << (ts->tm_year + 1900); replaceString(str, "|YEAR|", ss.str()); ss.str(""); ss << ts->tm_wday; replaceString(str, "|WEEKDAY|", ss.str()); ss.str(""); ss << ts->tm_yday; replaceString(str, "|YEARDAY|", ss.str()); ss.str(""); ss << ts->tm_hour << ":" << ts->tm_min << ":" << ts->tm_sec; replaceString(str, "|TIME|", ss.str()); ss.str(""); replaceString(str, "|DATE|", formatDateEx(now)); } s << std::endl << str; return s.str(); }
std::string Item::getDescription(const ItemType& it, const int32_t& lookDistance, const Item* item /*= NULL*/, int32_t subType /*= -1*/, bool addArticle /*= true*/) { std::stringstream s; if (item) { subType = item->getSubType(); } s << getLongName(it, lookDistance, item, subType, addArticle); if (it.isRune()) { s << " (\"" << it.runeSpellName << "\")."; if (it.runeLevel > 0 || it.runeMagLevel > 0) { s << std::endl << "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.amuType != AMMO_NONE) { s << " (Range:" << it.shootRange; if (it.attack != 0) { s << ", Atk" << std::showpos << it.attack << std::noshowpos; } if (it.hitChance > 0) //excludes both cases it.hitchance 0 and -1 { s << ", Hit%" << std::showpos << it.hitChance << std::noshowpos; } s << ")"; } else if (it.weaponType != WEAPON_AMMO && it.weaponType != WEAPON_WAND) // Arrows and Bolts doesn't show atk { s << " ("; if (it.attack != 0) { s << "Atk:" << (int32_t)it.attack; if (it.abilities.elementDamage != 0) { s << " " << "physical + "; switch (it.abilities.elementType) { case COMBAT_ICEDAMAGE: s << it.abilities.elementDamage << " Ice,"; break; case COMBAT_EARTHDAMAGE: s << it.abilities.elementDamage << " Earth,"; break; case COMBAT_FIREDAMAGE: s << it.abilities.elementDamage << " Fire,"; break; case COMBAT_ENERGYDAMAGE: s << it.abilities.elementDamage << " Energy,"; break; default: s << it.abilities.elementDamage << " Unknown,"; break; } } } if (it.defense != 0 || it.extraDef != 0) { if (it.attack != 0) { s << " "; } s << "Def:" << (int32_t)it.defense; if (it.extraDef != 0) { s << " " << std::showpos << (int32_t)it.extraDef << std::noshowpos; } } if (it.abilities.stats[STAT_MAGICPOINTS] != 0) { if (it.attack != 0 || it.defense != 0 || it.extraDef != 0) { s << ", "; } s << "magic level " << std::showpos << (int32_t)it.abilities.stats[STAT_MAGICPOINTS] << std::noshowpos; } s << ")"; } if (it.showCharges) { if (subType > 1) { s << " that has " << (int32_t)subType << " charges left"; } else { s << " that has 1 charge left"; } } s << "."; } else if (it.armor != 0 || it.abilities.skill.any() || it.abilities.absorb.any() || it.abilities.stats[STAT_MAGICPOINTS] != 0 || it.abilities.speed != 0 || it.defense != 0) { if (it.showCharges) { if (subType > 1) { s << " that has " << (int32_t)subType << " charges left"; } else { s << " that has 1 charge left"; } } else if (it.showDuration) { if (item && item->hasAttribute(ATTR_ITEM_DURATION)) { int32_t duration = item->getDuration() / 1000; s << " that has energy for "; if (duration >= 120) { s << duration / 60 << " minutes left."; } else if (duration > 60) { s << "1 minute left."; } else { s << "less than a minute left."; } } else { s << " that is brand-new."; } } s << " ("; bool prevDesc = false; if (it.armor != 0) { // as it is the first desc it isn't // really necessary to add it here //if(prevDesc) // s << ", "; s << "Arm:" << it.armor; prevDesc = true; } if (it.abilities.skill.any()) { if (prevDesc) { s << ", "; } it.abilities.skill.getDescription(s); prevDesc = true; } if (it.abilities.absorb.any()) { if (prevDesc) { s << ", "; } s << "protection"; it.abilities.absorb.getDescription(s); prevDesc = true; } if (it.abilities.stats[STAT_MAGICPOINTS] != 0) { if (prevDesc) { s << ", "; } s << "magic level " << std::showpos << (int32_t)it.abilities.stats[STAT_MAGICPOINTS] << std::noshowpos; prevDesc = true; } if (it.defense != 0) { if (prevDesc) { s << ", "; } s << "defense " << std::showpos << (int32_t)it.defense << std::noshowpos; prevDesc = true; } if (it.abilities.speed != 0) { if (prevDesc) { s << ", "; } s << "speed " << std::showpos << (int32_t)(it.abilities.speed / 2) << std::noshowpos; // last desc... same thing as the first //prevDesc = true; } s << ")."; } else if (it.isFluidContainer()) { if (subType > 0) { s << " of " << items[subType].name << "."; } else { s << ". It is empty."; } } else if (it.isSplash()) { s << " of "; if (subType > 0) { s << items[subType].name << "."; } else { s << items[1].name << "."; } } else if (it.isContainer()) { s << " (Vol:" << (int32_t)it.maxItems << ")."; } else if (it.isKey()) { if (item) { s << " (Key:" << (int32_t)item->getActionId() << ")."; } else { s << " (Key:0)."; } } else if (it.allowDistRead) { s << std::endl; if (item && item->getText() != "") { if (lookDistance <= 4) { if (item->getWriter().length()) { s << item->getWriter() << " wrote"; time_t wDate = item->getWrittenDate(); if (wDate > 0) { char date[16]; formatDateShort(wDate, date); s << " on " << date; } s << ": "; } else { s << "You read: "; } s << item->getText(); } else { s << "You are too far away to read it."; } } else { s << "Nothing is written on it."; } } else if (it.isLevelDoor() && item && item->getActionId() >= 1000) { s << " for level " << item->getActionId() - 1000; } else if (it.showCharges) { if (subType > 1) { s << " that has " << (int32_t)subType << " charges left."; } else { s << " that has 1 charge left."; } } else if (it.showDuration) { if (item && item->hasAttribute(ATTR_ITEM_DURATION)) { int32_t duration = item->getDuration() / 1000; s << " that has energy for "; if (duration >= 120) { s << duration / 60 << " minutes left."; } else if (duration > 60) { s << "1 minute left."; } else { s << "less than a minute left."; } } else { s << " that is brand-new."; } } else { 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 ? it.weight : item->getWeight()); if (weight > 0) { s << std::endl << getWeightDescription(it, weight); } } if (item && item->getSpecialDescription() != "") { s << std::endl << item->getSpecialDescription().c_str(); } else if (it.description.length() && lookDistance <= 1) { s << std::endl << it.description; } else if(it.isFluidContainer() && subType > 0 && items[subType].description.length() && lookDistance <= 1) { s << std::endl << items[subType].description; } return s.str(); }
std::string Item::getDescription(const ItemType& it, int32_t lookDistance, const Item* item /*= NULL*/, int32_t subType /*= -1*/, bool addArticle /*= true*/) { std::stringstream s; if (item){ subType = item->getSubType(); } if (it.name.length()){ if (it.stackable && item && item->getItemCount() > 1){ if (it.showCount){ s << (int)item->getItemCount() << " "; } s << it.pluralName; } else{ if (!it.article.empty()){ s << it.article << " "; } s << it.name; } } else{ s << "an item of type " << it.id; } if (it.isRune()){ uint32_t charges = std::max((uint32_t)1, (uint32_t)(item == NULL ? it.charges : item->getCharges())); if (it.runeLevel > 0 || it.runeMagLevel > 0){ if (it.runeLevel > 0){ s << " for level " << it.runeLevel; } if (it.runeMagLevel > 0){ if (it.runeLevel > 0){ s << " and"; } s << " for magic level " << it.runeMagLevel; } } s << ". It's an \"" << it.runeSpellName << "\"-spell (" << charges << "x). "; } else if ((it.id == ITEM_GATE_EXPERTISE_1 || it.id == ITEM_GATE_EXPERTISE_2 || it.id == ITEM_GATE_EXPERTISE_3 || it.id == ITEM_GATE_EXPERTISE_4 || it.id == ITEM_GATE_EXPERTISE_5 || it.id == ITEM_GATE_EXPERTISE_6 || it.id == ITEM_GATE_EXPERTISE_7 || it.id == ITEM_GATE_EXPERTISE_8) && (item->getActionId() >= 1000)) { s << " for level " << item->getActionId() - 1000 << "."; } else if (it.weaponType != WEAPON_NONE){ if (it.weaponType == WEAPON_DIST && it.amuType != AMMO_NONE){ if (it.attack != 0){ s << ", Atk" << std::showpos << it.attack << std::noshowpos; } } else if (it.weaponType != WEAPON_AMMO && it.weaponType != WEAPON_WAND){ // Arrows and Bolts doesn't show atk if (it.attack != 0 || it.defense != 0 || it.abilities.stats[STAT_MAGICPOINTS] != 0) { s << " ("; if (it.attack != 0){ s << "Atk:" << (int)it.attack; } if (it.defense != 0 || it.extraDef != 0){ if (it.attack != 0) s << " "; s << "Def:" << (int)it.defense; } if (it.abilities.stats[STAT_MAGICPOINTS] != 0){ if (it.attack != 0 || it.defense != 0 || it.extraDef != 0) s << ", "; s << "magic level " << std::showpos << (int)it.abilities.stats[STAT_MAGICPOINTS] << std::noshowpos; } s << ")"; } } s << "."; } else if (it.armor != 0 || it.abilities.absorb.any()){ if (it.showCharges){ if (subType > 1){ s << " that has " << (int32_t)subType << " charges left"; } else{ s << " that has 1 charge left"; } } if (it.armor != 0){ s << " (Arm:" << it.armor << ")"; } s << "."; } else if (it.isFluidContainer()){ if (item && item->getFluidType() != 0){ s << " of " << items[item->getFluidType()].name << "."; } else{ s << ". It is empty."; } } else if (it.isSplash()){ s << " of "; if (item && item->getFluidType() != 0){ s << items[item->getFluidType()].name << "."; } else{ s << items[1].name; } } else if (it.isContainer()){ s << " (Vol:" << (int)it.maxItems << ")."; } else if (it.isKey()){ if (item){ s << " (Key:" << (int)item->getActionId() << ")."; } else{ s << " (Key:" << (int)0 << ")."; } } else if (it.allowDistRead){ s << "." << std::endl; if (item && item->getText() != ""){ if (lookDistance <= 4){ if (item->getWriter().length()){ s << item->getWriter() << " wrote: "; } else{ s << "You read: "; } s << item->getText(); } else{ s << "You are too far away to read it."; } } else{ s << "Nothing is written on it."; } } else if (it.showCharges){ uint32_t charges = (item == NULL ? it.charges : item->getCharges()); if (charges > 1){ s << " that has " << (int)charges << " charges left."; } else{ s << " that has 1 charge left."; } } else if (it.showDuration){ if (item && item->hasAttribute(ATTR_ITEM_DURATION)){ int32_t duration = item->getDuration() / 1000; s << " that has energy for "; if (duration >= 120){ s << duration / 60 << " minutes left."; } else if (duration > 60){ s << "1 minute left."; } else{ s << " less than a minute left."; } } else{ s << " that is brand-new."; } } else{ 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 " << (int)it.minReqLevel << " or higher"; } if (it.wieldInfo & WIELDINFO_MAGLV){ if (it.wieldInfo & WIELDINFO_LEVEL){ s << " and"; } else{ s << " of"; } s << " magic level " << (int)it.minReqMagicLevel << " or higher"; } s << "."; } if (lookDistance <= 1){ double weight = (item == NULL ? it.weight : item->getWeight()); if (weight > 0){ s << std::endl << getWeightDescription(it, weight); } } if (item && item->getSpecialDescription() != ""){ s << std::endl << item->getSpecialDescription().c_str(); } else if (it.description.length() && lookDistance <= 1){ s << std::endl << it.description; } return s.str(); }
std::string Item::getDescription(const ItemType& it, int32_t lookDistance, const Item* item /*= NULL*/, int32_t subType /*= -1*/) { std::stringstream s; if(item){ subType = item->getSubType(); } if(it.name.length()){ if(it.stackable && subType > 1){ if(it.showCount){ s << subType << " "; } s << it.pluralName; } else{ if(!it.article.empty()){ s << it.article << " "; } s << it.name; } } else{ s << "an item of type " << it.id; } if(it.isRune()){ s << "(\"" << it.runeSpellName << "\", Charges:" << subType <<")."; if(it.runeLevel > 0 || it.runeMagLevel > 0){ s << std::endl << "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.amuType != 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 && it.weaponType != WEAPON_WAND){ // Arrows and Bolts doesn't show atk s << " ("; if(it.attack != 0){ s << "Atk:" << (int)it.attack; } if(it.defence != 0 || it.extraDef != 0){ if(it.attack != 0) s << " "; s << "Def:" << (int)it.defence; if(it.extraDef != 0){ s << " " << std::showpos << (int)it.extraDef << std::noshowpos; } } if(it.abilities.stats[STAT_MAGICPOINTS] != 0){ if(it.attack != 0 || it.defence != 0 || it.extraDef != 0) s << ", "; s << "magic level " << std::showpos << (int)it.abilities.stats[STAT_MAGICPOINTS] << std::noshowpos; } s << ")"; } if(it.showCharges){ if(subType > 1){ s << " that has " << (int32_t)subType << " charges left"; } else{ s << " that has 1 charge left"; } } s << "."; } else if(it.armor != 0){ s << " (Arm:" << it.armor; if(it.abilities.absorbPercentAll != 0 || it.abilities.absorbPercentDeath != 0 || it.abilities.absorbPercentDrown != 0 || it.abilities.absorbPercentEarth != 0 || it.abilities.absorbPercentEnergy != 0 || it.abilities.absorbPercentFire != 0 || it.abilities.absorbPercentHoly != 0 || it.abilities.absorbPercentIce != 0 || it.abilities.absorbPercentLifeDrain != 0 || it.abilities.absorbPercentManaDrain != 0 || it.abilities.absorbPercentPhysical != 0) { bool isBegin = true; s << ", protection"; if(it.abilities.absorbPercentAll != 0){ s << " all " << std::showpos << it.abilities.absorbPercentAll << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentDeath != 0){ if(!isBegin){ s << ","; } s << " death " << std::showpos << it.abilities.absorbPercentDeath << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentDrown != 0){ if(!isBegin){ s << ","; } s << " drown " << std::showpos << it.abilities.absorbPercentDrown << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentEarth != 0){ if(!isBegin){ s << ","; } s << " earth " << std::showpos << it.abilities.absorbPercentEarth << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentEnergy != 0){ if(!isBegin){ s << ","; } s << " energy " << std::showpos << it.abilities.absorbPercentEnergy << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentFire != 0){ if(!isBegin){ s << ","; } s << " fire " << std::showpos << it.abilities.absorbPercentFire << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentHoly != 0){ if(!isBegin){ s << ","; } s << " holy " << std::showpos << it.abilities.absorbPercentHoly << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentIce != 0){ if(!isBegin){ s << ","; } s << " ice " << std::showpos << it.abilities.absorbPercentIce << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentLifeDrain != 0){ if(!isBegin){ s << ","; } s << " life drain " << std::showpos << it.abilities.absorbPercentLifeDrain << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentManaDrain != 0){ if(!isBegin){ s << ","; } s << " mana drain " << std::showpos << it.abilities.absorbPercentManaDrain << std::noshowpos << "%"; isBegin = false; } if(it.abilities.absorbPercentPhysical != 0){ if(!isBegin){ s << ","; } s << " physical " << std::showpos << it.abilities.absorbPercentPhysical << std::noshowpos << "%"; isBegin = false; } } s << ")."; } else if(it.isFluidContainer()){ if(subType > 0){ s << " of " << items[subType].name << "."; } else{ s << ". It is empty."; } } else if(it.isSplash()){ s << " of "; if(subType > 0){ s << items[subType].name; } else{ s << items[1].name; } } else if(it.isContainer()){ s << " (Vol:" << (int)it.maxItems << ")."; } else if(it.isKey()){ if(item){ s << " (Key:" << (int)item->getActionId() << ")."; } else{ s << " (Key:0)."; } } else if(it.allowDistRead){ s << std::endl; if(item && item->getText() != ""){ if(lookDistance <= 4){ if(item->getWriter().length()){ s << item->getWriter() << " wrote"; time_t wDate = item->getWrittenDate(); if(wDate > 0){ char date[16]; formatDate2(wDate, date); s << " on " << date; } s << ": "; } else{ s << "You read: "; } s << item->getText(); } else{ s << "You are too far away to read it."; } } else{ s << "Nothing is written on it."; } } else if(it.showCharges){ if(subType > 1){ s << " that has " << (int32_t)subType << " charges left."; } else{ s << " that has 1 charge left."; } } else if(it.showDuration){ if(item && item->hasAttribute(ATTR_ITEM_DURATION)){ uint32_t duration = item->getDuration() / 1000; s << " that has energy for "; if(duration >= 120){ s << duration / 60 << " minutes left."; } else if(duration > 60){ s << "1 minute left."; } else{ s << " less than a minute left."; } } else{ s << " that is brand-new."; } } else{ 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 " << (int)it.minReqLevel << " or higher"; } if(it.wieldInfo & WIELDINFO_MAGLV){ if(it.wieldInfo & WIELDINFO_LEVEL){ s << " and"; } else{ s << " of"; } s << " magic level " << (int)it.minReqMagicLevel << " or higher"; } s << "."; } if(lookDistance <= 1){ double weight = (item == NULL ? it.weight : item->getWeight()); if(weight > 0){ s << std::endl << getWeightDescription(it, weight); } } if(item && item->getSpecialDescription() != ""){ s << std::endl << item->getSpecialDescription().c_str(); } else if(it.description.length() && lookDistance <= 1){ s << std::endl << it.description; } return s.str(); }