Example #1
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 #2
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;
	}
}