byte RouteableItem::getRoadClass() const {
   if ( getItemType() == ItemTypes::ferryItem )
      return item_cast< const FerryItem* >(this)->getRoadClass();
   if ( getItemType() == ItemTypes::streetSegmentItem )
      return item_cast< const StreetSegmentItem* >(this)->getRoadClass();
   if ( getItemType() == ItemTypes::busRouteItem ) 
      return item_cast< const BusRouteItem* >(this)->getRoadClass();

   mc2log << warn << here << " can not determine the right RouteableItem sub type for getRoadClass()" << endl;

   return ItemTypes::mainRoad;
}
enum OpenAB_Storage::Storage::eGetItem EDSCalendarStorage::getEvent(const OpenAB::PIMItem::ID & id,
                                                                 OpenAB::SmartPtr<OpenAB::PIMCalendarEventItem> & item)
{
  if (getItemType() != OpenAB::eEvent)
  {
    return eGetItemFail;
  }

  GError* gerror = NULL;
  GSList* events = NULL;
  std::vector<icalcomponent*> iCalComponents;

  if (!e_cal_client_get_objects_for_uid_sync(client, id.c_str(), &events, NULL, &gerror))
  {
    LOG_ERROR() << "Error e_cal_client_get_objects_for_uid_sync result: " << GERROR_MESSAGE(gerror) << std::endl;
    GERROR_FREE(gerror);
    return eGetItemFail;
  }

  GSList* current = events;
  while(current)
  {
    ECalComponent* component = (ECalComponent*)current->data;
    iCalComponents.push_back(icalcomponent_new_clone(e_cal_component_get_icalcomponent(component)));
    current = current->next;
  }

  item = (OpenAB::PIMCalendarEventItem*)EDSCalendarStorageCommon::processObject(iCalComponents);

  e_cal_client_free_ecalcomp_slist(events);
  return eGetItemOk;
}
Example #3
0
const ItemType& Items::getItemIdByClientId(uint16_t spriteId) const
{
	auto it = reverseItemMap.find(spriteId);
	if (it != reverseItemMap.end()) {
		return getItemType(it->second);
	}
	return items.front();
}
Example #4
0
void PlayerItem::onEnter()
{
    Node::onEnter();
    char buffer[50];
    sprintf(buffer, "%s_%d",getItemType().animationName.c_str(),0);
    auto appearAnimation = AnimationCache::getInstance()->getAnimation(buffer);
    auto appearAnimate = Animate::create(appearAnimation);
    auto itemSequence = Sequence::create(appearAnimate,CallFunc::create([&]()->void{
        char buffer[50];
        sprintf(buffer, "%s_%d",getItemType().animationName.c_str(),1);
        auto normalAnimation = AnimationCache::getInstance()->getAnimation(buffer);
        auto repeateAnimate = RepeatForever::create(Animate::create(normalAnimation));
        this->runAction(repeateAnimate);
    }), NULL);
    runAction(itemSequence);
    setAnchorPoint(Point(0.5f,0.0f));
    scheduleUpdate();
}
Example #5
0
bool Inventory::hasItem(string itemName)
{
	ItemType itemType = getItemType(itemName);
	for (int i = 0; i < TOTALSPACE; ++i)
	{
		if (items[i] == itemType)
			return true;
	}
	return false;
}
void ThingTypeManager::parseItemType(uint16 serverId, TiXmlElement* elem)
{
    ItemTypePtr itemType = nullptr;

    bool s;
    int d;

    if(g_game.getProtocolVersion() < 960) {
        s = serverId > 20000 && serverId < 20100;
        d = 20000;
    } else {
        s = serverId > 30000 && serverId < 30100;
        d = 30000;
    }

    if(s) {
        serverId -= d;
        itemType = ItemTypePtr(new ItemType);
        itemType->setServerId(serverId);
        addItemType(itemType);
    } else
        itemType = getItemType(serverId);

    itemType->setName(elem->Attribute("name"));
    for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
        std::string key = attrib->Attribute("key");
        if(key.empty())
            continue;

        stdext::tolower(key);
        if(key == "description")
            itemType->setDesc(attrib->Attribute("value"));
        else if(key == "weapontype")
            itemType->setCategory(ItemCategoryWeapon);
        else if(key == "ammotype")
            itemType->setCategory(ItemCategoryAmmunition);
        else if(key == "armor")
            itemType->setCategory(ItemCategoryArmor);
        else if(key == "charges")
            itemType->setCategory(ItemCategoryCharges);
        else if(key == "type") {
            std::string value = attrib->Attribute("value");
            stdext::tolower(value);

            if(value == "key")
                itemType->setCategory(ItemCategoryKey);
            else if(value == "magicfield")
                itemType->setCategory(ItemCategoryMagicField);
            else if(value == "teleport")
                itemType->setCategory(ItemCategoryTeleport);
            else if(value == "door")
                itemType->setCategory(ItemCategoryDoor);
        }
    }
}
Example #7
0
IContentItem* CRootItem::addContentItem(string textWoPath, CCategoryItem* parent, int posInParent) throw (ExMalformedPatch)
{
	CItemType itemType = getItemType(textWoPath);
	if(posInParent == -1) {
		posInParent = parent->numChildren();
	}
	beginInsertItems(posInParent, 1, parent );
	IContentItem* newItem = IContentItem::itemFactory( itemType, this, textWoPath, parent, posInParent);
	endInsertItems();
	return newItem;
}
Example #8
0
void PlayerItem::update(float delta)
{
    auto rect = getBoundingBox();
    rect.size = Size(TILE_WIDTH,TILE_HEIGHT/2);
    auto playerRect = GameManager::getInstance()->getPlayer()->getBoundingBox();
    if(playerRect.intersectsRect(rect))
    {
        auto manager = GameManager::getInstance();
        auto data = PlayerInfoParam::create();
        data->setType(getItemType().itemType);
        switch (data->getType()) {
            case PlayerInfoParam::kTypeBomb:
                manager->setBombNum(manager->getBombNum()+1);
                data->setValue(manager->getBombNum());
                Util::playEffect(SOUND_ITEM_GET_BOMB);
                break;
            case PlayerInfoParam::kTypeCoin:
                if(getIdx()==0)
                {
                    __userDefault->setIntegerForKey(KEY_COIN_NUM, __userDefault->getIntegerForKey(KEY_COIN_NUM)+50);
                    Util::playEffect(SOUND_ITEM_GET_LITTLE_COIN);
                }else{
                    __userDefault->setIntegerForKey(KEY_COIN_NUM, __userDefault->getIntegerForKey(KEY_COIN_NUM)+100);
                    Util::playEffect(SOUND_ITEM_GET_BIG_COIN);
                }
                data->setValue(__userDefault->getIntegerForKey(KEY_COIN_NUM));
                break;
            case PlayerInfoParam::kTypeShoe:
                Util::playEffect(SOUND_ITEM_GET_SHOE);
                manager->setShoe(manager->getShoe()+1);
                data->setValue(manager->getShoe());
                
                if(_speedUp==false)
                {
                    manager->setSpeed(manager->getSpeed()*1.3f);
                    manager->getPlayer()->setSpeed(manager->getPlayer()->getSpeed()*1.3f);
                    checkShoeNum();
                }
                
                break;
            case PlayerInfoParam::kTypePower:
                Util::playEffect(SOUND_ITEM_GET_POWER);
                manager->setBombPower(manager->getBombPower()+1);
                data->setValue(manager->getBombPower());
                break;
            default:
                break;
        }
        NotificationCenter::getInstance()->postNotification(UPDATE_PLAYER_INFO,data);
        removeFromParent();
    }
}
Example #9
0
string Inventory::dropItem(string itemName)
{
	ItemType item = getItemType(itemName);

	for (int i = 0; i < TOTALSPACE; ++i)
	{
		if (items[i] == item)
		{
			items[i] = ItemType::NOITEM;
			return "Item dropped.";
		}
	}

	return "Item not found.";
}
Example #10
0
IContentItem* CRootItem::addContentItem(string text, int posInParent) throw (ExMalformedPatch)
{
	string path = stripFirstSection(text);
	CItemType itemType = getItemType(text);
	if(itemType.getType() == CItemType::E_INVAL ) {
		throw ExMalformedPatch("invalid item type", -1);
	}

	CCategoryItem* parent = getCategoryPtr(path);
	if(parent == 0) {
		parent = mkPath(path);
	}

	//beginInsertItems(posInParent, 1, parent );
	IContentItem* newItem = IContentItem::itemFactory( itemType, this, text, parent, posInParent);
	//endInsertItems();
	return newItem;
}
Example #11
0
void getItemIndices(gamestate_t gs)
{
	for(int i=gs.max_players+1; i<1024; i++)
	{
		entity_t curr_ent = gs.entities[i];
		char model_name[64];
		bool known = qbGetModelString(curr_ent.modelindex, model_name);
		if(known)
		{
			qbLog("%s", model_name);
			int type = getItemType(model_name);
			if(type >=0)			{
				item_indices.push_back(i);
				item_types.push_back(type);
			}
		}
	}
}
    BigWigSectionHeader::BigWigSectionHeader(std::stringstream& bdis){

 // get Wig Section Header

       unsigned char type;
        try {

            bdis.read( reinterpret_cast<char*>(&chromID_) , sizeof(uint32_t) );
            chromID_=endian::LittleLong(chromID_);


            bdis.read( reinterpret_cast<char*>(&chromStart_) , sizeof(uint32_t) );
            chromStart_=endian::LittleLong(chromStart_);

            bdis.read( reinterpret_cast<char*>(&chromEnd_) , sizeof(uint32_t) );
            chromEnd_=endian::LittleLong(chromEnd_);

            bdis.read( reinterpret_cast<char*>(&itemStep_) , sizeof(uint32_t) );
            itemStep_=endian::LittleLong(itemStep_);

            bdis.read( reinterpret_cast<char*>(&itemSpan_) , sizeof(uint32_t) );
            itemSpan_=endian::LittleLong(itemSpan_);

            bdis.read( reinterpret_cast<char*>(&type) , sizeof(unsigned char) );
            type=endian::LittleByte(type);

            bdis.read( reinterpret_cast<char*>(&reserved_) , sizeof(unsigned char) );
            reserved_=endian::LittleByte(reserved_);

            bdis.read( reinterpret_cast<char*>(&itemCount_) , sizeof(uint16_t) );
            itemCount_=endian::LittleShort(itemCount_);

        }catch(...) {
            throw std::runtime_error("Error reading wig section header");
        }

        // tag as valid
        isValidType_ = getItemType(type);



    }
