int NpcScriptInterface::luagetDistanceTo(lua_State* L) { //getDistanceTo(uid) ScriptEnvironment* env = getScriptEnv(); Npc* npc = env->getNpc(); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_THING_NOT_FOUND)); lua_pushnil(L); return 1; } uint32_t uid = getNumber<uint32_t>(L, -1); Thing* thing = env->getThingByUID(uid); if (!thing) { reportErrorFunc(getErrorDesc(LUA_ERROR_THING_NOT_FOUND)); lua_pushnil(L); return 1; } const Position& thingPos = thing->getPosition(); const Position& npcPos = npc->getPosition(); if (npcPos.z != thingPos.z) { lua_pushnumber(L, -1); } else { int32_t dist = std::max<int32_t>(Position::getDistanceX(npcPos, thingPos), Position::getDistanceY(npcPos, thingPos)); lua_pushnumber(L, dist); } return 1; }
int NpcScriptInterface::luaCloseShop(lua_State *L) { //closeShopWindow(cid) ScriptEnviroment* env = getScriptEnv(); Npc* npc = env->getNpc(); Player* player = env->getPlayerByUID(popNumber(L)); int32_t buyCallback; int32_t sellCallback; if(player == NULL) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); lua_pushnumber(L, LUA_ERROR); return 1; } player->sendCloseShop(); player->getShopOwner(buyCallback, sellCallback); if(buyCallback != -1) luaL_unref(L, LUA_REGISTRYINDEX, buyCallback); if(sellCallback != -1) luaL_unref(L, LUA_REGISTRYINDEX, sellCallback); player->setShopOwner(NULL, -1, -1); return 1; }
int NpcScriptInterface::luagetDistanceTo(lua_State *L) { //getDistanceTo(uid) uint32_t uid = popNumber(L); ScriptEnviroment* env = getScriptEnv(); Npc* npc = env->getNpc(); Thing* thing = env->getThingByUID(uid); if(thing && npc){ Position thing_pos = thing->getPosition(); Position npc_pos = npc->getPosition(); if(npc_pos.z != thing_pos.z){ lua_pushnumber(L, -1); } else{ int32_t dist = std::max(std::abs(npc_pos.x - thing_pos.x), std::abs(npc_pos.y - thing_pos.y)); lua_pushnumber(L, dist); } } else{ reportErrorFunc(getErrorDesc(LUA_ERROR_THING_NOT_FOUND)); lua_pushnil(L); } return 1; }
int NpcScriptInterface::luaCreatureGetPos(lua_State *L) { /*/ //creatureGetPosition(cid) popNumber(L); reportErrorFunc("Deprecated function. Use getCreaturePosition"); /*/ uint32_t uid = popNumber(L); ScriptEnviroment* env = getScriptEnv(); Creature* creature = env->getCreatureByUID(uid); if(creature){ Position pos = creature->getPosition(); lua_pushnumber(L, pos.x); lua_pushnumber(L, pos.y); lua_pushnumber(L, pos.z); } else{ reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); } return 3; }
int32_t NpcScriptInterface::luaCloseShopWindow(lua_State* L) { //closeShopWindow(cid) ScriptEnvironment* env = getScriptEnv(); Player* player = g_game.getPlayerByID(popNumber(L)); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } Npc* npc = env->getNpc(); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } int32_t buyCallback; int32_t sellCallback; Npc* merchant = player->getShopOwner(buyCallback, sellCallback); //Check if we actually have a shop window with this player. if (merchant == npc) { player->sendCloseShop(); if (buyCallback != -1) { luaL_unref(L, LUA_REGISTRYINDEX, buyCallback); } if (sellCallback != -1) { luaL_unref(L, LUA_REGISTRYINDEX, sellCallback); } player->setShopOwner(NULL, -1, -1); npc->removeShopPlayer(player); } pushBoolean(L, true); return 1; }
int NpcScriptInterface::luaNpcCloseShopWindow(lua_State* L) { // npc:closeShopWindow(player) Player* player = getPlayer(L, 2); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } Npc* npc = getUserdata<Npc>(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } int32_t buyCallback; int32_t sellCallback; Npc* merchant = player->getShopOwner(buyCallback, sellCallback); if (merchant == npc) { player->sendCloseShop(); if (buyCallback != -1) { luaL_unref(L, LUA_REGISTRYINDEX, buyCallback); } if (sellCallback != -1) { luaL_unref(L, LUA_REGISTRYINDEX, sellCallback); } player->setShopOwner(nullptr, -1, -1); npc->removeShopPlayer(player); } pushBoolean(L, true); return 1; }
int NpcScriptInterface::luaNpcOpenShopWindow(lua_State* L) { // npc:openShopWindow(cid, items, buyCallback, sellCallback) if (!isTable(L, 3)) { reportErrorFunc("item list is not a table."); pushBoolean(L, false); return 1; } Player* player = getPlayer(L, 2); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } Npc* npc = getUserdata<Npc>(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } int32_t sellCallback = -1; if (LuaScriptInterface::isFunction(L, 5)) { sellCallback = luaL_ref(L, LUA_REGISTRYINDEX); } int32_t buyCallback = -1; if (LuaScriptInterface::isFunction(L, 4)) { buyCallback = luaL_ref(L, LUA_REGISTRYINDEX); } std::list<ShopInfo> items; lua_pushnil(L); while (lua_next(L, 3) != 0) { const auto tableIndex = lua_gettop(L); ShopInfo item; item.itemId = getField<uint32_t>(L, tableIndex, "id"); item.subType = getField<int32_t>(L, tableIndex, "subType"); if (item.subType == 0) { item.subType = getField<int32_t>(L, tableIndex, "subtype"); lua_pop(L, 1); } item.buyPrice = getField<uint32_t>(L, tableIndex, "buy"); item.sellPrice = getField<uint32_t>(L, tableIndex, "sell"); item.realName = getFieldString(L, tableIndex, "name"); items.push_back(item); lua_pop(L, 6); } lua_pop(L, 1); player->closeShopWindow(false); npc->addShopPlayer(player); player->setShopOwner(npc, buyCallback, sellCallback); player->openShopWindow(npc, items); pushBoolean(L, true); return 1; }
int NpcScriptInterface::luaDoSellItem(lua_State* L) { //doSellItem(cid, itemid, amount, <optional> subtype, <optional> actionid, <optional: default: 1> canDropOnMap) Player* player = getPlayer(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } uint32_t sellCount = 0; uint32_t itemId = getNumber<uint32_t>(L, 2); uint32_t amount = getNumber<uint32_t>(L, 3); uint32_t subType; int32_t n = getNumber<int32_t>(L, 4, -1); if (n != -1) { subType = n; } else { subType = 1; } uint32_t actionId = getNumber<uint32_t>(L, 5, 0); bool canDropOnMap = getBoolean(L, 6, true); 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) != RETURNVALUE_NOERROR) { delete item; lua_pushnumber(L, sellCount); return 1; } 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) != RETURNVALUE_NOERROR) { delete item; lua_pushnumber(L, sellCount); return 1; } ++sellCount; } } lua_pushnumber(L, sellCount); return 1; }
int NpcScriptInterface::luaOpenShopWindow(lua_State* L) { //openShopWindow(cid, items, onBuy callback, onSell callback) int32_t sellCallback; if (lua_isfunction(L, -1) == 0) { sellCallback = -1; lua_pop(L, 1); // skip it - use default value } else { sellCallback = popCallback(L); } int32_t buyCallback; if (lua_isfunction(L, -1) == 0) { buyCallback = -1; lua_pop(L, 1); // skip it - use default value } else { buyCallback = popCallback(L); } if (lua_istable(L, -1) == 0) { reportError(__FUNCTION__, "item list is not a table."); pushBoolean(L, false); return 1; } std::list<ShopInfo> items; lua_pushnil(L); while (lua_next(L, -2) != 0) { const auto tableIndex = lua_gettop(L); ShopInfo item; item.itemId = getField<uint32_t>(L, tableIndex, "id"); item.subType = getField<int32_t>(L, tableIndex, "subType"); if (item.subType == 0) { item.subType = getField<int32_t>(L, tableIndex, "subtype"); lua_pop(L, 1); } item.buyPrice = getField<uint32_t>(L, tableIndex, "buy"); item.sellPrice = getField<uint32_t>(L, tableIndex, "sell"); item.realName = getFieldString(L, tableIndex, "name"); items.push_back(item); lua_pop(L, 6); } lua_pop(L, 1); Player* player = getPlayer(L, -1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } //Close any eventual other shop window currently open. player->closeShopWindow(false); Npc* npc = getScriptEnv()->getNpc(); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } npc->addShopPlayer(player); player->setShopOwner(npc, buyCallback, sellCallback); player->openShopWindow(npc, items); pushBoolean(L, true); return 1; }
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; }
void DefaultSaveFileManager::assureCached(const Common::String &savePathName) { // Check that path exists and is usable. checkPath(Common::FSNode(savePathName)); #ifdef USE_LIBCURL Common::Array<Common::String> files = CloudMan.getSyncingFiles(); //returns empty array if not syncing if (!files.empty()) updateSavefilesList(files); //makes this cache invalid else _lockedFiles = files; #endif if (_cachedDirectory == savePathName) { return; } _saveFileCache.clear(); _cachedDirectory.clear(); if (getError().getCode() != Common::kNoError) { warning("DefaultSaveFileManager::assureCached: Can not cache path '%s': '%s'", savePathName.c_str(), getErrorDesc().c_str()); return; } // FSNode can cache its members, thus create it after checkPath to reflect // actual file system state. const Common::FSNode savePath(savePathName); Common::FSList children; if (!savePath.getChildren(children, Common::FSNode::kListFilesOnly)) { return; } // Build the savefile name cache. for (Common::FSList::const_iterator file = children.begin(), end = children.end(); file != end; ++file) { if (_saveFileCache.contains(file->getName())) { warning("DefaultSaveFileManager::assureCached: Name clash when building cache, ignoring file '%s'", file->getName().c_str()); } else { _saveFileCache[file->getName()] = *file; } } // Only now store that we cached 'savePathName' to indicate we successfully // cached the directory. _cachedDirectory = savePathName; }
// new: shop int NpcScriptInterface::luaSendShop(lua_State *L) { //sendShopWindow(cid, items, onBuy callback, onSell callback) int32_t buyCallback = -1; int32_t sellCallback = -1; std::list<ShopInfo> items; Player* player = NULL; ScriptEnviroment* env = getScriptEnv(); Npc* npc = env->getNpc(); if(lua_isfunction(L, -1) == 0) { lua_pop(L, 1); // skip it - use default value } else { sellCallback = popCallback(L); } if(lua_isfunction(L, -1) == 0) { lua_pop(L, 1); // skip it - use default value } else { buyCallback = popCallback(L); } if(lua_istable(L, -1) == 0) { reportError(__FUNCTION__, "item list is not a table."); lua_pushnumber(L, LUA_ERROR); return 1; } // first key lua_pushnil(L); while(lua_next(L, -2) != 0) { ShopInfo item; item.itemId = getField(L, "id"); item.itemCharges = getField(L, "charges"); item.buyPrice = getField(L, "buy"); item.salePrice = getField(L, "sell"); #ifdef __DEBUG_820__ std::cout << "Added Item " << item.itemId << " with charges " << item.itemCharges << " costs " << item.buyPrice << " and sells for " << item.salePrice << std::endl; #endif items.push_back(item); lua_pop(L, 1); } lua_pop(L, 1); player = env->getPlayerByUID(popNumber(L)); if(player == NULL) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); lua_pushnumber(L, LUA_ERROR); return 1; } player->setShopOwner(env->getNpc(), buyCallback, sellCallback); player->sendShop(items); player->sendCash(g_game.getMoney(player)); return 1; }