int32_t NpcScriptInterface::luaActionSay(lua_State* L) { //selfSay(words [[, target], publicize]) // publicize defaults to true if there is no target, false otherwise uint32_t parameters = lua_gettop(L); uint32_t target = 0; bool publicize; if (parameters >= 3) { publicize = popBoolean(L); } else { publicize = true; } if (parameters >= 2) { target = popNumber(L); if (target != 0) { publicize = false; } } std::string text = popString(L); Npc* npc = getScriptEnv()->getNpc(); if (npc) { if (publicize) { npc->doSay(text); } else { npc->doSayToPlayer(g_game.getPlayerByID(target), text); } } return 0; }
int32_t NpcScriptInterface::luaDoSellItem(lua_State* L) { //doSellItem(cid, itemid, amount, <optional> subtype, <optional> actionid, <optional: default: 1> canDropOnMap) int32_t parameters = lua_gettop(L); bool canDropOnMap; if (parameters > 5) { canDropOnMap = popBoolean(L); } else { canDropOnMap = true; } uint32_t actionId = 0; if (parameters > 4) { actionId = popNumber(L); } uint32_t subType = 1; if (parameters > 3) { int32_t n = popNumber(L); if (n != -1) { subType = n; } } uint32_t amount = popNumber(L); uint32_t itemId = popNumber(L); Player* player = g_game.getPlayerByID(popNumber(L)); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } uint32_t sellCount = 0; const ItemType& it = Item::items[itemId]; if (it.stackable) { while (amount > 0) { int32_t stackCount = std::min<int32_t>(100, amount); Item* item = Item::CreateItem(it.id, stackCount); if (item && actionId != 0) { item->setActionId(actionId); } if (g_game.internalPlayerAddItem(player, item, canDropOnMap) != RET_NOERROR) { delete item; lua_pushnumber(L, sellCount); return 1; } amount = amount - stackCount; sellCount += stackCount; } } else { for (uint32_t i = 0; i < amount; ++i) { Item* item = Item::CreateItem(it.id, subType); if (item && actionId != 0) { item->setActionId(actionId); } if (g_game.internalPlayerAddItem(player, item, canDropOnMap) != RET_NOERROR) { delete item; lua_pushnumber(L, sellCount); return 1; } ++sellCount; } } lua_pushnumber(L, sellCount); return 1; }
int LuaInterface::signalCall(int numArgs, int numRets) { int rets = 0; int funcIndex = -numArgs-1; try { // must be a function if(isFunction(funcIndex)) { rets = safeCall(numArgs); if(numRets != -1) { if(rets != numRets) throw LuaException("function call didn't return the expected number of results", 0); } } // can also calls table of functions else if(isTable(funcIndex)) { // loop through table values pushNil(); bool done = false; while(next(funcIndex-1)) { if(isFunction()) { // repush arguments for(int i=0;i<numArgs;++i) pushValue(-numArgs-2); int rets = safeCall(numArgs); if(rets == 1) { done = popBoolean(); if(done) { pop(); break; } } else if(rets != 0) throw LuaException("function call didn't return the expected number of results", 0); } else { throw LuaException("attempt to call a non function", 0); } } pop(numArgs + 1); // pops the table of function and arguments if(numRets == 1 || numRets == -1) { rets = 1; pushBoolean(done); } } // nil values are ignored else if(isNil(funcIndex)) { pop(numArgs + 1); // pops the function and arguments } // if not nil, warn else { throw LuaException("attempt to call a non function value", 0); } } catch(stdext::exception& e) { g_logger.error(stdext::format("protected lua call failed: %s", e.what())); } // pushes nil values if needed while(numRets != -1 && rets < numRets) { pushNil(); rets++; } // returns the number of results on the stack return rets; }
int32_t MoveEventScript::luaCallFunction(lua_State* L) { //callFunction(...) MoveEvent* event = MoveEventScript::event; if(!event) { error(__FUNCTION__, "MoveEvent not set!"); lua_pushboolean(L, false); return 1; } if(event->getEventType() == MOVE_EVENT_EQUIP || event->getEventType() == MOVE_EVENT_DE_EQUIP) { ScriptEnviroment* env = getEnv(); bool boolean = popBoolean(L); slots_t slot = (slots_t)popNumber(L); Item* item = env->getItemByUID(popNumber(L)); if(!item) { error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND)); lua_pushboolean(L, false); return 1; } Player* player = env->getPlayerByUID(popNumber(L)); if(!player) { error(__FUNCTION__, getError(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushboolean(L, false); return 1; } if(event->getEventType() != MOVE_EVENT_EQUIP) lua_pushboolean(L, MoveEvent::DeEquipItem(event, player, item, slot, boolean)); else lua_pushboolean(L, MoveEvent::EquipItem(event, player, item, slot, boolean)); return 1; } else if(event->getEventType() == MOVE_EVENT_STEP_IN) { ScriptEnviroment* env = getEnv(); Item* item = env->getItemByUID(popNumber(L)); if(!item) { error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND)); lua_pushboolean(L, false); return 1; } Creature* creature = env->getCreatureByUID(popNumber(L)); if(!creature) { error(__FUNCTION__, getError(LUA_ERROR_CREATURE_NOT_FOUND)); lua_pushboolean(L, false); return 1; } lua_pushboolean(L, MoveEvent::StepInField(creature, item)); return 1; } else if(event->getEventType() == MOVE_EVENT_ADD_ITEM) { ScriptEnviroment* env = getEnv(); Item* item = env->getItemByUID(popNumber(L)); if(!item) { error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND)); lua_pushboolean(L, false); return 1; } lua_pushboolean(L, MoveEvent::AddItemField(item)); return 1; } error(__FUNCTION__, "callFunction not available for current event."); lua_pushboolean(L, false); return 1; }