Example #13
0
//return if the item is added or if the inventory is full
void Inventory::addItem(string itemName)
{
	ItemType item = getItemType(itemName);
	if (!(item == ItemType::NOITEM))
	{
		for (int i = 0; i < TOTALSPACE; ++i)
		{
			if (items[i] == ItemType::NOITEM)
			{
				items[i] = item;
				cout << "Item " << itemName << " added to your inventory." << endl;
				return;
			}
		}
		cout << "Item " << itemName << " couldn't be added because the inventory is full" << endl;
	}
	else 
	{
		cout << "Cannot add item " << itemName << "it's invalid" << endl;
	}
}
Example #14
0
void ThingTypeManager::parseItemType(uint16 id, TiXmlElement* elem)
{
    uint16 serverId = id;
    if(serverId > 20000 && id < 20100) {
        serverId -= 20000;

        ItemTypePtr newType(new ItemType);
        newType->setServerId(serverId);
        addItemType(newType);
    }

    ItemTypePtr itemType = getItemType(serverId);
    itemType->setName(elem->Attribute("name"));
    for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
        if(attrib->ValueStr() != "attribute")
            break;

        if(attrib->Attribute("key") == "description") {
            itemType->setDesc(attrib->Attribute("value"));
            break;
        }
    }
}
Example #15
0
void JoystickMapper::unserializeMap(string serialConf)
{
    vector<string> splitConf;
    
    splitConf = strsplit(serialConf, ',');
    
    OEInt index = 0;
    for (OEInt i = 0; i < (splitConf.size() / 4); i++)
    {
        JoystickMapperItem item;
        
        OEInt usageId = getItemUsageId(splitConf[index++]);
        
        string usageName = splitConf[index++];
        float sensitivity = getFloat(splitConf[index++]);
        bool reverse = getOEInt(splitConf[index++]);
        
        usageIdMap[usageId].usageId = getItemUsageId(usageName);
        usageIdMap[usageId].type = getItemType(usageName);
        usageIdMap[usageId].sensitivity = sensitivity;
        usageIdMap[usageId].reverse = reverse;
        usageIdMap[usageId].value = 0.5F;
    }
}
enum OpenAB_Storage::Storage::eGetItem EDSCalendarStorage::getTask(const OpenAB::PIMItem::ID & id,
                                                                OpenAB::SmartPtr<OpenAB::PIMCalendarTaskItem> & item)
{
  if (getItemType() != OpenAB::eTask)
  {
    return eGetItemFail;
  }
  GError* gerror = NULL;

  std::vector<icalcomponent*> events;
  icalcomponent* event = NULL;
  if (!e_cal_client_get_object_sync(client, id.c_str(), NULL, &event, NULL, &gerror))
  {
    LOG_ERROR() << "Error e_cal_client_get_object_sync result: " << GERROR_MESSAGE(gerror) << std::endl;
    GERROR_FREE(gerror);
    return eGetItemFail;
  }

  events.push_back(event);

  item = (OpenAB::PIMCalendarTaskItem*)EDSCalendarStorageCommon::processObject(events);

  return eGetItemOk;
}
Example #17
0
void JoystickMapper::setMap(OEInt usageId, string value)
{
    usageIdMap[usageId].type = getItemType(value);
    usageIdMap[usageId].usageId = getItemUsageId(value);
    usageIdMap[usageId].value = 0.5F;
}
/**
 * Create detailed tooltip showing all relevant item info
 */
