Example #1
0
bool Vocations::parseVocationNode(xmlNodePtr p)
{
	std::string strValue;
	int32_t intValue;
	float floatValue;
	if(xmlStrcmp(p->name, (const xmlChar*)"vocation"))
		return false;

	if(!readXMLInteger(p, "id", intValue))
	{
		std::cout << "[Error - Vocations::parseVocationNode] Missing vocation id." << std::endl;
		return false;
	}

	Vocation* voc = new Vocation(intValue);
	if(readXMLString(p, "name", strValue))
		voc->setName(strValue);

	if(readXMLString(p, "description", strValue))
		voc->setDescription(strValue);

	if(readXMLString(p, "needpremium", strValue))
		voc->setNeedPremium(booleanString(strValue));

	if(readXMLInteger(p, "gaincap", intValue) || readXMLInteger(p, "gaincapacity", intValue))
		voc->setGainCap(intValue);

	if(readXMLInteger(p, "gainhp", intValue) || readXMLInteger(p, "gainhealth", intValue))
		voc->setGain(GAIN_HEALTH, intValue);

	if(readXMLInteger(p, "gainmana", intValue))
		voc->setGain(GAIN_MANA, intValue);

	if(readXMLInteger(p, "gainhpticks", intValue) || readXMLInteger(p, "gainhealthticks", intValue))
		voc->setGainTicks(GAIN_HEALTH, intValue);

	if(readXMLInteger(p, "gainhpamount", intValue) || readXMLInteger(p, "gainhealthamount", intValue))
		voc->setGainAmount(GAIN_HEALTH, intValue);

	if(readXMLInteger(p, "gainmanaticks", intValue))
		voc->setGainTicks(GAIN_MANA, intValue);

	if(readXMLInteger(p, "gainmanaamount", intValue))
		voc->setGainAmount(GAIN_MANA, intValue);

	if(readXMLFloat(p, "manamultiplier", floatValue))
		voc->setMultiplier(MULTIPLIER_MANA, floatValue);

	if(readXMLInteger(p, "attackspeed", intValue))
		voc->setAttackSpeed(intValue);

	if(readXMLInteger(p, "basespeed", intValue))
		voc->setBaseSpeed(intValue);

	if(readXMLInteger(p, "soulmax", intValue))
		voc->setGain(GAIN_SOUL, intValue);

	if(readXMLInteger(p, "gainsoulamount", intValue))
		voc->setGainAmount(GAIN_SOUL, intValue);

	if(readXMLInteger(p, "gainsoulticks", intValue))
		voc->setGainTicks(GAIN_SOUL, intValue);

	if(readXMLString(p, "attackable", strValue))
		voc->setAttackable(booleanString(strValue));

	if(readXMLInteger(p, "fromvoc", intValue) || readXMLInteger(p, "fromvocation", intValue))
		voc->setFromVocation(intValue);

	if(readXMLInteger(p, "lessloss", intValue))
		voc->setLessLoss(intValue);

	xmlNodePtr configNode = p->children;
	while(configNode)
	{
		if(!xmlStrcmp(configNode->name, (const xmlChar*)"skill"))
		{
			if(readXMLFloat(configNode, "fist", floatValue))
				voc->setSkillMultiplier(SKILL_FIST, floatValue);

			if(readXMLInteger(configNode, "fistBase", intValue))
				voc->setSkillBase(SKILL_FIST, intValue);

			if(readXMLFloat(configNode, "club", floatValue))
				voc->setSkillMultiplier(SKILL_CLUB, floatValue);

			if(readXMLInteger(configNode, "clubBase", intValue))
				voc->setSkillBase(SKILL_CLUB, intValue);

			if(readXMLFloat(configNode, "axe", floatValue))
				voc->setSkillMultiplier(SKILL_AXE, floatValue);

			if(readXMLInteger(configNode, "axeBase", intValue))
				voc->setSkillBase(SKILL_AXE, intValue);

			if(readXMLFloat(configNode, "sword", floatValue))
				voc->setSkillMultiplier(SKILL_SWORD, floatValue);

			if(readXMLInteger(configNode, "swordBase", intValue))
				voc->setSkillBase(SKILL_SWORD, intValue);

			if(readXMLFloat(configNode, "distance", floatValue) || readXMLFloat(configNode, "dist", floatValue))
				voc->setSkillMultiplier(SKILL_DIST, floatValue);

			if(readXMLInteger(configNode, "distanceBase", intValue) || readXMLInteger(configNode, "distBase", intValue))
				voc->setSkillBase(SKILL_DIST, intValue);

			if(readXMLFloat(configNode, "shielding", floatValue) || readXMLFloat(configNode, "shield", floatValue))
				voc->setSkillMultiplier(SKILL_SHIELD, floatValue);

			if(readXMLInteger(configNode, "shieldingBase", intValue) || readXMLInteger(configNode, "shieldBase", intValue))
				voc->setSkillBase(SKILL_SHIELD, intValue);

			if(readXMLFloat(configNode, "fishing", floatValue) || readXMLFloat(configNode, "fish", floatValue))
				voc->setSkillMultiplier(SKILL_FISH, floatValue);

			if(readXMLInteger(configNode, "fishingBase", intValue) || readXMLInteger(configNode, "fishBase", intValue))
				voc->setSkillBase(SKILL_FISH, intValue);

			if(readXMLFloat(configNode, "experience", floatValue) || readXMLFloat(configNode, "exp", floatValue))
				voc->setSkillMultiplier(SKILL__LEVEL, floatValue);

			if(readXMLInteger(configNode, "id", intValue))
			{
				skills_t skill = (skills_t)intValue;
				if(intValue < SKILL_FIRST || intValue >= SKILL__LAST)
				{
					std::cout << "[Error - Vocations::parseVocationNode] No valid skill id (" << intValue << ")." << std::endl;
					continue;
				}

				if(readXMLInteger(configNode, "base", intValue))
					voc->setSkillBase(skill, intValue);

				if(readXMLFloat(configNode, "multiplier", floatValue))
					voc->setSkillMultiplier(skill, floatValue);
			}
		}
		else if(!xmlStrcmp(configNode->name, (const xmlChar*)"formula"))
		{
			if(readXMLFloat(configNode, "meleeDamage", floatValue))
				voc->setMultiplier(MULTIPLIER_MELEE, floatValue);

			if(readXMLFloat(configNode, "distDamage", floatValue) || readXMLFloat(configNode, "distanceDamage", floatValue))
				voc->setMultiplier(MULTIPLIER_DISTANCE, floatValue);

			if(readXMLFloat(configNode, "wandDamage", floatValue) || readXMLFloat(configNode, "rodDamage", floatValue))
				voc->setMultiplier(MULTIPLIER_WAND, floatValue);

			if(readXMLFloat(configNode, "magDamage", floatValue) || readXMLFloat(configNode, "magicDamage", floatValue))
				voc->setMultiplier(MULTIPLIER_MAGIC, floatValue);

			if(readXMLFloat(configNode, "magHealingDamage", floatValue) || readXMLFloat(configNode, "magicHealingDamage", floatValue))
				voc->setMultiplier(MULTIPLIER_MAGICHEALING, floatValue);

			if(readXMLFloat(configNode, "defense", floatValue))
				voc->setMultiplier(MULTIPLIER_DEFENSE, floatValue);

			if(readXMLFloat(configNode, "magDefense", floatValue) || readXMLFloat(configNode, "magicDefense", floatValue))
				voc->setMultiplier(MULTIPLIER_MAGICDEFENSE, floatValue);

			if(readXMLFloat(configNode, "armor", floatValue))
				voc->setMultiplier(MULTIPLIER_ARMOR, floatValue);
		}
		else if(!xmlStrcmp(configNode->name, (const xmlChar*)"absorb"))
		{
			if(readXMLInteger(configNode, "percentAll", intValue))
			{
				for(uint32_t i = COMBAT_FIRST; i <= COMBAT_LAST; i++)
					voc->increaseAbsorbPercent((CombatType_t)i, intValue);
			}
			else if(readXMLInteger(configNode, "percentElements", intValue))
			{
				voc->increaseAbsorbPercent(COMBAT_ENERGYDAMAGE, intValue);
				voc->increaseAbsorbPercent(COMBAT_FIREDAMAGE, intValue);
				voc->increaseAbsorbPercent(COMBAT_EARTHDAMAGE, intValue);
				voc->increaseAbsorbPercent(COMBAT_ICEDAMAGE, intValue);
			}
			else if(readXMLInteger(configNode, "percentMagic", intValue))
			{
				voc->increaseAbsorbPercent(COMBAT_ENERGYDAMAGE, intValue);
				voc->increaseAbsorbPercent(COMBAT_FIREDAMAGE, intValue);
				voc->increaseAbsorbPercent(COMBAT_EARTHDAMAGE, intValue);
				voc->increaseAbsorbPercent(COMBAT_ICEDAMAGE, intValue);
				voc->increaseAbsorbPercent(COMBAT_HOLYDAMAGE, intValue);
				voc->increaseAbsorbPercent(COMBAT_DEATHDAMAGE, intValue);
			}
			else if(readXMLInteger(configNode, "percentEnergy", intValue))
				voc->increaseAbsorbPercent(COMBAT_ENERGYDAMAGE, intValue);
			else if(readXMLInteger(configNode, "percentFire", intValue))
				voc->increaseAbsorbPercent(COMBAT_FIREDAMAGE, intValue);
			else if(readXMLInteger(configNode, "percentPoison", intValue) || readXMLInteger(configNode, "percentEarth", intValue))
				voc->increaseAbsorbPercent(COMBAT_EARTHDAMAGE, intValue);
			else if(readXMLInteger(configNode, "percentIce", intValue))
				voc->increaseAbsorbPercent(COMBAT_ICEDAMAGE, intValue);
			else if(readXMLInteger(configNode, "percentHoly", intValue))
				voc->increaseAbsorbPercent(COMBAT_HOLYDAMAGE, intValue);
			else if(readXMLInteger(configNode, "percentDeath", intValue))
				voc->increaseAbsorbPercent(COMBAT_DEATHDAMAGE, intValue);
			else if(readXMLInteger(configNode, "percentLifeDrain", intValue))
				voc->increaseAbsorbPercent(COMBAT_LIFEDRAIN, intValue);
			else if(readXMLInteger(configNode, "percentManaDrain", intValue))
				voc->increaseAbsorbPercent(COMBAT_MANADRAIN, intValue);
			else if(readXMLInteger(configNode, "percentDrown", intValue))
				voc->increaseAbsorbPercent(COMBAT_DROWNDAMAGE, intValue);
			else if(readXMLInteger(configNode, "percentPhysical", intValue))
				voc->increaseAbsorbPercent(COMBAT_PHYSICALDAMAGE, intValue);
			else if(readXMLInteger(configNode, "percentHealing", intValue))
				voc->increaseAbsorbPercent(COMBAT_HEALING, intValue);
			else if(readXMLInteger(configNode, "percentUndefined", intValue))
				voc->increaseAbsorbPercent(COMBAT_UNDEFINEDDAMAGE, intValue);
		}

		configNode = configNode->next;
	}

	vocationsMap[voc->getId()] = voc;
	return true;
}
Example #2
0
bool parseVocationNode(xmlNodePtr vocationNode, VocationMap& vocationMap, StringVec& vocStringVec, std::string& errorStr)
{
	if(xmlStrcmp(vocationNode->name,(const xmlChar*)"vocation"))
		return true;

	int32_t vocationId = -1;
	std::string strValue, tmpStrValue;
	if(readXMLString(vocationNode, "name", strValue))
	{
		vocationId = Vocations::getInstance()->getVocationId(strValue);
		if(vocationId != -1)
		{
			vocationMap[vocationId] = true;
			int32_t promotedVocation = Vocations::getInstance()->getPromotedVocation(vocationId);
			if(promotedVocation != -1)
				vocationMap[promotedVocation] = true;
		}
		else
		{
			errorStr = "Wrong vocation name: " + strValue;
			return false;
		}
	}
	else if(readXMLString(vocationNode, "id", strValue))
	{
		IntegerVec intVector;
		if(!parseIntegerVec(strValue, intVector))
		{
			errorStr = "Invalid vocation id - '" + strValue + "'";
			return false;
		}

		size_t size = intVector.size();
		for(size_t i = 0; i < size; ++i)
		{
			Vocation* vocation = Vocations::getInstance()->getVocation(intVector[i]);
			if(vocation && vocation->getName() != "")
			{
				vocationId = vocation->getId();
				strValue = vocation->getName();

				vocationMap[vocationId] = true;
				int32_t promotedVocation = Vocations::getInstance()->getPromotedVocation(vocationId);
				if(promotedVocation != -1)
					vocationMap[promotedVocation] = true;
			}
			else
			{
				std::stringstream ss;
				ss << "Wrong vocation id: " << intVector[i];

				errorStr = ss.str();
				return false;
			}
		}
	}

	if(vocationId != -1 && (!readXMLString(vocationNode, "showInDescription", tmpStrValue) || booleanString(tmpStrValue)))
		vocStringVec.push_back(asLowerCaseString(strValue));

	return true;
}
Example #3
0
void ValueCallback::getMinMaxValues(Player* player, int32_t& min, int32_t& max, bool useCharges) const
{
	//"onGetPlayerMinMaxValues"(...)
	if(m_scriptInterface->reserveScriptEnv()){
		ScriptEnviroment* env = m_scriptInterface->getScriptEnv();
		lua_State* L = m_scriptInterface->getLuaState();

		if(!env->setCallbackId(m_scriptId, m_scriptInterface))
			return;

		uint32_t cid = env->addThing(player);

		m_scriptInterface->pushFunction(m_scriptId);
		lua_pushnumber(L, cid);

		int32_t parameters = 1;
		bool isMagicFormula = false;

		switch(type){
			case FORMULA_LEVELMAGIC:
			{
				//"onGetPlayerMinMaxValues"(cid, level, maglevel)
				lua_pushnumber(L, player->getLevel());
				lua_pushnumber(L, player->getMagicLevel());
				parameters += 2;
				isMagicFormula = true;
				break;
			}

			case FORMULA_SKILL:
			{
				//"onGetPlayerMinMaxValues"(cid, attackSkill, attackValue, attackFactor)
				Item* tool = player->getWeapon();
				int32_t attackSkill = player->getWeaponSkill(tool);
				int32_t attackValue = g_config.getNumber(ConfigManager::FIST_STRENGTH);
				if(tool){
					attackValue = tool->getAttack();

					if(useCharges && tool->hasCharges() && g_config.getNumber(ConfigManager::REMOVE_WEAPON_CHARGES)){
						int32_t newCharge = std::max(0, tool->getCharges() - 1);
						g_game.transformItem(tool, tool->getID(), newCharge);
					}
				}
				float attackFactor = player->getAttackFactor();

				lua_pushnumber(L, attackSkill);
				lua_pushnumber(L, attackValue);
				lua_pushnumber(L, attackFactor);
				parameters += 3;
				break;
			}

			default:
				std::cout << "ValueCallback::getMinMaxValues - unknown callback type" << std::endl;
				return;
				break;
		}

		int size0 = lua_gettop(L);
		if(lua_pcall(L, parameters, 2 /*nReturnValues*/, 0) != 0){
			LuaScriptInterface::reportError(NULL, LuaScriptInterface::popString(L));
		}
		else{
			max = LuaScriptInterface::popNumber(L);
			min = LuaScriptInterface::popNumber(L);

			Vocation* vocation = player->getVocation();
			if(isMagicFormula && vocation){
				if(max > 0 && min > 0 && vocation->getHealingBaseDamage() != 1.0){
					min = int32_t(min * vocation->getHealingBaseDamage());
					max = int32_t(max * vocation->getHealingBaseDamage());
				}
				else if(max < 0 && min < 0 && vocation->getMagicBaseDamage() != 1.0){
					min = int32_t(min * vocation->getMagicBaseDamage());
					max = int32_t(max * vocation->getMagicBaseDamage());
				}
			}
		}

		if((lua_gettop(L) + parameters /*nParams*/  + 1) != size0){
			LuaScriptInterface::reportError(NULL, "Stack size changed!");
		}

		env->resetCallback();
		m_scriptInterface->releaseScriptEnv();
	}
	else{
		std::cout << "[Error] Call stack overflow. ValueCallback::getMinMaxValues" << std::endl;
		return;
	}
}
Example #4
0
bool Combat::getMinMaxValues(Creature* creature, Creature* target, int32_t& min, int32_t& max) const
{
	if(creature){
		if(creature->getCombatValues(min, max)){
			return true;
		}
		else if(Player* player = creature->getPlayer()){
			if(params.valueCallback){
				params.valueCallback->getMinMaxValues(player, min, max, params.useCharges);
				return true;
			}
			else{
				switch(formulaType){
					case FORMULA_LEVELMAGIC:
					{
						max = (int32_t)((player->getLevel() + player->getMagicLevel() * 4) * 1. * mina + minb);
						min = (int32_t)((player->getLevel() + player->getMagicLevel() * 4) * 1. * maxa + maxb);

						Vocation* vocation = player->getVocation();
						if(vocation){
							if(max > 0 && min > 0 && vocation->getHealingBaseDamage() != 1.0){
								min = int32_t(min * vocation->getHealingBaseDamage());
								max = int32_t(max * vocation->getHealingBaseDamage());
							}
							else if(max < 0 && min < 0 && vocation->getMagicBaseDamage() != 1.0){
								min = int32_t(min * vocation->getMagicBaseDamage());
								max = int32_t(max * vocation->getMagicBaseDamage());
							}
						}

						return true;
						break;
					}

					case FORMULA_SKILL:
					{
						Item* tool = player->getWeapon();
						const Weapon* weapon = g_weapons->getWeapon(tool);

						min = (int32_t)minb;

						if(weapon){
							max = (int32_t)(weapon->getWeaponDamage(player, target, tool, true) * maxa + maxb);
							if(params.useCharges && tool->hasCharges() && g_config.getNumber(ConfigManager::REMOVE_WEAPON_CHARGES)){
								int32_t newCharge = std::max((int32_t)0, ((int32_t)tool->getCharges()) - 1);
								g_game.transformItem(tool, tool->getID(), newCharge);
							}
						}
						else{
							max = (int32_t)maxb;
						}

						return true;
						break;
					}

					case FORMULA_VALUE:
					{
						min = (int32_t)mina;
						max = (int32_t)maxa;
						return true;
						break;
					}

					default:
						min = 0;
						max = 0;
						return false;
						break;
				}

				//std::cout << "No callback set for combat" << std::endl;
			}
		}
	}

	if(formulaType == FORMULA_VALUE){
		min = (int32_t)mina;
		max = (int32_t)maxa;
		return true;
	}

	return false;
}
Example #5
0
bool Vocations::loadFromXml(const std::string& datadir)
{
	std::string filename = datadir + "vocations.xml";

	xmlDocPtr doc = xmlParseFile(filename.c_str());
	if(doc){
		xmlNodePtr root, p;
		root = xmlDocGetRootElement(doc);

		if(xmlStrcmp(root->name,(const xmlChar*)"vocations") != 0){
			xmlFreeDoc(doc);
			return false;
		}

		p = root->children;

		while(p){
			if(xmlStrcmp(p->name, (const xmlChar*)"vocation") == 0){
				std::string str;
				int intVal;
				float floatVal;
				Vocation* voc = NULL;
				xmlNodePtr skillNode;
				if(readXMLInteger(p, "id", intVal)){
					voc = new Vocation(intVal);
					if(readXMLString(p, "name", str)){
						voc->name = str;
					}
					if(readXMLString(p, "description", str)){
						voc->description = str;
					}
					if(readXMLInteger(p, "gaincap", intVal)){
						voc->gainCap = intVal;
					}
					if(readXMLInteger(p, "gainhp", intVal)){
						voc->gainHP = intVal;
					}
					if(readXMLInteger(p, "gainmana", intVal)){
						voc->gainMana = intVal;
					}
					if(readXMLInteger(p, "gainhpticks", intVal)){
						voc->gainHealthTicks = intVal;
					}
					if(readXMLInteger(p, "gainhpamount", intVal)){
						voc->gainHealthAmount = intVal;
					}
					if(readXMLInteger(p, "gainmanaticks", intVal)){
						voc->gainManaTicks = intVal;
					}
					if(readXMLInteger(p, "gainmanaamount", intVal)){
						voc->gainManaAmount = intVal;
					}
					if(readXMLInteger(p, "maxsoul", intVal)){
						voc->maxSoul = intVal;
					}
					if(readXMLInteger(p, "gainsoulticks", intVal)){
						voc->gainSoulTicks = intVal;
					}
					if(readXMLFloat(p, "manamultiplier", floatVal)){
						voc->manaMultiplier = floatVal;
					}
					skillNode = p->children;
					while(skillNode){
						if(xmlStrcmp(skillNode->name, (const xmlChar*)"skill") == 0){
							SkillType skill_id;
							try {
								if(readXMLInteger(skillNode, "id", intVal)){
									skill_id = SkillType::fromInteger(intVal);
								} else if(readXMLString(skillNode, "name", str)){
									skill_id = SkillType::fromString(str);
								}
								if(readXMLInteger(skillNode, "base", intVal)){
									voc->skillBases[skill_id.value()] = intVal;
								}
								if(readXMLFloat(skillNode, "multiplier", floatVal)){
									voc->skillMultipliers[skill_id.value()] = floatVal;
								}
							} catch(enum_conversion_error&){
								std::cout << "Missing skill id ." << std::endl;
							}
						}
						else if(xmlStrcmp(skillNode->name, (const xmlChar*)"damage") == 0){
							if(readXMLFloat(skillNode, "magicDamage", floatVal)){
								voc->magicBaseDamage = floatVal;
							}
							if(readXMLFloat(skillNode, "wandDamage", floatVal)){
								voc->wandBaseDamage = floatVal;
							}
							if(readXMLFloat(skillNode, "healingDamage", floatVal)){
								voc->healingBaseDamage = floatVal;
							}
						}
						else if(xmlStrcmp(skillNode->name, (const xmlChar*)"meleeDamage") == 0){
							if(readXMLFloat(skillNode, "sword", floatVal)){
								voc->swordBaseDamage = floatVal;
							}
							if(readXMLFloat(skillNode, "axe", floatVal)){
								voc->axeBaseDamage = floatVal;
							}
							if(readXMLFloat(skillNode, "club", floatVal)){
								voc->clubBaseDamage = floatVal;
							}
							if(readXMLFloat(skillNode, "dist", floatVal)){
								voc->distBaseDamage = floatVal;
							}
							if(readXMLFloat(skillNode, "fist", floatVal)){
								voc->fistBaseDamage = floatVal;
							}
						}
						else if(xmlStrcmp(skillNode->name, (const xmlChar*)"defense") == 0){
							if(readXMLFloat(skillNode, "baseDefense", floatVal)){
								voc->baseDefense = floatVal;
							}
							if(readXMLFloat(skillNode, "armorDefense", floatVal)){
								voc->armorDefense = floatVal;
							}
						}
						skillNode = skillNode->next;
					}

					//std::cout << "Voc id: " << voc_id << std::endl;
					//voc->debugVocation();
					vocationsMap[voc->getID()] = voc;

				}
				else{
					std::cout << "Missing vocation id." << std::endl;
				}
			}
			p = p->next;
		}
		xmlFreeDoc(doc);
	}
	return true;
}