bool ConditionSpeed::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	switch(attr)
	{
		case CONDITIONATTR_SPEEDDELTA:
		{
			int32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			speedDelta = value;
			return true;
		}

		case CONDITIONATTR_FORMULA_MINA:
		{
			float value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			mina = value;
			return true;
		}

		case CONDITIONATTR_FORMULA_MINB:
		{
			float value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			minb = value;
			return true;
		}

		case CONDITIONATTR_FORMULA_MAXA:
		{
			float value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			maxa = value;
			return true;
		}

		case CONDITIONATTR_FORMULA_MAXB:
		{
			float value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			maxb = value;
			return true;
		}

		default:
			break;
	}

	return ConditionOutfit::unserializeProp(attr, propStream);
}
bool ConditionAttributes::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	switch(attr)
	{
		case CONDITIONATTR_SKILLS:
		{
			int32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			skills[currentSkill++] = value;
			return true;
		}

		case CONDITIONATTR_STATS:
		{
			int32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			stats[currentStat++] = value;
			return true;
		}

		default:
			break;
	}

	return ConditionGeneric::unserializeProp(attr, propStream);
}
Пример #3
0
bool Condition::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	switch (attr) {
		case CONDITIONATTR_TYPE: {
			int32_t value;
			if (!propStream.GET_VALUE(value)) {
				return false;
			}

			conditionType = (ConditionType_t)value;
			return true;
		}

		case CONDITIONATTR_ID: {
			int32_t value;
			if (!propStream.GET_VALUE(value)) {
				return false;
			}

			id = (ConditionId_t)value;
			return true;
		}

		case CONDITIONATTR_TICKS: {
			int32_t value;
			if (!propStream.GET_VALUE(value)) {
				return false;
			}

			ticks = value;
			return true;
		}

		case CONDITIONATTR_ISBUFF: {
			int8_t value;
			if (!propStream.GET_VALUE(value)) {
				return false;
			}

			isBuff = value != 0;
			return true;
		}

		case CONDITIONATTR_SUBID: {
			int32_t value;
			if (!propStream.GET_VALUE(value)) {
				return false;
			}

			subId = value;
			return true;
		}

		case CONDITIONATTR_END:
			return true;

		default:
			return false;
	}
}
bool ConditionSoul::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	switch(attr)
	{
		case CONDITIONATTR_SOULGAIN:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			soulGain = value;
			return true;
		}

		case CONDITIONATTR_SOULTICKS:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			soulTicks = value;
			return true;
		}

		default:
			break;
	}

	return ConditionGeneric::unserializeProp(attr, propStream);
}
Пример #5
0
bool ConditionAttributes::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	if (attr == CONDITIONATTR_SKILLS) {
		int32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		skills[currentSkill] = value;
		++currentSkill;
		return true;
	} else if (attr == CONDITIONATTR_STATS) {
		int32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		stats[currentStat] = value;
		++currentStat;
		return true;
	}

	return Condition::unserializeProp(attr, propStream);
}
bool ConditionDamage::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	switch(attr)
	{
		case CONDITIONATTR_DELAYED:
		{
			bool value = false;
			if(!propStream.GET_VALUE(value))
				return false;

			delayed = value;
			return true;
		}

		case CONDITIONATTR_PERIODDAMAGE:
		{
			int32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			periodDamage = value;
			return true;
		}

		case CONDITIONATTR_OWNER:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			owner = value;
			return true;
		}

		case CONDITIONATTR_INTERVALDATA:
		{
			IntervalInfo damageInfo;
			if(!propStream.GET_VALUE(damageInfo))
				return false;

			damageList.push_back(damageInfo);
			if(getTicks() != -1)
				setTicks(getTicks() + damageInfo.interval);

			return true;
		}

		default:
			break;
	}

	return Condition::unserializeProp(attr, propStream);
}
Пример #7
0
bool ConditionSpeed::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	if (attr == CONDITIONATTR_SPEEDDELTA) {
		int32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		speedDelta = value;
		return true;
	} else if (attr == CONDITIONATTR_FORMULA_MINA) {
		float value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		mina = value;
		return true;
	} else if (attr == CONDITIONATTR_FORMULA_MINB) {
		float value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		minb = value;
		return true;
	} else if (attr == CONDITIONATTR_FORMULA_MAXA) {
		float value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		maxa = value;
		return true;
	} else if (attr == CONDITIONATTR_FORMULA_MAXB) {
		float value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		maxb = value;
		return true;
	}

	return Condition::unserializeProp(attr, propStream);
}
bool ConditionRegeneration::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	switch(attr)
	{
		case CONDITIONATTR_HEALTHTICKS:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			healthTicks = value;
			return true;
		}

		case CONDITIONATTR_HEALTHGAIN:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			healthGain = value;
			return true;
		}

		case CONDITIONATTR_MANATICKS:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			manaTicks = value;
			return true;
		}

		case CONDITIONATTR_MANAGAIN:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			manaGain = value;
			return true;
		}

		default:
			break;
	}

	return ConditionGeneric::unserializeProp(attr, propStream);
}
bool ConditionLight::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	switch(attr)
	{
		case CONDITIONATTR_LIGHTCOLOR:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			lightInfo.color = value;
			return true;
		}

		case CONDITIONATTR_LIGHTLEVEL:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			lightInfo.level = value;
			return true;
		}

		case CONDITIONATTR_LIGHTTICKS:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			internalLightTicks = value;
			return true;
		}

		case CONDITIONATTR_LIGHTINTERVAL:
		{
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value))
				return false;

			lightChangeInterval = value;
			return true;
		}

		default:
			break;
	}

	return Condition::unserializeProp(attr, propStream);
}
Пример #10
0
bool ConditionOutfit::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	if (attr == CONDITIONATTR_OUTFIT) {
		return propStream.GET_VALUE(this->outfit);
	}
	return Condition::unserializeProp(attr, propStream);
}
Пример #11
0
bool ConditionDamage::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	if (attr == CONDITIONATTR_DELAYED) {
		bool value = false;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		delayed = value;
		return true;
	} else if (attr == CONDITIONATTR_PERIODDAMAGE) {
		int32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		periodDamage = value;
		return true;
	} else if (attr == CONDITIONATTR_OWNER) {
		uint32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		// owner = value;
		return true;
	} else if (attr == CONDITIONATTR_INTERVALDATA) {
		IntervalInfo damageInfo;

		if (!propStream.GET_VALUE(damageInfo)) {
			return false;
		}

		damageList.push_back(damageInfo);

		if (getTicks() != -1) {
			setTicks(getTicks() + damageInfo.interval);
		}

		return true;
	}

	return Condition::unserializeProp(attr, propStream);
}
Пример #12
0
bool ConditionRegeneration::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	if (attr == CONDITIONATTR_HEALTHTICKS) {
		uint32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		healthTicks = value;
		return true;
	} else if (attr == CONDITIONATTR_HEALTHGAIN) {
		uint32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		healthGain = value;
		return true;
	} else if (attr == CONDITIONATTR_MANATICKS) {
		uint32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		manaTicks = value;
		return true;
	} else if (attr == CONDITIONATTR_MANAGAIN) {
		uint32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		manaGain = value;
		return true;
	}

	return Condition::unserializeProp(attr, propStream);
}
Пример #13
0
bool ConditionLight::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	if (attr == CONDITIONATTR_LIGHTCOLOR) {
		uint32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		lightInfo.color = value;
		return true;
	} else if (attr == CONDITIONATTR_LIGHTLEVEL) {
		uint32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		lightInfo.level = value;
		return true;
	} else if (attr == CONDITIONATTR_LIGHTTICKS) {
		uint32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		internalLightTicks = value;
		return true;
	} else if (attr == CONDITIONATTR_LIGHTINTERVAL) {
		uint32_t value = 0;

		if (!propStream.GET_VALUE(value)) {
			return false;
		}

		lightChangeInterval = value;
		return true;
	}

	return Condition::unserializeProp(attr, propStream);
}
Пример #14
0
bool ConditionSoul::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	if(attr == CONDITIONATTR_SOULGAIN)
	{
		uint32_t value = 0;
		if(!propStream.GET_VALUE(value))
			return false;

		soulGain = value;
		return true;
	}
	else if(attr == CONDITIONATTR_SOULTICKS)
	{
		uint32_t value = 0;
		if(!propStream.GET_VALUE(value))
			return false;

		soulTicks = value;
		return true;
	}
	return Condition::unserializeProp(attr, propStream);
}
Пример #15
0
bool ConditionOutfit::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	if(attr == CONDITIONATTR_OUTFIT)
	{
		Outfit_t outfit;
		if(!propStream.GET_VALUE(outfit))
			return false;

		outfits.push_back(outfit);
		return true;
	}
	return Condition::unserializeProp(attr, propStream);
}
bool ConditionOutfit::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
	Outfit_t outfit;
	switch(attr)
	{
		case CONDITIONATTR_OUTFIT:
		{
			if(!propStream.GET_VALUE(outfit))
				return false;

			outfits.push_back(outfit);
			return true;
		}

		default:
			break;
	}

	return Condition::unserializeProp(attr, propStream);
}
Пример #17
0
int32_t Items::loadFromOtb(const std::string& file)
{
	FileLoader f;
	if (!f.openFile(file.c_str(), "OTBI")) {
		return f.getError();
	}

	uint32_t type;
	NODE node = f.getChildNode(NO_NODE, type);

	PropStream props;
	if (f.getProps(node, props)) {
		//4 byte flags
		//attributes
		//0x01 = version data
		uint32_t flags;
		if (!props.GET_ULONG(flags)) {
			return ERROR_INVALID_FORMAT;
		}

		uint8_t attr;
		if (!props.GET_VALUE(attr)) {
			return ERROR_INVALID_FORMAT;
		}

		if (attr == ROOT_ATTR_VERSION) {
			uint16_t datalen;
			if (!props.GET_VALUE(datalen)) {
				return ERROR_INVALID_FORMAT;
			}

			if (datalen != sizeof(VERSIONINFO)) {
				return ERROR_INVALID_FORMAT;
			}

			VERSIONINFO* vi;
			if (!props.GET_STRUCT(vi)) {
				return ERROR_INVALID_FORMAT;
			}

			Items::dwMajorVersion = vi->dwMajorVersion; //items otb format file version
			Items::dwMinorVersion = vi->dwMinorVersion; //client version
			Items::dwBuildNumber = vi->dwBuildNumber; //revision
		}
	}

	if (Items::dwMajorVersion == 0xFFFFFFFF) {
		std::cout << "[Warning - Items::loadFromOtb] items.otb using generic client version." << std::endl;
	} else if (Items::dwMajorVersion != 3) {
		std::cout << "Old version detected, a newer version of items.otb is required." << std::endl;
		return ERROR_INVALID_FORMAT;
	} else if (Items::dwMinorVersion < CLIENT_VERSION_1035) {
		std::cout << "A newer version of items.otb is required." << std::endl;
		return ERROR_INVALID_FORMAT;
	}

	node = f.getChildNode(node, type);
	while (node != NO_NODE) {
		PropStream stream;
		if (!f.getProps(node, stream)) {
			return f.getError();
		}

		uint32_t flags;
		if (!stream.GET_VALUE(flags)) {
			return ERROR_INVALID_FORMAT;
		}

		uint16_t serverId = 0;
		uint16_t clientId = 0;
		uint16_t speed = 0;
		uint16_t lightLevel = 0;
		uint16_t lightColor = 0;
		uint16_t wareId = 0;
		uint8_t alwaysOnTopOrder = 0;

		uint8_t attrib;
		while (stream.GET_VALUE(attrib)) {
			uint16_t datalen;
			if (!stream.GET_VALUE(datalen)) {
				return ERROR_INVALID_FORMAT;
			}

			switch (attrib) {
				case ITEM_ATTR_SERVERID: {
					if (datalen != sizeof(uint16_t)) {
						return ERROR_INVALID_FORMAT;
					}

					if (!stream.GET_USHORT(serverId)) {
						return ERROR_INVALID_FORMAT;
					}

					if (serverId > 30000 && serverId < 30100) {
						serverId -= 30000;
					}
					break;
				}

				case ITEM_ATTR_CLIENTID: {
					if (datalen != sizeof(uint16_t)) {
						return ERROR_INVALID_FORMAT;
					}

					if (!stream.GET_USHORT(clientId)) {
						return ERROR_INVALID_FORMAT;
					}
					break;
				}

				case ITEM_ATTR_SPEED: {
					if (datalen != sizeof(uint16_t)) {
						return ERROR_INVALID_FORMAT;
					}

					if (!stream.GET_USHORT(speed)) {
						return ERROR_INVALID_FORMAT;
					}
					break;
				}

				case ITEM_ATTR_LIGHT2: {
					if (datalen != sizeof(lightBlock2)) {
						return ERROR_INVALID_FORMAT;
					}

					lightBlock2* lb2;
					if (!stream.GET_STRUCT(lb2)) {
						return ERROR_INVALID_FORMAT;
					}

					lightLevel = lb2->lightLevel;
					lightColor = lb2->lightColor;
					break;
				}

				case ITEM_ATTR_TOPORDER: {
					if (datalen != sizeof(uint8_t)) {
						return ERROR_INVALID_FORMAT;
					}

					if (!stream.GET_UCHAR(alwaysOnTopOrder)) {
						return ERROR_INVALID_FORMAT;
					}
					break;
				}

				case ITEM_ATTR_WAREID: {
					if (datalen != sizeof(uint16_t)) {
						return ERROR_INVALID_FORMAT;
					}

					if (!stream.GET_USHORT(wareId)) {
						return ERROR_INVALID_FORMAT;
					}
					break;
				}

				default: {
					//skip unknown attributes
					if (!stream.SKIP_N(datalen)) {
						return ERROR_INVALID_FORMAT;
					}
					break;
				}
			}
		}

		if (reverseItemMap.find(clientId) == reverseItemMap.end()) {
			reverseItemMap[clientId] = serverId;
		}

		// store the found item
		if (serverId >= items.size()) {
			items.resize(serverId + 1);
		}
		ItemType& iType = items[serverId];

		iType.group = (itemgroup_t)type;
		switch (type) {
			case ITEM_GROUP_CONTAINER:
				iType.type = ITEM_TYPE_CONTAINER;
				break;
			case ITEM_GROUP_DOOR:
				//not used
				iType.type = ITEM_TYPE_DOOR;
				break;
			case ITEM_GROUP_MAGICFIELD:
				//not used
				iType.type = ITEM_TYPE_MAGICFIELD;
				break;
			case ITEM_GROUP_TELEPORT:
				//not used
				iType.type = ITEM_TYPE_TELEPORT;
				break;
			case ITEM_GROUP_NONE:
			case ITEM_GROUP_GROUND:
			case ITEM_GROUP_SPLASH:
			case ITEM_GROUP_FLUID:
			case ITEM_GROUP_CHARGES:
			case ITEM_GROUP_DEPRECATED:
				break;
			default:
				return ERROR_INVALID_FORMAT;
		}

		iType.blockSolid = hasBitSet(FLAG_BLOCK_SOLID, flags);
		iType.blockProjectile = hasBitSet(FLAG_BLOCK_PROJECTILE, flags);
		iType.blockPathFind = hasBitSet(FLAG_BLOCK_PATHFIND, flags);
		iType.hasHeight = hasBitSet(FLAG_HAS_HEIGHT, flags);
		iType.useable = hasBitSet(FLAG_USEABLE, flags);
		iType.pickupable = hasBitSet(FLAG_PICKUPABLE, flags);
		iType.moveable = hasBitSet(FLAG_MOVEABLE, flags);
		iType.stackable = hasBitSet(FLAG_STACKABLE, flags);

		iType.alwaysOnTop = hasBitSet(FLAG_ALWAYSONTOP, flags);
		iType.isVertical = hasBitSet(FLAG_VERTICAL, flags);
		iType.isHorizontal = hasBitSet(FLAG_HORIZONTAL, flags);
		iType.isHangable = hasBitSet(FLAG_HANGABLE, flags);
		iType.allowDistRead = hasBitSet(FLAG_ALLOWDISTREAD, flags);
		iType.rotable = hasBitSet(FLAG_ROTABLE, flags);
		iType.canReadText = hasBitSet(FLAG_READABLE, flags);
		iType.lookThrough = hasBitSet(FLAG_LOOKTHROUGH, flags);
		iType.isAnimation = hasBitSet(FLAG_ANIMATION, flags);
		// iType.walkStack = !hasBitSet(FLAG_FULLTILE, flags);

		iType.id = serverId;
		iType.clientId = clientId;
		iType.speed = speed;
		iType.lightLevel = lightLevel;
		iType.lightColor = lightColor;
		iType.wareId = wareId;
		iType.alwaysOnTopOrder = alwaysOnTopOrder;

		node = f.getNextNode(node, type);
	}

	items.shrink_to_fit();
	return ERROR_NONE;
}
Пример #18
0
int Items::loadFromOtb(std::string file)
{
	ItemLoader f;
	if(!f.openFile(file.c_str(), false, true)){
		return f.getError();
	}

	unsigned long type,len;
	const unsigned char* data;
	NODE node = f.getChildNode(NO_NODE, type);

	PropStream props;
	if(f.getProps(node,props)){
		//4 byte flags
		//attributes
		//0x01 = version data
		unsigned long flags;
		if(!props.GET_ULONG(flags)){
			return ERROR_INVALID_FORMAT;
		}
		attribute_t attr;
		datasize_t datalen = 0;
		if(!props.GET_VALUE(attr)){
			return ERROR_INVALID_FORMAT;
		}
		if(attr == ROOT_ATTR_VERSION){
			if(!props.GET_VALUE(datalen)){
				return ERROR_INVALID_FORMAT;
			}
			if(datalen != sizeof(VERSIONINFO)){
				return ERROR_INVALID_FORMAT;
			}
			VERSIONINFO *vi;
			if(!props.GET_STRUCT(vi)){
				return ERROR_INVALID_FORMAT;
			}
			Items::dwMajorVersion = vi->dwMajorVersion;
			Items::dwMinorVersion = vi->dwMinorVersion;
			Items::dwBuildNumber = vi->dwBuildNumber;
		}
	}

	if(Items::dwMinorVersion != CLIENT_VERSION_760){
		std::cout << "Not supported items.otb client version." << std::endl;
		return ERROR_INVALID_FORMAT;
	}

	node = f.getChildNode(node, type);

	while(node != NO_NODE) {
		data = f.getProps(node, len);
		if(data == NULL && f.getError() != ERROR_NONE)
			return f.getError();

		flags_t flags;
		if(data != NULL) {
			const unsigned char* p = &data[0];
			ItemType* iType = new ItemType();
			bool loadedFlags = false;

			while(p < data + len) {
				iType->group = (itemgroup_t)type;

				switch(type) {
					case ITEM_GROUP_NONE:
					case ITEM_GROUP_GROUND:
					case ITEM_GROUP_CONTAINER:
					case ITEM_GROUP_WEAPON:
					case ITEM_GROUP_AMMUNITION:
					case ITEM_GROUP_ARMOR:
					case ITEM_GROUP_RUNE:
					case ITEM_GROUP_TELEPORT:
					case ITEM_GROUP_MAGICFIELD:
					case ITEM_GROUP_WRITEABLE:
					case ITEM_GROUP_KEY:
					case ITEM_GROUP_SPLASH:
					case ITEM_GROUP_FLUID:
					{
						if(!loadedFlags) {
							//read 4 byte flags
							memcpy((void*)&flags, p, sizeof(flags_t)); p+= sizeof(flags_t);

							iType->blockSolid = ((flags & FLAG_BLOCK_SOLID) == FLAG_BLOCK_SOLID);
							iType->blockProjectile = ((flags & FLAG_BLOCK_PROJECTILE) == FLAG_BLOCK_PROJECTILE);
							iType->blockPathFind = ((flags & FLAG_BLOCK_PATHFIND) == FLAG_BLOCK_PATHFIND);
							iType->hasHeight = ((flags & FLAG_HAS_HEIGHT) == FLAG_HAS_HEIGHT);
							iType->useable = ((flags & FLAG_USEABLE) == FLAG_USEABLE);
							iType->pickupable = ((flags & FLAG_PICKUPABLE) == FLAG_PICKUPABLE);
							iType->moveable = ((flags & FLAG_MOVEABLE) == FLAG_MOVEABLE);
							iType->stackable = ((flags & FLAG_STACKABLE) == FLAG_STACKABLE);
							iType->floorChangeDown = ((flags & FLAG_FLOORCHANGEDOWN) == FLAG_FLOORCHANGEDOWN);
							iType->floorChangeNorth = ((flags & FLAG_FLOORCHANGENORTH) == FLAG_FLOORCHANGENORTH);
							iType->floorChangeEast = ((flags & FLAG_FLOORCHANGEEAST) == FLAG_FLOORCHANGEEAST);
							iType->floorChangeSouth = ((flags & FLAG_FLOORCHANGESOUTH) == FLAG_FLOORCHANGESOUTH);
							iType->floorChangeWest = ((flags & FLAG_FLOORCHANGEWEST) == FLAG_FLOORCHANGEWEST);
							iType->alwaysOnTop = ((flags & FLAG_ALWAYSONTOP) == FLAG_ALWAYSONTOP);
							iType->canDecay = !((flags & FLAG_CANNOTDECAY) == FLAG_CANNOTDECAY);

							if(type == ITEM_GROUP_WRITEABLE) {
								iType->RWInfo |= CAN_BE_WRITTEN;
							}

							if((flags & FLAG_READABLE) == FLAG_READABLE)
								iType->RWInfo |= CAN_BE_READ;

							iType->rotable = ((flags & FLAG_ROTABLE) == FLAG_ROTABLE);

							if(p >= data + len) //no attributes
								break;
							loadedFlags = true;
						}

						//attribute
						attribute_t attrib = *p; p+= sizeof(attribute_t);
						if(p >= data + len) {
							delete iType;
							return ERROR_INVALID_FORMAT;
						}

						datasize_t datalen = 0;
						//size of data
						memcpy(&datalen, p, sizeof(datasize_t)); p+= sizeof(datalen);
						if(p >= data + len) {
							delete iType;
							return ERROR_INVALID_FORMAT;
						}

						switch(attrib) {

							case ITEM_ATTR_SERVERID:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;

								unsigned short serverid = *(unsigned short*)p;
								if(serverid > 20000 && serverid < 20100)
									serverid = serverid - 20000;

								iType->id = serverid;
								break;
							}
							case ITEM_ATTR_CLIENTID:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;

								memcpy(&iType->clientId, p, sizeof(unsigned short));
								break;
							}
							case ITEM_ATTR_NAME:
							{
								char name[128];
								if(datalen >= sizeof(name))
									return ERROR_INVALID_FORMAT;

								memcpy(name, p, datalen);
								name[datalen] = 0;
								iType->name = name;
								break;
							}
							case ITEM_ATTR_DESCR:
							{
								char descr[128];
								if(datalen >= sizeof(descr))
									return ERROR_INVALID_FORMAT;

								memcpy(descr, p, datalen);
								descr[datalen] = 0;
								iType->description = descr;

								break;
							}
							case ITEM_ATTR_SPEED:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;

								memcpy(&iType->speed, p, sizeof(unsigned short));
								break;
							}
							case ITEM_ATTR_SLOT:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;

								unsigned short otb_slot = *(unsigned short*)p;

								switch(otb_slot){
								case OTB_SLOT_DEFAULT:
								case OTB_SLOT_WEAPON:
								case OTB_SLOT_HAND:
									//default
									break;
								case OTB_SLOT_HEAD:
									iType->slot_position = SLOTP_HEAD;
									break;
								case OTB_SLOT_BODY:
									iType->slot_position = SLOTP_ARMOR;
									break;
								case OTB_SLOT_LEGS:
									iType->slot_position = SLOTP_LEGS;
									break;
								case OTB_SLOT_BACKPACK:
									iType->slot_position = SLOTP_BACKPACK;
									break;
								case OTB_SLOT_2HAND:
									iType->slot_position  = SLOTP_TWO_HAND;
									break;
								case OTB_SLOT_FEET:
									iType->slot_position = SLOTP_FEET;
									break;
								case OTB_SLOT_AMULET:
									iType->slot_position = SLOTP_NECKLACE;
									break;
								case OTB_SLOT_RING:
									iType->slot_position = SLOTP_RING;
									break;
								}
								iType->slot_position = iType->slot_position | SLOTP_LEFT | SLOTP_RIGHT | SLOTP_AMMO;
								break;
							}
							case ITEM_ATTR_MAXITEMS:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;

								memcpy(&iType->maxItems, p, sizeof(unsigned short));
								break;
							}
							case ITEM_ATTR_WEIGHT:
							{
								if(datalen != sizeof(double))
									return ERROR_INVALID_FORMAT;
#ifdef YUR_CONFIG_CAP
								if (g_config.CAP_SYSTEM)
#endif //YUR_CONFIG_CAP
									memcpy(&iType->weight, p, sizeof(double));
								break;
							}
							/*case ITEM_ATTR_WEAPON:
							{
								if(datalen != sizeof(weaponBlock))
									return ERROR_INVALID_FORMAT;

								weaponBlock wb;
								memcpy(&wb, p, sizeof(weaponBlock));
								iType->weaponType = (WeaponType)wb.weaponType;
								iType->shootType = (subfight_t)wb.shootType;
								iType->amuType = (amu_t)wb.amuType;
								iType->attack = wb.attack;
								iType->defence = wb.defence;
								break;
							}
							case ITEM_ATTR_AMU:
							{
								if(datalen != sizeof(amuBlock))
									return ERROR_INVALID_FORMAT;

								amuBlock ab;
								memcpy(&ab, p, sizeof(amuBlock));
								iType->weaponType = AMO;
								iType->shootType = (subfight_t)ab.shootType;
								iType->amuType = (amu_t)ab.amuType;
								iType->attack = ab.attack;
								break;
							}
							case ITEM_ATTR_ARMOR:
							{
								if(datalen != sizeof(armorBlock))
									return ERROR_INVALID_FORMAT;

								armorBlock ab;
								memcpy(&ab, p, sizeof(armorBlock));

								iType->armor = ab.armor;
#ifdef YUR_CONFIG_CAP
								if (g_config.CAP_SYSTEM)
#endif //YUR_CONFIG_CAP
									iType->weight = ab.weight;
								//ignore this value
								//iType->slot_position = ab.slot_position;

								break;
							}*/
							case ITEM_ATTR_MAGLEVEL:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;

								memcpy(&iType->runeMagLevel, p, sizeof(unsigned short));

								break;
							}
							case ITEM_ATTR_MAGFIELDTYPE:
							{
								if(datalen != sizeof(unsigned char))
									return ERROR_INVALID_FORMAT;

								memcpy(&iType->magicfieldtype, p, sizeof(unsigned char));

								break;
							}
							/*case ITEM_ATTR_WRITEABLE:
							{
								if(datalen != sizeof(writeableBlock))
									return ERROR_INVALID_FORMAT;

								struct writeableBlock wb;
								memcpy(&wb, p, sizeof(writeableBlock));

								iType->readOnlyId = wb.readOnlyId;

								break;
							}*/
							case ITEM_ATTR_ROTATETO:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;

								iType->rotateTo = *(unsigned short*)p;

								break;
							}
							/*case ITEM_ATTR_DECAY:
							{
								if(datalen != sizeof(decayBlock))
									return ERROR_INVALID_FORMAT;

								decayBlock db;
								memcpy(&db, p, sizeof(decayBlock));
								iType->decayTime = db.decayTime;
								iType->decayTo = db.decayTo;
								break;
							}*/
							case ITEM_ATTR_SPRITEHASH:
							{
								if(datalen != 16)
									return ERROR_INVALID_FORMAT;
								break;
							}

							case ITEM_ATTR_MINIMAPCOLOR:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;
								break;
							}
							case ITEM_ATTR_07:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;
								break;
							}

							case ITEM_ATTR_08:
							{
								if(datalen != sizeof(unsigned short))
									return ERROR_INVALID_FORMAT;
								break;
							}
							/*case ITEM_ATTR_LIGHT:
							{
								if(datalen != sizeof(lightBlock))
									return ERROR_INVALID_FORMAT;

								lightBlock lb;
								memcpy(&lb, p, sizeof(lightBlock));
								iType->lightLevel = lb.lightLevel;
								iType->lightColor = lb.lightColor;
								break;
							}*/
							case ITEM_ATTR_DECAY2:
							{
								if(datalen != sizeof(decayBlock2))
									return ERROR_INVALID_FORMAT;

								decayBlock2 db2;
								memcpy(&db2, p, sizeof(decayBlock2));
								iType->decayTime = db2.decayTime;
								iType->decayTo = db2.decayTo;
								break;
							}
							case ITEM_ATTR_WEAPON2:
							{
								if(datalen != sizeof(weaponBlock2))
									return ERROR_INVALID_FORMAT;

								weaponBlock2 wb2;
								memcpy(&wb2, p, sizeof(weaponBlock2));
								iType->weaponType = (WeaponType)wb2.weaponType;
								iType->shootType = translateOTBsubfight_t((subfightOTB_t)wb2.shootType);
								iType->amuType = (amu_t)wb2.amuType;
								iType->attack = wb2.attack;
								iType->defence = wb2.defence;
								break;
							}
							case ITEM_ATTR_AMU2:
							{
								if(datalen != sizeof(amuBlock2))
									return ERROR_INVALID_FORMAT;

								amuBlock2 ab2;
								memcpy(&ab2, p, sizeof(amuBlock2));
								iType->weaponType = AMO;
								iType->shootType = translateOTBsubfight_t((subfightOTB_t)ab2.shootType);
								iType->amuType = (amu_t)ab2.amuType;
								iType->attack = ab2.attack;
								break;
							}
							case ITEM_ATTR_ARMOR2:
							{
								if(datalen != sizeof(armorBlock2))
									return ERROR_INVALID_FORMAT;

								armorBlock2 ab2;
								memcpy(&ab2, p, sizeof(armorBlock2));
								iType->armor = ab2.armor;
#ifdef YUR_CONFIG_CAP
								if (g_config.CAP_SYSTEM)
#endif //YUR_CONFIG_CAP
									iType->weight = ab2.weight;
								//ignore this value
								//iType->slot_position = (slots_t)ab2.slot_position;

								break;
							}
							case ITEM_ATTR_WRITEABLE2:
							{
								if(datalen != sizeof(writeableBlock2))
									return ERROR_INVALID_FORMAT;

								struct writeableBlock2 wb2;
								memcpy(&wb2, p, sizeof(writeableBlock2));
								iType->readOnlyId = wb2.readOnlyId;

								break;
							}
							case ITEM_ATTR_LIGHT2:
							{
								if(datalen != sizeof(lightBlock2))
									return ERROR_INVALID_FORMAT;

								lightBlock2 lb2;
								memcpy(&lb2, p, sizeof(lightBlock2));
								iType->lightLevel = lb2.lightLevel;
								iType->lightColor = lb2.lightColor;
								break;
							}
							default:
								//ignore unknown attributes
								//delete iType;
								//return ERROR_INVALID_FORMAT;
								break;
						}


						p+= datalen;
						break;
					}

					default:
						return ERROR_INVALID_FORMAT;
						break;
				}
			}

			//get rune mag level from spells.xml
			if(iType->group == ITEM_GROUP_RUNE){
				std::map<unsigned short, Spell*>::iterator it = spells.getAllRuneSpells()->find(iType->id);
				if(it != spells.getAllRuneSpells()->end()){
					iType->runeMagLevel = it->second->getMagLv();
				}
				else{
					iType->runeMagLevel = 0;
				}

			}
			// store the found item
			items[iType->id] = iType;
			revItems[iType->clientId] = iType->id;
		}

		node = f.getNextNode(node, type);
	}

	return ERROR_NONE;
}
Пример #19
0
bool Condition::unserialize(PropStream& propStream)
{
	uint8_t attr_type;
	while(propStream.GET_UCHAR(attr_type) && attr_type != CONDITIONATTR_END.value()){

		if(attr_type == enums::CONDITIONATTRIBUTE_MECHANIC){
			int32_t value = 0;
			if(!propStream.GET_VALUE(value)){
				return false;
			}

			mechanicType = (MechanicType)value;
		}
		else if(attr_type == enums::CONDITIONATTRIBUTE_COMBAT){
			int32_t value = 0;
			if(!propStream.GET_VALUE(value)){
				return false;
			}

			combatType = (CombatType)value;
			return true;
		}
		else if(attr_type == enums::CONDITIONATTRIBUTE_TICKS){
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value)){
				return false;
			}

			ticks = value;
		}
		else if(attr_type == enums::CONDITIONATTRIBUTE_NAME){
			std::string value;
			if(!propStream.GET_STRING(value)){
				return false;
			}

			name = value;
		}
		else if(attr_type == enums::CONDITIONATTRIBUTE_FLAGS){
			uint32_t value = 0;
			if(!propStream.GET_VALUE(value)){
				return false;
			}

			flags = value;
		}
		else if(attr_type == enums::CONDITIONATTRIBUTE_EFFECT){
			ConditionEffect effect;
			if(!effect.unserialize(propStream)){
				return false;
			}

			addEffect(effect);
		}
		else{
			return false;
		}
	}

	return true;
}
Пример #20
0
bool ConditionEffect::unserialize(PropStream& propStream)
{
	uint32_t value;
	if(!propStream.GET_VALUE(value)){
		return false;
	}

	type = ConditionEffect::Type(value);

	if(!propStream.GET_VALUE(interval)){
		return false;
	}

	//revision
	uint16_t revision;
	if(!propStream.GET_VALUE(revision)){
		return false;
	}

	switch(type){
		case ConditionEffect::PERIODIC_HEAL:
		case ConditionEffect::PERIODIC_DAMAGE:
		{
			if(revision != 1){
				return false;
			}

			ConditionEffect::ModPeriodicDamage mod;
			if(!propStream.GET_VALUE(value)){
				return false;
			}
			mod.type = CombatType::fromInteger(value);

			if(!propStream.GET_VALUE(mod.min)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.max)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.value)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.total)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.percent)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.first)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.rounds)){
				return false;
			}

			data = mod;
			break;
		}
		case ConditionEffect::PERIODIC_MOD_STAMINA:
		{
			if(revision != 1){
				return false;
			}
			ConditionEffect::ModPeriodicStamina mod;
			if(!propStream.GET_VALUE(mod.value)){
				return false;
			}
			data = mod;
			break;
		}
		case ConditionEffect::REGEN_HEALTH:
		case ConditionEffect::REGEN_MANA:
		case ConditionEffect::REGEN_SOUL:
		{
			if(revision != 1){
				return false;
			}
			uint32_t value;
			if(!propStream.GET_VALUE(value)){
				return false;
			}

			ConditionEffect::ModRegen mod;
			mod.type = PlayerStatType::fromInteger(value);

			if(!propStream.GET_VALUE(mod.percent)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.value)){
				return false;
			}
			data = mod;
			break;
		}
		case ConditionEffect::MOD_SPEED:
		{
			if(revision != 1){
				return false;
			}
			ConditionEffect::ModSpeed mod;
			if(!propStream.GET_VALUE(mod.percent)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.value)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.delta)){
				return false;
			}
			data = mod;
			break;
		}
		case ConditionEffect::MOD_STAT:
		{
			if(revision != 1){
				return false;
			}
			uint32_t value;
			if(!propStream.GET_VALUE(value)){
				return false;
			}

			ConditionEffect::ModStat mod;
			mod.type = PlayerStatType::fromInteger(value);

			if(!propStream.GET_VALUE(mod.percent)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.value)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.delta)){
				return false;
			}
			data = mod;
			break;
		}
		case ConditionEffect::MOD_SKILL:
		{
			if(revision != 1){
				return false;
			}
			uint32_t value;
			if(!propStream.GET_VALUE(value)){
				return false;
			}

			ConditionEffect::ModSkill mod;
			mod.type = SkillType::fromInteger(value);

			if(!propStream.GET_VALUE(mod.percent)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.value)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.delta)){
				return false;
			}
			data = mod;
			break;
		}
		case ConditionEffect::SHAPESHIFT:
		{
			if(revision != 1){
				return false;
			}
			ConditionEffect::ModShapeShift mod;
			if(!propStream.GET_VALUE(mod.lookType)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.lookTypeEx)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.lookHead)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.lookBody)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.lookLegs)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.lookFeet)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.lookAddons)){
				return false;
			}
			data = mod;
			break;
		}
		case ConditionEffect::LIGHT:
		{
			if(revision != 1){
				return false;
			}
			ConditionEffect::ModLight mod;
			if(!propStream.GET_VALUE(mod.level)){
				return false;
			}
			if(!propStream.GET_VALUE(mod.color)){
				return false;
			}
			data = mod;
			break;
		}
		case ConditionEffect::DISPEL:
		{
			if(revision != 1){
				return false;
			}
			ConditionEffect::ModDispel mod;
			if(!propStream.GET_STRING(mod.name)){
				return false;
			}
			data = mod;
			break;
		}

		case ConditionEffect::SCRIPT:
		{
			if(revision != 1){
				return false;
			}
			ConditionEffect::ModScript mod;
			if(!propStream.GET_STRING(mod.name)){
				return false;
			}
			data = mod;
			break;
		}
		default: return false;
	}

	return true;
}
Пример #21
0
int Items::loadFromOtb(std::string file)
{
	ItemLoader f;
	if(!f.openFile(file.c_str(), false, true)){
		return f.getError();
	}
	
	unsigned long type;
	NODE node = f.getChildNode(NO_NODE, type);
	
	PropStream props;
	if(f.getProps(node,props)){
		//4 byte flags
		//attributes
		//0x01 = version data
		unsigned long flags;
		if(!props.GET_ULONG(flags)){
			return ERROR_INVALID_FORMAT;
		}
		attribute_t attr;
		if(!props.GET_VALUE(attr)){
			return ERROR_INVALID_FORMAT;
		}
		if(attr == ROOT_ATTR_VERSION){
			datasize_t datalen = 0;
			if(!props.GET_VALUE(datalen)){
				return ERROR_INVALID_FORMAT;
			}
			if(datalen != sizeof(VERSIONINFO)){
				return ERROR_INVALID_FORMAT;
			}
			VERSIONINFO *vi;
			if(!props.GET_STRUCT(vi)){
				return ERROR_INVALID_FORMAT;
			}
			Items::dwMajorVersion = vi->dwMajorVersion;	//items otb format file version
			Items::dwMinorVersion = vi->dwMinorVersion; //client version
			Items::dwBuildNumber = vi->dwBuildNumber;	//revision
		}
	}
	
	if(Items::dwMajorVersion != 1){
		std::cout << "Not supported items.otb version." << std::endl;
		return ERROR_INVALID_FORMAT;
	}
	
	if(Items::dwMinorVersion != CLIENT_VERSION_760){
		std::cout << "Not supported items.otb client version." << std::endl;
		return ERROR_INVALID_FORMAT;
	}
	
	node = f.getChildNode(node, type);

	while(node != NO_NODE){
		PropStream props;	
		if(!f.getProps(node,props)){
			return f.getError();	
		}
			
		flags_t flags;
		ItemType* iType = new ItemType();
		iType->group = (itemgroup_t)type;

		switch(type){
		case ITEM_GROUP_NONE:
		case ITEM_GROUP_GROUND:
		case ITEM_GROUP_CONTAINER:
		case ITEM_GROUP_WEAPON:
		case ITEM_GROUP_AMMUNITION:
		case ITEM_GROUP_ARMOR:
		case ITEM_GROUP_RUNE:
		case ITEM_GROUP_TELEPORT:
		case ITEM_GROUP_MAGICFIELD:
		case ITEM_GROUP_WRITEABLE:
		case ITEM_GROUP_KEY:
		case ITEM_GROUP_SPLASH:
		case ITEM_GROUP_FLUID:
		case ITEM_GROUP_DOOR:
			break;
		default:
			return ERROR_INVALID_FORMAT;
			break;
		}

		//read 4 byte flags
		if(!props.GET_VALUE(flags)){
			return ERROR_INVALID_FORMAT;
		}

		iType->blockSolid = ((flags & FLAG_BLOCK_SOLID) == FLAG_BLOCK_SOLID);
		iType->blockProjectile = ((flags & FLAG_BLOCK_PROJECTILE) == FLAG_BLOCK_PROJECTILE);
		iType->blockPathFind = ((flags & FLAG_BLOCK_PATHFIND) == FLAG_BLOCK_PATHFIND);
		iType->hasHeight = ((flags & FLAG_HAS_HEIGHT) == FLAG_HAS_HEIGHT);
		iType->useable = ((flags & FLAG_USEABLE) == FLAG_USEABLE);
		iType->pickupable = ((flags & FLAG_PICKUPABLE) == FLAG_PICKUPABLE);
		iType->moveable = ((flags & FLAG_MOVEABLE) == FLAG_MOVEABLE);
		iType->stackable = ((flags & FLAG_STACKABLE) == FLAG_STACKABLE);
		iType->floorChangeDown = ((flags & FLAG_FLOORCHANGEDOWN) == FLAG_FLOORCHANGEDOWN);
		iType->floorChangeNorth = ((flags & FLAG_FLOORCHANGENORTH) == FLAG_FLOORCHANGENORTH);
		iType->floorChangeEast = ((flags & FLAG_FLOORCHANGEEAST) == FLAG_FLOORCHANGEEAST);
		iType->floorChangeSouth = ((flags & FLAG_FLOORCHANGESOUTH) == FLAG_FLOORCHANGESOUTH);
		iType->floorChangeWest = ((flags & FLAG_FLOORCHANGEWEST) == FLAG_FLOORCHANGEWEST);
		iType->alwaysOnTop = ((flags & FLAG_ALWAYSONTOP) == FLAG_ALWAYSONTOP);
		iType->canDecay = !((flags & FLAG_CANNOTDECAY) == FLAG_CANNOTDECAY);
		iType->isVertical = ((flags & FLAG_VERTICAL) == FLAG_VERTICAL);
		iType->isHorizontal = ((flags & FLAG_HORIZONTAL) == FLAG_HORIZONTAL);
		iType->isHangable = ((flags & FLAG_HANGABLE) == FLAG_HANGABLE);
		iType->allowDistRead = ((flags & FLAG_ALLOWDISTREAD) == FLAG_ALLOWDISTREAD);
							
							
		if(type == ITEM_GROUP_WRITEABLE) {
			iType->RWInfo |= CAN_BE_WRITTEN;
		}

		if((flags & FLAG_READABLE) == FLAG_READABLE)
			iType->RWInfo |= CAN_BE_READ;

		iType->rotable = ((flags & FLAG_ROTABLE) == FLAG_ROTABLE);
		
		attribute_t attrib;
		datasize_t datalen = 0;
		while(props.GET_VALUE(attrib)){
			//size of data
			if(!props.GET_VALUE(datalen)){
				delete iType;
				return ERROR_INVALID_FORMAT;
			}
	
			switch(attrib){
			case ITEM_ATTR_SERVERID:
			{
				if(datalen != sizeof(unsigned short))
					return ERROR_INVALID_FORMAT;
				
				unsigned short serverid;				
				if(!props.GET_USHORT(serverid))
					return ERROR_INVALID_FORMAT;
				
				if(serverid > 20000 && serverid < 20100)
					serverid = serverid - 20000;
						
				iType->id = serverid;
				break;
			}
			case ITEM_ATTR_CLIENTID:
			{
				if(datalen != sizeof(unsigned short))
					return ERROR_INVALID_FORMAT;

				if(!props.GET_USHORT(iType->clientId))
					return ERROR_INVALID_FORMAT;
				
				break;
			}		
			case ITEM_ATTR_NAME:
			{
				char name[128];
				if(datalen >= sizeof(name))
					return ERROR_INVALID_FORMAT;

				if(!props.GET_NSTRING(datalen, iType->name))
					return ERROR_INVALID_FORMAT;
				
				break;
			}	
			case ITEM_ATTR_DESCR:
			{
				char descr[128];
				if(datalen >= sizeof(descr))
					return ERROR_INVALID_FORMAT;
	
				if(!props.GET_NSTRING(datalen, iType->description))
					return ERROR_INVALID_FORMAT;

				break;
			}	
			case ITEM_ATTR_SPEED:
			{
				if(datalen != sizeof(unsigned short))
					return ERROR_INVALID_FORMAT;

				if(!props.GET_USHORT(iType->speed))
					return ERROR_INVALID_FORMAT;

				break;
			}					
			case ITEM_ATTR_SLOT:
			{
				if(datalen != sizeof(unsigned short))
					return ERROR_INVALID_FORMAT;
				
				unsigned short otb_slot;
				
				if(!props.GET_USHORT(otb_slot))
					return ERROR_INVALID_FORMAT;
				
				switch(otb_slot){
				case OTB_SLOT_DEFAULT:
				case OTB_SLOT_WEAPON:
				case OTB_SLOT_HAND:
					//default	
					break;
				case OTB_SLOT_HEAD:
					iType->slot_position = SLOTP_HEAD;
					break;
				case OTB_SLOT_BODY:
					iType->slot_position = SLOTP_ARMOR;
					break;
				case OTB_SLOT_LEGS:
					iType->slot_position = SLOTP_LEGS;
					break;
				case OTB_SLOT_BACKPACK:
					iType->slot_position = SLOTP_BACKPACK;
					break;
				case OTB_SLOT_2HAND:
					iType->slot_position  = SLOTP_TWO_HAND;
					break;
				case OTB_SLOT_FEET:
					iType->slot_position = SLOTP_FEET;
					break;
				case OTB_SLOT_AMULET:
					iType->slot_position = SLOTP_NECKLACE;
					break;
				case OTB_SLOT_RING:
					iType->slot_position = SLOTP_RING;
					break;
					}
				iType->slot_position = iType->slot_position | SLOTP_LEFT | SLOTP_RIGHT | SLOTP_AMMO;
				break;
			}	
			case ITEM_ATTR_MAXITEMS:
			{
				if(datalen != sizeof(unsigned short))
					return ERROR_INVALID_FORMAT;
				
				if(!props.GET_USHORT(iType->maxItems))
					return ERROR_INVALID_FORMAT;

				break;
			}		
			case ITEM_ATTR_WEIGHT:
			{
				if(datalen != sizeof(double))
					return ERROR_INVALID_FORMAT;

				if(!props.GET_VALUE(iType->weight))
					return ERROR_INVALID_FORMAT;

				break;
			}
			case ITEM_ATTR_MAGLEVEL:
			{
				if(datalen != sizeof(unsigned short))
					return ERROR_INVALID_FORMAT;
					
				unsigned short maglev;
				if(!props.GET_USHORT(maglev))
					return ERROR_INVALID_FORMAT;
				
				iType->runeMagLevel = maglev;
				break;
			}
			case ITEM_ATTR_MAGFIELDTYPE:
			{
				if(datalen != sizeof(unsigned char))
					return ERROR_INVALID_FORMAT;
				
				unsigned char fieldtype;
				if(!props.GET_UCHAR(fieldtype))
					return ERROR_INVALID_FORMAT;

				iType->magicfieldtype = fieldtype;
				break;
			}	
			case ITEM_ATTR_ROTATETO:
			{
				if(datalen != sizeof(unsigned short))
					return ERROR_INVALID_FORMAT;
				
				unsigned short rotate;
				if(!props.GET_USHORT(rotate))
					return ERROR_INVALID_FORMAT;
				
				iType->rotateTo = rotate;
				break;
			}	
			case ITEM_ATTR_DECAY2:
			{
				if(datalen != sizeof(decayBlock2))
					return ERROR_INVALID_FORMAT;

				decayBlock2* db2;
				if(!props.GET_STRUCT(db2))
					return ERROR_INVALID_FORMAT;
				
				iType->decayTime = db2->decayTime;
				iType->decayTo = db2->decayTo;
				break;
			}	
			case ITEM_ATTR_WEAPON2:
			{
				if(datalen != sizeof(weaponBlock2))
					return ERROR_INVALID_FORMAT;

				weaponBlock2* wb2;
				if(!props.GET_STRUCT(wb2))
					return ERROR_INVALID_FORMAT;
				
				iType->weaponType = (WeaponType_t)wb2->weaponType;
				iType->shootType = translateOTBShootType((ShootTypeOtb_t)wb2->shootType);
				iType->amuType = (Ammo_t)wb2->amuType;
				iType->attack = wb2->attack;
				iType->defence = wb2->defence;
				break;
			}
			case ITEM_ATTR_AMU2:
			{
				if(datalen != sizeof(amuBlock2))
					return ERROR_INVALID_FORMAT;

				amuBlock2* ab2;
				if(!props.GET_STRUCT(ab2))
					return ERROR_INVALID_FORMAT;
					
				iType->weaponType = WEAPON_AMMO;
				iType->shootType = translateOTBShootType((ShootTypeOtb_t)ab2->shootType);
				iType->amuType = (Ammo_t)ab2->amuType;
				iType->attack = ab2->attack;
				break;
			}
			case ITEM_ATTR_ARMOR2:
			{
				if(datalen != sizeof(armorBlock2))
					return ERROR_INVALID_FORMAT;

				armorBlock2* ab2;
				if(!props.GET_STRUCT(ab2))
					return ERROR_INVALID_FORMAT;
				
				iType->armor = ab2->armor;
				iType->weight = ab2->weight;
				//ignore this value
				//iType->slot_position = (slots_t)ab2.slot_position;

				break;
			}
			case ITEM_ATTR_WRITEABLE3:
			{
				if(datalen != sizeof(writeableBlock3))
					return ERROR_INVALID_FORMAT;

				writeableBlock3* wb3;
				if(!props.GET_STRUCT(wb3))
					return ERROR_INVALID_FORMAT;
					
				iType->readOnlyId = wb3->readOnlyId;
				iType->maxTextLen = wb3->maxTextLen;

				break;
			}	
			case ITEM_ATTR_LIGHT2:
			{
				if(datalen != sizeof(lightBlock2))
					return ERROR_INVALID_FORMAT;

				lightBlock2* lb2;
				if(!props.GET_STRUCT(lb2))
					return ERROR_INVALID_FORMAT;
			
				iType->lightLevel = lb2->lightLevel;
				iType->lightColor = lb2->lightColor;
				break;
			}
			case ITEM_ATTR_TOPORDER:
			{
				if(datalen != sizeof(unsigned char))
					return ERROR_INVALID_FORMAT;
				
				if(!props.GET_UCHAR(iType->alwaysOnTopOrder))
					return ERROR_INVALID_FORMAT;
				break;
			}
			default:
				//skip unknown attributes
				if(!props.SKIP_N(datalen))
					return ERROR_INVALID_FORMAT;
				break;
			}
		}
		
		//get rune mag level from spells.xml
		if(iType->group == ITEM_GROUP_RUNE){
			/*
			std::map<unsigned short, Spell*>::iterator it = spells.getAllRuneSpells()->find(iType->id);
			if(it != spells.getAllRuneSpells()->end()){
				iType->runeMagLevel = it->second->getMagLv();
			}
			else{
				iType->runeMagLevel = 0;
			}
			*/
		}

		// store the found item	 
		items[iType->id] = iType;
		//revItems[iType->clientId] = iType->id;
		
		node = f.getNextNode(node, type);
	}
	
	return ERROR_NONE;
}