#ifdef SHOP_SEARCH #include #include "shop_manager.h" #include "shop.h" #include "target.h" #include "shop_search.h" struct shop_search_func { const char* m_str; shop_search_func(const char* str) : m_str(str) {} void operator() (LPDESC d) { if (!d->GetCharacter()) { return; } d->GetCharacter()->ChatPacket(CHAT_TYPE_COMMAND, m_str); } }; void ClearSearchShopItem(BYTE pos,DWORD shop_vid) { const DESC_MANAGER::DESC_SET& c_ref_set = DESC_MANAGER::instance().GetClientSet(); char szBuf[256] = { '\0' }; sprintf(szBuf, "RemoveItemFromList %d %d", shop_vid,pos); std::for_each(c_ref_set.begin(), c_ref_set.end(), shop_search_func(szBuf)); } void ClearSearchShopItems(DWORD shop_vid) { const DESC_MANAGER::DESC_SET& c_ref_set = DESC_MANAGER::instance().GetClientSet(); char szBuf[256] = { '\0' }; sprintf(szBuf, "RemoveItemsFromList %d", shop_vid); std::for_each(c_ref_set.begin(), c_ref_set.end(), shop_search_func(szBuf)); } void UpdateSearchShopItem(DWORD shop_vid) { const DESC_MANAGER::DESC_SET& c_ref_set = DESC_MANAGER::instance().GetClientSet(); char szBuf[256] = { '\0' }; sprintf(szBuf, "ShopResearchItem %d", shop_vid); std::for_each(c_ref_set.begin(), c_ref_set.end(), shop_search_func(szBuf)); } ACMD(do_shop_show) { char arg1[256]; one_argument(argument, arg1, sizeof(arg1)); DWORD vid; str_to_number(vid,arg1); CTargetManager::Instance().DeleteTarget(ch->GetPlayerID(), 100, "SHOP_SEARCH_TARGET"); if(!ch->CountSpecifyItem(60004) || !ch->CountSpecifyItem(60005) || !ch->CountSpecifyItem(60006)) return; if(*arg1) { LPCHARACTER seller_ch = CHARACTER_MANAGER::instance().Find(vid); if (!seller_ch) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d isn't online or in other channel"), vid); return; } if (!CTargetManager::instance().GetTargetInfo(ch->GetPlayerID(), TARGET_TYPE_SHOP, (DWORD)seller_ch->GetVID())) CTargetManager::Instance().CreateTarget(ch->GetPlayerID(), 100, "SHOP_SEARCH_TARGET", TARGET_TYPE_SHOP, (DWORD)seller_ch->GetVID(), 0, seller_ch->GetMapIndex(), "shop"); } } ACMD(do_shop_buy) { char arg1[256]; one_argument(argument, arg1, sizeof(arg1)); std::vector args; boost::split(args, arg1, boost::is_any_of("|")); if (args.size()<3) { sys_err("SHOP SEARCH BUY USER: %s -- HAVE A NOT ENOUGHT ARGUMENTS", ch->GetName()); return; } int x = 0; BYTE iBuyType; BYTE bItemPos; DWORD dwSellerVID; str_to_number(dwSellerVID, args[x++].c_str()); str_to_number(bItemPos, args[x++].c_str()); str_to_number(iBuyType, args[x++].c_str()); if (get_global_time() < ch->GetQuestFlag("search.flood_check")) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can not use too fast")); return; } sys_log(0, "TPacketCGShopSearch: SHOP_SEARCH_SUBHEADER_BUY USER: %s POS: %d SELLER VID: %d", ch->GetName(), bItemPos, dwSellerVID); LPCHARACTER seller_ch = CHARACTER_MANAGER::instance().Find(dwSellerVID); if (!seller_ch) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d isn't online or in other channel"), dwSellerVID); return; } if (seller_ch == ch) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can not buy item from yourself")); return; } if (ch->GetMyShop()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can not buy item when your shop is active")); return; } if (quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID())->IsRunning() || quest::CQuestManager::instance().GetPCForce(seller_ch->GetPlayerID())->IsRunning()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can not use this in now")); return; } ch->SetQuestFlag("item_search.flood_check", get_global_time()); if (iBuyType == SHOP_SEARCH_TYPE_FIND) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Only with Trading glass or Trading Glass+ you can use this function")); return; } else { CTargetManager::Instance().DeleteTarget(ch->GetPlayerID(), 100, "SHOP_SEARCH_TARGET"); if (ch->GetShop() || ch->GetShopOwner()) { sys_err("Close opened shop and npc's and try again"); return; } LPSHOP pkShop = seller_ch->GetMyShop(); if (!pkShop) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s isn't shop owner"), seller_ch->GetName()); return; } if(pkShop->IsLocked()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can't buy this item right now.")); return; } switch (iBuyType) { case SHOP_SEARCH_TYPE_BUY: { if (ch->GetMapIndex() != seller_ch->GetMapIndex()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You are isn't same map with seller")); return; } if (!ch->CountSpecifyItem(60005)) { ch->ChatPacket(CHAT_TYPE_INFO, "You don't have trading glass"); if (ch->GetGMLevel()) ch->ChatPacket(CHAT_TYPE_INFO, "You are GM so pass."); else return; } } break; case SHOP_SEARCH_TYPE_BUY_PREMIUM: { if (!ch->CountSpecifyItem(60006)) { ch->ChatPacket(CHAT_TYPE_INFO, "You don't have trading glass+"); if (ch->GetGMLevel()) ch->ChatPacket(CHAT_TYPE_INFO, "You are GM so pass."); else return; } } break; } //PREVENT_ITEM_COPY ch->SetMyShopTime(); //END_PREVENT_ITEM_COPY int ret = pkShop->Buy(ch, bItemPos,true); if (SHOP_SUBHEADER_GC_SOLD_OUT == ret || SHOP_SUBHEADER_GC_OK == ret) ClearSearchShopItem(bItemPos, dwSellerVID); if (SHOP_SUBHEADER_GC_OK != ret) // 1제? A??만?o?1?. { TPacketGCShop pack; pack.header = HEADER_GC_SHOP; pack.subheader = ret; pack.size = sizeof(TPacketGCShop); ch->GetDesc()->Packet(&pack, sizeof(pack)); } } ch->SetQuestFlag("item_search.flood_check", get_global_time() + 5); } ACMD(do_shop_search) { if (get_global_time() < ch->GetQuestFlag("search.flood_check")) { ch->ChatPacket(CHAT_TYPE_INFO, "You can not use too fast"); return; } if (!ch->CountSpecifyItem(60004) && !ch->CountSpecifyItem(60005) && !ch->CountSpecifyItem(60006)) { if (ch->GetGMLevel()) ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You don't have search glass but you are GM so pass.")); else return; } BYTE iJob; BYTE iType; BYTE iSubtype; DWORD iMinLevel; DWORD iMaxLevel; BYTE iMinRefine; BYTE iMaxRefine; #ifdef FULL_YANG long long iMinPrice; long long iMaxPrice; #else DWORD iMinPrice; DWORD iMaxPrice; #endif std::string itemName; char arg1[256]; one_argument(argument,arg1,sizeof(arg1)); std::vector args; boost::split(args,arg1, boost::is_any_of("|")); if (args.size()<10) { sys_err("SHOP SEARCH USER: %s -- HAVE A NOT ENOUGHT ARGUMENTS", ch->GetName()); return; } int x = 0; // _job_index, _type_index, _subtype_index, ItemLevelMin, ItemLevelMax, ItemRefineLevelMin, ItemRefineLevelMax, ItemGoldMin, ItemGoldMax, ItemNameValue str_to_number(iJob, args[x++].c_str()); str_to_number(iType, args[x++].c_str()); str_to_number(iSubtype, args[x++].c_str()); str_to_number(iMinLevel, args[x++].c_str()); str_to_number(iMaxLevel, args[x++].c_str()); str_to_number(iMinRefine, args[x++].c_str()); str_to_number(iMaxRefine, args[x++].c_str()); str_to_number(iMinPrice, args[x++].c_str()); str_to_number(iMaxPrice, args[x++].c_str()); itemName=args[x++]; boost::replace_all(itemName, "_", " "); if (!iType && !iSubtype) { sys_err("TPacketCGShop2: SHOP2_SUBHEADER_CG_SEARCH USER: %s -- HAVE A EMPTY ARGUMENT", ch->GetName()); return; } sys_log(0, "TPacketCGShop2: SHOP2_SUBHEADER_CG_SEARCH USER: %s", ch->GetName()); if (quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID())->IsRunning()) { ch->ChatPacket(CHAT_TYPE_INFO, "You can not use this in now"); return; } TShopMap shops = CShopManager::Instance().GetShops(); TShopMap::iterator it = shops.begin(); int items_found = 0; while (it != shops.end() && items_found<120) { CShop * shop = (it++)->second; LPCHARACTER shop_pc = shop->GetPC(); if (!shop_pc) { sys_err("Shop %d not have LPCHARACTER", it->first); continue; } if(shop->IsLocked()) continue; std::vector items = shop->GetShopItems(); for (DWORD i = 0; i < items.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i) { const CShop::SHOP_ITEM & item = items[i]; if (!item.vnum || !item.pkItem) continue; TItemTable * item_table = ITEM_MANAGER::Instance().GetTable(item.vnum); if (!item_table) continue; // Item name bool namePass = (itemName.length() ? strstr(item_table->szLocaleName, itemName.c_str()) != NULL : true); // Item job bool jobPass = (iJob!= 99 && (iType == ITEM_WEAPON || iType == ITEM_ARMOR ? ( item_table && iJob == JOB_WARRIOR && !(item_table->dwAntiFlags & ITEM_ANTIFLAG_WARRIOR ) || item_table && iJob == JOB_ASSASSIN && !(item_table->dwAntiFlags & ITEM_ANTIFLAG_ASSASSIN) || item_table && iJob == JOB_SURA && !(item_table->dwAntiFlags & ITEM_ANTIFLAG_SURA) || item_table && iJob == JOB_SHAMAN && !(item_table->dwAntiFlags & ITEM_ANTIFLAG_SHAMAN) || item_table && iJob == JOB_LYCAN && !(item_table->dwAntiFlags & ITEM_ANTIFLAG_LYCAN) )) : true); //Item level DWORD itemLevel = 0; bool levelPass = true; for (int limit = 0; limit < ITEM_LIMIT_MAX_NUM; limit++) if (item_table->aLimits[limit].bType == LIMIT_LEVEL) { itemLevel = item_table->aLimits[limit].lValue; if (itemLevel >= iMinLevel && itemLevel <= iMaxLevel) levelPass = true; else levelPass = false; } // Price bool pricePass = (item.price >= iMinPrice && item.price <= iMaxPrice); //Refine level int itemRefine = 0; const char *p = const_cast (strrchr(item_table->szLocaleName, '+')); if (p) str_to_number(itemRefine, p + 1); bool refinePass = (itemRefine >= iMinRefine && itemRefine <= iMaxRefine); // Type bool typePass = false; if (iType == 99) { switch (item_table->bType) { case ITEM_NONE: case ITEM_WEAPON: case ITEM_ARMOR: case ITEM_USE: case ITEM_AUTOUSE: case ITEM_ELK: case ITEM_METIN: case ITEM_FISH: case ITEM_ROD: case ITEM_RESOURCE: case ITEM_UNIQUE: case ITEM_SKILLBOOK: case ITEM_QUEST: case ITEM_TREASURE_BOX: case ITEM_SKILLFORGET: case ITEM_GIFTBOX: case ITEM_PICK: case ITEM_COSTUME: case ITEM_DS: case ITEM_BELT: case 35: typePass = false; break; default: typePass = true; } } else if (iType == ITEM_FISH) { if (iType == item_table->bType || ITEM_SPECIAL == item_table->bType) typePass = true; } else typePass = (iType == item_table->bType); // Subtype bool subtypePass = (iSubtype == 99 ? true : (iSubtype == item_table->bSubType)); //Seller name #ifdef OFFLINE_SHOP std::string c_szSellerName = shop_pc->IsPrivShop() ? shop_pc->GetShopOwnerName() : shop_pc->GetName(); #else std::string c_szSellerName = shop_pc->GetName(); #endif // Item name std::string c_szItemVnum = item_table->szLocaleName; boost::replace_all(c_szSellerName, " ", "_"); boost::replace_all(c_szItemVnum, " ", "_"); // Verify all if (namePass && jobPass && levelPass && refinePass && pricePass && typePass && subtypePass) { char szSockets[1024] = { '\0' }; char *tempSockets = szSockets; for (int soc = 0; soc < ITEM_SOCKET_MAX_NUM; soc++) tempSockets += sprintf(tempSockets, "%ld%s", item.pkItem->GetSocket(soc), (soc < ITEM_SOCKET_MAX_NUM - 1 ? "|" : "")); char szAttrs[1024] = { '\0' }; char *tempAttrs = szAttrs; for (int attr = 0; attr < ITEM_ATTRIBUTE_MAX_NUM; attr++) tempAttrs += sprintf(tempAttrs, "%u,%d%s", item.pkItem->GetAttributeType(attr), item.pkItem->GetAttributeValue(attr), (attr < ITEM_ATTRIBUTE_MAX_NUM - 1 ? "|" : "")); ch->ChatPacket(CHAT_TYPE_COMMAND, #ifdef FULL_YANG "GetSearchedItemData %d %s %d %d %d %d %lld %d %s %s %d", #else "GetSearchedItemData %d %s %d %d %d %d %d %d %s %s %d", #endif items_found, c_szSellerName.c_str(), (DWORD)shop_pc->GetVID(), item.vnum, item.count, itemRefine, item.price, itemLevel, szSockets, szAttrs, i ); }else continue; items_found++; } } if (items_found) { ch->ChatPacket(CHAT_TYPE_COMMAND, "CreateSearchedItemList"); ch->SetQuestFlag("item_search.flood_check", get_global_time() + 5); } } #endif