Guest User

Untitled

a guest
May 19th, 2020
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.39 KB | None | 0 0
  1.  
  2. //Add this on last line in top
  3.  
  4. #include <boost/algorithm/string.hpp>
  5.  
  6.  
  7. //find and add new varibles
  8. void CHARACTER::Initialize()
  9. {
  10. [..]
  11. #ifdef OFFLINE_SHOP
  12. m_pkRefreshShopEvent = NULL;
  13. bprivShop = 0;
  14. bprivShopOwner = 0;
  15. bprivShop = 0;
  16. bprivShopOwner = 0;
  17. dw_ShopTime = 0;
  18. m_mapshops.clear();
  19. #endif
  20. #ifdef GIFT_SYSTEM
  21. m_pkGiftRefresh = NULL;
  22. m_dwLastGiftPage = 0;
  23. m_mapGiftGrid.clear();
  24. #endif
  25. [..]
  26. }
  27. //find and add new varibles
  28. void CHARACTER::Destroy()
  29. {
  30. [..]
  31. #ifdef GIFT_SYSTEM
  32. event_cancel(&m_pkGiftRefresh);
  33. m_dwLastGiftPage = 0;
  34. m_mapGiftGrid.clear();
  35. #endif
  36. #ifdef OFFLINE_SHOP
  37. event_cancel(&m_pkRefreshShopEvent);
  38. bprivShop = 0;
  39. bprivShopOwner = 0;
  40. dw_ShopTime = 0;
  41. m_mapshops.clear();
  42. #endif
  43. [..]
  44. }
  45.  
  46.  
  47.  
  48. /*Find in function void CHARACTER::EncodeInsertPacket (LPENTITY entity) :
  49.  
  50. strlcpy (addPacket.name, GetName(), sizeof (addPacket.name));
  51. and replace with this:
  52. */
  53. #if defined(SHOP_HIDE_NAME) && defined(OFFLINE_SHOP)
  54. if (IsPC() || GetRaceNum() != 30000 && !IsPrivShop())
  55. #endif
  56. strlcpy(addPacket.name, GetName(), sizeof(addPacket.name));
  57.  
  58.  
  59. //find and replace function
  60.  
  61. void CHARACTER::OnClick(LPCHARACTER pkChrCauser)
  62. {
  63. if (!pkChrCauser)
  64. {
  65. sys_err("OnClick %s by NULL", GetName());
  66. return;
  67. }
  68.  
  69. DWORD vid = GetVID();
  70. //if (test_server)
  71. sys_log(0, "OnClick %s[vnum %d ServerUniqueID %d, pid %d] by %s", GetName(), GetRaceNum(), vid, GetPlayerID(), pkChrCauser->GetName());
  72.  
  73. // ??? ???? ???? ??? ? ??.
  74. {
  75. // ?, ??? ??? ??? ??? ? ??.
  76. if (pkChrCauser->GetMyShop() && pkChrCauser != this)
  77. {
  78. if (test_server)
  79. sys_err("OnClick Fail (%s->%s) - pc has shop", pkChrCauser->GetName(), GetName());
  80. return;
  81. }
  82. }
  83.  
  84. // ????? ???? ??? ? ??.
  85. {
  86. if (pkChrCauser->GetExchange())
  87. {
  88. if (test_server)
  89. sys_err("OnClick Fail (%s->%s) - pc is exchanging", pkChrCauser->GetName(), GetName());
  90. return;
  91. }
  92. }
  93.  
  94. #ifdef OFFLINE_SHOP
  95. if (IsPC() || IsNPC() && GetRaceNum() == 30000)
  96. {
  97. if (!CTargetManager::instance().GetTargetInfo(pkChrCauser->GetPlayerID(), TARGET_TYPE_VID, GetVID()) || GetRaceNum() == 30000)
  98. #else
  99.  
  100. if (IsPC())
  101. {
  102. if (!CTargetManager::instance().GetTargetInfo(pkChrCauser->GetPlayerID(), TARGET_TYPE_VID, GetVID()))
  103. #endif
  104. {
  105. // 2005.03.17.myevan.Ÿ°ŮŔĚ ľĆ´Ń °ćżě´Â °łŔÎ »óÁˇ Ăł¸® ±â´ÉŔ» Ŕ۵ż˝ĂŲ´Ů.
  106. if (GetMyShop())
  107. {
  108. if (pkChrCauser->IsDead() == true) return;
  109.  
  110. //PREVENT_TRADE_WINDOW
  111. if (pkChrCauser == this) // ŔÚ±â´Â °ˇ´É
  112. {
  113. if ((GetExchange() || IsOpenSafebox() || GetShopOwner()) || IsCubeOpen())
  114. {
  115. pkChrCauser->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ů¸Ą °Ĺ·ˇÁß(â°í,±łČŻ,»óÁˇ)żˇ´Â °łŔλóÁˇŔ» »çżëÇŇ Ľö ľř˝Ŕ´Ď´Ů."));
  116. return;
  117. }
  118. }
  119. else // ´Ů¸Ą »ç¶÷ŔĚ Ĺ¬¸ŻÇßŔ»¶§
  120. {
  121. // Ŭ¸ŻÇŃ »ç¶÷ŔĚ ±łČŻ/â°í/°łŔλóÁˇ/»óÁˇŔĚżëÁßŔ̶ó¸é şŇ°ˇ
  122. if ((pkChrCauser->GetExchange() || pkChrCauser->IsOpenSafebox() || pkChrCauser->GetMyShop() || pkChrCauser->GetShopOwner()) || pkChrCauser->IsCubeOpen())
  123. {
  124. pkChrCauser->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ů¸Ą °Ĺ·ˇÁß(â°í,±łČŻ,»óÁˇ)żˇ´Â °łŔλóÁˇŔ» »çżëÇŇ Ľö ľř˝Ŕ´Ď´Ů."));
  125. return;
  126. }
  127.  
  128. // Ŭ¸ŻÇŃ ´ë»óŔĚ ±łČŻ/â°í/»óÁˇŔĚżëÁßŔ̶ó¸é şŇ°ˇ
  129. //if ((GetExchange() || IsOpenSafebox() || GetShopOwner()))
  130. if ((GetExchange() || IsOpenSafebox() || IsCubeOpen()))
  131. {
  132. pkChrCauser->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("»ó´ëąćŔĚ ´Ů¸Ą °Ĺ·ˇ¸¦ Çϰí ŔÖ´Â ÁßŔÔ´Ď´Ů."));
  133. return;
  134. }
  135. }
  136. //END_PREVENT_TRADE_WINDOW
  137. #ifdef OFFLINE_SHOP
  138. if (GetMyShop()->IsLocked())
  139. return;
  140. #endif
  141. GetMyShop()->AddGuest(pkChrCauser, GetVID(), false);
  142.  
  143. pkChrCauser->SetShopOwner(this);
  144. return;
  145. }
  146.  
  147. if (test_server)
  148. sys_err("%s.OnClickFailure(%s) - target is PC", pkChrCauser->GetName(), GetName());
  149.  
  150. return;
  151. }
  152. }
  153. pkChrCauser->SetQuestNPCID(GetVID());
  154.  
  155. if (quest::CQuestManager::instance().Click(pkChrCauser->GetPlayerID(), this))
  156. {
  157. return;
  158. }
  159.  
  160.  
  161. // NPC ?? ?? ?? : ?? ?? ?
  162. if (!IsPC())
  163. {
  164. if (!m_triggerOnClick.pFunc)
  165. {
  166. return;
  167. }
  168.  
  169. m_triggerOnClick.pFunc(this, pkChrCauser);
  170. }
  171.  
  172. }
  173.  
  174. //find and replace function
  175. void CHARACTER::CloseMyShop()
  176. {
  177. if (GetMyShop())
  178. {
  179.  
  180. m_stShopSign.clear();
  181. CShopManager::instance().DestroyPCShop(this);
  182. m_pkMyShop = NULL;
  183.  
  184. TPacketGCShopSign p;
  185.  
  186. p.bHeader = HEADER_GC_SHOP_SIGN;
  187. p.dwVID = GetVID();
  188. p.szSign[0] = '\0';
  189.  
  190. PacketAround(&p, sizeof(p));
  191.  
  192. #ifdef OFFLINE_SHOP
  193. if (IsPrivShop())
  194. {
  195. M2_DESTROY_CHARACTER(this);
  196. return;
  197. }
  198. #endif
  199. SetPolymorph(GetJob(), true);
  200. }
  201. }
  202. //add new function
  203.  
  204. #ifdef GIFT_SYSTEM
  205. #include <boost/algorithm/string.hpp>
  206. EVENTFUNC(gift_refresh_event)
  207. {
  208. char_event_info* info = dynamic_cast<char_event_info*>(event->info);
  209. if (info == NULL)
  210. {
  211. sys_err("gift_refresh_event> <Factor> Null pointer");
  212. return 0;
  213. }
  214.  
  215. LPCHARACTER ch = info->ch;
  216.  
  217. if (NULL == ch || ch->IsNPC())
  218. return 0;
  219. ch->RefreshGift();
  220. return PASSES_PER_SEC(5 * 60);
  221. }
  222. void CHARACTER::StartRefreshGift()
  223. {
  224. if (m_pkGiftRefresh)
  225. return;
  226. char_event_info* info = AllocEventInfo<char_event_info>();
  227.  
  228. info->ch = this;
  229. m_pkGiftRefresh = event_create(gift_refresh_event, info, PASSES_PER_SEC(1)); // 1o?
  230. }
  231. void SendGift(LPCHARACTER ch, TGiftItem item)
  232. {
  233. char szSockets[1024] = { '\0' };
  234. char *tempSockets = szSockets;
  235. for (int soc = 0; soc < ITEM_SOCKET_MAX_NUM; soc++)
  236. tempSockets += sprintf(tempSockets, "%ld%s", item.alSockets[soc], (soc<ITEM_SOCKET_MAX_NUM - 1 ? "|" : ""));
  237. char szAttrs[1024] = { '\0' };
  238. char *tempAttrs = szAttrs;
  239. for (int attr = 0; attr < ITEM_ATTRIBUTE_MAX_NUM; attr++)
  240. tempAttrs += sprintf(tempAttrs, "%u,%d%s", item.aAttr[attr].bType, item.aAttr[attr].sValue, (attr<ITEM_ATTRIBUTE_MAX_NUM - 1 ? "|" : ""));
  241. #ifdef FULL_YANG
  242. ch->ChatPacket(CHAT_TYPE_COMMAND, "gift_item %d %d %lld %d %d %s %s %s %s", item.id, item.vnum, item.count, item.pos, item.dwDateAdd, item.szFrom, item.szReason, szSockets, szAttrs);
  243. #else
  244. ch->ChatPacket(CHAT_TYPE_COMMAND, "gift_item %d %d %d %d %d %s %s %s %s", item.id, item.vnum, item.count, item.pos, item.dwDateAdd, item.szFrom, item.szReason, szSockets, szAttrs);
  245. #endif
  246. }
  247. void CHARACTER::LoadGiftPage(int page)
  248. {
  249. page = MINMAX(1, page, m_mapGiftGrid.size());
  250. ChatPacket(CHAT_TYPE_COMMAND, "gift_clear");
  251. GIFT_MAP::iterator it = m_mapGiftGrid.find(page);
  252. if (it == m_mapGiftGrid.end())
  253. return;
  254. m_dwLastGiftPage = page;
  255. for (int i = 0; i < it->second.size(); i++)
  256. SendGift(this, it->second[i]);
  257. ChatPacket(CHAT_TYPE_COMMAND, "gift_load");
  258.  
  259. }
  260. static CGrid* grid;
  261. void CHARACTER::AddGiftGrid(int page)
  262. {
  263. if (m_mapGiftGrid.find(page) == m_mapGiftGrid.end())
  264. {
  265. std::vector<TGiftItem> vec;
  266. m_mapGiftGrid.insert(std::make_pair(page, vec));
  267. }
  268.  
  269. }
  270. int CHARACTER::AddGiftGridItem( int page, int size)
  271. {
  272. AddGiftGrid(page);
  273. int iPos = grid->FindBlank(1, size);
  274.  
  275. if (iPos < 0)
  276. return -1;
  277.  
  278. if (!grid->IsEmpty(iPos, 1, size))
  279. return -1;
  280.  
  281.  
  282. grid->Put(iPos, 1, size);
  283. return iPos;
  284.  
  285. }
  286. void CHARACTER::RefreshGift()
  287. {
  288. char szSockets[1024] = { '\0' };
  289. char *tempSockets = szSockets;
  290. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
  291. {
  292. tempSockets += sprintf(tempSockets, "socket%d", i);
  293.  
  294. if (i<ITEM_SOCKET_MAX_NUM - 1)
  295. tempSockets += sprintf(tempSockets, ",");
  296. }
  297. char szAttrs[1024] = { '\0' };
  298. char *tempAttrs = szAttrs;
  299. for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; i++)
  300. {
  301. if (i < 7)
  302. tempAttrs += sprintf(tempAttrs, "attrtype%d,attrvalue%d", i, i);
  303. else
  304. tempAttrs += sprintf(tempAttrs, "applytype%d,applyvalue%d", i - 7, i - 7);
  305. if (i<ITEM_ATTRIBUTE_MAX_NUM - 1)
  306. tempAttrs += sprintf(tempAttrs, ",");
  307. }
  308. SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT id,vnum,count,unix_timestamp(date_add),replace(reason,' ','_'),replace(`from`,' ','_'),%s,%s from player_gift where owner_id = %d and status = 'WAIT' ORDER BY date_add ", szSockets, szAttrs, GetPlayerID()));
  309. SQLResult * pRes = pkMsg->Get();
  310. m_mapGiftGrid.clear();
  311. grid = M2_NEW CGrid(15, 8);
  312. grid->Clear();
  313. int page = 1;
  314. if (pRes->uiNumRows>0)
  315. {
  316. AddGiftGrid(page);
  317. MYSQL_ROW row;
  318. while ((row = mysql_fetch_row(pRes->pSQLResult)) != NULL)
  319. {
  320. int col = 0;
  321. TGiftItem item;
  322. memset(&item, 0, sizeof(item));
  323. str_to_number(item.id, row[col++]);
  324. str_to_number(item.vnum, row[col++]);
  325. str_to_number(item.count, row[col++]);
  326. str_to_number(item.dwDateAdd, row[col++]);
  327. strlcpy(item.szReason, row[col++], sizeof(item.szReason) - 1);
  328. strlcpy(item.szFrom, row[col++], sizeof(item.szFrom) - 1);
  329. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
  330. str_to_number(item.alSockets[i], row[col++]);
  331. for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; i++)
  332. {
  333. str_to_number(item.aAttr[i].bType, row[col++]);
  334. str_to_number(item.aAttr[i].sValue, row[col++]);
  335. }
  336.  
  337. const TItemTable * item_table = ITEM_MANAGER::instance().GetTable(item.vnum);
  338. if (!item_table)
  339. continue;
  340. int iPos = AddGiftGridItem( page, item_table->bSize);
  341. if (iPos < 0)
  342. {
  343. page++;
  344. grid->Clear();
  345. iPos = AddGiftGridItem(page, item_table->bSize);
  346. if (iPos < 0)
  347. {
  348. sys_err("iPos <0");
  349. break;
  350. }
  351. }
  352. item.pos = iPos;
  353. m_mapGiftGrid[page].push_back(item);
  354.  
  355. }
  356. M2_DELETE(grid);
  357. }
  358. if(GetGiftPages()>0)
  359. ChatPacket(CHAT_TYPE_COMMAND, "gift_info %d", GetGiftPages());
  360. }
  361. #endif
  362.  
  363. #ifdef OFFLINE_SHOP
  364.  
  365. extern std::map<DWORD, DWORD> g_ShopIndexCount;
  366. extern std::map<int, TShopCost> g_ShopCosts;
  367. void CHARACTER::OpenMyShop(const char * c_pszSign, TShopItemTable * pTable, BYTE bItemCount, DWORD id)
  368. {
  369.  
  370. if (g_ShopCosts.find(id) == g_ShopCosts.end())
  371. {
  372. sys_log(0, "Shop days error %s %d", c_pszSign, id);
  373. return;
  374. }
  375. int days = g_ShopCosts[id].days;
  376. long long price = g_ShopCosts[id].price;
  377. if (price > 0 && GetGold() < price)
  378. {
  379. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "SHOP_NEED_MONEY"), price);
  380. return;
  381. }
  382. if (days == 0 && GetPart(PART_MAIN) > 2)
  383. {
  384. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°©żĘŔ» ąţľîľß °łŔÎ »óÁˇŔ» ż­ Ľö ŔÖ˝Ŕ´Ď´Ů."));
  385. return;
  386. }
  387.  
  388. if (GetMyShop())
  389. {
  390. CloseMyShop();
  391. return;
  392. }
  393.  
  394.  
  395. int gShopMax = quest::CQuestManager::Instance().GetEventFlag("shop_max");
  396. if (m_mapshops.size() >= (gShopMax ? gShopMax : 2))
  397. {
  398. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "SHOP_MAX_ERR"));
  399. return;
  400. }
  401.  
  402.  
  403. if (g_ShopIndexCount.count(GetMapIndex())>0)
  404. {
  405. int shop_max = g_ShopIndexCount[GetMapIndex()];
  406. bool block = false;
  407.  
  408. #ifdef SHOP_ONLY_ALLOWED_INDEX
  409. if (shop_max > 0)
  410. {
  411. #else
  412. if (shop_max == 0)
  413. block = true;
  414. else{
  415. #endif
  416. std::auto_ptr<SQLMsg> pkMsg(DBManager::instance().DirectQuery("SELECT map_index from player_shop WHERE channel=%d and status='OK' and map_index=%d", g_bChannel, GetMapIndex()));
  417. SQLResult * pRes = pkMsg->Get();
  418. if (pRes->uiNumRows >= shop_max)
  419. block = true;
  420. }
  421. if (block)
  422. {
  423. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "SHOP_MAP_MAX"));
  424. return;
  425. }
  426. }
  427. #ifdef SHOP_ONLY_ALLOWED_INDEX
  428. else
  429. {
  430. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "SHOP_CANNOT_OPEN_HERE"));
  431. return;
  432. }
  433. #endif
  434. if (GetMyShop()) // AI1I 1YAI ?­·Á AÖA¸¸é ´Ý´Â´U.
  435. {
  436. CloseMyShop();
  437. return;
  438. }
  439. #ifndef FULL_YANG
  440. int64_t nTotalMoney = 0;
  441.  
  442. for (int n = 0; n < bItemCount; ++n)
  443. {
  444. nTotalMoney += static_cast<int64_t> ((pTable + n)->price);
  445. }
  446.  
  447. nTotalMoney += static_cast<int64_t> (GetGold());
  448.  
  449. if (GOLD_MAX <= nTotalMoney)
  450. {
  451. sys_err("[OVERFLOW_GOLD] Overflow (GOLD_MAX) id %u name %s", GetPlayerID(), GetName());
  452. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("20ľď łÉŔ» ĂʰúÇĎż© »óÁˇŔ» ż­Ľö°ˇ ľř˝Ŕ´Ď´Ů"));
  453. return;
  454. }
  455. #endif
  456. #ifdef ACCE_FIX
  457. if(IsAcceOpen())
  458. Acce_close(this);
  459. #endif
  460. quest::PC * pPC = quest::CQuestManager::instance().GetPCForce(GetPlayerID());
  461. if (pPC->IsRunning())
  462. return;
  463. std::vector<TShopItemTable *> map_shop;
  464. for (BYTE i = 0; i < bItemCount; ++i)
  465. {
  466. // ANTI_GIVE, ANTI_MYSHOP check
  467. LPITEM pkItem = GetItem((pTable + i)->pos);
  468.  
  469. if (pkItem)
  470. {
  471. const TItemTable * item_table = pkItem->GetProto();
  472.  
  473. if (item_table && (IS_SET(item_table->dwAntiFlags, ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_MYSHOP)))
  474. {
  475. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "ŔŻ·áČ­ ľĆŔĚĹŰŔş °łŔλóÁˇżˇĽ­ ĆǸĹÇŇ Ľö ľř˝Ŕ´Ď´Ů."));
  476. return;
  477. }
  478.  
  479. if (pkItem->IsEquipped())
  480. {
  481. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "ŔĺşńÁßŔÎ ľĆŔĚĹŰŔş °łŔλóÁˇżˇĽ­ ĆǸĹÇŇ Ľö ľř˝Ŕ´Ď´Ů."));
  482. return;
  483. }
  484.  
  485. if (pkItem->isLocked())
  486. {
  487. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "»çżëÁßŔÎ ľĆŔĚĹŰŔş °łŔλóÁˇżˇĽ­ ĆǸĹÇŇ Ľö ľř˝Ŕ´Ď´Ů."));
  488. return;
  489. }
  490. if (pkItem->GetOwner() != this)
  491. {
  492. return;
  493. }
  494. #ifdef SOULBIND_SYSTEM
  495. if (pkItem->IsSoulBind())
  496. {
  497. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "You can't sell in private shop item with soul bind."));
  498. return;
  499. }
  500. #endif
  501. }
  502. if (days != 0)
  503. map_shop.push_back(pTable++);
  504. }
  505. if (days != 0 && map_shop.size() == 0)
  506. return;
  507. char szName[256];
  508. DBManager::instance().EscapeString(szName, 256, c_pszSign, strlen(c_pszSign));
  509. m_stShopSign = szName;
  510. boost::replace_all(m_stShopSign, "%", "%%");
  511.  
  512.  
  513. if (m_stShopSign.length()>30)
  514. m_stShopSign.resize(30);
  515. if (m_stShopSign.length() == 0)
  516. return;
  517. #ifdef STRING_PROTECTION
  518. if (CBanwordManager::instance().CheckString(m_stShopSign.c_str(), m_stShopSign.length()) != "")
  519. {
  520. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "şńĽÓľîłŞ Ŕşľî°ˇ Ć÷ÇÔµČ »óÁˇ Ŕ̸§Ŕ¸·Î »óÁˇŔ» ż­ Ľö ľř˝Ŕ´Ď´Ů."));
  521. return;
  522. }
  523. #else
  524. if (CBanwordManager::instance().CheckString(m_stShopSign.c_str(), m_stShopSign.length()))
  525. {
  526. ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "şńĽÓľîłŞ Ŕşľî°ˇ Ć÷ÇÔµČ »óÁˇ Ŕ̸§Ŕ¸·Î »óÁˇŔ» ż­ Ľö ľř˝Ŕ´Ď´Ů."));
  527. return;
  528. }
  529. #endif
  530. if (m_pkExchange)
  531. m_pkExchange->Cancel();
  532. if (price > 0)
  533. #ifdef FULL_YANG_OWN
  534. ChangeGold(-price);
  535. #else
  536. PointChange(POINT_GOLD, -price);
  537. #endif
  538. if (days != 0)
  539. {
  540. CShopManager::instance().CreateOfflineShop(this, m_stShopSign.c_str(), map_shop, id);
  541. m_stShopSign.clear();
  542. return;
  543. }
  544. TPacketGCShopSign p;
  545. p.bHeader = HEADER_GC_SHOP_SIGN;
  546. p.dwVID = GetVID();
  547. strlcpy(p.szSign, m_stShopSign.c_str(), sizeof(p.szSign));
  548.  
  549. PacketAround(&p, sizeof(TPacketGCShopSign));
  550.  
  551. m_pkMyShop = CShopManager::instance().CreatePCShop(this, pTable, bItemCount);
  552. if (!m_pkMyShop)
  553. {
  554. sys_err("Cannot open normal shop %s %s", GetName(), m_stShopSign.c_str());
  555. return;
  556. }
  557. if (IsPolymorphed() == true)
  558. {
  559. RemoveAffect(AFFECT_POLYMORPH);
  560. }
  561.  
  562. if (GetHorse())
  563. {
  564. HorseSummon(false, true);
  565. }
  566. else if (GetMountVnum())
  567. {
  568. RemoveAffect(AFFECT_MOUNT);
  569. RemoveAffect(AFFECT_MOUNT_BONUS);
  570. }
  571.  
  572. SetPolymorph(30000, true);
  573.  
  574. }
  575. void CHARACTER::SetShopSign(const char * name)
  576. {
  577. m_stShopSign = name;
  578. TPacketGCShopSign p;
  579. p.bHeader = HEADER_GC_SHOP_SIGN;
  580. p.dwVID = GetVID();
  581. strlcpy(p.szSign, m_stShopSign.c_str(), sizeof(p.szSign));
  582. PacketAround(&p, sizeof(TPacketGCShopSign));
  583. }
  584.  
  585. TPrivShop CHARACTER::GetPrivShopTable(DWORD id)
  586. {
  587. TPrivShop shop;
  588. memset(&shop, 0, sizeof(TPrivShop));
  589. PSHOP_MAP::iterator it = m_mapshops.find(id);
  590. if (it != m_mapshops.end())
  591. return it->second;
  592. return shop;
  593.  
  594. }
  595. void CHARACTER::UpdatePrivShopTable(DWORD id, TPrivShop shop)
  596. {
  597. if (m_mapshops.find(id) != m_mapshops.end())
  598. m_mapshops[id]=shop;
  599. SendShops();
  600. }
  601. void CHARACTER::RemovePrivShopTable(DWORD id)
  602. {
  603. if (m_mapshops.find(id) != m_mapshops.end())
  604. m_mapshops.erase(m_mapshops.find(id));
  605. SendShops();
  606. }
  607. void CHARACTER::UpdateShopItems()
  608. {
  609. LPSHOP npcshop = GetMyShop();
  610. LPCHARACTER owner = CHARACTER_MANAGER::instance().FindByPID(GetPrivShopOwner());
  611. if (!npcshop || !IsPrivShop())
  612. return;
  613. npcshop->RemoveGuests(owner);
  614. npcshop->SetLocked(true);
  615. npcshop->ClearItems();
  616. std::vector<TShopItemTable *> map_shop;
  617. char szSockets[1024] = { '\0' };
  618. char *tempSockets = szSockets;
  619. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
  620. {
  621. tempSockets += sprintf(tempSockets, "socket%d", i);
  622.  
  623. if (i<ITEM_SOCKET_MAX_NUM - 1)
  624. tempSockets += sprintf(tempSockets, ",");
  625. }
  626. char szAttrs[1024] = { '\0' };
  627. char *tempAttrs = szAttrs;
  628. for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; i++)
  629. {
  630. if (i < 7)
  631. tempAttrs += sprintf(tempAttrs, "attrtype%d,attrvalue%d", i, i);
  632. else
  633. tempAttrs += sprintf(tempAttrs, "applytype%d,applyvalue%d", i - 7, i - 7);
  634. if (i<ITEM_ATTRIBUTE_MAX_NUM - 1)
  635. tempAttrs += sprintf(tempAttrs, ",");
  636. }
  637. SQLMsg * Msg(DBManager::instance().DirectQuery("SELECT id,vnum,count,display_pos,price,%s,%s from player_shop_items where shop_id='%d'",szSockets,szAttrs, GetPrivShop()));
  638. SQLResult * Res = Msg->Get();
  639. if (Res->uiNumRows > 0)
  640. {
  641. MYSQL_ROW row;
  642. while ((row = mysql_fetch_row(Res->pSQLResult)) != NULL)
  643. {
  644.  
  645. int col = 0;
  646.  
  647.  
  648.  
  649. TShopItemTable *shop = new TShopItemTable;
  650. memset(shop, 0, sizeof(TShopItemTable));
  651. DWORD id;
  652. shop->pos.window_type = INVENTORY;
  653. str_to_number(id, row[col++]);
  654. str_to_number(shop->vnum, row[col++]);
  655. str_to_number(shop->count, row[col++]);
  656. str_to_number(shop->display_pos, row[col++]);
  657. //col++;
  658. str_to_number(shop->price, row[col++]);
  659.  
  660. const TItemTable * item_table = ITEM_MANAGER::instance().GetTable(shop->vnum);
  661.  
  662.  
  663. if (!item_table)
  664. {
  665. sys_err("Shop: no item table by item vnum #%d", shop->vnum);
  666. continue;
  667. }
  668. for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
  669. {
  670. if (NULL != GetInventoryItem(i) && GetInventoryItem(i)->GetRealID() == id)
  671. GetInventoryItem(i)->RemoveFromCharacter();
  672. }
  673. LPITEM item = ITEM_MANAGER::instance().CreateItem(shop->vnum, shop->count, id, false, -1, true);
  674. if (-1 == (shop->pos.cell = GetEmptyInventory(item_table->bSize)))
  675. {
  676. sys_err("no empty position in npc inventory");
  677. return;
  678. }
  679. if (item)
  680. {
  681. item->ClearAttribute();
  682. item->SetRealID(id);
  683. for (int s = 0;s<ITEM_SOCKET_MAX_NUM;s++)
  684. {
  685. DWORD soc;
  686. str_to_number(soc, row[col++]);
  687. item->SetSocket(s, soc, false);
  688. }
  689. for (int at = 0;at<ITEM_ATTRIBUTE_MAX_NUM;at++)
  690. {
  691. DWORD attr;
  692. long val;
  693. str_to_number(attr, row[col++]);
  694. str_to_number(val, row[col++]);
  695. item->SetForceAttribute(at, attr, val);
  696. }
  697.  
  698. item->AddToCharacter(this, shop->pos);
  699. }
  700. else
  701. {
  702. sys_err("%d is not item", shop->vnum);
  703. continue;
  704. }
  705. map_shop.push_back(shop);
  706. }
  707. }
  708.  
  709.  
  710.  
  711. if (map_shop.size() == 0 || map_shop.size() > SHOP_HOST_ITEM_MAX_NUM)
  712. {
  713. DeleteMyShop();
  714. return;
  715. }
  716. npcshop->SetPrivShopItems(map_shop);
  717. npcshop->SetLocked(false);
  718. for (int i = 0;i < SHOP_HOST_ITEM_MAX_NUM;i++)
  719. npcshop->BroadcastUpdateItem(i);
  720.  
  721. if (owner)
  722. {
  723. owner->LoadPrivShops();
  724. owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("SHOP_EDIT_SUCCESS"));
  725. }
  726. }
  727. void CHARACTER::LoadPrivShops()
  728. {
  729. m_mapshops.clear();
  730. SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT id,shop_vid,replace(replace(name,' ','\\\\'),'#','_'),gold,item_count,(select count(id) from player_shop_items where shop_id=player_shop.id),DATEDIFF(date_close,now()) AS days,UNIX_TIMESTAMP(date_close) from player_shop WHERE player_id=%d", GetPlayerID()));
  731. SQLResult * pRes = pkMsg->Get();
  732. if (pRes->uiNumRows>0)
  733. {
  734.  
  735. MYSQL_ROW row;
  736. while ((row = mysql_fetch_row(pRes->pSQLResult)) != NULL)
  737. {
  738. int col = 0;
  739. TPrivShop shop;
  740. memset(&shop, 0, sizeof(TPrivShop));
  741. str_to_number(shop.shop_id, row[col++]);
  742. str_to_number(shop.shop_vid, row[col++]);
  743. strlcpy(shop.szSign, row[col++], sizeof(shop.szSign));
  744. str_to_number(shop.gold, row[col++]);
  745. str_to_number(shop.item_count, row[col++]);
  746. str_to_number(shop.rest_count, row[col++]);
  747. str_to_number(shop.days, row[col++]);
  748. str_to_number(shop.date_close, row[col++]);
  749. m_mapshops.insert(std::make_pair(shop.shop_id, shop));
  750. }
  751. }
  752. SendShops();
  753. }
  754. void CHARACTER::SendShops(bool isGm)
  755. {
  756. ChatPacket(CHAT_TYPE_COMMAND, "shop_clear");
  757. PSHOP_MAP::iterator it = m_mapshops.begin();
  758. while (it != m_mapshops.end())
  759. {
  760. ChatPacket(CHAT_TYPE_COMMAND, "shop_add %d %d %s %lld %d %d %d %d", it->second.shop_id, it->second.shop_vid, it->second.szSign, it->second.gold, it->second.item_count, it->second.rest_count, it->second.days, it->second.date_close);
  761. it++;
  762. }
  763.  
  764.  
  765. }
  766. void CHARACTER::SendShopCost()
  767. {
  768. extern std::map<int, TShopCost> g_ShopCosts;
  769. ChatPacket(CHAT_TYPE_COMMAND, "shop_cost_clear");
  770. std::map<int, TShopCost>::iterator it = g_ShopCosts.begin();
  771. while (it != g_ShopCosts.end())
  772. {
  773. ChatPacket(CHAT_TYPE_COMMAND, "shop_cost %d %d %d %lld", it->first,it->second.days, it->second.time, it->second.price);
  774. it++;
  775. }
  776.  
  777.  
  778. }
  779. void CHARACTER::OpenShop(DWORD id, const char *name, bool onboot)
  780. {
  781. if (GetMyShop())
  782. {
  783. CloseMyShop();
  784. return;
  785. }
  786. if (IsPC())
  787. return;
  788. char szSockets[1024] = { '\0' };
  789. char *tempSockets = szSockets;
  790. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
  791. {
  792. tempSockets += sprintf(tempSockets, "socket%d", i);
  793.  
  794. if (i<ITEM_SOCKET_MAX_NUM - 1)
  795. tempSockets += sprintf(tempSockets, ",");
  796. }
  797. char szAttrs[1024] = { '\0' };
  798. char *tempAttrs = szAttrs;
  799. for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; i++)
  800. {
  801. if (i < 7)
  802. tempAttrs += sprintf(tempAttrs, "attrtype%d,attrvalue%d", i, i);
  803. else
  804. tempAttrs += sprintf(tempAttrs, "applytype%d,applyvalue%d", i - 7, i - 7);
  805. if (i<ITEM_ATTRIBUTE_MAX_NUM - 1)
  806. tempAttrs += sprintf(tempAttrs, ",");
  807. }
  808. SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT id,vnum,count,display_pos,price,%s,%s from player_shop_items where shop_id='%d'",szSockets,szAttrs, id));
  809.  
  810. SQLResult * pRes = pkMsg->Get();
  811. BYTE bItemCount = pRes->uiNumRows;
  812.  
  813. TShopItemTable * m_pShopTable = new TShopItemTable[bItemCount];
  814. memset(&m_pShopTable[0], 0, sizeof(TShopItemTable) * bItemCount);
  815.  
  816. std::vector<TShopItemTable *> map_shop;
  817.  
  818. if (bItemCount>0)
  819. {
  820. bItemCount = 0;
  821. MYSQL_ROW row;
  822. int c = 0;
  823. while ((row = mysql_fetch_row(pRes->pSQLResult)) != NULL)
  824. {
  825. int col = 0;
  826.  
  827.  
  828.  
  829. TShopItemTable *shop = new TShopItemTable;
  830. memset(shop, 0, sizeof(TShopItemTable));
  831. DWORD id;
  832. shop->pos.window_type = INVENTORY;
  833. str_to_number(id, row[col++]);
  834. str_to_number(shop->vnum, row[col++]);
  835. str_to_number(shop->count, row[col++]);
  836. str_to_number(shop->display_pos, row[col++]);
  837. //col++;
  838. str_to_number(shop->price, row[col++]);
  839.  
  840. const TItemTable * item_table = ITEM_MANAGER::instance().GetTable(shop->vnum);
  841.  
  842.  
  843. if (!item_table)
  844. {
  845. sys_err("Shop: no item table by item vnum #%d", shop->vnum);
  846. continue;
  847. }
  848. if (-1 == (shop->pos.cell = GetEmptyInventory(item_table->bSize)))
  849. {
  850. sys_err("no empty position in npc inventory");
  851. return;
  852. }
  853.  
  854. LPITEM item = ITEM_MANAGER::instance().CreateItem(shop->vnum, shop->count, 0, false, -1, true);
  855.  
  856. if (item)
  857. {
  858. item->ClearAttribute();
  859. item->SetSkipSave(true);
  860. item->SetRealID(id);
  861. for (int s = 0;s<ITEM_SOCKET_MAX_NUM;s++)
  862. {
  863. DWORD soc;
  864. str_to_number(soc, row[col++]);
  865. item->SetSocket(s, soc, false);
  866. }
  867. for (int at = 0;at<ITEM_ATTRIBUTE_MAX_NUM;at++)
  868. {
  869. DWORD attr;
  870. long val;
  871. str_to_number(attr, row[col++]);
  872. str_to_number(val, row[col++]);
  873. item->SetForceAttribute(at, attr, val);
  874. }
  875.  
  876.  
  877. item->AddToCharacter(this, shop->pos);
  878. }
  879. else
  880. {
  881. sys_err("%d is not item", shop->vnum);
  882. continue;
  883. }
  884.  
  885. map_shop.push_back(shop);
  886. ++bItemCount;
  887. }
  888. }
  889.  
  890.  
  891.  
  892. if (bItemCount == 0 && !onboot || bItemCount > SHOP_HOST_ITEM_MAX_NUM)
  893. return;
  894.  
  895.  
  896. m_stShopSign = name;
  897.  
  898. if (m_stShopSign.length()>30)
  899. m_stShopSign.resize(30);
  900. if (m_stShopSign.length() == 0)
  901. return;
  902.  
  903.  
  904. TPacketGCShopSign p;
  905.  
  906. p.bHeader = HEADER_GC_SHOP_SIGN;
  907. p.dwVID = GetVID();
  908. strlcpy(p.szSign, m_stShopSign.c_str(), sizeof(p.szSign));
  909.  
  910. PacketAround(&p, sizeof(TPacketGCShopSign));
  911.  
  912. m_pkMyShop = CShopManager::instance().CreateNPCShop(this, map_shop);
  913.  
  914. }
  915. void CHARACTER::DeleteMyShop()
  916. {
  917. if (GetMyShop())
  918. {
  919. SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT gold FROM player_shop where id='%d'", GetPrivShop()));
  920. SQLResult * pRes = pkMsg->Get();
  921. if (pRes->uiNumRows>0)
  922. {
  923. MYSQL_ROW row;
  924. while ((row = mysql_fetch_row(pRes->pSQLResult)) != NULL)
  925. {
  926. long long gold;
  927. str_to_number(gold, row[0]);
  928. if (gold>0)
  929. {
  930. char query[1024];
  931. sprintf(query, "INSERT INTO player_gift SET \
  932. owner_id=%d,vnum=1,count='%s',reason=\"%s\",`from`=replace(\"%s\",' ','_'),status='WAIT',date_add=NOW()",
  933. GetPrivShopOwner(), row[0], LC_TEXT("SHOP_REASON"), GetName());
  934. DBManager::instance().DirectQuery(query);
  935. }
  936.  
  937. }
  938. GetMyShop()->GetItems();
  939. LPCHARACTER owner = CHARACTER_MANAGER::instance().FindByPID(GetPrivShopOwner());
  940. if (owner)
  941. {
  942. #ifdef GIFT_SYSTEM
  943. owner->RefreshGift();
  944. #endif
  945. owner->RemovePrivShopTable(GetPrivShop());
  946. owner->SendShops();
  947. owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "SHOP_SUCCESS_CLOSE"));
  948. }
  949. else{
  950. TPacketShopClose packet;
  951. packet.shop_id = GetPrivShop();
  952. packet.pid = GetPrivShopOwner();
  953. db_clientdesc->DBPacket(HEADER_GD_SHOP_CLOSE, 0, &packet, sizeof(packet));
  954. }
  955.  
  956. DBManager::instance().DirectQuery("delete from player_shop where id='%d'", GetPrivShop());
  957. CloseMyShop();
  958. }
  959. return;
  960. }
  961. M2_DESTROY_CHARACTER(this);
  962. }
  963.  
  964.  
  965.  
  966. EVENTFUNC(RefreshShopEvent)
  967. {
  968. char_event_info* info = dynamic_cast<char_event_info*>(event->info);
  969. if (info == NULL)
  970. {
  971. sys_err("ishop_refresh_event> <Factor> Null pointer");
  972. return 0;
  973. }
  974.  
  975. LPCHARACTER ch = info->ch;
  976.  
  977. if (NULL == ch)
  978. return 0;
  979.  
  980.  
  981. ch->SendShops();
  982. ch->SendShopCost();
  983. if(ch->GetGiftPages()>0)
  984. ch->ChatPacket(CHAT_TYPE_COMMAND, "gift_info %d", ch->GetGiftPages());
  985. return PASSES_PER_SEC(10);
  986. }
  987. void CHARACTER::StartRefreshShopEvent()
  988. {
  989. if (m_pkRefreshShopEvent)
  990. return;
  991.  
  992. char_event_info* info = AllocEventInfo<char_event_info>();
  993.  
  994. info->ch = this;
  995.  
  996. m_pkRefreshShopEvent = event_create(RefreshShopEvent, info, PASSES_PER_SEC(1)); // 1o?
  997. }
  998. #endif
Add Comment
Please, Sign In to add comment