uint32_t MoveEvent::executeStep(Creature* creature, Item* item, const Position& fromPos, const Position& toPos) { //onStepIn(cid, item, topos, frompos) //onStepOut(cid, item, topos, frompos) if (m_scriptInterface->reserveScriptEnv()) { ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << creature->getName() << " itemid: " << item->getID() << " - " << toPos; env->setEventDesc(desc.str()); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(creature->getPosition()); uint32_t cid = env->addThing(creature); uint32_t itemid = env->addThing(item); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); LuaScriptInterface::pushThing(L, item, itemid); LuaScriptInterface::pushPosition(L, toPos, 0); LuaScriptInterface::pushPosition(L, fromPos, 0); bool result = m_scriptInterface->callFunction(4); m_scriptInterface->releaseScriptEnv(); return result; } else { std::cout << "[Error] Call stack overflow. MoveEvent::executeStep" << std::endl; return 0; } }
void TargetCallback::onTargetCombat(const CreatureP& creature, const CreatureP& target) const { //"onTargetCombat"(cid, target) if(m_interface->reserveEnv()) { ScriptEnviroment* env = m_interface->getEnv(); if(!env->setCallbackId(m_scriptId, m_interface)) return; uint32_t cid = 0; if(creature) cid = env->addThing(creature); m_interface->pushFunction(m_scriptId); lua_State* L = m_interface->getState(); lua_pushnumber(L, cid); lua_pushnumber(L, env->addThing(target)); int32_t size = lua_gettop(L); if(lua_pcall(L, 2, 0 /*nReturnValues*/, 0) != 0) LuaScriptInterface::error(nullptr, std::string(LuaScriptInterface::popString(L))); if((lua_gettop(L) + 2 /*nParams*/ + 1) != size) LuaScriptInterface::error(__FUNCTION__, "Stack size changed!"); env->resetCallback(); m_interface->releaseEnv(); } else { LOGe("[TargetCallback::onTargetCombat] Call stack overflow."); return; } }
uint32_t MoveEvent::executeEquip(Player* player, Item* item, slots_t slot) { //onEquip(cid, item, slot) //onDeEquip(cid, item, slot) if (m_scriptInterface->reserveScriptEnv()) { ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << player->getName() << " itemid:" << item->getID() << " slot:" << slot; env->setEventDesc(desc.str()); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(player->getPosition()); uint32_t cid = env->addThing(player); uint32_t itemid = env->addThing(item); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); LuaScriptInterface::pushThing(L, item, itemid); lua_pushnumber(L, slot); bool result = m_scriptInterface->callFunction(3); m_scriptInterface->releaseScriptEnv(); return result; } else { std::cout << "[Error] Call stack overflow. MoveEvent::executeEquip" << std::endl; return 0; } }
void CreatureEvent::executeOnDie(Creature* creature, Item* corpse) { //onDie(cid, corpse) if(m_scriptInterface->reserveScriptEnv()) { ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << creature->getName(); env->setEventDesc(desc.str()); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(creature->getPosition()); uint32_t cid = env->addThing(creature); uint32_t corpseid = env->addThing(corpse); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); lua_pushnumber(L, corpseid); m_scriptInterface->callFunction(2); m_scriptInterface->releaseScriptEnv(); } else { std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnDie" << std::endl; } }
void CreatureEvent::executeOnKill(Creature* creature, Creature* target, bool lastHit) { //onKill(cid, target, lasthit) if(m_scriptInterface->reserveScriptEnv()) { ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << creature->getName(); env->setEventDesc(desc.str()); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(creature->getPosition()); uint32_t cid = env->addThing(creature); uint32_t targetId = env->addThing(target); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); lua_pushnumber(L, targetId); lua_pushboolean(L, (lastHit ? true : false)); m_scriptInterface->callFunction(3); m_scriptInterface->releaseScriptEnv(); } else { std::cout << "[Error] __ENABLE_SERVER_DIAGNOSTIC__Call stack overflow. CreatureEvent::executeOnKill" << std::endl; } }
void CreatureEvent::executeOnAdvance(Player* player, levelTypes_t type, uint32_t oldLevel, uint32_t newLevel) { //onAdvance(cid, type, oldlevel, newlevel) if(m_scriptInterface->reserveScriptEnv()) { ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << player->getName(); env->setEventDesc(desc.str()); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(player->getPosition()); uint32_t cid = env->addThing(player); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); lua_pushnumber(L, (uint32_t)type); lua_pushnumber(L, oldLevel); lua_pushnumber(L, newLevel); m_scriptInterface->callFunction(4); m_scriptInterface->releaseScriptEnv(); } else { std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnAdvance" << std::endl; } }
bool CreatureEvent::executeOnLogout(Player* player) { //onLogout(cid) if(m_scriptInterface->reserveScriptEnv()) { ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << player->getName(); env->setEventDesc(desc.str()); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(player->getPosition()); uint32_t cid = env->addThing(player); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); bool result = m_scriptInterface->callFunction(1); m_scriptInterface->releaseScriptEnv(); return result; } else { std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnLogout" << std::endl; return 0; } }
void NpcScript::onCreatureAppear(const Creature* creature) { if(m_onCreatureAppear == -1){ return; } //onCreatureAppear(creature) if(m_scriptInterface->reserveScriptEnv()){ ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << "npc " << m_npc->getName(); env->setEventDesc(desc.str()); #endif lua_State* L = m_scriptInterface->getLuaState(); env->setScriptId(m_onCreatureAppear, m_scriptInterface); env->setRealPos(m_npc->getPosition()); env->setNpc(m_npc); uint32_t cid = env->addThing(const_cast<Creature*>(creature)); m_scriptInterface->pushFunction(m_onCreatureAppear); lua_pushnumber(L, cid); m_scriptInterface->callFunction(1); m_scriptInterface->releaseScriptEnv(); } else{ std::cout << "[Error] Call stack overflow. NpcScript::onCreatureAppear" << std::endl; } }
bool TalkAction::executeSay(Creature* creature, const std::string& words, const std::string& param) { // onSay(cid, words, param) if(m_scriptInterface->reserveScriptEnv()){ ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << creature->getName() << " - " << words << " " << param; env->setEventDesc(desc.str()); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(creature->getPosition()); uint32_t cid = env->addThing(creature); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); lua_pushstring(L, words.c_str()); lua_pushstring(L, param.c_str()); bool result = m_scriptInterface->callFunction(3); m_scriptInterface->releaseScriptEnv(); return result; } else{ std::cout << "[Error] Call stack overflow. TalkAction::executeSay" << std::endl; return 0; } }
void TileCallback::onTileCombat(Creature* creature, Tile* tile) const { //"onTileCombat"(cid, pos) 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 = 0; if(creature) cid = env->addThing(creature); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); m_scriptInterface->pushPosition(L, tile->getPosition(), 0); m_scriptInterface->callFunction(2); env->resetCallback(); m_scriptInterface->releaseScriptEnv(); } else { std::cout << "[Error] Call stack overflow. TileCallback::onTileCombat" << std::endl; return; } }
void NpcScript::onPlayerTrade(const Player* player, int32_t callback, uint16_t itemid, uint8_t count, uint8_t amount) { if(callback == -1){ return; } //"onBuy"(cid, itemid, count, amount) if(m_scriptInterface->reserveScriptEnv()){ ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); env->setScriptId(-1, m_scriptInterface); env->setRealPos(m_npc->getPosition()); env->setNpc(m_npc); uint32_t cid = env->addThing(const_cast<Player*>(player)); lua_State* L = m_scriptInterface->getLuaState(); LuaScriptInterface::pushCallback(L, callback); lua_pushnumber(L, cid); lua_pushnumber(L, itemid); lua_pushnumber(L, count); lua_pushnumber(L, amount); m_scriptInterface->callFunction(4); m_scriptInterface->releaseScriptEnv(); } else{ std::cout << "[Error] Call stack overflow. NpcScript::onPlayerTrade" << std::endl; } }
bool CreatureEvent::executeOnLook(Player* player, Thing* target, uint16_t itemId) { //onLook(cid, thing, itemId) if(m_scriptInterface->reserveScriptEnv()) { ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << player->getName(); env->setEventDesc(desc.str()); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(player->getPosition()); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); uint32_t cid = env->addThing(player); lua_pushnumber(L, cid); uint32_t target_id = 0; if(target) { if(target->getCreature()) target_id = env->addThing(target->getCreature()); else if(target->getItem()) target_id = env->addThing(target->getItem()); else target = NULL; } if(target) LuaScriptInterface::pushThing(L, target, target_id); else lua_pushnil(L); lua_pushnumber(L, itemId); bool result = m_scriptInterface->callFunction(3); m_scriptInterface->releaseScriptEnv(); return result; } else { std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnLook" << std::endl; return 0; } }
void TargetCallback::onTargetCombat(Creature* creature, Creature* target) const { //"onTargetCombat"(cid, target) 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 = 0; if (creature) { cid = env->addThing(creature); } uint32_t targetCid = env->addThing(target); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); lua_pushnumber(L, targetCid); int size0 = lua_gettop(L); if (lua_pcall(L, 2, 0 /*nReturnValues*/, 0) != 0) { LuaScriptInterface::reportError(NULL, LuaScriptInterface::popString(L)); } if ((lua_gettop(L) + 2 /*nParams*/ + 1) != size0) { LuaScriptInterface::reportError(NULL, "Stack size changed!"); } env->resetCallback(); m_scriptInterface->releaseScriptEnv(); } else { std::cout << "[Error] Call stack overflow. TargetCallback::onTargetCombat" << std::endl; return; } }
uint32_t MoveEvent::executeAddRemItem(Item* item, Item* tileItem, const Position& pos) { //onAddItem(moveitem, tileitem, pos) //onRemoveItem(moveitem, tileitem, pos) if(m_scriptInterface->reserveScriptEnv()){ ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; if(tileItem){ desc << "tileid: " << tileItem->getID(); } desc << " itemid: " << item->getID() << " - " << pos; env->setEventDesc(desc.str()); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(pos); uint32_t itemidMoved = env->addThing(item); uint32_t itemidTile = env->addThing(tileItem); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); LuaScriptInterface::pushThing(L, item, itemidMoved); LuaScriptInterface::pushThing(L, tileItem, itemidTile); LuaScriptInterface::pushPosition(L, pos, 0); int32_t result = m_scriptInterface->callFunction(3); m_scriptInterface->releaseScriptEnv(); return (result != LUA_FALSE); } else{ std::cout << "[Error] Call stack overflow. MoveEvent::executeAddRemItem" << std::endl; return 0; } }
int NpcScriptInterface::luaGetNpcCid(lua_State* L) { //getNpcCid() ScriptEnviroment* env = getScriptEnv(); Npc* npc = env->getNpc(); if(npc){ uint32_t cid = env->addThing(npc); lua_pushnumber(L, cid); } else{ lua_pushnil(L); } return 1; }
void TileCallback::onTileCombat(const CreatureP& creature, Tile* tile) const { //"onTileCombat"(cid, pos) if(m_interface->reserveEnv()) { ScriptEnviroment* env = m_interface->getEnv(); if(!env->setCallbackId(m_scriptId, m_interface)) return; m_interface->pushFunction(m_scriptId); lua_State* L = m_interface->getState(); lua_pushnumber(L, creature ? env->addThing(creature) : 0); m_interface->pushPosition(L, tile->getPosition()); m_interface->callFunction(2); env->resetCallback(); m_interface->releaseEnv(); } else LOGe("[TileCallback::onTileCombat] Call stack overflow."); }
int32_t TalkAction::executeSay(Creature* creature, const std::string& words, const std::string& param) { //onSay(cid, words, param) if(m_scriptInterface->reserveScriptEnv()) { ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); #ifdef __DEBUG_LUASCRIPTS__ char desc[125]; sprintf(desc, "%s - %s- %s", creature->getName().c_str(), words.c_str(), param.c_str()); env->setEventDesc(desc); #endif env->setScriptId(m_scriptId, m_scriptInterface); env->setRealPos(creature->getPosition()); uint32_t cid = env->addThing(creature); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_scriptId); lua_pushnumber(L, cid); lua_pushstring(L, words.c_str()); lua_pushstring(L, param.c_str()); int32_t result = m_scriptInterface->callFunction(3); m_scriptInterface->releaseScriptEnv(); return (result != LUA_FALSE); } else { std::cout << "[Error] Call stack overflow. TalkAction::executeSay" << std::endl; return 0; } }
void NpcScript::onPlayerEndTrade(const Player* player) { if(m_onPlayerCloseChannel == -1){ return; } //onPlayerEndTrade(cid) if(m_scriptInterface->reserveScriptEnv()){ ScriptEnviroment* env = m_scriptInterface->getScriptEnv(); env->setScriptId(m_onPlayerCloseChannel, m_scriptInterface); env->setRealPos(m_npc->getPosition()); env->setNpc(m_npc); uint32_t cid = env->addThing(const_cast<Player*>(player)); lua_State* L = m_scriptInterface->getLuaState(); m_scriptInterface->pushFunction(m_onPlayerEndTrade); lua_pushnumber(L, cid); m_scriptInterface->callFunction(1); m_scriptInterface->releaseScriptEnv(); } else{ std::cout << "[Error] Call stack overflow. NpcScript::onPlayerEndTrade" << std::endl; } }
void ValueCallback::getMinMaxValues(Player* player, CombatParams& params, int32_t& min, int32_t& max) const { //"onGetPlayerMinMaxValues"(cid, ...) if(!m_interface->reserveEnv()) { std::clog << "[Error - ValueCallback::getMinMaxValues] Callstack overflow." << std::endl; return; } ScriptEnviroment* env = m_interface->getEnv(); if(!env->setCallbackId(m_scriptId, m_interface)) return; m_interface->pushFunction(m_scriptId); lua_State* L = m_interface->getState(); lua_pushnumber(L, env->addThing(player)); int32_t parameters = 1; switch(type) { case FORMULA_LEVELMAGIC: { //"onGetPlayerMinMaxValues"(cid, level, magLevel) lua_pushnumber(L, player->getLevel()); lua_pushnumber(L, player->getMagicLevel()); parameters += 2; break; } case FORMULA_SKILL: { //"onGetPlayerMinMaxValues"(cid, level, skill, attack, element, factor) lua_pushnumber(L, player->getLevel()); if(Item* weapon = player->getWeapon(false)) { lua_pushnumber(L, player->getWeaponSkill(weapon)); if(params.useCharges && weapon->hasCharges() && g_config.getBool(ConfigManager::REMOVE_WEAPON_CHARGES)) g_game.transformItem(weapon, weapon->getID(), std::max(0, weapon->getCharges() - 1)); uint32_t attack = weapon->getAttack() + weapon->getExtraAttack(); if(weapon->getWeaponType() == WEAPON_AMMO) { if(Item* bow = player->getWeapon(true)) attack += bow->getAttack() + bow->getExtraAttack(); } if(weapon->getElementType() != COMBAT_NONE) { attack -= weapon->getElementDamage(); lua_pushnumber(L, attack); lua_pushnumber(L, weapon->getElementDamage()); params.element.type = weapon->getElementType(); } else { lua_pushnumber(L, attack); lua_pushnumber(L, 0); } } else { lua_pushnumber(L, player->getSkill(SKILL_FIST, SKILL_LEVEL)); lua_pushnumber(L, g_config.getNumber(ConfigManager::FIST_BASE_ATTACK)); lua_pushnumber(L, 0); } lua_pushnumber(L, player->getAttackFactor()); parameters += 5; break; } default: { std::clog << "[Warning - ValueCallback::getMinMaxValues] Unknown callback type" << std::endl; return; } } int32_t args = lua_gettop(L); if(!lua_pcall(L, parameters, 3, 0)) { params.element.damage = LuaInterface::popNumber(L); max = LuaInterface::popNumber(L); min = LuaInterface::popNumber(L); player->increaseCombatValues(min, max, params.useCharges, type != FORMULA_SKILL); } else LuaInterface::error(NULL, std::string(LuaInterface::popString(L))); if((lua_gettop(L) + parameters + 1) != args) LuaInterface::error(__FUNCTION__, "Stack size changed!"); env->resetCallback(); m_interface->releaseEnv(); }
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; switch(type) { case FORMULA_LEVELMAGIC: { //"onGetPlayerMinMaxValues"(cid, level, maglevel) lua_pushnumber(L, player->getLevel()); lua_pushnumber(L, player->getMagicLevel()); parameters += 2; break; } case FORMULA_SKILL: { //"onGetPlayerMinMaxValues"(cid, attackSkill, attackValue, attackFactor) Item* tool = player->getWeapon(); int32_t attackSkill = player->getWeaponSkill(tool); int32_t attackValue = 7; if(tool) { attackValue = tool->getAttack(); if(useCharges && tool->hasCharges()) { 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; } } int32_t 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); } 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; } }
void ValueCallback::getMinMaxValues(Player* player, int32_t& min, int32_t& max, bool useCharges) const { //"onGetPlayerMinMaxValues"(cid, ...) if(!m_interface->reserveEnv()) { LOGe("[ValueCallback::getMinMaxValues] Callstack overflow."); return; } ScriptEnviroment* env = m_interface->getEnv(); if(!env->setCallbackId(m_scriptId, m_interface)) return; m_interface->pushFunction(m_scriptId); lua_State* L = m_interface->getState(); lua_pushnumber(L, env->addThing(player)); int32_t parameters = 1; switch(type) { case FORMULA_LEVELMAGIC: { //"onGetPlayerMinMaxValues"(cid, level, magLevel) lua_pushnumber(L, player->getLevel()); lua_pushnumber(L, player->getMagicLevel()); parameters += 2; break; } case FORMULA_SKILL: { //"onGetPlayerMinMaxValues"(cid, level, skill, attack, factor) Item* tool = player->getWeapon(); lua_pushnumber(L, player->getLevel()); lua_pushnumber(L, player->getWeaponSkill(tool)); int32_t attack = 7; if(tool) { attack = tool->getAttack(); if(useCharges && tool->hasCharges() && server.configManager().getBool(ConfigManager::REMOVE_WEAPON_CHARGES)) server.game().transformItem(tool, tool->getId(), std::max(0, tool->getCharges() - 1)); } lua_pushnumber(L, attack); lua_pushnumber(L, player->getAttackFactor()); parameters += 4; break; } default: { LOGe("[ValueCallback::getMinMaxValues] Unknown callback type"); return; } } int32_t params = lua_gettop(L); if(!lua_pcall(L, parameters, 2, 0)) { min = LuaScriptInterface::popNumber(L); max = LuaScriptInterface::popNumber(L); player->increaseCombatValues(min, max, useCharges, type != FORMULA_SKILL); } else LuaScriptInterface::error(nullptr, std::string(LuaScriptInterface::popString(L))); if((lua_gettop(L) + parameters + 1) != params) LuaScriptInterface::error(__FUNCTION__, "Stack size changed!"); env->resetCallback(); m_interface->releaseEnv(); }
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; } }