TooltipData ItemManager::getTooltip(ItemStack stack, StatBlock *stats, int context) {
	TooltipData tip;

	if (stack.empty()) return tip;

	Color color = getItemColor(stack.item);

	// name
	std::stringstream ss;
	if (stack.quantity == 1)
		ss << getItemName(stack.item);
	else
		ss << getItemName(stack.item) << " (" << stack.quantity << ")";
	tip.addColoredText(ss.str(), color);

	// quest item
	if (items[stack.item].quest_item) {
		tip.addColoredText(msg->get("Quest Item"), font->getColor(FontEngine::COLOR_ITEM_BONUS));
	}

	// only show the name of the currency item
	if (stack.item == eset->misc.currency_id)
		return tip;

	// flavor text
	if (items[stack.item].flavor != "") {
		tip.addColoredText(Utils::substituteVarsInString(items[stack.item].flavor, pc), font->getColor(FontEngine::COLOR_ITEM_FLAVOR));
	}

	// level
	if (items[stack.item].level != 0) {
		tip.addText(msg->get("Level %d", items[stack.item].level));
	}

	// type
	if (items[stack.item].type != "") {
		tip.addText(msg->get(getItemType(items[stack.item].type)));
	}

	// item quality text for colorblind users
	if (settings->colorblind && items[stack.item].quality != "") {
		color = font->getColor(FontEngine::COLOR_WIDGET_NORMAL);
		for (size_t i=0; i<item_qualities.size(); ++i) {
			if (item_qualities[i].id == items[stack.item].quality) {
				tip.addColoredText(msg->get("Quality: %s", msg->get(item_qualities[i].name)), color);
				break;
			}
		}
	}

	// damage
	for (size_t i = 0; i < eset->damage_types.list.size(); ++i) {
		if (items[stack.item].dmg_max[i] > 0) {
			std::stringstream dmg_str;
			dmg_str << eset->damage_types.list[i].name;
			if (items[stack.item].dmg_min[i] < items[stack.item].dmg_max[i]) {
				dmg_str << ": " << items[stack.item].dmg_min[i] << "-" << items[stack.item].dmg_max[i];
				tip.addText(dmg_str.str());
			}
			else {
				dmg_str << ": " << items[stack.item].dmg_max[i];
				tip.addText(dmg_str.str());
			}
		}
	}

	// absorb
	if (items[stack.item].abs_max > 0) {
		if (items[stack.item].abs_min < items[stack.item].abs_max)
			tip.addText(msg->get("Absorb: %d-%d", items[stack.item].abs_min, items[stack.item].abs_max));
		else
			tip.addText(msg->get("Absorb: %d", items[stack.item].abs_max));
	}

	// bonuses
	unsigned bonus_counter = 0;
	while (bonus_counter < items[stack.item].bonus.size()) {
		ss.str("");

		BonusData* bdata = &items[stack.item].bonus[bonus_counter];

		if (bdata->is_speed || bdata->is_attack_speed) {
			if (bdata->value >= 100)
				color = font->getColor(FontEngine::COLOR_ITEM_BONUS);
			else
				color = font->getColor(FontEngine::COLOR_ITEM_PENALTY);
		}
		else {
			if (bdata->value > 0)
				color = font->getColor(FontEngine::COLOR_ITEM_BONUS);
			else
				color = font->getColor(FontEngine::COLOR_ITEM_PENALTY);
		}

		getBonusString(ss, bdata);
		tip.addColoredText(ss.str(), color);
		bonus_counter++;
	}

	// power
	if (items[stack.item].power_desc != "") {
		tip.addColoredText(items[stack.item].power_desc, font->getColor(FontEngine::COLOR_ITEM_BONUS));
	}

	// level requirement
	if (items[stack.item].requires_level > 0) {
		if (stats->level < items[stack.item].requires_level)
			color = font->getColor(FontEngine::COLOR_REQUIREMENTS_NOT_MET);
		else
			color = font->getColor(FontEngine::COLOR_WIDGET_NORMAL);

		tip.addColoredText(msg->get("Requires Level %d", items[stack.item].requires_level), color);
	}

	// base stat requirement
	for (unsigned i=0; i<items[stack.item].req_stat.size(); ++i) {
		if (items[stack.item].req_val[i] > 0) {
			if (stats->get_primary(items[stack.item].req_stat[i]) < items[stack.item].req_val[i])
				color = font->getColor(FontEngine::COLOR_REQUIREMENTS_NOT_MET);
			else
				color = font->getColor(FontEngine::COLOR_WIDGET_NORMAL);

			tip.addColoredText(msg->get("Requires %s %d", eset->primary_stats.list[items[stack.item].req_stat[i]].name, items[stack.item].req_val[i]), color);
		}
	}

	// requires class
	if (items[stack.item].requires_class != "") {
		if (items[stack.item].requires_class != stats->character_class)
			color = font->getColor(FontEngine::COLOR_REQUIREMENTS_NOT_MET);
		else
			color = font->getColor(FontEngine::COLOR_WIDGET_NORMAL);

		tip.addColoredText(msg->get("Requires Class: %s", msg->get(items[stack.item].requires_class)), color);
	}

	// buy or sell price
	if (items[stack.item].getPrice() > 0 && stack.item != eset->misc.currency_id) {

		int price_per_unit;
		if (context == VENDOR_BUY) {
			price_per_unit = items[stack.item].getPrice();
			if (stats->currency < price_per_unit)
				color = font->getColor(FontEngine::COLOR_REQUIREMENTS_NOT_MET);
			else
				color = font->getColor(FontEngine::COLOR_WIDGET_NORMAL);

			if (items[stack.item].max_quantity <= 1)
				tip.addColoredText(msg->get("Buy Price: %d %s", price_per_unit, eset->loot.currency), color);
			else
				tip.addColoredText(msg->get("Buy Price: %d %s each", price_per_unit, eset->loot.currency), color);
		}
		else if (context == VENDOR_SELL) {
			price_per_unit = items[stack.item].getSellPrice(stack.can_buyback);
			if (stats->currency < price_per_unit)
				color = font->getColor(FontEngine::COLOR_REQUIREMENTS_NOT_MET);
			else
				color = font->getColor(FontEngine::COLOR_WIDGET_NORMAL);

			if (items[stack.item].max_quantity <= 1)
				tip.addColoredText(msg->get("Buy Price: %d %s", price_per_unit, eset->loot.currency), color);
			else
				tip.addColoredText(msg->get("Buy Price: %d %s each", price_per_unit, eset->loot.currency), color);
		}
		else if (context == PLAYER_INV) {
			price_per_unit = items[stack.item].getSellPrice(DEFAULT_SELL_PRICE);
			if (price_per_unit == 0)
				price_per_unit = 1;

			if (items[stack.item].max_quantity <= 1)
				tip.addText(msg->get("Sell Price: %d %s", price_per_unit, eset->loot.currency));
			else
				tip.addText(msg->get("Sell Price: %d %s each", price_per_unit, eset->loot.currency));
		}
	}

	if (items[stack.item].set > 0) {
		// item set bonuses
		ItemSet set = item_sets[items[stack.item].set];
		bonus_counter = 0;

		tip.addColoredText("\n" + msg->get("Set:") + ' ' + msg->get(item_sets[items[stack.item].set].name), set.color);

		while (bonus_counter < set.bonus.size()) {
			ss.str("");

			SetBonusData* bdata = &set.bonus[bonus_counter];

			ss << msg->get("%d items:", bdata->requirement) << ' ';

			getBonusString(ss, bdata);
			tip.addColoredText(ss.str(), set.color);
			bonus_counter++;
		}
	}

	// input hint for consumables/books
	// TODO hint when not using mouse control. The action for using an item there is hard to describe
	if (context == PLAYER_INV && !settings->no_mouse) {
		int power_id = items[stack.item].power;
		if (power_id > 0 && items[stack.item].type == "consumable") {
			tip.addColoredText('\n' + msg->get("Press [%s] to use", inpt->getBindingString(Input::MAIN2)), font->getColor(FontEngine::COLOR_ITEM_BONUS));
		}
		else if (!items[stack.item].book.empty()) {
			tip.addColoredText('\n' + msg->get("Press [%s] to read", inpt->getBindingString(Input::MAIN2)), font->getColor(FontEngine::COLOR_ITEM_BONUS));
		}
	}

	return tip;
}
Example #19
0
void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
{
	if (id > 30000 && id < 30100) {
		id -= 30000;

		if (id >= items.size()) {
			items.resize(id + 1);
		}
		ItemType& iType = items[id];
		iType.id = id;
	}

	ItemType& it = getItemType(id);
	if (it.id == 0) {
		return;
	}

	it.name = itemNode.attribute("name").as_string();

	pugi::xml_attribute articleAttribute = itemNode.attribute("article");
	if (articleAttribute) {
		it.article = articleAttribute.as_string();
	}

	pugi::xml_attribute pluralAttribute = itemNode.attribute("plural");
	if (pluralAttribute) {
		it.pluralName = pluralAttribute.as_string();
	}

	for (auto attributeNode : itemNode.children()) {
		pugi::xml_attribute keyAttribute = attributeNode.attribute("key");
		if (!keyAttribute) {
			continue;
		}

		pugi::xml_attribute valueAttribute = attributeNode.attribute("value");
		if (!valueAttribute) {
			continue;
		}

		std::string tmpStrValue = asLowerCaseString(keyAttribute.as_string());
		if (tmpStrValue == "type") {
			tmpStrValue = asLowerCaseString(valueAttribute.as_string());
			if (tmpStrValue == "key") {
				it.type = ITEM_TYPE_KEY;
			} else if (tmpStrValue == "magicfield") {
				it.type = ITEM_TYPE_MAGICFIELD;
			} else if (tmpStrValue == "container") {
				it.group = ITEM_GROUP_CONTAINER;
				it.type = ITEM_TYPE_CONTAINER;
			} else if (tmpStrValue == "depot") {
				it.type = ITEM_TYPE_DEPOT;
			} else if (tmpStrValue == "mailbox") {
				it.type = ITEM_TYPE_MAILBOX;
			} else if (tmpStrValue == "trashholder") {
				it.type = ITEM_TYPE_TRASHHOLDER;
			} else if (tmpStrValue == "teleport") {
				it.type = ITEM_TYPE_TELEPORT;
			} else if (tmpStrValue == "door") {
				it.type = ITEM_TYPE_DOOR;
			} else if (tmpStrValue == "bed") {
				it.type = ITEM_TYPE_BED;
			} else if (tmpStrValue == "rune") {
				it.type = ITEM_TYPE_RUNE;
			} else {
				std::cout << "[Warning - Items::parseItemNode] Unknown type: " << valueAttribute.as_string() << std::endl;
			}
		} else if (tmpStrValue == "description") {
			it.description = valueAttribute.as_string();
		} else if (tmpStrValue == "runespellname") {
			it.runeSpellName = valueAttribute.as_string();
		} else if (tmpStrValue == "weight") {
			it.weight = pugi::cast<uint32_t>(valueAttribute.value());
		} else if (tmpStrValue == "showcount") {
			it.showCount = valueAttribute.as_bool();
		} else if (tmpStrValue == "armor") {
			it.armor = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "defense") {
			it.defense = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "extradef") {
			it.extraDefense = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "attack") {
			it.attack = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "rotateto") {
			it.rotateTo = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "moveable" || tmpStrValue == "movable") {
			it.moveable = valueAttribute.as_bool();
		} else if (tmpStrValue == "blockprojectile") {
			it.blockProjectile = valueAttribute.as_bool();
		} else if (tmpStrValue == "allowpickupable" || tmpStrValue == "pickupable") {
			it.allowPickupable = valueAttribute.as_bool();
		} else if (tmpStrValue == "floorchange") {
			tmpStrValue = asLowerCaseString(valueAttribute.as_string());
			if (tmpStrValue == "down") {
				it.floorChange = TILESTATE_FLOORCHANGE_DOWN;
			} else if (tmpStrValue == "north") {
				it.floorChange = TILESTATE_FLOORCHANGE_NORTH;
			} else if (tmpStrValue == "south") {
				it.floorChange = TILESTATE_FLOORCHANGE_SOUTH;
			} else if (tmpStrValue == "southalt") {
				it.floorChange = TILESTATE_FLOORCHANGE_SOUTH_ALT;
			} else if (tmpStrValue == "west") {
				it.floorChange = TILESTATE_FLOORCHANGE_WEST;
			} else if (tmpStrValue == "east") {
				it.floorChange = TILESTATE_FLOORCHANGE_EAST;
			} else if (tmpStrValue == "eastalt") {
				it.floorChange = TILESTATE_FLOORCHANGE_EAST_ALT;
			} else {
				std::cout << "[Warning - Items::parseItemNode] Unknown floorChange: " << valueAttribute.as_string() << std::endl;
			}
		} else if (tmpStrValue == "corpsetype") {
			tmpStrValue = asLowerCaseString(valueAttribute.as_string());
			if (tmpStrValue == "venom") {
				it.corpseType = RACE_VENOM;
			} else if (tmpStrValue == "blood") {
				it.corpseType = RACE_BLOOD;
			} else if (tmpStrValue == "undead") {
				it.corpseType = RACE_UNDEAD;
			} else if (tmpStrValue == "fire") {
				it.corpseType = RACE_FIRE;
			} else if (tmpStrValue == "energy") {
				it.corpseType = RACE_ENERGY;
			} else {
				std::cout << "[Warning - Items::parseItemNode] Unknown corpseType: " << valueAttribute.as_string() << std::endl;
			}
		} else if (tmpStrValue == "containersize") {
			it.maxItems = pugi::cast<uint16_t>(valueAttribute.value());
		} else if (tmpStrValue == "fluidsource") {
			tmpStrValue = asLowerCaseString(valueAttribute.as_string());
			if (tmpStrValue == "water") {
				it.fluidSource = FLUID_WATER;
			} else if (tmpStrValue == "blood") {
				it.fluidSource = FLUID_BLOOD;
			} else if (tmpStrValue == "beer") {
				it.fluidSource = FLUID_BEER;
			} else if (tmpStrValue == "slime") {
				it.fluidSource = FLUID_SLIME;
			} else if (tmpStrValue == "lemonade") {
				it.fluidSource = FLUID_LEMONADE;
			} else if (tmpStrValue == "milk") {
				it.fluidSource = FLUID_MILK;
			} else if (tmpStrValue == "mana") {
				it.fluidSource = FLUID_MANA;
			} else if (tmpStrValue == "life") {
				it.fluidSource = FLUID_LIFE;
			} else if (tmpStrValue == "oil") {
				it.fluidSource = FLUID_OIL;
			} else if (tmpStrValue == "urine") {
				it.fluidSource = FLUID_URINE;
			} else if (tmpStrValue == "coconut") {
				it.fluidSource = FLUID_COCONUTMILK;
			} else if (tmpStrValue == "wine") {
				it.fluidSource = FLUID_WINE;
			} else if (tmpStrValue == "mud") {
				it.fluidSource = FLUID_MUD;
			} else if (tmpStrValue == "fruitjuice") {
				it.fluidSource = FLUID_FRUITJUICE;
			} else if (tmpStrValue == "lava") {
				it.fluidSource = FLUID_LAVA;
			} else if (tmpStrValue == "rum") {
				it.fluidSource = FLUID_RUM;
			} else if (tmpStrValue == "swamp") {
				it.fluidSource = FLUID_SWAMP;
			} else if (tmpStrValue == "tea") {
				it.fluidSource = FLUID_TEA;
			} else if (tmpStrValue == "mead") {
				it.fluidSource = FLUID_MEAD;
			} else {
				std::cout << "[Warning - Items::parseItemNode] Unknown fluidSource: " << valueAttribute.as_string() << std::endl;
			}
		} else if (tmpStrValue == "readable") {
			it.canReadText = valueAttribute.as_bool();
		} else if (tmpStrValue == "writeable") {
			it.canWriteText = valueAttribute.as_bool();
			it.canReadText = it.canWriteText;
		} else if (tmpStrValue == "maxtextlen") {
			it.maxTextLen = pugi::cast<uint16_t>(valueAttribute.value());
		} else if (tmpStrValue == "writeonceitemid") {
			it.writeOnceItemId = pugi::cast<uint16_t>(valueAttribute.value());
		} else if (tmpStrValue == "weapontype") {
			tmpStrValue = asLowerCaseString(valueAttribute.as_string());
			if (tmpStrValue == "sword") {
				it.weaponType = WEAPON_SWORD;
			} else if (tmpStrValue == "club") {
				it.weaponType = WEAPON_CLUB;
			} else if (tmpStrValue == "axe") {
				it.weaponType = WEAPON_AXE;
			} else if (tmpStrValue == "shield") {
				it.weaponType = WEAPON_SHIELD;
			} else if (tmpStrValue == "distance") {
				it.weaponType = WEAPON_DISTANCE;
			} else if (tmpStrValue == "wand") {
				it.weaponType = WEAPON_WAND;
			} else if (tmpStrValue == "ammunition") {
				it.weaponType = WEAPON_AMMO;
			} else {
				std::cout << "[Warning - Items::parseItemNode] Unknown weaponType: " << valueAttribute.as_string() << std::endl;
			}
		} else if (tmpStrValue == "slottype") {
			tmpStrValue = asLowerCaseString(valueAttribute.as_string());
			if (tmpStrValue == "head") {
				it.slotPosition |= SLOTP_HEAD;
			} else if (tmpStrValue == "body") {
				it.slotPosition |= SLOTP_ARMOR;
			} else if (tmpStrValue == "legs") {
				it.slotPosition |= SLOTP_LEGS;
			} else if (tmpStrValue == "feet") {
				it.slotPosition |= SLOTP_FEET;
			} else if (tmpStrValue == "backpack") {
				it.slotPosition |= SLOTP_BACKPACK;
			} else if (tmpStrValue == "two-handed") {
				it.slotPosition |= SLOTP_TWO_HAND;
			} else if (tmpStrValue == "right-hand") {
				it.slotPosition &= ~SLOTP_LEFT;
			} else if (tmpStrValue == "left-hand") {
				it.slotPosition &= ~SLOTP_RIGHT;
			} else if (tmpStrValue == "necklace") {
				it.slotPosition |= SLOTP_NECKLACE;
			} else if (tmpStrValue == "ring") {
				it.slotPosition |= SLOTP_RING;
			} else if (tmpStrValue == "ammo") {
				it.slotPosition |= SLOTP_AMMO;
			} else if (tmpStrValue == "hand") {
				it.slotPosition |= SLOTP_HAND;
			} else {
				std::cout << "[Warning - Items::parseItemNode] Unknown slotType: " << valueAttribute.as_string() << std::endl;
			}
		} else if (tmpStrValue == "ammotype") {
			it.ammoType = getAmmoType(valueAttribute.as_string());
			if (it.ammoType == AMMO_NONE) {
				std::cout << "[Warning - Items::parseItemNode] Unknown ammoType: " << valueAttribute.as_string() << std::endl;
			}
		} else if (tmpStrValue == "shoottype") {
			ShootType_t shoot = getShootType(valueAttribute.as_string());
			if (shoot != CONST_ANI_NONE) {
				it.shootType = shoot;
			} else {
				std::cout << "[Warning - Items::parseItemNode] Unknown shootType: " << valueAttribute.as_string() << std::endl;
			}
		} else if (tmpStrValue == "effect") {
			MagicEffectClasses effect = getMagicEffect(valueAttribute.as_string());
			if (effect != CONST_ME_NONE) {
				it.magicEffect = effect;
			} else {
				std::cout << "[Warning - Items::parseItemNode] Unknown effect: " << valueAttribute.as_string() << std::endl;
			}
		} else if (tmpStrValue == "range") {
			it.shootRange = pugi::cast<uint16_t>(valueAttribute.value());
		} else if (tmpStrValue == "stopduration") {
			it.stopTime = valueAttribute.as_bool();
		} else if (tmpStrValue == "decayto") {
			it.decayTo = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "transformequipto") {
			it.transformEquipTo = pugi::cast<uint16_t>(valueAttribute.value());
		} else if (tmpStrValue == "transformdeequipto") {
			it.transformDeEquipTo = pugi::cast<uint16_t>(valueAttribute.value());
		} else if (tmpStrValue == "duration") {
			it.decayTime = pugi::cast<uint32_t>(valueAttribute.value());
		} else if (tmpStrValue == "showduration") {
			it.showDuration = valueAttribute.as_bool();
		} else if (tmpStrValue == "charges") {
			it.charges = pugi::cast<uint32_t>(valueAttribute.value());
		} else if (tmpStrValue == "showcharges") {
			it.showCharges = valueAttribute.as_bool();
		} else if (tmpStrValue == "showattributes") {
			it.showAttributes = valueAttribute.as_bool();
		} else if (tmpStrValue == "hitchance") {
			it.hitChance = std::min<int8_t>(100, std::max<int8_t>(-100, pugi::cast<int16_t>(valueAttribute.value())));
		} else if (tmpStrValue == "maxhitchance") {
			it.maxHitChance = std::min<uint32_t>(100, pugi::cast<uint32_t>(valueAttribute.value()));
		} else if (tmpStrValue == "invisible") {
			it.getAbilities().invisible = valueAttribute.as_bool();
		} else if (tmpStrValue == "speed") {
			it.getAbilities().speed = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "healthgain") {
			Abilities& abilities = it.getAbilities();
			abilities.regeneration = true;
			abilities.healthGain = pugi::cast<uint32_t>(valueAttribute.value());
		} else if (tmpStrValue == "healthticks") {
			Abilities& abilities = it.getAbilities();
			abilities.regeneration = true;
			abilities.healthTicks = pugi::cast<uint32_t>(valueAttribute.value());
		} else if (tmpStrValue == "managain") {
			Abilities& abilities = it.getAbilities();
			abilities.regeneration = true;
			abilities.manaGain = pugi::cast<uint32_t>(valueAttribute.value());
		} else if (tmpStrValue == "manaticks") {
			Abilities& abilities = it.getAbilities();
			abilities.regeneration = true;
			abilities.manaTicks = pugi::cast<uint32_t>(valueAttribute.value());
		} else if (tmpStrValue == "manashield") {
			it.getAbilities().manaShield = valueAttribute.as_bool();
		} else if (tmpStrValue == "skillsword") {
			it.getAbilities().skills[SKILL_SWORD] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "skillaxe") {
			it.getAbilities().skills[SKILL_AXE] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "skillclub") {
			it.getAbilities().skills[SKILL_CLUB] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "skilldist") {
			it.getAbilities().skills[SKILL_DISTANCE] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "skillfish") {
			it.getAbilities().skills[SKILL_FISHING] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "skillshield") {
			it.getAbilities().skills[SKILL_SHIELD] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "skillfist") {
			it.getAbilities().skills[SKILL_FIST] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "maxhitpoints") {
			it.getAbilities().stats[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "maxhitpointspercent") {
			it.getAbilities().statsPercent[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "maxmanapoints") {
			it.getAbilities().stats[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "maxmanapointspercent") {
			it.getAbilities().statsPercent[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "magicpoints" || tmpStrValue == "magiclevelpoints") {
			it.getAbilities().stats[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "magicpointspercent") {
			it.getAbilities().statsPercent[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
		} else if (tmpStrValue == "fieldabsorbpercentenergy") {
			it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "fieldabsorbpercentfire") {
			it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "fieldabsorbpercentpoison" || tmpStrValue == "fieldabsorpercentearth") {
			it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "absorbpercentall" || tmpStrValue == "absorbpercentallelements") {
			int16_t value = pugi::cast<int16_t>(valueAttribute.value());
			Abilities& abilities = it.getAbilities();
			for (size_t i = 0; i < COMBAT_COUNT; ++i) {
				abilities.absorbPercent[i] += value;
			}
		} else if (tmpStrValue == "absorbpercentelements") {
			int16_t value = pugi::cast<int16_t>(valueAttribute.value());
			Abilities& abilities = it.getAbilities();
			abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
			abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
			abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
		} else if (tmpStrValue == "absorbpercentmagic") {
			int16_t value = pugi::cast<int16_t>(valueAttribute.value());
			Abilities& abilities = it.getAbilities();
			abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
			abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
			abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
		} else if (tmpStrValue == "absorbpercentenergy") {
			it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "absorbpercentfire") {
			it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "absorbpercentpoison" ||	tmpStrValue == "absorbpercentearth") {
			it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "absorbpercentlifedrain") {
			it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "absorbpercentmanadrain") {
			it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "absorbpercentdrown") {
			it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "absorbpercentphysical") {
			it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "absorbpercenthealing") {
			it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "absorbpercentundefined") {
			it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
		} else if (tmpStrValue == "suppressdrunk") {
			if (valueAttribute.as_bool()) {
				it.getAbilities().conditionSuppressions |= CONDITION_DRUNK;
			}
		} else if (tmpStrValue == "suppressenergy") {
			if (valueAttribute.as_bool()) {
				it.getAbilities().conditionSuppressions |= CONDITION_ENERGY;
			}
		} else if (tmpStrValue == "suppressfire") {
			if (valueAttribute.as_bool()) {
				it.getAbilities().conditionSuppressions |= CONDITION_FIRE;
			}
		} else if (tmpStrValue == "suppresspoison") {
			if (valueAttribute.as_bool()) {
				it.getAbilities().conditionSuppressions |= CONDITION_POISON;
			}
		} else if (tmpStrValue == "suppressdrown") {
			if (valueAttribute.as_bool()) {
				it.getAbilities().conditionSuppressions |= CONDITION_DROWN;
			}
		} else if (tmpStrValue == "suppressphysical") {
			if (valueAttribute.as_bool()) {
				it.getAbilities().conditionSuppressions |= CONDITION_BLEEDING;
			}
		} else if (tmpStrValue == "field") {
			it.group = ITEM_GROUP_MAGICFIELD;
			it.type = ITEM_TYPE_MAGICFIELD;

			CombatType_t combatType = COMBAT_NONE;
			ConditionDamage* conditionDamage = nullptr;

			tmpStrValue = asLowerCaseString(valueAttribute.as_string());
			if (tmpStrValue == "fire") {
				conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_FIRE);
				combatType = COMBAT_FIREDAMAGE;
			} else if (tmpStrValue == "energy") {
				conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_ENERGY);
				combatType = COMBAT_ENERGYDAMAGE;
			} else if (tmpStrValue == "poison") {
				conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_POISON);
				combatType = COMBAT_EARTHDAMAGE;
			} else if (tmpStrValue == "drown") {
				conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_DROWN);
				combatType = COMBAT_DROWNDAMAGE;
			} else if (tmpStrValue == "physical") {
				conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_BLEEDING);
				combatType = COMBAT_PHYSICALDAMAGE;
			} else {
				std::cout << "[Warning - Items::parseItemNode] Unknown field value: " << valueAttribute.as_string() << std::endl;
			}

			if (combatType != COMBAT_NONE) {
				it.combatType = combatType;
				it.conditionDamage.reset(conditionDamage);
				uint32_t ticks = 0;
				int32_t damage = 0;
				int32_t start = 0;
				int32_t count = 1;

				for (auto subAttributeNode : attributeNode.children()) {
					pugi::xml_attribute subKeyAttribute = subAttributeNode.attribute("key");
					if (!subKeyAttribute) {
						continue;
					}

					pugi::xml_attribute subValueAttribute = subAttributeNode.attribute("value");
					if (!subValueAttribute) {
						continue;
					}

					tmpStrValue = asLowerCaseString(subKeyAttribute.as_string());
					if (tmpStrValue == "ticks") {
						ticks = pugi::cast<uint32_t>(subValueAttribute.value());
					} else if (tmpStrValue == "count") {
						count = std::max<int32_t>(1, pugi::cast<int32_t>(subValueAttribute.value()));
					} else if (tmpStrValue == "start") {
						start = std::max<int32_t>(0, pugi::cast<int32_t>(subValueAttribute.value()));
					} else if (tmpStrValue == "damage") {
						damage = -pugi::cast<int32_t>(subValueAttribute.value());

						if (start > 0) {
							std::list<int32_t> damageList;
							ConditionDamage::generateDamageList(damage, start, damageList);
							for (int32_t damageValue : damageList) {
								conditionDamage->addDamage(1, ticks, -damageValue);
							}

							start = 0;
						} else {
							conditionDamage->addDamage(count, ticks, damage);
						}
					}
				}

				conditionDamage->setParam(CONDITION_PARAM_FIELD, 1);

				if (conditionDamage->getTotalDamage() > 0) {
					conditionDamage->setParam(CONDITION_PARAM_FORCEUPDATE, 1);
				}
			}
		} else if (tmpStrValue == "replaceable") {
			it.replaceable = valueAttribute.as_bool();
		} else if (tmpStrValue == "partnerdirection") {
			it.bedPartnerDir = getDirection(valueAttribute.as_string());
		} else if (tmpStrValue == "leveldoor") {
			it.levelDoor = pugi::cast<uint32_t>(valueAttribute.value());
		} else if (tmpStrValue == "maletransformto" || tmpStrValue == "malesleeper") {
			uint16_t value = pugi::cast<uint16_t>(valueAttribute.value());
			it.transformToOnUse[PLAYERSEX_MALE] = value;
			ItemType& other = getItemType(value);
			if (other.transformToFree == 0) {
				other.transformToFree = it.id;
			}

			if (it.transformToOnUse[PLAYERSEX_FEMALE] == 0) {
				it.transformToOnUse[PLAYERSEX_FEMALE] = value;
			}
		} else if (tmpStrValue == "femaletransformto" || tmpStrValue == "femalesleeper") {
			uint16_t value = pugi::cast<uint16_t>(valueAttribute.value());
			it.transformToOnUse[PLAYERSEX_FEMALE] = value;

			ItemType& other = getItemType(value);
			if (other.transformToFree == 0) {
				other.transformToFree = it.id;
			}

			if (it.transformToOnUse[PLAYERSEX_MALE] == 0) {
				it.transformToOnUse[PLAYERSEX_MALE] = value;
			}
		} else if (tmpStrValue == "transformto") {
			it.transformToFree = pugi::cast<uint16_t>(valueAttribute.value());
		} else if (tmpStrValue == "destroyto") {
			it.destroyTo = pugi::cast<uint16_t>(valueAttribute.value());
		} else if (tmpStrValue == "elementearth") {
			Abilities& abilities = it.getAbilities();
			abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
			abilities.elementType = COMBAT_EARTHDAMAGE;
		} else if (tmpStrValue == "elementfire") {
			Abilities& abilities = it.getAbilities();
			abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
			abilities.elementType = COMBAT_FIREDAMAGE;
		} else if (tmpStrValue == "elementenergy") {
			Abilities& abilities = it.getAbilities();
			abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
			abilities.elementType = COMBAT_ENERGYDAMAGE;
		} else if (tmpStrValue == "walkstack") {
			it.walkStack = valueAttribute.as_bool();
		} else if (tmpStrValue == "blocking") {
			it.blockSolid = valueAttribute.as_bool();
		} else if (tmpStrValue == "allowdistread") {
			it.allowDistRead = booleanString(valueAttribute.as_string());
		} else {
			std::cout << "[Warning - Items::parseItemNode] Unknown key value: " << keyAttribute.as_string() << std::endl;
		}
	}

	//check bed items
	if ((it.transformToFree != 0 || it.transformToOnUse[PLAYERSEX_FEMALE] != 0 || it.transformToOnUse[PLAYERSEX_MALE] != 0) && it.type != ITEM_TYPE_BED) {
		std::cout << "[Warning - Items::parseItemNode] Item " << it.id << " is not set as a bed-type" << std::endl;
	}
}
enum OpenAB_Storage::Storage::eInit EDSCalendarStorage::init()
{
  LOG_FUNC() << "DB: " << database<<std::endl;

  GError *gerror = NULL;

  // 1. Get access to all databases in EDS.
  registry = e_source_registry_new_sync(NULL, &gerror);
  if (!registry)
  {
    LOG_ERROR() << "e_source_registry not found " << GERROR_MESSAGE(gerror)<<std::endl;
    GERROR_FREE(gerror);
    return eInitFail;
  }

  // 2. Look up one particular database.
  // special use case - "system" db - use system storage
  std::string dbName = database;
  if (dbName == "system")
  {
    if (OpenAB::eEvent == getItemType())
    {
      source = e_source_registry_ref_default_calendar(registry);
    }
    else if (OpenAB::eTask == getItemType())
    {
      source = e_source_registry_ref_default_task_list(registry);
    }
  }
  else
  {
    source = e_source_registry_ref_source(registry, dbName.c_str());
  }

  if (!source)
  {
    LOG_ERROR() << "e_source not found"<<std::endl;
    GERROR_FREE(gerror);
    return eInitFail;
  }

  GERROR_FREE(gerror);

  const gchar *userDataDir = NULL;
  userDataDir = e_get_user_data_dir();
  gchar* dirname = NULL;

  if (OpenAB::eEvent == getItemType())
  {
    client = (ECalClient *) e_cal_client_connect_sync(source, E_CAL_CLIENT_SOURCE_TYPE_EVENTS, NULL, &gerror);
    dirname = g_build_filename(userDataDir, "calendar", dbName.c_str(), "calendar.ics", NULL);

  }
  else
  {
    client = (ECalClient *) e_cal_client_connect_sync(source, E_CAL_CLIENT_SOURCE_TYPE_TASKS, NULL, &gerror);
    dirname = g_build_filename(userDataDir, "tasks", dbName.c_str(), "tasks.ics", NULL);
  }

  databaseFileName = dirname;
  g_free(dirname);

  if (gerror)
  {
    LOG_ERROR() << "Error e_cal_client_connect_sync results: " << GERROR_MESSAGE(gerror)<<std::endl;
    GERROR_FREE(gerror);
    return eInitFail;
  }
  LOG_VERBOSE() << "e_cal_client_connect_sync\n"<<std::endl;

  return eInitOk;
}
Example #21
0
void CSeparate::SetItem( CItem* pItem )
{
	assert( pItem );
	tagITEM& Item = pItem->GetItem();
/*
	int a = CSeparateDlg::GetInstance()->m_OutputItemSlots.size();
	// 초기화를 안해줬더니;; 쓰레기값이 4개가 더 들어있어서 나중에 빈 슬롯 계산할때 삑 난다;;
//	CSeparateDlg::GetInstance()->OutputItemSlotClear(); 
	int c = CSeparateDlg::GetInstance()->m_OutputItemSlots.size();	
*/
	m_iType = TYPE_NONE;

	if( !Item.IsEnableSeparate() )
	{
		g_itMGR.OpenMsgBox(STR_ITEM_CANT_SEPARATED);
		return;
	}

	if( Item.HasSocket() && Item.GetGemNO() > 300 )
		return;

#ifdef _NEWBREAK
	else if( ITEM_DECOMPOSITION_NUMBER( Item.GetTYPE(), Item.GetItemNO() ) )
#else
	else if( ITEM_PRODUCT_IDX( Item.GetTYPE(), Item.GetItemNO() ) )
#endif
		m_iType = TYPE_DECOMPOSITION;
	else
	{
		assert( 0 && "Invalid Separate Type" );
		return;
	}

	if( m_pMaterialItem )
		RemoveItem();

	m_pMaterialItem = new CItemFragment( pItem );	
	
	if( Item.IsEnableDupCNT() )
		m_pMaterialItem->SetQuantity( 1 );

	m_Event.SetID( CTEventSeparate::EID_SET_MATERIAL_ITEM );
	m_Event.SetItem( m_pMaterialItem );
	SetChanged();
	NotifyObservers( &m_Event );

	m_iRequireMoney = Item.GetSeparateCost();

	switch( m_iType )
	{
	case TYPE_SEPARATE:
		{
			tagITEM MainMaterialItem;		

			MainMaterialItem.Init(  setItemFullNo( pItem->GetType(), pItem->GetItemNo() ) );

			CItem* pMainMaterialItem = new CItem;
			pMainMaterialItem->SetItem( MainMaterialItem );
			m_pItems.push_back( pMainMaterialItem );

			m_Event.SetID( CTEventSeparate::EID_SET_OUTPUT_ITEM );
			m_Event.SetIndex( 0 );
			m_Event.SetItem( pMainMaterialItem );
			SetChanged(); 
			NotifyObservers( &m_Event );


			tagITEM GemItem;
			GemItem.Init( setItemFullNo( ITEM_TYPE_GEM, Item.GetGemNO() ) );
			CItem* pGemItem	 = new CItem;
			pGemItem->SetItem( GemItem );
			m_pItems.push_back( pGemItem );

			m_Event.SetID( CTEventSeparate::EID_SET_OUTPUT_ITEM );
			m_Event.SetIndex( 1 );
			m_Event.SetItem( pGemItem );
			SetChanged();
			NotifyObservers( &m_Event);

			m_iRequireMp = ITEM_QUALITY( MainMaterialItem.GetTYPE(), MainMaterialItem.GetItemNO() ) / 2 +
				ITEM_QUALITY( GemItem.GetTYPE(), GemItem.GetItemNO() );

			break;
		}
	case TYPE_DECOMPOSITION:
		{
	//05.11.03 - 김주현 : 분해 관련 새로운 시스템.
	#if defined ( _NEWBREAK )

			m_iNumMat = 1;
			tagITEM MaterialItem;
			CItem*  pMaterialItem = NULL;

			int iCompositionIdx = ITEM_DECOMPOSITION_NUMBER( Item.GetTYPE(), Item.GetItemNO() );
			//PY temporary fix for items that point off the end of the break list
			if(iCompositionIdx > 2028) iCompositionIdx = 2028; //There are currently only 2028 entries in LIST_BREAK.STB and some items point to 2300 +
			if( int iRawMaterial = ITEM_BREAK_POTISION( iCompositionIdx ) )
			{

				int iOriQual = ITEM_QUALITY( Item.GetTYPE(), Item.GetItemNO() );

				if( getItemType( iRawMaterial ) )
				{
					MaterialItem.Init( iRawMaterial );
				}
				else
				{
					int iTemp    = ( iOriQual - 20 ) / 12;

					if( iTemp < 1 ) 	iTemp = 1;
					if( iTemp > 10 )	iTemp = 10;

					int iItemNo = ( iRawMaterial - 421 ) * 10 + iTemp;

					assert( iItemNo >= 1 && iItemNo <= g_TblNATUAL.m_nDataCnt );
					if( iItemNo < 0 || iItemNo > g_TblNATUAL.m_nDataCnt )
						return;

					MaterialItem.Init( setItemFullNo( ITEM_TYPE_NATURAL, iItemNo ) );
				}

				if( MaterialItem.IsEnableDupCNT() )
					MaterialItem.m_uiQuantity = ITEM_BREAK_NEED_CNT( iCompositionIdx, 0 );


				pMaterialItem = new CItem;
				pMaterialItem->SetItem( MaterialItem );
	


				m_pItems.push_back( pMaterialItem );
				m_Event.SetID( CTEventSeparate::EID_SET_OUTPUT_ITEM );
				m_Event.SetIndex( 0 );
				m_Event.SetItem( pMaterialItem );
				SetChanged(); 
				NotifyObservers( &m_Event );

				int iMaterialIdx  = 0 ;
				int iClass = 0;
				int iIndex = 0;

				for( int i = 1 ; i < 4; ++i )
				{
					if( iMaterialIdx = ITEM_BREAK_COUNT( iCompositionIdx, i ) )
					{
						MaterialItem.Init( iMaterialIdx );
						if( MaterialItem.IsEnableDupCNT() )
							MaterialItem.m_uiQuantity = ITEM_BREAK_NEED_CNT( iCompositionIdx, i);

						pMaterialItem = new CItem;
						pMaterialItem->SetItem( MaterialItem );
						m_pItems.push_back( pMaterialItem );						
						++iIndex;
						
						m_Event.SetID( CTEventSeparate::EID_SET_OUTPUT_ITEM );
						m_Event.SetIndex( iIndex );
						m_Event.SetItem( pMaterialItem );
						SetChanged(); 
						NotifyObservers( &m_Event );
						++m_iNumMat;

					}
				}

				m_iRequireMp = iOriQual + 30;


#else
		
			tagITEM MaterialItem;
			CItem*  pMaterialItem = NULL;
			int iProductIdx = ITEM_PRODUCT_IDX( Item.GetTYPE(), Item.GetItemNO() );
			if( int iRawMaterial = PRODUCT_RAW_MATERIAL( iProductIdx ) )
			{
				int iOriQual = ITEM_QUALITY( Item.GetTYPE(), Item.GetItemNO() );
	
				if( getItemType( iRawMaterial ) )
				{
					MaterialItem.Init( iRawMaterial );
				}
				else
				{
					int iTemp    = ( iOriQual - 20 ) / 12;

					if( iTemp < 1 ) 	iTemp = 1;
					if( iTemp > 10 )	iTemp = 10;

					int iItemNo = ( iRawMaterial - 421 ) * 10 + iTemp;

					assert( iItemNo >= 1 && iItemNo <= g_TblNATUAL.m_nDataCnt );
					if( iItemNo < 0 || iItemNo > g_TblNATUAL.m_nDataCnt )
						return;

					MaterialItem.Init( setItemFullNo( ITEM_TYPE_NATURAL, iItemNo ) );
				}

				if( MaterialItem.IsEnableDupCNT() )
					MaterialItem.m_uiQuantity = GetQuantity( Item, PRODUCT_NEED_ITEM_CNT( iProductIdx, 0 ) );


				pMaterialItem = new CItem;
				pMaterialItem->SetItem( MaterialItem );	

				m_pItems.push_back( pMaterialItem );
				m_Event.SetID( CTEventSeparate::EID_SET_OUTPUT_ITEM );
				m_Event.SetIndex( 0 );
				m_Event.SetItem( pMaterialItem );
				SetChanged(); 
				NotifyObservers( &m_Event );

				int iMaterialIdx  = 0 ;
				int iClass = 0;
				int iIndex = 0;
				for( int i = 1 ; i < 4; ++i )
				{
					if( iMaterialIdx = PRODUCT_NEED_ITEM_NO( iProductIdx, i ) )
					{
						MaterialItem.Init( iMaterialIdx );
						if( MaterialItem.IsEnableDupCNT() )
							MaterialItem.m_uiQuantity = GetQuantity( Item, PRODUCT_NEED_ITEM_CNT( iProductIdx, i) );

						pMaterialItem = new CItem;
						pMaterialItem->SetItem( MaterialItem );
						m_pItems.push_back( pMaterialItem );						
						++iIndex;
						
						m_Event.SetID( CTEventSeparate::EID_SET_OUTPUT_ITEM );
						m_Event.SetIndex( iIndex );
						m_Event.SetItem( pMaterialItem );
						SetChanged(); 
						NotifyObservers( &m_Event );
					}
				}

				m_iRequireMp = iOriQual + 30;
			///		

#endif
			}
		break;
	}
	default:
		break;
	}
}

void CSeparate::Update( CObservable* pObservable, CTObject* pObj )
{
	assert( pObservable );
	assert( pObj );

	if( m_pMaterialItem && pObj && strcmp( pObj->toString(), "CTEventItem") == 0  )
	{
		CTEventItem* pEvent = (CTEventItem*)pObj;
		int iIndex = pEvent->GetIndex();
		if( pEvent->GetID() == CTEventItem::EID_DEL_ITEM || 
			pEvent->GetID() == CTEventItem::EID_CHANGE_ITEM )
		{

			if( iIndex == m_pMaterialItem->GetIndex() )
			{
				m_bWaitServerReply = false;

				m_Event.SetID( CTEventSeparate::EID_REMOVE_MATERIAL_ITEM );
				SetChanged();
				NotifyObservers( &m_Event );
				delete m_pMaterialItem;
				m_pMaterialItem = NULL;

				std::vector< CItem* >::iterator iter;
				int iIndex = 0;
				for( iter = m_pItems.begin(); iter != m_pItems.end(); ++iIndex )
				{
					m_Event.SetID( CTEventSeparate::EID_REMOVE_OUTPUT_ITEM );
					m_Event.SetIndex( iIndex );
					SetChanged();
					NotifyObservers( &m_Event );

					delete *iter;
					iter = m_pItems.erase( iter );
				}
			}
		}
	}
}
Example #22
0
bool ItemDatabase::loadItemFromGameXml(pugi::xml_node itemNode, int id)
{
	ClientVersionID clientVersion = gui.GetCurrentVersionID();
	if(clientVersion < CLIENT_VERSION_980 && id > 20000 && id < 20100) {
		itemNode = itemNode.next_sibling();
		return true;
	} else if(id > 30000 && id < 30100) {
		itemNode = itemNode.next_sibling();
		return true;
	}

	ItemType& it = getItemType(id);

	it.name = itemNode.attribute("name").as_string();
	it.editorsuffix = itemNode.attribute("editorsuffix").as_string();

	pugi::xml_attribute attribute;
	for(pugi::xml_node itemAttributesNode = itemNode.first_child(); itemAttributesNode; itemAttributesNode = itemAttributesNode.next_sibling()) {
		if(!(attribute = itemAttributesNode.attribute("key"))) {
			continue;
		}

		std::string key = attribute.as_string();
		to_lower_str(key);
		if(key == "type") {
			if(!(attribute = itemAttributesNode.attribute("value"))) {
				continue;
			}

			std::string typeValue = attribute.as_string();
			to_lower_str(key);
			if(typeValue == "magicfield") {
				it.group = ITEM_GROUP_MAGICFIELD;
				it.type = ITEM_TYPE_MAGICFIELD;
			} else if(typeValue == "key") {
				it.type = ITEM_TYPE_KEY;
			} else if(typeValue == "depot") {
				it.type = ITEM_TYPE_DEPOT;
			} else if(typeValue == "teleport") {
				it.type = ITEM_TYPE_TELEPORT;
			} else if(typeValue == "bed") {
				it.type = ITEM_TYPE_BED;
			} else if(typeValue == "door") {
				it.type = ITEM_TYPE_DOOR;
			} else {
				// We ignore many types, no need to complain
				//warnings.push_back("items.xml: Unknown type " + typeValue);
			}
		} else if(key == "name") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.name = attribute.as_string();
			}
		} else if(key == "description") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.description = attribute.as_string();
			}
		}else if(key == "runespellName") {
			/*if((attribute = itemAttributesNode.attribute("value"))) {
				it.runeSpellName = attribute.as_string();
			}*/
		} else if(key == "weight") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.weight = pugi::cast<int32_t>(attribute.value()) / 100.f;
			}
		} else if(key == "armor") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.armor = pugi::cast<int32_t>(attribute.value());
			}
		} else if(key == "defense") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.defense = pugi::cast<int32_t>(attribute.value());
			}
		} else if(key == "rotateto") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.rotateTo = pugi::cast<int32_t>(attribute.value());
			}
		} else if(key == "containersize") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.volume = pugi::cast<int32_t>(attribute.value());
			}
		} else if(key == "readable") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.canReadText = attribute.as_bool();
			}
		} else if(key == "writeable") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.canWriteText = it.canReadText = attribute.as_bool();
			}
		} else if(key == "decayto") {
			it.decays = true;
		} else if(key == "maxtextlen" || key == "maxtextlength") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.maxTextLen = pugi::cast<int32_t>(attribute.value());
				it.canReadText = it.maxTextLen > 0;
			}
		} else if(key == "writeonceitemid") {
			/*if((attribute = itemAttributesNode.attribute("value"))) {
				it.writeOnceItemId = pugi::cast<int32_t>(attribute.value());
			}*/
		} else if(key == "allowdistread") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.allowDistRead = attribute.as_bool();
			}
		} else if(key == "charges") {
			if((attribute = itemAttributesNode.attribute("value"))) {
				it.charges = pugi::cast<int32_t>(attribute.value());
				it.extra_chargeable = true;
			}
		}
	}
	return true;
}
Example #23
0
void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
{
	if (id > 30000 && id < 30100) {
		id -= 30000;

		if (id >= items.size()) {
			items.resize(id + 1);
		}
		ItemType& iType = items[id];
		iType.id = id;
	}

	ItemType& it = getItemType(id);
	if (it.id == 0) {
		return;
	}

	it.name = itemNode.attribute("name").as_string();

	nameToItems.insert({ asLowerCaseString(it.name), id });

	pugi::xml_attribute articleAttribute = itemNode.attribute("article");
	if (articleAttribute) {
		it.article = articleAttribute.as_string();
	}

	pugi::xml_attribute pluralAttribute = itemNode.attribute("plural");
	if (pluralAttribute) {
		it.pluralName = pluralAttribute.as_string();
	}

	Abilities& abilities = it.getAbilities();

	for (auto attributeNode : itemNode.children()) {
		pugi::xml_attribute keyAttribute = attributeNode.attribute("key");
		if (!keyAttribute) {
			continue;
		}

		pugi::xml_attribute valueAttribute = attributeNode.attribute("value");
		if (!valueAttribute) {
			continue;
		}

		std::string tmpStrValue = asLowerCaseString(keyAttribute.as_string());
		auto parseAttribute = ItemParseAttributesMap.find(tmpStrValue);
		if (parseAttribute != ItemParseAttributesMap.end()) {
			ItemParseAttributes_t parseType = parseAttribute->second;
			switch (parseType) {
				case ITEM_PARSE_TYPE: {
					tmpStrValue = asLowerCaseString(valueAttribute.as_string());
					auto it2 = ItemTypesMap.find(tmpStrValue);
					if (it2 != ItemTypesMap.end()) {
						it.type = it2->second;
						if (it.type == ITEM_TYPE_CONTAINER) {
							it.group = ITEM_GROUP_CONTAINER;
						}
					} else {
						std::cout << "[Warning - Items::parseItemNode] Unknown type: " << valueAttribute.as_string() << std::endl;
					}
					break;
				}

				case ITEM_PARSE_DESCRIPTION: {
					it.description = valueAttribute.as_string();
					break;
				}

				case ITEM_PARSE_RUNESPELLNAME: {
					it.runeSpellName = valueAttribute.as_string();
					break;
				}

				case ITEM_PARSE_WEIGHT: {
					it.weight = pugi::cast<uint32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SHOWCOUNT: {
					it.showCount = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_ARMOR: {
					it.armor = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_DEFENSE: {
					it.defense = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_EXTRADEF: {
					it.extraDefense = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ATTACK: {
					it.attack = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ROTATETO: {
					it.rotateTo = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MOVEABLE: {
					it.moveable = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_BLOCKPROJECTILE: {
					it.blockProjectile = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_PICKUPABLE: {
					it.allowPickupable = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_FORCESERIALIZE: {
					it.forceSerialize = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_FLOORCHANGE: {
					tmpStrValue = asLowerCaseString(valueAttribute.as_string());
					auto it2 = TileStatesMap.find(tmpStrValue);
					if (it2 != TileStatesMap.end()) {
						it.floorChange = it2->second;
					} else {
						std::cout << "[Warning - Items::parseItemNode] Unknown floorChange: " << valueAttribute.as_string() << std::endl;
					}
					break;
				}

				case ITEM_PARSE_CORPSETYPE: {
					tmpStrValue = asLowerCaseString(valueAttribute.as_string());
					auto it2 = RaceTypesMap.find(tmpStrValue);
					if (it2 != RaceTypesMap.end()) {
						it.corpseType = it2->second; 
					} else {
						std::cout << "[Warning - Items::parseItemNode] Unknown corpseType: " << valueAttribute.as_string() << std::endl;
					}
					break;
				}

				case ITEM_PARSE_CONTAINERSIZE: {
					it.maxItems = pugi::cast<uint16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_FLUIDSOURCE: {
					tmpStrValue = asLowerCaseString(valueAttribute.as_string());
					auto it2 = FluidTypesMap.find(tmpStrValue);
					if (it2 != FluidTypesMap.end()) {
						it.fluidSource = it2->second;
					} else {
						std::cout << "[Warning - Items::parseItemNode] Unknown fluidSource: " << valueAttribute.as_string() << std::endl;
					}
					break;
				}

				case ITEM_PARSE_READABLE: {
					it.canReadText = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_WRITEABLE: {
					it.canWriteText = valueAttribute.as_bool();
					it.canReadText = it.canWriteText;
					break;
				}

				case ITEM_PARSE_MAXTEXTLEN: {
					it.maxTextLen = pugi::cast<uint16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_WRITEONCEITEMID: {
					it.writeOnceItemId = pugi::cast<uint16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_WEAPONTYPE: {
					tmpStrValue = asLowerCaseString(valueAttribute.as_string());
					auto it2 = WeaponTypesMap.find(tmpStrValue);
					if (it2 != WeaponTypesMap.end()) {
						it.weaponType = it2->second;
					} else {
						std::cout << "[Warning - Items::parseItemNode] Unknown weaponType: " << valueAttribute.as_string() << std::endl;
					}
					break;
				}

				case ITEM_PARSE_SLOTTYPE: {
					tmpStrValue = asLowerCaseString(valueAttribute.as_string());
					if (tmpStrValue == "head") {
						it.slotPosition |= SLOTP_HEAD;
					} else if (tmpStrValue == "body") {
						it.slotPosition |= SLOTP_ARMOR;
					} else if (tmpStrValue == "legs") {
						it.slotPosition |= SLOTP_LEGS;
					} else if (tmpStrValue == "feet") {
						it.slotPosition |= SLOTP_FEET;
					} else if (tmpStrValue == "backpack") {
						it.slotPosition |= SLOTP_BACKPACK;
					} else if (tmpStrValue == "two-handed") {
						it.slotPosition |= SLOTP_TWO_HAND;
					} else if (tmpStrValue == "right-hand") {
						it.slotPosition &= ~SLOTP_LEFT;
					} else if (tmpStrValue == "left-hand") {
						it.slotPosition &= ~SLOTP_RIGHT;
					} else if (tmpStrValue == "necklace") {
						it.slotPosition |= SLOTP_NECKLACE;
					} else if (tmpStrValue == "ring") {
						it.slotPosition |= SLOTP_RING;
					} else if (tmpStrValue == "ammo") {
						it.slotPosition |= SLOTP_AMMO;
					} else if (tmpStrValue == "hand") {
						it.slotPosition |= SLOTP_HAND;
					} else {
						std::cout << "[Warning - Items::parseItemNode] Unknown slotType: " << valueAttribute.as_string() << std::endl;
					}
					break;
				}

				case ITEM_PARSE_AMMOTYPE: {
					it.ammoType = getAmmoType(asLowerCaseString(valueAttribute.as_string()));
					if (it.ammoType == AMMO_NONE) {
						std::cout << "[Warning - Items::parseItemNode] Unknown ammoType: " << valueAttribute.as_string() << std::endl;
					}
					break;
				}

				case ITEM_PARSE_SHOOTTYPE: {
					ShootType_t shoot = getShootType(asLowerCaseString(valueAttribute.as_string()));
					if (shoot != CONST_ANI_NONE) {
						it.shootType = shoot;
					} else {
						std::cout << "[Warning - Items::parseItemNode] Unknown shootType: " << valueAttribute.as_string() << std::endl;
					}
					break;
				}

				case ITEM_PARSE_EFFECT: {
					MagicEffectClasses effect = getMagicEffect(asLowerCaseString(valueAttribute.as_string()));
					if (effect != CONST_ME_NONE) {
						it.magicEffect = effect;
					} else {
						std::cout << "[Warning - Items::parseItemNode] Unknown effect: " << valueAttribute.as_string() << std::endl;
					}
					break;
				}

				case ITEM_PARSE_RANGE: {
					it.shootRange = pugi::cast<uint16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_STOPDURATION: {
					it.stopTime = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_DECAYTO: {
					it.decayTo = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_TRANSFORMEQUIPTO: {
					it.transformEquipTo = pugi::cast<uint16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_TRANSFORMDEEQUIPTO: {
					it.transformDeEquipTo = pugi::cast<uint16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_DURATION: {
					it.decayTime = pugi::cast<uint32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SHOWDURATION: {
					it.showDuration = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_CHARGES: {
					it.charges = pugi::cast<uint32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SHOWCHARGES: {
					it.showCharges = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_SHOWATTRIBUTES: {
					it.showAttributes = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_HITCHANCE: {
					it.hitChance = std::min<int8_t>(100, std::max<int8_t>(-100, pugi::cast<int16_t>(valueAttribute.value())));
					break;
				}

				case ITEM_PARSE_MAXHITCHANCE: {
					it.maxHitChance = std::min<uint32_t>(100, pugi::cast<uint32_t>(valueAttribute.value()));
					break;
				}

				case ITEM_PARSE_INVISIBLE: {
					abilities.invisible = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_SPEED: {
					abilities.speed = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_HEALTHGAIN: {
					abilities.regeneration = true;
					abilities.healthGain = pugi::cast<uint32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_HEALTHTICKS: {
					abilities.regeneration = true;
					abilities.healthTicks = pugi::cast<uint32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MANAGAIN: {
					abilities.regeneration = true;
					abilities.manaGain = pugi::cast<uint32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MANATICKS: {
					abilities.regeneration = true;
					abilities.manaTicks = pugi::cast<uint32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MANASHIELD: {
					abilities.manaShield = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_SKILLSWORD: {
					abilities.skills[SKILL_SWORD] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SKILLAXE: {
					abilities.skills[SKILL_AXE] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SKILLCLUB: {
					abilities.skills[SKILL_CLUB] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SKILLDIST: {
					abilities.skills[SKILL_DISTANCE] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SKILLFISH: {
					abilities.skills[SKILL_FISHING] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SKILLSHIELD: {
					abilities.skills[SKILL_SHIELD] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SKILLFIST: {
					abilities.skills[SKILL_FIST] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MAXHITPOINTS: {
					abilities.stats[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MAXHITPOINTSPERCENT: {
					abilities.statsPercent[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MAXMANAPOINTS: {
					abilities.stats[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MAXMANAPOINTSPERCENT: {
					abilities.statsPercent[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MAGICPOINTS: {
					abilities.stats[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MAGICPOINTSPERCENT: {
					abilities.statsPercent[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_FIELDABSORBPERCENTENERGY: {
					abilities.fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_FIELDABSORBPERCENTFIRE: {
					abilities.fieldAbsorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_FIELDABSORBPERCENTPOISON: {
					abilities.fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTALL: {
					int16_t value = pugi::cast<int16_t>(valueAttribute.value());
					for (auto& i : abilities.absorbPercent) {
						i += value;
					}
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTELEMENTS: {
					int16_t value = pugi::cast<int16_t>(valueAttribute.value());
					abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
					abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
					abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
					abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value;
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTMAGIC: {
					int16_t value = pugi::cast<int16_t>(valueAttribute.value());
					abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
					abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
					abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
					abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value;
					abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += value;
					abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += value;
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTENERGY: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTFIRE: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTPOISON: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTICE: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTHOLY: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTDEATH: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTLIFEDRAIN: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTMANADRAIN: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTDROWN: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTPHYSICAL: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTHEALING: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ABSORBPERCENTUNDEFINED: {
					abilities.absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_SUPPRESSDRUNK: {
					if (valueAttribute.as_bool()) {
						abilities.conditionSuppressions |= CONDITION_DRUNK;
					}
					break;
				}

				case ITEM_PARSE_SUPPRESSENERGY: {
					if (valueAttribute.as_bool()) {
						abilities.conditionSuppressions |= CONDITION_ENERGY;
					}
					break;
				}

				case ITEM_PARSE_SUPPRESSFIRE: {
					if (valueAttribute.as_bool()) {
						abilities.conditionSuppressions |= CONDITION_FIRE;
					}
					break;
				}

				case ITEM_PARSE_SUPPRESSPOISON: {
					if (valueAttribute.as_bool()) {
						abilities.conditionSuppressions |= CONDITION_POISON;
					}
					break;
				}

				case ITEM_PARSE_SUPPRESSDROWN: {
					if (valueAttribute.as_bool()) {
						abilities.conditionSuppressions |= CONDITION_DROWN;
					}
					break;
				}

				case ITEM_PARSE_SUPPRESSPHYSICAL: {
					if (valueAttribute.as_bool()) {
						abilities.conditionSuppressions |= CONDITION_BLEEDING;
					}
					break;
				}

				case ITEM_PARSE_SUPPRESSFREEZE: {
					if (valueAttribute.as_bool()) {
						abilities.conditionSuppressions |= CONDITION_FREEZING;
					}
					break;
				}

				case ITEM_PARSE_SUPPRESSDAZZLE: {
					if (valueAttribute.as_bool()) {
						abilities.conditionSuppressions |= CONDITION_DAZZLED;
					}
					break;
				}

				case ITEM_PARSE_SUPPRESSCURSE: {
					if (valueAttribute.as_bool()) {
						abilities.conditionSuppressions |= CONDITION_CURSED;
					}
					break;
				}

				case ITEM_PARSE_FIELD: {
					it.group = ITEM_GROUP_MAGICFIELD;
					it.type = ITEM_TYPE_MAGICFIELD;

					CombatType_t combatType = COMBAT_NONE;
					ConditionDamage* conditionDamage = nullptr;

					tmpStrValue = asLowerCaseString(valueAttribute.as_string());
					if (tmpStrValue == "fire") {
						conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_FIRE);
						combatType = COMBAT_FIREDAMAGE;
					} else if (tmpStrValue == "energy") {
						conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_ENERGY);
						combatType = COMBAT_ENERGYDAMAGE;
					} else if (tmpStrValue == "poison") {
						conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_POISON);
						combatType = COMBAT_EARTHDAMAGE;
					} else if (tmpStrValue == "drown") {
						conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_DROWN);
						combatType = COMBAT_DROWNDAMAGE;
					} else if (tmpStrValue == "physical") {
						conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_BLEEDING);
						combatType = COMBAT_PHYSICALDAMAGE;
					} else {
						std::cout << "[Warning - Items::parseItemNode] Unknown field value: " << valueAttribute.as_string() << std::endl;
					}

					if (combatType != COMBAT_NONE) {
						it.combatType = combatType;
						it.conditionDamage.reset(conditionDamage);

						uint32_t ticks = 0;
						int32_t start = 0;
						int32_t count = 1;
						for (auto subAttributeNode : attributeNode.children()) {
							pugi::xml_attribute subKeyAttribute = subAttributeNode.attribute("key");
							if (!subKeyAttribute) {
								continue;
							}

							pugi::xml_attribute subValueAttribute = subAttributeNode.attribute("value");
							if (!subValueAttribute) {
								continue;
							}

							tmpStrValue = asLowerCaseString(subKeyAttribute.as_string());
							if (tmpStrValue == "ticks") {
								ticks = pugi::cast<uint32_t>(subValueAttribute.value());
							} else if (tmpStrValue == "count") {
								count = std::max<int32_t>(1, pugi::cast<int32_t>(subValueAttribute.value()));
							} else if (tmpStrValue == "start") {
								start = std::max<int32_t>(0, pugi::cast<int32_t>(subValueAttribute.value()));
							} else if (tmpStrValue == "damage") {
								int32_t damage = -pugi::cast<int32_t>(subValueAttribute.value());
								if (start > 0) {
									std::list<int32_t> damageList;
									ConditionDamage::generateDamageList(damage, start, damageList);
									for (int32_t damageValue : damageList) {
										conditionDamage->addDamage(1, ticks, -damageValue);
									}

									start = 0;
								} else {
									conditionDamage->addDamage(count, ticks, damage);
								}
							}
						}

						conditionDamage->setParam(CONDITION_PARAM_FIELD, 1);

						if (conditionDamage->getTotalDamage() > 0) {
							conditionDamage->setParam(CONDITION_PARAM_FORCEUPDATE, 1);
						}
					}
					break;
				}

				case ITEM_PARSE_REPLACEABLE: {
					it.replaceable = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_PARTNERDIRECTION: {
					it.bedPartnerDir = getDirection(valueAttribute.as_string());
					break;
				}

				case ITEM_PARSE_LEVELDOOR: {
					it.levelDoor = pugi::cast<uint32_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_MALETRANSFORMTO: {
					uint16_t value = pugi::cast<uint16_t>(valueAttribute.value());
					it.transformToOnUse[PLAYERSEX_MALE] = value;
					ItemType& other = getItemType(value);
					if (other.transformToFree == 0) {
						other.transformToFree = it.id;
					}

					if (it.transformToOnUse[PLAYERSEX_FEMALE] == 0) {
						it.transformToOnUse[PLAYERSEX_FEMALE] = value;
					}
					break;
				}

				case ITEM_PARSE_FEMALETRANSFORMTO: {
					uint16_t value = pugi::cast<uint16_t>(valueAttribute.value());
					it.transformToOnUse[PLAYERSEX_FEMALE] = value;

					ItemType& other = getItemType(value);
					if (other.transformToFree == 0) {
						other.transformToFree = it.id;
					}

					if (it.transformToOnUse[PLAYERSEX_MALE] == 0) {
						it.transformToOnUse[PLAYERSEX_MALE] = value;
					}
					break;
				}

				case ITEM_PARSE_TRANSFORMTO: {
					it.transformToFree = pugi::cast<uint16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_DESTROYTO: {
					it.destroyTo = pugi::cast<uint16_t>(valueAttribute.value());
					break;
				}

				case ITEM_PARSE_ELEMENTICE: {
					abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
					abilities.elementType = COMBAT_ICEDAMAGE;
					break;
				}

				case ITEM_PARSE_ELEMENTEARTH: {
					abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
					abilities.elementType = COMBAT_EARTHDAMAGE;
					break;
				}

				case ITEM_PARSE_ELEMENTFIRE: {
					abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
					abilities.elementType = COMBAT_FIREDAMAGE;
					break;
				}

				case ITEM_PARSE_ELEMENTENERGY: {
					abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
					abilities.elementType = COMBAT_ENERGYDAMAGE;
					break;
				}

				case ITEM_PARSE_WALKSTACK: {
					it.walkStack = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_BLOCKING: {
					it.blockSolid = valueAttribute.as_bool();
					break;
				}

				case ITEM_PARSE_ALLOWDISTREAD: {
					it.allowDistRead = booleanString(valueAttribute.as_string());
					break;
				}

				default: {
					// It should not ever get to here, only if you add a new key to the map and don't configure a case for it.
					std::cout << "[Warning - Items::parseItemNode] Not configured key value: " << keyAttribute.as_string() << std::endl;
					break;
				}
			}
		} else {
			std::cout << "[Warning - Items::parseItemNode] Unknown key value: " << keyAttribute.as_string() << std::endl;
		}
	}

	//check bed items
	if ((it.transformToFree != 0 || it.transformToOnUse[PLAYERSEX_FEMALE] != 0 || it.transformToOnUse[PLAYERSEX_MALE] != 0) && it.type != ITEM_TYPE_BED) {
		std::cout << "[Warning - Items::parseItemNode] Item " << it.id << " is not set as a bed-type" << std::endl;
	}
}
Example #24
0
//-------------------------------------------------------------------------------------------------
int		QF_getQuestItemQuantity ( int iQuestID, int iItemNo/*A five-digit:Type+No*/ )
{
	//--------------------------------------------------------------------------------
	LOGOUT( "QF_getQuestItemQuantity( %d, %d ) ", iQuestID, iItemNo );
	//--------------------------------------------------------------------------------

	tagITEM* pQuestItem = NULL;
	for (short nI=0; nI<QUEST_PER_PLAYER; nI++)
	{
		if ( g_pAVATAR->m_Quests.m_QUEST[ nI ].GetID() == iQuestID )
		{
			for( short nItemIdx = 0 ; nItemIdx < QUEST_ITEM_PER_QUEST; ++nItemIdx )
			{
				pQuestItem = g_pAVATAR->m_Quests.m_QUEST[ nI ].GetSlotITEM( nItemIdx );
				if( pQuestItem && pQuestItem->GetItemNO() == getItemNo( iItemNo ) && pQuestItem->GetTYPE() == getItemType( iItemNo ) )
				{
					if( pQuestItem->IsEnableDupCNT() )
					{
						//--------------------------------------------------------------------------------
						LOGOUT( "QF_getQuestItemQuantity( %d, %d ) [ The number of duplicate items : %d ] ", iQuestID, iItemNo, pQuestItem->m_uiQuantity );
						//--------------------------------------------------------------------------------

						return pQuestItem->m_uiQuantity;///중복가능한 아이템의 개수
					}
					else
					{
						//--------------------------------------------------------------------------------
						LOGOUT( "QF_getQuestItemQuantity( %d, %d ) [ Duplicates items : %d ] ", iQuestID, iItemNo, 1 );
						//--------------------------------------------------------------------------------
						return 1;///Duplicates items
					}
				}
			}
			//--------------------------------------------------------------------------------
			LOGERR( "QF_getQuestItemQuantity( %d, %d ) FAILED[ There is no corresponding items ] ", iQuestID, iItemNo );
			//--------------------------------------------------------------------------------

			return 0;///해당 아이템이 없다
		}
	}

	//--------------------------------------------------------------------------------
	LOGERR( "QF_getQuestItemQuantity( %d, %d ) FAILED[ No the quest ] ", iQuestID, iItemNo );
	//--------------------------------------------------------------------------------

	return -1;///There is no corresponding quests
}
Example #25
0
/**
 * Create detailed tooltip showing all relevant item info
 */
TooltipData ItemManager::getTooltip(ItemStack stack, StatBlock *stats, int context) {
	TooltipData tip;

	if (stack.empty()) return tip;

	Color color = getItemColor(stack.item);

	// name
	std::stringstream ss;
	if (stack.quantity == 1)
		ss << getItemName(stack.item);
	else
		ss << getItemName(stack.item) << " (" << stack.quantity << ")";
	tip.addText(ss.str(), color);

	// quest item
	if (items[stack.item].quest_item) {
		tip.addText(msg->get("Quest Item"), color_bonus);
	}

	// only show the name of the currency item
	if (stack.item == CURRENCY_ID)
		return tip;

	// flavor text
	if (items[stack.item].flavor != "") {
		tip.addText(substituteVarsInString(items[stack.item].flavor, pc), color_flavor);
	}

	// level
	if (items[stack.item].level != 0) {
		tip.addText(msg->get("Level %d", items[stack.item].level));
	}

	// type
	if (items[stack.item].type != "") {
		tip.addText(msg->get(getItemType(items[stack.item].type)));
	}

	// item quality text for colorblind users
	if (COLORBLIND && items[stack.item].quality != "") {
		color = color_normal;
		for (size_t i=0; i<item_qualities.size(); ++i) {
			if (item_qualities[i].id == items[stack.item].quality) {
				tip.addText(msg->get("Quality: %s", msg->get(item_qualities[i].name)), color);
				break;
			}
		}
	}

	// damage
	if (items[stack.item].dmg_melee_max > 0) {
		if (items[stack.item].dmg_melee_min < items[stack.item].dmg_melee_max)
			tip.addText(msg->get("Melee damage: %d-%d", items[stack.item].dmg_melee_min, items[stack.item].dmg_melee_max));
		else
			tip.addText(msg->get("Melee damage: %d", items[stack.item].dmg_melee_max));
	}
	if (items[stack.item].dmg_ranged_max > 0) {
		if (items[stack.item].dmg_ranged_min < items[stack.item].dmg_ranged_max)
			tip.addText(msg->get("Ranged damage: %d-%d", items[stack.item].dmg_ranged_min, items[stack.item].dmg_ranged_max));
		else
			tip.addText(msg->get("Ranged damage: %d", items[stack.item].dmg_ranged_max));
	}
	if (items[stack.item].dmg_ment_max > 0) {
		if (items[stack.item].dmg_ment_min < items[stack.item].dmg_ment_max)
			tip.addText(msg->get("Mental damage: %d-%d", items[stack.item].dmg_ment_min, items[stack.item].dmg_ment_max));
		else
			tip.addText(msg->get("Mental damage: %d", items[stack.item].dmg_ment_max));
	}

	// absorb
	if (items[stack.item].abs_max > 0) {
		if (items[stack.item].abs_min < items[stack.item].abs_max)
			tip.addText(msg->get("Absorb: %d-%d", items[stack.item].abs_min, items[stack.item].abs_max));
		else
			tip.addText(msg->get("Absorb: %d", items[stack.item].abs_max));
	}

	// bonuses
	unsigned bonus_counter = 0;
	while (bonus_counter < items[stack.item].bonus.size()) {
		ss.str("");

		BonusData* bdata = &items[stack.item].bonus[bonus_counter];

		if (bdata->is_speed) {
			ss << msg->get("%d%% Speed", bdata->value);
			if (bdata->value >= 100) color = color_bonus;
			else color = color_penalty;
		}
		else {
			if (bdata->value > 0) {
				color = color_bonus;
			}
			else {
				color = color_penalty;
			}

			getBonusString(ss, bdata);
		}

		tip.addText(ss.str(), color);
		bonus_counter++;
	}

	// power
	if (items[stack.item].power_desc != "") {
		tip.addText(items[stack.item].power_desc, color_bonus);
	}

	// level requirement
	if (items[stack.item].requires_level > 0) {
		if (stats->level < items[stack.item].requires_level) color = color_requirements_not_met;
		else color = color_normal;
		tip.addText(msg->get("Requires Level %d", items[stack.item].requires_level), color);
	}

	// base stat requirement
	for (unsigned i=0; i<items[stack.item].req_stat.size(); ++i) {
		if (items[stack.item].req_val[i] > 0) {
			if (items[stack.item].req_stat[i] == REQUIRES_PHYS) {
				if (stats->get_physical() < items[stack.item].req_val[i]) color = color_requirements_not_met;
				else color = color_normal;
				tip.addText(msg->get("Requires Physical %d", items[stack.item].req_val[i]), color);
			}
			else if (items[stack.item].req_stat[i] == REQUIRES_MENT) {
				if (stats->get_mental() < items[stack.item].req_val[i]) color = color_requirements_not_met;
				else color = color_normal;
				tip.addText(msg->get("Requires Mental %d", items[stack.item].req_val[i]), color);
			}
			else if (items[stack.item].req_stat[i] == REQUIRES_OFF) {
				if (stats->get_offense() < items[stack.item].req_val[i]) color = color_requirements_not_met;
				else color = color_normal;
				tip.addText(msg->get("Requires Offense %d", items[stack.item].req_val[i]), color);
			}
			else if (items[stack.item].req_stat[i] == REQUIRES_DEF) {
				if (stats->get_defense() < items[stack.item].req_val[i]) color = color_requirements_not_met;
				else color = color_normal;
				tip.addText(msg->get("Requires Defense %d", items[stack.item].req_val[i]), color);
			}
		}
	}

	// requires class
	if (items[stack.item].requires_class != "") {
		if (items[stack.item].requires_class != stats->character_class) color = color_requirements_not_met;
		else color = color_normal;
		tip.addText(msg->get("Requires Class: %s", msg->get(items[stack.item].requires_class)), color);
	}

	// buy or sell price
	if (items[stack.item].getPrice() > 0 && stack.item != CURRENCY_ID) {

		int price_per_unit;
		if (context == VENDOR_BUY) {
			price_per_unit = items[stack.item].getPrice();
			if (stats->currency < price_per_unit) color = color_requirements_not_met;
			else color = color_normal;
			if (items[stack.item].max_quantity <= 1)
				tip.addText(msg->get("Buy Price: %d %s", price_per_unit, CURRENCY), color);
			else
				tip.addText(msg->get("Buy Price: %d %s each", price_per_unit, CURRENCY), color);
		}
		else if (context == VENDOR_SELL) {
			price_per_unit = items[stack.item].getSellPrice();
			if (stats->currency < price_per_unit) color = color_requirements_not_met;
			else color = color_normal;
			if (items[stack.item].max_quantity <= 1)
				tip.addText(msg->get("Buy Price: %d %s", price_per_unit, CURRENCY), color);
			else
				tip.addText(msg->get("Buy Price: %d %s each", price_per_unit, CURRENCY), color);
		}
		else if (context == PLAYER_INV) {
			price_per_unit = items[stack.item].getSellPrice();
			if (price_per_unit == 0) price_per_unit = 1;
			if (items[stack.item].max_quantity <= 1)
				tip.addText(msg->get("Sell Price: %d %s", price_per_unit, CURRENCY));
			else
				tip.addText(msg->get("Sell Price: %d %s each", price_per_unit, CURRENCY));
		}
	}

	if (items[stack.item].set > 0) {
		// item set bonuses
		ItemSet set = item_sets[items[stack.item].set];
		bonus_counter = 0;

		tip.addText("\n" + msg->get("Set: ") + msg->get(item_sets[items[stack.item].set].name), set.color);

		while (bonus_counter < set.bonus.size()) {
			ss.str("");

			Set_bonus* bdata = &set.bonus[bonus_counter];

			ss << msg->get("%d items: ", bdata->requirement);

			if (bdata->is_speed) {
				ss << msg->get("%d%% Speed", bdata->value);
			}
			else {
				getBonusString(ss, bdata);
			}

			tip.addText(ss.str(), set.color);
			bonus_counter++;
		}
	}

	return tip;
}