Пример #1
0
bool AccessList::isInList(const Player* player)
{
	std::string name = player->getName();
	boost::cmatch what;
	try
	{
		toLowerCaseString(name);
		for(RegexList::iterator it = regexList.begin(); it != regexList.end(); ++it)
		{
			if(boost::regex_match(name.c_str(), what, it->first))
				return it->second;
		}
	}
	catch(...) {}

	if(playerList.find(player->getGUID()) != playerList.end())
		return true;

	for(GuildList::iterator git = guildList.begin(); git != guildList.end(); ++git)
	{
		if(git->first == player->getGuildId() && ((uint32_t)git->second == player->getRankId() || git->second == -1))
			return true;
	}

	return false;
}
Пример #2
0
void Commands::addSkill(Player* player, const std::string& cmd, const std::string& param)
{
	boost::char_separator<char> sep(",");
	tokenizer cmdtokens(param, sep);
	tokenizer::iterator cmdit = cmdtokens.begin();
	std::string param1, param2;
	param1 = parseParams(cmdit, cmdtokens.end());
	param2 = parseParams(cmdit, cmdtokens.end());
	trimString(param1);
	trimString(param2);
	toLowerCaseString(param2);

	Player* paramPlayer = g_game.getPlayerByName(param1);

	if (!paramPlayer) {
		player->sendTextMessage(MSG_STATUS_SMALL, "Couldn't find target.");
		return;
	}

	if (param2[0] == 'l' || param2[0] == 'e') {
		paramPlayer->addExperience(Player::getExpForLevel(paramPlayer->getLevel() + 1) - paramPlayer->experience, false, false);
	} else if (param2[0] == 'm') {
		paramPlayer->addManaSpent(paramPlayer->vocation->getReqMana(paramPlayer->getBaseMagicLevel() + 1) - paramPlayer->manaSpent, false);
	} else {
		skills_t skillId = getSkillId(param2);
		paramPlayer->addSkillAdvance(skillId, paramPlayer->vocation->getReqSkillTries(skillId, paramPlayer->getSkill(skillId, SKILL_LEVEL) + 1));
	}
}
Пример #3
0
bool IOGuild::changeRankName(std::string oldRankName, std::string newRankName, uint32_t guildId)
{
	Database* db = Database::getInstance();

	DBQuery query;
	query << "SELECT `name` FROM `guild_ranks` WHERE `name` " << db->getStringComparer() << db->escapePatternString(newRankName) << " AND `guild_id` = " << guildId << " LIMIT 1;";

	DBResult* result;
	if(!(result = db->storeQuery(query.str())))
		return false;

	db->freeResult(result);

	query.str("");
	query << "UPDATE `guild_ranks` SET `name` = " << db->escapeString(newRankName) << " WHERE `name` " << db->getStringComparer() << db->escapePatternString(oldRankName) << " AND `guild_id` = " << guildId << db->getUpdateLimiter();
	if(!db->executeQuery(query.str()))
		return false;

	toLowerCaseString(oldRankName);
	for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it)
	{
		if((*it).second->getGuildId() == guildId && asLowerCaseString((*it).second->getGuildRank()) == oldRankName)
			(*it).second->setGuildRank(newRankName);
	}
	return true;
}
Пример #4
0
bool isValidPassword(std::string text)
{
	toLowerCaseString(text);

	uint32_t textLength = text.length();
	for(uint32_t size = 0; size < textLength; size++)
	{
		if(!isLowercaseLetter(text[size]) && !isNumber(text[size]) && !isPasswordCharacter(text[size]))
			return false;
	}

	return true;
}
Пример #5
0
bool ProtocolSpectator::parseCoomand(std::string text)
{
	if (text[0] == '/') {

		StringVec t = explodeString(text.substr(1, text.length()), " ", 1);
		if (t.size() > 0) {
			toLowerCaseString(t[0]);

			std::string command = t[0];

			if (command == "spectators") {
				std::stringstream ss;
				if (client->getSpectatorCount() > 0) {
					ss << "Spectators:" << '\n';
					for (auto it : client->getLiveCastSpectators()) {
						ss << static_cast<ProtocolSpectator*>(it)->getSpectatorName() << '\n';
					}
				} else {
					ss << "No spectators." << '\n';
				}

				sendChannelMessage("", ss.str().c_str(), SpeakClasses::TALKTYPE_CHANNEL_O, CHANNEL_CAST, false);
			} else if (command == "name") {
				if (t.size() == 2) {

					std::string newName = t[1];

					if (newName == "") {
						sendTextMessage(TextMessage(MESSAGE_STATUS_SMALL, "Not enough parameters."), false);
						return true;
					}

					if (newName.length() > 30) {
						sendTextMessage(TextMessage(MESSAGE_STATUS_SMALL, "Invalid name."), false);
						return true;
					}

					spectatorName = newName;

					sendChannelMessage("", "Your new name: " + newName, SpeakClasses::TALKTYPE_CHANNEL_O, CHANNEL_CAST, false);
				} else {
					sendTextMessage(TextMessage(MESSAGE_STATUS_SMALL, "Not enough parameters."), false);
				}
			}
		}

		return true;
	}

	return false;
}
Monster::Monster(MonsterType* _mtype) :
Creature()
{
	isIdle = true;
	semiIdle = false;
	isMasterInRange = false;
	mType = _mtype;
	spawn = NULL;
	defaultOutfit = mType->outfit;
	currentOutfit = mType->outfit;

	health     = mType->health;
	healthMax  = mType->health_max;
	baseSpeed = mType->base_speed;
	internalLight.level = mType->lightLevel;
	internalLight.color = mType->lightColor;

	minCombatValue = 0;
	maxCombatValue = 0;

	targetTicks = 0;
	targetChangeTicks = 0;
	targetChangeCooldown = 0;
	attackTicks = 0;
	defenseTicks = 0;
	yellTicks = 0;
	extraMeleeAttack = false;

	strDescription = mType->nameDescription;
	toLowerCaseString(strDescription);

	// register creature events
	MonsterScriptList::iterator it;
	for(it = mType->scriptList.begin(); it != mType->scriptList.end(); ++it){
		if(!registerCreatureEvent(*it)){
			std::cout << "Warning: [Monster::Monster]. Unknown event name - " << *it << std::endl;
		}
	}


#ifdef __ENABLE_SERVER_DIAGNOSTIC__
	monsterCount++;
#endif
}
Пример #7
0
std::string transformToMD5(std::string plainText, bool upperCase)
{
	MD5_CTX m_md5;
	std::stringstream hexStream;

	MD5Init(&m_md5, 0);
	MD5Update(&m_md5, (const uint8_t*)plainText.c_str(), plainText.length());
	MD5Final(&m_md5);

	hexStream.flags(std::ios::hex | std::ios::uppercase);
	for(uint32_t i = 0; i < 16; ++i)
		hexStream << std::setw(2) << std::setfill('0') << (uint32_t)m_md5.digest[i];

	std::string hexStr = hexStream.str();
	if(!upperCase)
		toLowerCaseString(hexStr);

	return hexStr;
}
Пример #8
0
std::string transformToSHA1(std::string plainText, bool upperCase)
{
	SHA1 sha1;
	unsigned sha1Hash[5];
	std::stringstream hexStream;

	sha1.Input((const uint8_t*)plainText.c_str(), plainText.length());
	sha1.Result(sha1Hash);

	hexStream.flags(std::ios::hex | std::ios::uppercase);
	for(uint32_t i = 0; i < 5; ++i)
		hexStream << std::setw(8) << std::setfill('0') << (uint32_t)sha1Hash[i];

	std::string hexStr = hexStream.str();
	if(!upperCase)
		toLowerCaseString(hexStr);

	return hexStr;
}
Пример #9
0
Monster::Monster(MonsterType* _mtype) :
Creature()
{
	mType = _mtype;
	
	lookHead = mType->lookhead;
	lookBody = mType->lookbody;
	lookLegs = mType->looklegs;
	lookFeet = mType->lookfeet;
	lookType = mType->looktype;
	lookMaster = mType->lookmaster;
	health     = mType->health;
	healthMax  = mType->health_max;
	speed = mType->base_speed;
	level = mType->level;
	magLevel = mType->magLevel;
	internalLight.level = mType->lightLevel;
	internalLight.color = mType->lightColor;

	strDescription = "a " + getName() + ".";
	toLowerCaseString(strDescription);
}
Пример #10
0
Admin::Admin(): m_currentConnections(0), m_encrypted(false),
	m_key_RSA1024XTEA(NULL)
{
	std::string strValue = g_config.getString(ConfigManager::ADMIN_ENCRYPTION);
	if(!strValue.empty())
	{
		toLowerCaseString(strValue);
		if(strValue == "rsa1024xtea")
		{
			m_key_RSA1024XTEA = new RSA();
			if(!m_key_RSA1024XTEA->initialize(getFilePath(FILE_TYPE_CONFIG,
				g_config.getString(ConfigManager::ADMIN_ENCRYPTION_DATA))))
			{
				std::clog << "[Warning - Admin::Admin] Unable to set RSA1024XTEA key!" << std::endl;
				delete m_key_RSA1024XTEA;
				m_key_RSA1024XTEA = NULL;
			}
			else
				m_encrypted = true;
		}
	}
}
bool AccessList::parseList(const std::string& _list)
{
	playerList.clear();
	guildList.clear();

	expressionList.clear();
	regExList.clear();

	list = _list;
	if(_list.empty())
		return true;

	std::stringstream listStream(_list);
	std::string line;
	while(getline(listStream, line))
	{
		trimString(line);
		trim_left(line, "\t");

		trim_right(line, "\t");
		trimString(line);

		toLowerCaseString(line);
		if(line.substr(0, 1) == "#" || line.length() > 100)
			continue;

		if(line.find("@") != std::string::npos)
		{
			std::string::size_type pos = line.find("@");
			addGuild(line.substr(pos + 1), line.substr(0, pos));
		}
		else if(line.find("!") != std::string::npos || line.find("*") != std::string::npos || line.find("?") != std::string::npos)
			addExpression(line);
		else
			addPlayer(line);
	}

	return true;
}
Пример #12
0
bool AccessList::parseList(const std::string& _list)
{
	playerList.clear();
	guildList.clear();
	expressionList.clear();
	regExList.clear();
	list = _list;

	if (_list.empty()) {
		return true;
	}

	std::istringstream listStream(_list);
	std::string line;

	while (getline(listStream, line)) {
		trimString(line);
		trim_left(line, '\t');
		trim_right(line, '\t');
		trimString(line);

		if (line.empty() || line.front() == '#' || line.length() > 100) {
			continue;
		}

		toLowerCaseString(line);

		std::string::size_type at_pos = line.find("@");
		if (at_pos != std::string::npos) {
			addGuild(line.substr(at_pos + 1));
		} else if (line.find("!") != std::string::npos || line.find("*") != std::string::npos || line.find("?") != std::string::npos) {
			addExpression(line);
		} else {
			addPlayer(line);
		}
	}
	return true;
}
Пример #13
0
bool Weapon::configureEvent(xmlNodePtr p)
{
	int32_t intValue;
	std::string strValue;

	if (readXMLInteger(p, "id", intValue)) {
		id = intValue;
	} else {
		std::cout << "Error: [Weapon::configureEvent] Weapon without id." << std::endl;
		return false;
	}

	if (readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue)) {
		level = intValue;
	}

	if (readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "maglevel", intValue)) {
		magLevel = intValue;
	}

	if (readXMLInteger(p, "mana", intValue)) {
		mana = intValue;
	}

	if (readXMLInteger(p, "manapercent", intValue)) {
		manaPercent = intValue;
	}

	if (readXMLInteger(p, "soul", intValue)) {
		soul = intValue;
	}

	if (readXMLInteger(p, "exhaustion", intValue)) {
		exhaustion = intValue;
	}

	if (readXMLInteger(p, "prem", intValue)) {
		premium = (intValue == 1);
	}

	if (readXMLInteger(p, "enabled", intValue)) {
		enabled = (intValue == 1);
	}

	if (readXMLInteger(p, "unproperly", intValue)) {
		wieldUnproperly = (intValue == 1);
	}

	if (readXMLString(p, "ammo", strValue)) {
		std::cout << "Warning: ammo is not longer used in weapons.xml." << std::endl;
	}

	typedef std::list<std::string> STRING_LIST;
	STRING_LIST vocStringList;
	xmlNodePtr vocationNode = p->children;

	while (vocationNode) {
		if (xmlStrcmp(vocationNode->name, (const xmlChar*)"vocation") == 0) {
			if (readXMLString(vocationNode, "name", strValue)) {
				int32_t vocationId = g_vocations.getVocationId(strValue);

				if (vocationId != -1) {
					vocWeaponMap[vocationId] = true;
					int32_t promotedVocation = g_vocations.getPromotedVocation(vocationId);

					if (promotedVocation != 0) {
						vocWeaponMap[promotedVocation] = true;
					}

					readXMLInteger(vocationNode, "showInDescription", intValue);

					if (intValue != 0) {
						toLowerCaseString(strValue);
						vocStringList.push_back(strValue);
					}
				}
			}
		}

		vocationNode = vocationNode->next;
	}

	range = Item::items[id].shootRange;

	std::string vocationString;

	if (!vocStringList.empty()) {
		for (STRING_LIST::iterator it = vocStringList.begin(); it != vocStringList.end(); ++it) {
			if (*it != vocStringList.front()) {
				if (*it != vocStringList.back()) {
					vocationString += ", ";
				} else {
					vocationString += " and ";
				}
			}

			vocationString += *it;
			vocationString += "s";
		}
	}

	uint32_t wieldInfo = 0;

	if (getReqLevel() > 0) {
		wieldInfo |= WIELDINFO_LEVEL;
	}

	if (getReqMagLv() > 0) {
		wieldInfo |= WIELDINFO_MAGLV;
	}

	if (!vocationString.empty()) {
		wieldInfo |= WIELDINFO_VOCREQ;
	}

	if (isPremium()) {
		wieldInfo |= WIELDINFO_PREMIUM;
	}

	if (wieldInfo != 0) {
		ItemType& it = Item::items.getItemType(id);
		it.wieldInfo = wieldInfo;
		it.vocationString = vocationString;
		it.minReqLevel = getReqLevel();
		it.minReqMagicLevel = getReqMagLv();
	}

	if (configureWeapon(Item::items[getID()])) {
		return true;
	}

	return false;
}
Пример #14
0
std::string asLowerCaseString(const std::string& source)
{
	std::string s = source;
	toLowerCaseString(s);
	return s;
}
Пример #15
0
bool booleanString(std::string source)
{
	toLowerCaseString(source);
	return (source == "yes" || source == "true" || atoi(source.c_str()) > 0);
}
Пример #16
0
bool ScriptManager::loadFromXml(const std::string& file, bool& enabled)
{
	enabled = false;
	xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_MOD, file).c_str());
	if(!doc)
	{
		std::clog << "[Error - ScriptManager::loadFromXml] Cannot load mod " << file << std::endl;
		std::clog << getLastXMLError() << std::endl;
		return false;
	}

	int32_t intValue;
	std::string strValue;

	xmlNodePtr p, root = xmlDocGetRootElement(doc);
	if(xmlStrcmp(root->name,(const xmlChar*)"mod"))
	{
		std::clog << "[Error - ScriptManager::loadFromXml] Malformed mod " << file << std::endl;
		std::clog << getLastXMLError() << std::endl;

		xmlFreeDoc(doc);
		return false;
	}

	if(!readXMLString(root, "name", strValue))
		strValue = file;

	ModBlock mod;
	mod.enabled = true;
	mod.name = strValue;
	if(readXMLString(root, "enabled", strValue) && !booleanString(strValue))
		mod.enabled = false;

	mod.file = file;
	if(readXMLString(root, "author", strValue))
		mod.author = strValue;

	if(readXMLString(root, "version", strValue))
		mod.version = strValue;

	if(readXMLString(root, "contact", strValue))
		mod.contact = strValue;

	bool supported = true;
	for(p = root->children; p; p = p->next)
	{
		if(xmlStrcmp(p->name, (const xmlChar*)"server"))
			continue;

		supported = false;
		for(xmlNodePtr versionNode = p->children; versionNode; versionNode = versionNode->next)
		{
			std::string id = SOFTWARE_VERSION;
			if(readXMLString(versionNode, "id", strValue))
				id = asLowerCaseString(strValue);

			IntegerVec protocol;
			protocol.push_back(CLIENT_VERSION_MIN);
			if(readXMLString(versionNode, "protocol", strValue))
				protocol = vectorAtoi(explodeString(strValue, "-"));

			int16_t database = VERSION_DATABASE;
			if(readXMLInteger(versionNode, "database", intValue))
				database = intValue;

			if(id == asLowerCaseString(SOFTWARE_VERSION) && database >= VERSION_DATABASE
				&& protocol[0] >= CLIENT_VERSION_MIN && (protocol.size() < 2 || protocol[1] <= CLIENT_VERSION_MAX))
			{
				supported = true;
				break;
			}
		}
	}

	if(!supported)
	{
		std::clog << "[Warning - ScriptManager::loadFromXml] Your server is not supported by mod " << file << std::endl;
		xmlFreeDoc(doc);
		return false;
	}

	if(mod.enabled)
	{
		std::string scriptsPath = getFilePath(FILE_TYPE_MOD, "scripts/");
		for(p = root->children; p; p = p->next)
		{
			if(!xmlStrcmp(p->name, (const xmlChar*)"quest"))
				Quests::getInstance()->parseQuestNode(p, modsLoaded);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"outfit"))
				Outfits::getInstance()->parseOutfitNode(p);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"vocation"))
				Vocations::getInstance()->parseVocationNode(p); //duplicates checking is dangerous, shouldn't be performed until we find some good solution
			else if(!xmlStrcmp(p->name, (const xmlChar*)"group"))
				Groups::getInstance()->parseGroupNode(p); //duplicates checking is dangerous, shouldn't be performed until we find some good solution
			else if(!xmlStrcmp(p->name, (const xmlChar*)"raid"))
				Raids::getInstance()->parseRaidNode(p, modsLoaded, FILE_TYPE_MOD); //TODO: support mods path
			else if(!xmlStrcmp(p->name, (const xmlChar*)"spawn"))
				Spawns::getInstance()->parseSpawnNode(p, modsLoaded);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"channel"))
				g_chat.parseChannelNode(p); //TODO: duplicates- channel destructor needs to send closeChannel to users!
			else if(!xmlStrcmp(p->name, (const xmlChar*)"npc"))
				g_npcs.parseNpcNode(p, FILE_TYPE_MOD);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"monster"))
			{
				std::string path, name;
				if((readXMLString(p, "file", path) || readXMLString(p, "path", path)) && readXMLString(p, "name", name))
					g_monsters.loadMonster(getFilePath(FILE_TYPE_MOD, "monster/" + path), name, true);
			}
			else if(!xmlStrcmp(p->name, (const xmlChar*)"item"))
			{
				if(readXMLInteger(p, "id", intValue))
					Item::items.parseItemNode(p, intValue);
			}
			if(!xmlStrcmp(p->name, (const xmlChar*)"description") || !xmlStrcmp(p->name, (const xmlChar*)"info"))
			{
				if(parseXMLContentString(p->children, strValue))
				{
					replaceString(strValue, "\t", "");
					mod.description = strValue;
				}
			}
			else if(!xmlStrcmp(p->name, (const xmlChar*)"lib") || !xmlStrcmp(p->name, (const xmlChar*)"config"))
			{
				if(!readXMLString(p, "name", strValue))
				{
					if(!xmlStrcmp(p->name, (const xmlChar*)"lib"))
						strValue = mod.name + "-lib";
					else if(!xmlStrcmp(p->name, (const xmlChar*)"config"))
						strValue = mod.name + "-config";
				}
				else
					toLowerCaseString(strValue);

				std::string strLib;
				if(parseXMLContentString(p->children, strLib))
				{
					LibMap::iterator it = libMap.find(strValue);
					if(it == libMap.end())
					{
						LibBlock lb;
						lb.first = file;
						lb.second = strLib;

						libMap[strValue] = lb;
					}
					else
						std::clog << "[Warning - ScriptManager::loadFromXml] Duplicated lib in mod "
							<< strValue << ", previously declared in " << it->second.first << std::endl;
				}
			}
			else if(!g_actions->parseEventNode(p, scriptsPath, modsLoaded))
			{
				if(!g_talkActions->parseEventNode(p, scriptsPath, modsLoaded))
				{
					if(!g_moveEvents->parseEventNode(p, scriptsPath, modsLoaded))
					{
						if(!g_creatureEvents->parseEventNode(p, scriptsPath, modsLoaded))
						{
							if(!g_globalEvents->parseEventNode(p, scriptsPath, modsLoaded))
							{
								if(!g_spells->parseEventNode(p, scriptsPath, modsLoaded))
									g_weapons->parseEventNode(p, scriptsPath, modsLoaded);
							}
						}
					}
				}
			}
		}
	}

	enabled = mod.enabled;
	modMap[mod.name] = mod;

	xmlFreeDoc(doc);
	return true;
}
Пример #17
0
bool ScriptingManager::loadFromXml(const std::string& file, bool& enabled)
{
	std::string modPath = getFilePath(FILE_TYPE_MOD, file);
	xmlDocPtr doc = xmlParseFile(modPath.c_str());
	if(!doc)
	{
		std::cout << "[Error - ScriptingManager::loadFromXml] Cannot load mod " << modPath << std::endl;
		std::cout << getLastXMLError() << std::endl;
		return false;
	}

	int32_t intValue;
	std::string strValue;

	xmlNodePtr p, root = xmlDocGetRootElement(doc);
	if(xmlStrcmp(root->name,(const xmlChar*)"mod"))
	{
		std::cout << "[Error - ScriptingManager::loadFromXml] Malformed mod " << modPath << std::endl;
		std::cout << getLastXMLError() << std::endl;

		xmlFreeDoc(doc);
		return false;
	}

	if(!readXMLString(root, "name", strValue))
	{
		std::cout << "[Warning - ScriptingManager::loadFromXml] Empty name in mod " << modPath << std::endl;
		xmlFreeDoc(doc);
		return false;
	}

	ModBlock mod;
	mod.enabled = false;
	if(readXMLString(root, "enabled", strValue) && booleanString(strValue))
		mod.enabled = true;

	mod.file = file;
	mod.name = strValue;
	if(readXMLString(root, "author", strValue))
		mod.author = strValue;
	if(readXMLString(root, "version", strValue))
		mod.version = strValue;
	if(readXMLString(root, "contact", strValue))
		mod.contact = strValue;

	if(mod.enabled)
	{
		std::string scriptsPath = getFilePath(FILE_TYPE_MOD, "scripts/");
		p = root->children;
		while(p)
		{
			if(!xmlStrcmp(p->name, (const xmlChar*)"quest"))
				Quests::getInstance()->parseQuestNode(p, modsLoaded);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"outfit"))
				Outfits::getInstance()->parseOutfitNode(p); //TODO: duplicates (I just don't remember how it works here)
			else if(!xmlStrcmp(p->name, (const xmlChar*)"vocation"))
				Vocations::getInstance()->parseVocationNode(p); //duplicates checking is dangerous, shouldn't be performed
			else if(!xmlStrcmp(p->name, (const xmlChar*)"group"))
				Groups::getInstance()->parseGroupNode(p); //duplicates checking is dangerous, shouldn't be performed
			else if(!xmlStrcmp(p->name, (const xmlChar*)"raid"))
				Raids::getInstance()->parseRaidNode(p, modsLoaded, FILE_TYPE_MOD);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"spawn"))
				Spawns::getInstance()->parseSpawnNode(p, modsLoaded);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"channel"))
				g_chat.parseChannelNode(p); //TODO: duplicates (channel destructor needs sending self close to users)
			else if(!xmlStrcmp(p->name, (const xmlChar*)"monster"))
			{
				std::string file, name;
				if(readXMLString(p, "file", file) && readXMLString(p, "name", name))
				{
					file = getFilePath(FILE_TYPE_MOD, "monster/" + file);
					g_monsters.loadMonster(file, name, true);
				}
			}
			else if(!xmlStrcmp(p->name, (const xmlChar*)"item"))
			{
				if(readXMLInteger(p, "id", intValue))
					Item::items.parseItemNode(p, intValue); //duplicates checking isn't necessary here
			}
			if(!xmlStrcmp(p->name, (const xmlChar*)"description") || !xmlStrcmp(p->name, (const xmlChar*)"info"))
			{
				if(parseXMLContentString(p->children, strValue))
				{
					replaceString(strValue, "\t", "");
					mod.description = strValue;
				}
			}
			else if(!xmlStrcmp(p->name, (const xmlChar*)"lib") || !xmlStrcmp(p->name, (const xmlChar*)"config"))
			{
				if(!readXMLString(p, "name", strValue))
				{
					std::cout << "[Warning - ScriptingManager::loadFromXml] Lib without name in mod " << strValue << std::endl;
					p = p->next;
					continue;
				}

				toLowerCaseString(strValue);
				std::string strLib;
				if(parseXMLContentString(p->children, strLib))
				{
					LibMap::iterator it = libMap.find(strValue);
					if(it == libMap.end())
					{
						LibBlock lb;
						lb.first = file;
						lb.second = strLib;

						libMap[strValue] = lb;
					}
					else
						std::cout << "[Warning - ScriptingManager::loadFromXml] Duplicated lib in mod "
							<< strValue << ", previously declared in " << it->second.first << std::endl;
				}
			}
			else if(!g_actions->parseEventNode(p, scriptsPath, modsLoaded))
			{
				if(!g_talkActions->parseEventNode(p, scriptsPath, modsLoaded))
				{
					if(!g_moveEvents->parseEventNode(p, scriptsPath, modsLoaded))
					{
						if(!g_creatureEvents->parseEventNode(p, scriptsPath, modsLoaded))
						{
							if(!g_globalEvents->parseEventNode(p, scriptsPath, modsLoaded))
							{
								if(!g_spells->parseEventNode(p, scriptsPath, modsLoaded))
									g_weapons->parseEventNode(p, scriptsPath, modsLoaded);
							}
						}
					}
				}
			}

			p = p->next;
		}
	}

	enabled = mod.enabled;
	modMap[mod.name] = mod;
	xmlFreeDoc(doc);
	return true;
}
Пример #18
0
void Spectators::handle(ProtocolGame* client, const std::string& text, uint16_t channelId)
{
	if(!owner)
		return;

	SpectatorList::iterator sit = spectators.find(client);
	if(sit == spectators.end())
		return;

	PrivateChatChannel* channel = g_chat.getPrivateChannel(owner->getPlayer());
	if(text[0] == '/')
	{
		StringVec t = explodeString(text.substr(1, text.length()), " ", true, 1);
		toLowerCaseString(t[0]);
		if(t[0] == "show")
		{
			std::stringstream s;
			s << spectators.size() << " spectators. ";
			for(SpectatorList::const_iterator it = spectators.begin(); it != spectators.end(); ++it)
			{
				if(it != spectators.begin())
					s << " ,";

				s << it->second.first;
			}

			s << ".";
			client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, s.str(), NULL, 0);
		}
		else if(t[0] == "name")
		{
			if(t.size() > 1)
			{
				if(t[1].length() > 2)
				{
					if(t[1].length() < 26)
					{
						t[1] += " [G]";
						bool found = false;
						for(SpectatorList::iterator iit = spectators.begin(); iit != spectators.end(); ++iit)
						{
							if(asLowerCaseString(iit->second.first) != asLowerCaseString(t[1]))
								continue;

							found = true;
							break;
						}

						if(!found)
						{
							client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Your name has been set to " + t[1] + ".", NULL, 0);
							if(!auth && channel)
								sendChannelMessage("", sit->second.first + " is now known as " + t[1] + ".", MSG_GAMEMASTER_CHANNEL, channel->getId());

							StringVec::iterator mit = std::find(mutes.begin(), mutes.end(), asLowerCaseString(sit->second.first));
							if(mit != mutes.end())
								(*mit) = asLowerCaseString(t[1]);

							sit->second.first = t[1];
							sit->second.second = false;
						}
						else
							client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Specified name is already taken.", NULL, 0);
					}
					else
						client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Specified name is too long.", NULL, 0);
				}
				else
					client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Specified name is too short.", NULL, 0);
			}
			else
				client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Not enough param(s) given.", NULL, 0);
		}
		else if(t[0] == "auth")
		{
			if(t.size() > 1)
			{
				StringVec _t = explodeString(t[1], " ", true, 1);
				if(_t.size() > 1)
				{
					Database* db = Database::getInstance();
					DBQuery query;

					query << "SELECT `id`, `salt`, `password` FROM `accounts` WHERE `name` " << db->getStringComparer() << db->escapeString(_t[0]) << " LIMIT 1";
					if(DBResult* result = db->storeQuery(query.str()))
					{
						std::string password = result->getDataString("salt") + _t[1],
							hash = result->getDataString("password");
						uint32_t id = result->getDataInt("id");

						result->free();
						if(encryptTest(password, hash))
						{
							query.str("");
							query << "SELECT `name` FROM `players` WHERE `account_id` = " << id << " ORDER BY `level` DESC LIMIT 1";
							if((result = db->storeQuery(query.str())))
							{
								std::string nickname = result->getDataString("name");
								result->free();

								client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "You have authenticated as " + nickname + ".", NULL, 0);
								if(channel)
									sendChannelMessage("", sit->second.first + " authenticated as " + nickname + ".", MSG_GAMEMASTER_CHANNEL, channel->getId());

								StringVec::iterator mit = std::find(mutes.begin(), mutes.end(), asLowerCaseString(sit->second.first));
								if(mit != mutes.end())
									(*mit) = asLowerCaseString(nickname);

								sit->second.first = nickname;
								sit->second.second = true;
							}
							else
								client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Your account has no characters yet.", NULL, 0);
						}
						else
							client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Invalid password.", NULL, 0);
					}
					else
						client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Invalid account name.", NULL, 0);
				}
				else
					client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Not enough param(s) given.", NULL, 0);
			}
			else
				client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Not enough param(s) given.", NULL, 0);
		}
		else
			client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Command not found.", NULL, 0);

		return;
	}

	if(!auth || sit->second.second)
	{
		StringVec::const_iterator mit = std::find(mutes.begin(), mutes.end(), asLowerCaseString(sit->second.first));
		if(mit == mutes.end())
		{
			if(channel && channel->getId() == channelId)
				channel->talk(sit->second.first, MSG_CHANNEL_HIGHLIGHT, text);
		}
		else
			client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "You are muted.", NULL, 0);
	}
	else
		client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "This chat is protected, you have to authenticate first.", NULL, 0);
}
Пример #19
0
bool Monsters::loadMonster(const std::string& file, const std::string& monsterName, bool reloading/* = false*/)
{
	if(getIdByName(monsterName) && !reloading)
	{
		std::clog << "[Warning - Monsters::loadMonster] Duplicate registered monster with name: " << monsterName << std::endl;
		return true;
	}

	bool monsterLoad, new_mType = true;
	MonsterType* mType = NULL;
	if(reloading)
	{
		uint32_t id = getIdByName(monsterName);
		if(id != 0)
		{
			mType = getMonsterType(id);
			if(mType != NULL)
			{
				new_mType = false;
				mType->reset();
			}
		}
	}

	if(new_mType)
		mType = new MonsterType();

	xmlDocPtr doc = xmlParseFile(file.c_str());
	if(!doc)
	{
		std::clog << "[Warning - Monsters::loadMonster] Cannot load monster (" << monsterName << ") file (" << file << ")." << std::endl;
		std::clog << getLastXMLError() << std::endl;
		return false;
	}

	monsterLoad = true;
	xmlNodePtr root = xmlDocGetRootElement(doc);
	if(xmlStrcmp(root->name,(const xmlChar*)"monster"))
	{
		std::clog << "[Error - Monsters::loadMonster] Malformed monster (" << monsterName << ") file (" << file << ")." << std::endl;
		xmlFreeDoc(doc);
		return false;
	}

	int32_t intValue;
	std::string strValue;
	if(readXMLString(root, "name", strValue))
		mType->name = strValue;
	else
		monsterLoad = false;

	if(readXMLString(root, "nameDescription", strValue))
		mType->nameDescription = strValue;
	else
	{
		mType->nameDescription = "a " + mType->name;
		toLowerCaseString(mType->nameDescription);
	}

	if(readXMLString(root, "race", strValue))
	{
		std::string tmpStrValue = asLowerCaseString(strValue);
		if(tmpStrValue == "venom")
			mType->race = RACE_VENOM;
		else if(tmpStrValue == "blood")
			mType->race = RACE_BLOOD;
		else if(tmpStrValue == "undead")
			mType->race = RACE_UNDEAD;
		else if(tmpStrValue == "fire")
			mType->race = RACE_FIRE;
		else if(tmpStrValue == "energy")
			mType->race = RACE_ENERGY;
		else
		{
			int32_t race = atoi(strValue.c_str());
			if(race < RACE_VENOM || race > RACE_ENERGY)
			{
				SHOW_XML_WARNING("Unknown race type " << strValue);
			}
			else
				mType->race = (RaceType_t)race;
		}
	}

	if(readXMLInteger(root, "experience", intValue))
		mType->experience = intValue;

	if(readXMLInteger(root, "speed", intValue))
		mType->baseSpeed = intValue;

	if(readXMLInteger(root, "manacost", intValue))
		mType->manaCost = intValue;

	if(readXMLString(root, "skull", strValue))
		mType->skull = getSkulls(strValue);

	if(readXMLString(root, "shield", strValue))
		mType->partyShield = getShields(strValue);

	if(readXMLString(root, "emblem", strValue))
		mType->guildEmblem = getEmblems(strValue);

	for(xmlNodePtr p = root->children; p; p = p->next)
	{
		if(p->type != XML_ELEMENT_NODE)
			continue;

		if(!xmlStrcmp(p->name, (const xmlChar*)"health"))
		{
			if(!readXMLInteger(p, "max", intValue))
			{
				SHOW_XML_ERROR("Missing health.max");
				monsterLoad = false;
				break;
			}

			mType->healthMax = intValue;
			if(!readXMLInteger(p, "now", intValue))
				mType->health = mType->healthMax;
			else
				mType->health = intValue;
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"flags"))
		{
			for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
			{
				if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"flag"))
				{
					if(readXMLString(tmpNode, "summonable", strValue))
						mType->isSummonable = booleanString(strValue);

					if(readXMLString(tmpNode, "attackable", strValue))
						mType->isAttackable = booleanString(strValue);

					if(readXMLString(tmpNode, "hostile", strValue))
						mType->isHostile = booleanString(strValue);

					if(readXMLString(tmpNode, "illusionable", strValue))
						mType->isIllusionable = booleanString(strValue);

					if(readXMLString(tmpNode, "convinceable", strValue))
						mType->isConvinceable = booleanString(strValue);

					if(readXMLString(tmpNode, "pushable", strValue))
						mType->pushable = booleanString(strValue);

					if(readXMLString(tmpNode, "canpushitems", strValue))
						mType->canPushItems = booleanString(strValue);

					if(readXMLString(tmpNode, "canpushcreatures", strValue))
						mType->canPushCreatures = booleanString(strValue);

					if(readXMLString(tmpNode, "hidename", strValue))
						mType->hideName = booleanString(strValue);

					if(readXMLString(tmpNode, "hidehealth", strValue))
						mType->hideHealth = booleanString(strValue);

					if(readXMLInteger(tmpNode, "lootmessage", intValue))
						mType->lootMessage = (LootMessage_t)intValue;

					if(readXMLInteger(tmpNode, "staticattack", intValue))
					{
						if(intValue < 0 || intValue > 100)
						{
							SHOW_XML_WARNING("staticattack lower than 0 or greater than 100");
							intValue = 0;
						}

						mType->staticAttackChance = intValue;
					}

					if(readXMLInteger(tmpNode, "lightlevel", intValue))
						mType->lightLevel = intValue;

					if(readXMLInteger(tmpNode, "lightcolor", intValue))
						mType->lightColor = intValue;

					if(readXMLInteger(tmpNode, "targetdistance", intValue))
					{
						if(intValue > Map::maxViewportX)
							SHOW_XML_WARNING("targetdistance greater than maxViewportX");

						mType->targetDistance = std::max(1, intValue);
					}

					if(readXMLInteger(tmpNode, "runonhealth", intValue))
						mType->runAwayHealth = intValue;

					if(readXMLString(tmpNode, "lureable", strValue))
						mType->isLureable = booleanString(strValue);

					if(readXMLString(tmpNode, "walkable", strValue))
						mType->isWalkable = booleanString(strValue);

					if(readXMLString(tmpNode, "skull", strValue))
						mType->skull = getSkulls(strValue);

					if(readXMLString(tmpNode, "shield", strValue))
						mType->partyShield = getShields(strValue);

					if(readXMLString(tmpNode, "emblem", strValue))
						mType->guildEmblem = getEmblems(strValue);
				}
			}

			//if a monster can push creatures, it should not be pushable
			if(mType->canPushCreatures && mType->pushable)
				mType->pushable = false;
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"targetchange"))
		{
			if(readXMLInteger(p, "speed", intValue) || readXMLInteger(p, "interval", intValue))
				mType->changeTargetSpeed = std::max(1, intValue);
			else
				SHOW_XML_WARNING("Missing targetchange.speed");

			if(readXMLInteger(p, "chance", intValue))
				mType->changeTargetChance = intValue;
			else
				SHOW_XML_WARNING("Missing targetchange.chance");
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"strategy"))
		{
			if(readXMLInteger(p, "attack", intValue)) {}
				//mType->attackStrength = intValue;

			if(readXMLInteger(p, "defense", intValue)) {}
				//mType->defenseStrength = intValue;
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"look"))
		{
			if(readXMLInteger(p, "type", intValue))
			{
				mType->outfit.lookType = intValue;
				if(readXMLInteger(p, "head", intValue))
					mType->outfit.lookHead = intValue;

				if(readXMLInteger(p, "body", intValue))
					mType->outfit.lookBody = intValue;

				if(readXMLInteger(p, "legs", intValue))
					mType->outfit.lookLegs = intValue;

				if(readXMLInteger(p, "feet", intValue))
					mType->outfit.lookFeet = intValue;

				if(readXMLInteger(p, "addons", intValue))
					mType->outfit.lookAddons = intValue;
			}
			else if(readXMLInteger(p, "typeex", intValue))
				mType->outfit.lookTypeEx = intValue;
			else
				SHOW_XML_WARNING("Missing look type/typeex");

			if(readXMLInteger(p, "corpse", intValue))
				mType->lookCorpse = intValue;

			if(readXMLInteger(p, "corpseUniqueId", intValue) || readXMLInteger(p, "corpseUid", intValue))
				mType->corpseUnique = intValue;

			if(readXMLInteger(p, "corpseActionId", intValue) || readXMLInteger(p, "corpseAid", intValue))
				mType->corpseAction = intValue;
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"attacks"))
		{
			for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
			{
				if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"attack"))
				{
					spellBlock_t sb;
					if(deserializeSpell(tmpNode, sb, monsterName))
						mType->spellAttackList.push_back(sb);
					else
						SHOW_XML_WARNING("Cant load spell");
				}
			}
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"defenses"))
		{
			if(readXMLInteger(p, "defense", intValue))
				mType->defense = intValue;

			if(readXMLInteger(p, "armor", intValue))
				mType->armor = intValue;

			for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
			{
				if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"defense"))
				{
					spellBlock_t sb;
					if(deserializeSpell(tmpNode, sb, monsterName))
						mType->spellDefenseList.push_back(sb);
					else
						SHOW_XML_WARNING("Cant load spell");
				}
			}
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"immunities"))
		{
			for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
			{
				if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"immunity"))
				{
					if(readXMLString(tmpNode, "name", strValue))
					{
						std::string tmpStrValue = asLowerCaseString(strValue);
						if(tmpStrValue == "physical")
						{
							mType->damageImmunities |= COMBAT_PHYSICALDAMAGE;
							mType->conditionImmunities |= CONDITION_PHYSICAL;
						}
						else if(tmpStrValue == "energy")
						{
							mType->damageImmunities |= COMBAT_ENERGYDAMAGE;
							mType->conditionImmunities |= CONDITION_ENERGY;
						}
						else if(tmpStrValue == "fire")
						{
							mType->damageImmunities |= COMBAT_FIREDAMAGE;
							mType->conditionImmunities |= CONDITION_FIRE;
						}
						else if(tmpStrValue == "poison" || tmpStrValue == "earth")
						{
							mType->damageImmunities |= COMBAT_EARTHDAMAGE;
							mType->conditionImmunities |= CONDITION_POISON;
						}
						else if(tmpStrValue == "ice")
						{
							mType->damageImmunities |= COMBAT_ICEDAMAGE;
							mType->conditionImmunities |= CONDITION_FREEZING;
						}
						else if(tmpStrValue == "holy")
						{
							mType->damageImmunities |= COMBAT_HOLYDAMAGE;
							mType->conditionImmunities |= CONDITION_DAZZLED;
						}
						else if(tmpStrValue == "death")
						{
							mType->damageImmunities |= COMBAT_DEATHDAMAGE;
							mType->conditionImmunities |= CONDITION_CURSED;
						}
						else if(tmpStrValue == "drown")
						{
							mType->damageImmunities |= COMBAT_DROWNDAMAGE;
							mType->conditionImmunities |= CONDITION_DROWN;
						}
						else if(tmpStrValue == "lifedrain")
							mType->damageImmunities |= COMBAT_LIFEDRAIN;
						else if(tmpStrValue == "manadrain")
							mType->damageImmunities |= COMBAT_MANADRAIN;
						else if(tmpStrValue == "paralyze")
							mType->conditionImmunities |= CONDITION_PARALYZE;
						else if(tmpStrValue == "outfit")
							mType->conditionImmunities |= CONDITION_OUTFIT;
						else if(tmpStrValue == "drunk")
							mType->conditionImmunities |= CONDITION_DRUNK;
						else if(tmpStrValue == "invisible")
							mType->conditionImmunities |= CONDITION_INVISIBLE;
						else
							SHOW_XML_WARNING("Unknown immunity name " << strValue);
					}
					else if(readXMLString(tmpNode, "physical", strValue) && booleanString(strValue))
					{
						mType->damageImmunities |= COMBAT_PHYSICALDAMAGE;
						//mType->conditionImmunities |= CONDITION_PHYSICAL;
					}
					else if(readXMLString(tmpNode, "energy", strValue) && booleanString(strValue))
					{
						mType->damageImmunities |= COMBAT_ENERGYDAMAGE;
						mType->conditionImmunities |= CONDITION_ENERGY;
					}
					else if(readXMLString(tmpNode, "fire", strValue) && booleanString(strValue))
					{
						mType->damageImmunities |= COMBAT_FIREDAMAGE;
						mType->conditionImmunities |= CONDITION_FIRE;
					}
					else if((readXMLString(tmpNode, "poison", strValue) || readXMLString(tmpNode, "earth", strValue))
						&& booleanString(strValue))
					{
						mType->damageImmunities |= COMBAT_EARTHDAMAGE;
						mType->conditionImmunities |= CONDITION_POISON;
					}
					else if(readXMLString(tmpNode, "drown", strValue) && booleanString(strValue))
					{
						mType->damageImmunities |= COMBAT_DROWNDAMAGE;
						mType->conditionImmunities |= CONDITION_DROWN;
					}
					else if(readXMLString(tmpNode, "ice", strValue) && booleanString(strValue))
					{
						mType->damageImmunities |= COMBAT_ICEDAMAGE;
						mType->conditionImmunities |= CONDITION_FREEZING;
					}
					else if(readXMLString(tmpNode, "holy", strValue) && booleanString(strValue))
					{
						mType->damageImmunities |= COMBAT_HOLYDAMAGE;
						mType->conditionImmunities |= CONDITION_DAZZLED;
					}
					else if(readXMLString(tmpNode, "death", strValue) && booleanString(strValue))
					{
						mType->damageImmunities |= COMBAT_DEATHDAMAGE;
						mType->conditionImmunities |= CONDITION_CURSED;
					}
					else if(readXMLString(tmpNode, "lifedrain", strValue) && booleanString(strValue))
						mType->damageImmunities |= COMBAT_LIFEDRAIN;
					else if(readXMLString(tmpNode, "manadrain", strValue) && booleanString(strValue))
						mType->damageImmunities |= COMBAT_LIFEDRAIN;
					else if(readXMLString(tmpNode, "paralyze", strValue) && booleanString(strValue))
						mType->conditionImmunities |= CONDITION_PARALYZE;
					else if(readXMLString(tmpNode, "outfit", strValue) && booleanString(strValue))
						mType->conditionImmunities |= CONDITION_OUTFIT;
					else if(readXMLString(tmpNode, "drunk", strValue) && booleanString(strValue))
						mType->conditionImmunities |= CONDITION_DRUNK;
					else if(readXMLString(tmpNode, "invisible", strValue) && booleanString(strValue))
						mType->conditionImmunities |= CONDITION_INVISIBLE;
				}
			}
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"voices"))
		{
			if(readXMLInteger(p, "speed", intValue) || readXMLInteger(p, "interval", intValue))
				mType->yellSpeedTicks = intValue;
			else
				SHOW_XML_WARNING("Missing voices.speed");

			if(readXMLInteger(p, "chance", intValue))
				mType->yellChance = intValue;
			else
				SHOW_XML_WARNING("Missing voices.chance");

			for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
			{
				if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"voice"))
				{
					voiceBlock_t vb;
					vb.text = "";
					vb.yellText = false;

					if(readXMLString(tmpNode, "sentence", strValue))
						vb.text = strValue;
					else
						SHOW_XML_WARNING("Missing voice.sentence");

					if(readXMLString(tmpNode, "yell", strValue))
						vb.yellText = booleanString(strValue);

					mType->voiceVector.push_back(vb);
				}
			}
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"loot"))
		{
			for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
			{
				if(tmpNode->type != XML_ELEMENT_NODE)
					continue;

				LootBlock rootBlock;
				if(loadLoot(tmpNode, rootBlock))
					mType->lootItems.push_back(rootBlock);
				else
					SHOW_XML_WARNING("Cant load loot");
			}
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"elements"))
		{
			for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
			{
				if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"element"))
				{
					if(readXMLInteger(tmpNode, "firePercent", intValue))
						mType->elementMap[COMBAT_FIREDAMAGE] = intValue;
					else if(readXMLInteger(tmpNode, "energyPercent", intValue))
						mType->elementMap[COMBAT_ENERGYDAMAGE] = intValue;
					else if(readXMLInteger(tmpNode, "icePercent", intValue))
						mType->elementMap[COMBAT_ICEDAMAGE] = intValue;
					else if(readXMLInteger(tmpNode, "poisonPercent", intValue) || readXMLInteger(tmpNode, "earthPercent", intValue))
						mType->elementMap[COMBAT_EARTHDAMAGE] = intValue;
					else if(readXMLInteger(tmpNode, "holyPercent", intValue))
						mType->elementMap[COMBAT_HOLYDAMAGE] = intValue;
					else if(readXMLInteger(tmpNode, "deathPercent", intValue))
						mType->elementMap[COMBAT_DEATHDAMAGE] = intValue;
					else if(readXMLInteger(tmpNode, "drownPercent", intValue))
						mType->elementMap[COMBAT_DROWNDAMAGE] = intValue;
					else if(readXMLInteger(tmpNode, "physicalPercent", intValue))
						mType->elementMap[COMBAT_PHYSICALDAMAGE] = intValue;
					else if(readXMLInteger(tmpNode, "lifeDrainPercent", intValue))
						mType->elementMap[COMBAT_LIFEDRAIN] = intValue;
					else if(readXMLInteger(tmpNode, "manaDrainPercent", intValue))
						mType->elementMap[COMBAT_MANADRAIN] = intValue;
					else if(readXMLInteger(tmpNode, "healingPercent", intValue))
						mType->elementMap[COMBAT_HEALING] = intValue;
					else if(readXMLInteger(tmpNode, "undefinedPercent", intValue))
						mType->elementMap[COMBAT_UNDEFINEDDAMAGE] = intValue;
				}
			}
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"summons"))
		{
			if(readXMLInteger(p, "maxSummons", intValue) || readXMLInteger(p, "max", intValue))
				mType->maxSummons = intValue;

			for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
			{
				if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"summon"))
				{
					uint32_t chance = 100, interval = 1000, amount = 1;
					if(readXMLInteger(tmpNode, "speed", intValue) || readXMLInteger(tmpNode, "interval", intValue))
						interval = intValue;

					if(readXMLInteger(tmpNode, "chance", intValue))
						chance = intValue;

					if(readXMLInteger(tmpNode, "amount", intValue) || readXMLInteger(tmpNode, "max", intValue))
						amount = intValue;

					if(readXMLString(tmpNode, "name", strValue))
					{
						summonBlock_t sb;
						sb.name = strValue;
						sb.interval = interval;
						sb.chance = chance;
						sb.amount = amount;

						mType->summonList.push_back(sb);
					}
					else
						SHOW_XML_WARNING("Missing summon.name");
				}
			}
		}
		else if(!xmlStrcmp(p->name, (const xmlChar*)"script"))
		{
			for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
			{
				if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"event"))
				{
					if(readXMLString(tmpNode, "name", strValue))
						mType->scriptList.push_back(strValue);
					else
						SHOW_XML_WARNING("Missing name for script event");
				}
			}
		}
		else
			SHOW_XML_WARNING("Unknown attribute type - " << p->name);
	}

	xmlFreeDoc(doc);
	if(!monsterLoad)
	{
		if(new_mType)
			delete mType;

		return false;
	}

	static uint32_t id = 0;
	if(new_mType)
	{
		monsterNames[asLowerCaseString(monsterName)] = ++id;
		monsters[id] = mType;
	}

	return true;
}
Пример #20
0
bool Monsters::loadMonster(const std::string& file, const std::string& monsterName, std::list<std::pair<MonsterType*, std::string>>& monsterScriptList, bool reloading /*= false*/)
{
	MonsterType* mType = nullptr;
	bool new_mType = true;

	pugi::xml_document doc;
	pugi::xml_parse_result result = doc.load_file(file.c_str());
	if (!result) {
		printXMLError("Error - Monsters::loadMonster", file, result);
		return false;
	}

	pugi::xml_node monsterNode = doc.child("monster");
	if (!monsterNode) {
		std::cout << "[Error - Monsters::loadMonster] Missing monster node in: " << file << std::endl;
		return false;
	}

	pugi::xml_attribute attr;
	if (!(attr = monsterNode.attribute("name"))) {
		std::cout << "[Error - Monsters::loadMonster] Missing name in: " << file << std::endl;
		return false;
	}

	if (reloading) {
		mType = getMonsterType(monsterName);
		if (mType != nullptr) {
			new_mType = false;
			mType->reset();
		}
	}

	if (new_mType) {
		mType = &monsters[asLowerCaseString(monsterName)];
	}

	mType->name = attr.as_string();

	if ((attr = monsterNode.attribute("nameDescription"))) {
		mType->nameDescription = attr.as_string();
	} else {
		mType->nameDescription = "a " + mType->name;
		toLowerCaseString(mType->nameDescription);
	}

	if ((attr = monsterNode.attribute("race"))) {
		std::string tmpStrValue = asLowerCaseString(attr.as_string());
		uint16_t tmpInt = pugi::cast<uint16_t>(attr.value());
		if (tmpStrValue == "venom" || tmpInt == 1) {
			mType->race = RACE_VENOM;
		} else if (tmpStrValue == "blood" || tmpInt == 2) {
			mType->race = RACE_BLOOD;
		} else if (tmpStrValue == "undead" || tmpInt == 3) {
			mType->race = RACE_UNDEAD;
		} else if (tmpStrValue == "fire" || tmpInt == 4) {
			mType->race = RACE_FIRE;
		} else if (tmpStrValue == "energy" || tmpInt == 5) {
			mType->race = RACE_ENERGY;
		} else {
			std::cout << "[Warning - Monsters::loadMonster] Unknown race type " << attr.as_string() << ". " << file << std::endl;
		}
	}

	if ((attr = monsterNode.attribute("experience"))) {
		mType->experience = pugi::cast<uint64_t>(attr.value());
	}

	if ((attr = monsterNode.attribute("speed"))) {
		mType->baseSpeed = pugi::cast<int32_t>(attr.value());
	}

	if ((attr = monsterNode.attribute("manacost"))) {
		mType->manaCost = pugi::cast<uint32_t>(attr.value());
	}

	if ((attr = monsterNode.attribute("skull"))) {
		mType->skull = getSkullType(attr.as_string());
	}

	if ((attr = monsterNode.attribute("script"))) {
		monsterScriptList.emplace_back(mType, attr.as_string());
	}

	pugi::xml_node node;
	if ((node = monsterNode.child("health"))) {
		if ((attr = node.attribute("now"))) {
			mType->health = pugi::cast<int32_t>(attr.value());
		} else {
			std::cout << "[Error - Monsters::loadMonster] Missing health now. " << file << std::endl;
		}

		if ((attr = node.attribute("max"))) {
			mType->healthMax = pugi::cast<int32_t>(attr.value());
		} else {
			std::cout << "[Error - Monsters::loadMonster] Missing health max. " << file << std::endl;
		}
	}

	if ((node = monsterNode.child("flags"))) {
		for (auto flagNode : node.children()) {
			attr = flagNode.first_attribute();
			const char* attrName = attr.name();
			if (strcasecmp(attrName, "summonable") == 0) {
				mType->isSummonable = attr.as_bool();
			} else if (strcasecmp(attrName, "rewardboss") == 0) {
				mType->isRewardBoss = attr.as_bool();
			} else if (strcasecmp(attrName, "attackable") == 0) {
				mType->isAttackable = attr.as_bool();
			} else if (strcasecmp(attrName, "hostile") == 0) {
				mType->isHostile = attr.as_bool();
			} else if (strcasecmp(attrName, "illusionable") == 0) {
				mType->isIllusionable = attr.as_bool();
			} else if (strcasecmp(attrName, "convinceable") == 0) {
				mType->isConvinceable = attr.as_bool();
			} else if (strcasecmp(attrName, "pushable") == 0) {
				mType->pushable = attr.as_bool();
			} else if (strcasecmp(attrName, "canpushitems") == 0) {
				mType->canPushItems = attr.as_bool();
			} else if (strcasecmp(attrName, "canpushcreatures") == 0) {
				mType->canPushCreatures = attr.as_bool();
			} else if (strcasecmp(attrName, "staticattack") == 0) {
				uint32_t staticAttack = pugi::cast<uint32_t>(attr.value());
				if (staticAttack > 100) {
					std::cout << "[Warning - Monsters::loadMonster] staticattack greater than 100. " << file << std::endl;
					staticAttack = 100;
				}

				mType->staticAttackChance = staticAttack;
			} else if (strcasecmp(attrName, "lightlevel") == 0) {
				mType->lightLevel = pugi::cast<uint16_t>(attr.value());
			} else if (strcasecmp(attrName, "lightcolor") == 0) {
				mType->lightColor = pugi::cast<uint16_t>(attr.value());
			} else if (strcasecmp(attrName, "targetdistance") == 0) {
				mType->targetDistance = std::max<int32_t>(1, pugi::cast<int32_t>(attr.value()));
			} else if (strcasecmp(attrName, "runonhealth") == 0) {
				mType->runAwayHealth = pugi::cast<int32_t>(attr.value());
			} else if (strcasecmp(attrName, "hidehealth") == 0) {
				mType->hiddenHealth = attr.as_bool();
			} else if (strcasecmp(attrName, "isblockable") == 0) {
				mType->isBlockable = attr.as_bool();
			} else {
				std::cout << "[Warning - Monsters::loadMonster] Unknown flag attribute: " << attrName << ". " << file << std::endl;
			}
		}

		//if a monster can push creatures,
		// it should not be pushable
		if (mType->canPushCreatures && mType->pushable) {
			mType->pushable = false;
		}
	}

	if ((node = monsterNode.child("targetchange"))) {
		if ((attr = node.attribute("speed")) || (attr = node.attribute("interval"))) {
			mType->changeTargetSpeed = pugi::cast<uint32_t>(attr.value());
		} else {
			std::cout << "[Warning - Monsters::loadMonster] Missing targetchange speed. " << file << std::endl;
		}

		if ((attr = node.attribute("chance"))) {
			mType->changeTargetChance = pugi::cast<int32_t>(attr.value());
		} else {
			std::cout << "[Warning - Monsters::loadMonster] Missing targetchange chance. " << file << std::endl;
		}
	}

	if ((node = monsterNode.child("look"))) {
		if ((attr = node.attribute("type"))) {
			mType->outfit.lookType = pugi::cast<uint16_t>(attr.value());

			if ((attr = node.attribute("head"))) {
				mType->outfit.lookHead = pugi::cast<uint16_t>(attr.value());
			}

			if ((attr = node.attribute("body"))) {
				mType->outfit.lookBody = pugi::cast<uint16_t>(attr.value());
			}

			if ((attr = node.attribute("legs"))) {
				mType->outfit.lookLegs = pugi::cast<uint16_t>(attr.value());
			}

			if ((attr = node.attribute("feet"))) {
				mType->outfit.lookFeet = pugi::cast<uint16_t>(attr.value());
			}

			if ((attr = node.attribute("addons"))) {
				mType->outfit.lookAddons = pugi::cast<uint16_t>(attr.value());
			}
		} else if ((attr = node.attribute("typeex"))) {
			mType->outfit.lookTypeEx = pugi::cast<uint16_t>(attr.value());
		} else {
			std::cout << "[Warning - Monsters::loadMonster] Missing look type/typeex. " << file << std::endl;
		}

		if ((attr = node.attribute("mount"))) {
			mType->outfit.lookMount = pugi::cast<uint16_t>(attr.value());
		}

		if ((attr = node.attribute("corpse"))) {
			mType->lookcorpse = pugi::cast<uint16_t>(attr.value());
		}
	}

	if ((node = monsterNode.child("attacks"))) {
		for (auto attackNode : node.children()) {
			spellBlock_t sb;
			if (deserializeSpell(attackNode, sb, monsterName)) {
				mType->attackSpells.emplace_back(std::move(sb));
			} else {
				std::cout << "[Warning - Monsters::loadMonster] Cant load spell. " << file << std::endl;
			}
		}
	}

	if ((node = monsterNode.child("defenses"))) {
		if ((attr = node.attribute("defense"))) {
			mType->defense = pugi::cast<int32_t>(attr.value());
		}

		if ((attr = node.attribute("armor"))) {
			mType->armor = pugi::cast<int32_t>(attr.value());
		}

		for (auto defenseNode : node.children()) {
			spellBlock_t sb;
			if (deserializeSpell(defenseNode, sb, monsterName)) {
				mType->defenseSpells.emplace_back(std::move(sb));
			} else {
				std::cout << "[Warning - Monsters::loadMonster] Cant load spell. " << file << std::endl;
			}
		}
	}

	if ((node = monsterNode.child("immunities"))) {
		for (auto immunityNode : node.children()) {
			if ((attr = immunityNode.attribute("name"))) {
				std::string tmpStrValue = asLowerCaseString(attr.as_string());
				if (tmpStrValue == "physical") {
					mType->damageImmunities |= COMBAT_PHYSICALDAMAGE;
					mType->conditionImmunities |= CONDITION_BLEEDING;
				} else if (tmpStrValue == "energy") {
					mType->damageImmunities |= COMBAT_ENERGYDAMAGE;
					mType->conditionImmunities |= CONDITION_ENERGY;
				} else if (tmpStrValue == "fire") {
					mType->damageImmunities |= COMBAT_FIREDAMAGE;
					mType->conditionImmunities |= CONDITION_FIRE;
				} else if (tmpStrValue == "poison" ||
							tmpStrValue == "earth") {
					mType->damageImmunities |= COMBAT_EARTHDAMAGE;
					mType->conditionImmunities |= CONDITION_POISON;
				} else if (tmpStrValue == "drown") {
					mType->damageImmunities |= COMBAT_DROWNDAMAGE;
					mType->conditionImmunities |= CONDITION_DROWN;
				} else if (tmpStrValue == "ice") {
					mType->damageImmunities |= COMBAT_ICEDAMAGE;
					mType->conditionImmunities |= CONDITION_FREEZING;
				} else if (tmpStrValue == "holy") {
					mType->damageImmunities |= COMBAT_HOLYDAMAGE;
					mType->conditionImmunities |= CONDITION_DAZZLED;
				} else if (tmpStrValue == "death") {
					mType->damageImmunities |= COMBAT_DEATHDAMAGE;
					mType->conditionImmunities |= CONDITION_CURSED;
				} else if (tmpStrValue == "lifedrain") {
					mType->damageImmunities |= COMBAT_LIFEDRAIN;
				} else if (tmpStrValue == "manadrain") {
					mType->damageImmunities |= COMBAT_MANADRAIN;
				} else if (tmpStrValue == "paralyze") {
					mType->conditionImmunities |= CONDITION_PARALYZE;
				} else if (tmpStrValue == "outfit") {
					mType->conditionImmunities |= CONDITION_OUTFIT;
				} else if (tmpStrValue == "drunk") {
					mType->conditionImmunities |= CONDITION_DRUNK;
				} else if (tmpStrValue == "invisible" || tmpStrValue == "invisibility") {
					mType->conditionImmunities |= CONDITION_INVISIBLE;
				} else if (tmpStrValue == "bleed") {
					mType->conditionImmunities |= CONDITION_BLEEDING;
				} else {
					std::cout << "[Warning - Monsters::loadMonster] Unknown immunity name " << attr.as_string() << ". " << file << std::endl;
				}
			} else if ((attr = immunityNode.attribute("physical"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_PHYSICALDAMAGE;
					mType->conditionImmunities |= CONDITION_BLEEDING;
				}
			} else if ((attr = immunityNode.attribute("energy"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_ENERGYDAMAGE;
					mType->conditionImmunities |= CONDITION_ENERGY;
				}
			} else if ((attr = immunityNode.attribute("fire"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_FIREDAMAGE;
					mType->conditionImmunities |= CONDITION_FIRE;
				}
			} else if ((attr = immunityNode.attribute("poison")) || (attr = immunityNode.attribute("earth"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_EARTHDAMAGE;
					mType->conditionImmunities |= CONDITION_POISON;
				}
			} else if ((attr = immunityNode.attribute("drown"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_DROWNDAMAGE;
					mType->conditionImmunities |= CONDITION_DROWN;
				}
			} else if ((attr = immunityNode.attribute("ice"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_ICEDAMAGE;
					mType->conditionImmunities |= CONDITION_FREEZING;
				}
			} else if ((attr = immunityNode.attribute("holy"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_HOLYDAMAGE;
					mType->conditionImmunities |= CONDITION_DAZZLED;
				}
			} else if ((attr = immunityNode.attribute("death"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_DEATHDAMAGE;
					mType->conditionImmunities |= CONDITION_CURSED;
				}
			} else if ((attr = immunityNode.attribute("lifedrain"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_LIFEDRAIN;
				}
			} else if ((attr = immunityNode.attribute("manadrain"))) {
				if (attr.as_bool()) {
					mType->damageImmunities |= COMBAT_MANADRAIN;
				}
			} else if ((attr = immunityNode.attribute("paralyze"))) {
				if (attr.as_bool()) {
					mType->conditionImmunities |= CONDITION_PARALYZE;
				}
			} else if ((attr = immunityNode.attribute("outfit"))) {
				if (attr.as_bool()) {
					mType->conditionImmunities |= CONDITION_OUTFIT;
				}
			} else if ((attr = immunityNode.attribute("bleed"))) {
				if (attr.as_bool()) {
					mType->conditionImmunities |= CONDITION_BLEEDING;
				}
			} else if ((attr = immunityNode.attribute("drunk"))) {
				if (attr.as_bool()) {
					mType->conditionImmunities |= CONDITION_DRUNK;
				}
			} else if ((attr = immunityNode.attribute("invisible")) || (attr = immunityNode.attribute("invisibility"))) {
				if (attr.as_bool()) {
					mType->conditionImmunities |= CONDITION_INVISIBLE;
				}
			} else {
				std::cout << "[Warning - Monsters::loadMonster] Unknown immunity. " << file << std::endl;
			}
		}
	}

	if ((node = monsterNode.child("voices"))) {
		if ((attr = node.attribute("speed")) || (attr = node.attribute("interval"))) {
			mType->yellSpeedTicks = pugi::cast<uint32_t>(attr.value());
		} else {
			std::cout << "[Warning - Monsters::loadMonster] Missing voices speed. " << file << std::endl;
		}

		if ((attr = node.attribute("chance"))) {
			mType->yellChance = pugi::cast<uint32_t>(attr.value());
		} else {
			std::cout << "[Warning - Monsters::loadMonster] Missing voices chance. " << file << std::endl;
		}

		for (auto voiceNode : node.children()) {
			voiceBlock_t vb;
			if ((attr = voiceNode.attribute("sentence"))) {
				vb.text = attr.as_string();
			} else {
				std::cout << "[Warning - Monsters::loadMonster] Missing voice sentence. " << file << std::endl;
			}

			if ((attr = voiceNode.attribute("yell"))) {
				vb.yellText = attr.as_bool();
			} else {
				vb.yellText = false;
			}
			mType->voiceVector.emplace_back(vb);
		}
	}

	if ((node = monsterNode.child("loot"))) {
		for (auto lootNode : node.children()) {
			LootBlock lootBlock;
			if (loadLootItem(lootNode, lootBlock)) {
				mType->lootItems.emplace_back(std::move(lootBlock));
			} else {
				std::cout << "[Warning - Monsters::loadMonster] Cant load loot. " << file << std::endl;
			}
		}
	}

	if ((node = monsterNode.child("elements"))) {
		for (auto elementNode : node.children()) {
			if ((attr = elementNode.attribute("physicalPercent"))) {
				mType->elementMap[COMBAT_PHYSICALDAMAGE] = pugi::cast<int32_t>(attr.value());
			} else if ((attr = elementNode.attribute("icePercent"))) {
				mType->elementMap[COMBAT_ICEDAMAGE] = pugi::cast<int32_t>(attr.value());
			} else if ((attr = elementNode.attribute("poisonPercent")) || (attr = elementNode.attribute("earthPercent"))) {
				mType->elementMap[COMBAT_EARTHDAMAGE] = pugi::cast<int32_t>(attr.value());
			} else if ((attr = elementNode.attribute("firePercent"))) {
				mType->elementMap[COMBAT_FIREDAMAGE] = pugi::cast<int32_t>(attr.value());
			} else if ((attr = elementNode.attribute("energyPercent"))) {
				mType->elementMap[COMBAT_ENERGYDAMAGE] = pugi::cast<int32_t>(attr.value());
			} else if ((attr = elementNode.attribute("holyPercent"))) {
				mType->elementMap[COMBAT_HOLYDAMAGE] = pugi::cast<int32_t>(attr.value());
			} else if ((attr = elementNode.attribute("deathPercent"))) {
				mType->elementMap[COMBAT_DEATHDAMAGE] = pugi::cast<int32_t>(attr.value());
			} else if ((attr = elementNode.attribute("drownPercent"))) {
				mType->elementMap[COMBAT_DROWNDAMAGE] = pugi::cast<int32_t>(attr.value());
			} else if ((attr = elementNode.attribute("lifedrainPercent"))) {
				mType->elementMap[COMBAT_LIFEDRAIN] = pugi::cast<int32_t>(attr.value());
			} else if ((attr = elementNode.attribute("manadrainPercent"))) {
				mType->elementMap[COMBAT_MANADRAIN] = pugi::cast<int32_t>(attr.value());
			} else {
				std::cout << "[Warning - Monsters::loadMonster] Unknown element percent. " << file << std::endl;
			}
		}
	}

	if ((node = monsterNode.child("summons"))) {
		if ((attr = node.attribute("maxSummons"))) {
			mType->maxSummons = std::min<uint32_t>(pugi::cast<uint32_t>(attr.value()), 100);
		} else {
			std::cout << "[Warning - Monsters::loadMonster] Missing summons maxSummons. " << file << std::endl;
		}

		for (auto summonNode : node.children()) {
			int32_t chance = 100;
			int32_t speed = 1000;
			bool force = false;

			if ((attr = summonNode.attribute("speed")) || (attr = summonNode.attribute("interval"))) {
				speed = pugi::cast<int32_t>(attr.value());
			}

			if ((attr = summonNode.attribute("chance"))) {
				chance = pugi::cast<int32_t>(attr.value());
			}
			
			if ((attr = summonNode.attribute("force"))) {
				force = attr.as_bool();
			}

			if ((attr = summonNode.attribute("name"))) {
				summonBlock_t sb;
				sb.name = attr.as_string();
				sb.speed = speed;
				sb.chance = chance;
				sb.force = force;
				mType->summons.emplace_back(sb);
			} else {
				std::cout << "[Warning - Monsters::loadMonster] Missing summon name. " << file << std::endl;
			}
		}
	}

	if ((node = monsterNode.child("script"))) {
		for (auto eventNode : node.children()) {
			if ((attr = eventNode.attribute("name"))) {
				mType->scripts.emplace_back(attr.as_string());
			} else {
				std::cout << "[Warning - Monsters::loadMonster] Missing name for script event. " << file << std::endl;
			}
		}
	}

	mType->summons.shrink_to_fit();
	mType->lootItems.shrink_to_fit();
	mType->attackSpells.shrink_to_fit();
	mType->defenseSpells.shrink_to_fit();
	mType->voiceVector.shrink_to_fit();
	mType->scripts.shrink_to_fit();
	return true;
}
Пример #21
0
bool MoveEvent::configureEvent(xmlNodePtr p)
{
	std::string str;
	int intValue;
	if(readXMLString(p, "event", str)){
		if(asLowerCaseString(str) == "stepin"){
			m_eventType = MOVE_EVENT_STEP_IN;
		}
		else if(asLowerCaseString(str) == "stepout"){
			m_eventType = MOVE_EVENT_STEP_OUT;
		}
		else if(asLowerCaseString(str) == "equip"){
			m_eventType = MOVE_EVENT_EQUIP;
		}
		else if(asLowerCaseString(str) == "deequip"){
			m_eventType = MOVE_EVENT_DEEQUIP;
		}
		else if(asLowerCaseString(str) == "additem"){
			m_eventType = MOVE_EVENT_ADD_ITEM;
		}
		else if(asLowerCaseString(str) == "removeitem"){
			m_eventType = MOVE_EVENT_REMOVE_ITEM;
		}
		else{
			std::cout << "Error: [MoveEvent::configureMoveEvent] No valid event name " << str << std::endl;
			return false;
		}

		if(m_eventType == MOVE_EVENT_EQUIP || m_eventType == MOVE_EVENT_DEEQUIP){
			if(readXMLString(p, "slot", str)){
				if(asLowerCaseString(str) == "head"){
					slot = SLOT_HEAD;
				}
				else if(asLowerCaseString(str) == "necklace"){
					slot = SLOT_NECKLACE;
				}
				else if(asLowerCaseString(str) == "backpack"){
					slot = SLOT_BACKPACK;
				}
				else if(asLowerCaseString(str) == "armor"){
					slot = SLOT_ARMOR;
				}
				else if(asLowerCaseString(str) == "right-hand"){
					slot = SLOT_RIGHT;
				}
				else if(asLowerCaseString(str) == "left-hand"){
					slot = SLOT_LEFT;
				}
				else if(asLowerCaseString(str) == "legs"){
					slot = SLOT_LEGS;
				}
				else if(asLowerCaseString(str) == "feet"){
					slot = SLOT_FEET;
				}
				else if(asLowerCaseString(str) == "ring"){
					slot = SLOT_RING;
				}
				else if(asLowerCaseString(str) == "ammo"){
					slot = SLOT_AMMO;
				}
				else{
					std::cout << "Warning: [MoveEvent::configureMoveEvent] " << "Unknown slot type " << str << std::endl;
				}
			}

			wieldInfo = 0;
			if(readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue)){
	 			reqLevel = intValue;
				if(reqLevel > 0){
					wieldInfo |= WIELDINFO_LEVEL;
				}
			}
			if(readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "maglevel", intValue)){
	 			reqMagLevel = intValue;
				if(reqMagLevel > 0){
					wieldInfo |= WIELDINFO_MAGLV;
				}
			}
			if(readXMLInteger(p, "prem", intValue) || readXMLInteger(p, "premium", intValue)){
				premium = (intValue != 0);
				if(premium){
					wieldInfo |= WIELDINFO_PREMIUM;
				}
			}

			//Gather vocation information
			typedef std::list<std::string> STRING_LIST;
			STRING_LIST vocStringList;
			xmlNodePtr vocationNode = p->children;
			while(vocationNode){
				if(xmlStrcmp(vocationNode->name,(const xmlChar*)"vocation") == 0){
					if(readXMLString(vocationNode, "name", str)){
						int32_t vocationId = g_vocations.getVocationId(str);

						if(vocationId != -1){
							vocEquipMap[vocationId] = true;
							intValue = 1;
							readXMLInteger(vocationNode, "showInDescription", intValue);
							if(intValue != 0){
								toLowerCaseString(str);
								vocStringList.push_back(str);
							}
						}
					}
				}

				vocationNode = vocationNode->next;
			}

			if(!vocStringList.empty()){
				for(STRING_LIST::iterator it = vocStringList.begin(); it != vocStringList.end(); ++it){
					if(*it != vocStringList.front()){
						if(*it != vocStringList.back()){
							vocationString += ", ";
						}
						else{
							vocationString += " and ";
						}
					}
					vocationString += *it;
					vocationString += "s";
				}
				wieldInfo |= WIELDINFO_VOCREQ;
			}
		}
	}
	else{
		std::cout << "Error: [MoveEvent::configureMoveEvent] No event found." << std::endl;
		return false;
	}
	return true;
}
Пример #22
0
void Actor::updateNameDescription()
{
  strDescription = cType.nameDescription();
  toLowerCaseString(strDescription);
}