Advertisement
Guest User

Untitled

a guest
Apr 18th, 2019
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.89 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "../../libgame/include/grid.h"
  3. #include "constants.h"
  4. #include "utils.h"
  5. #include "config.h"
  6. #include "shop.h"
  7. #include "desc.h"
  8. #include "desc_manager.h"
  9. #include "char.h"
  10. #include "char_manager.h"
  11. #include "item.h"
  12. #include "item_manager.h"
  13. #include "buffer_manager.h"
  14. #include "packet.h"
  15. #include "log.h"
  16. #include "db.h"
  17. #include "questmanager.h"
  18. #include "monarch.h"
  19. #include "mob_manager.h"
  20. #include "locale_service.h"
  21. #include "desc_client.h"
  22.  
  23. /* ------------------------------------------------------------------------------------ */
  24. #ifdef __OFFLINE_SHOP__
  25. CShop::CShop() : m_dwVnum(0), m_dwNPCVnum(0), m_pkPC(NULL), m_dwOwnerAID(0), m_dwOwnerPID(0), m_Money(0), m_bColor(0), m_bSize(0), m_bIsLocked(0)
  26. #else
  27. CShop::CShop() : m_dwVnum(0), m_dwNPCVnum(0), m_pkPC(NULL)
  28. #endif
  29. {
  30. m_pGrid = M2_NEW CGrid(5, 9);
  31. }
  32.  
  33. CShop::~CShop()
  34. {
  35. #ifdef __OFFLINE_SHOP__
  36. m_bIsLocked = true;
  37.  
  38. if (HasOwner())
  39. {
  40. for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  41. {
  42. LPITEM item = m_itemVector[i].pkItem;
  43.  
  44. if (item == NULL)
  45. continue;
  46.  
  47. item->SetSkipSave(true);
  48. M2_DESTROY_ITEM(item);
  49. }
  50. }
  51. #endif
  52.  
  53. TPacketGCShop pack;
  54.  
  55. pack.header = HEADER_GC_SHOP;
  56. pack.subheader = SHOP_SUBHEADER_GC_END;
  57. pack.size = sizeof(TPacketGCShop);
  58.  
  59. Broadcast(&pack, sizeof(pack));
  60.  
  61. GuestMapType::iterator it;
  62.  
  63. it = m_map_guest.begin();
  64.  
  65. while (it != m_map_guest.end())
  66. {
  67. LPCHARACTER ch = it->first;
  68. ch->SetShop(NULL);
  69. ++it;
  70. }
  71.  
  72. #ifdef __OFFLINE_SHOP__
  73. m_SoldItems.clear();
  74. #endif
  75. M2_DELETE(m_pGrid);
  76. }
  77.  
  78. #ifdef __OFFLINE_SHOP__
  79. void CShop::SetOwner(DWORD dwOwnerAID, DWORD dwOwnerPID)
  80. {
  81. m_dwOwnerAID = dwOwnerAID;
  82. m_dwOwnerPID = dwOwnerPID;
  83. }
  84. #endif
  85.  
  86. bool CShop::Create(DWORD dwVnum, DWORD dwNPCVnum, TShopItemTable * pTable)
  87. {
  88. /*
  89. if (NULL == CMobManager::instance().Get(dwNPCVnum))
  90. {
  91. sys_err("No such a npc by vnum %d", dwNPCVnum);
  92. return false;
  93. }
  94. */
  95. sys_log(0, "SHOP #%d (Shopkeeper %d)", dwVnum, dwNPCVnum);
  96.  
  97. m_dwVnum = dwVnum;
  98. m_dwNPCVnum = dwNPCVnum;
  99.  
  100. BYTE bItemCount;
  101.  
  102. for (bItemCount = 0; bItemCount < SHOP_HOST_ITEM_MAX_NUM; ++bItemCount)
  103. if (0 == (pTable + bItemCount)->vnum)
  104. break;
  105.  
  106. #ifdef __OFFLINE_SHOP__
  107. SetShopItems(NULL, pTable, bItemCount);
  108. #else
  109. SetShopItems(pTable, bItemCount);
  110. #endif
  111. return true;
  112. }
  113. #ifdef __OFFLINE_SHOP__
  114. bool CShop::Create(TOfflineShopTable* table)
  115. {
  116. sys_log(1, "OFFLINESHOP PID %u (Shopkeeper)", table->dwPID);
  117.  
  118. BYTE bGridTable[6][2] = {
  119. { 5, 8 },{ 5, 10 },{ 6, 10 },{ 7, 10, },{ 8, 10 },{ 9, 10 }
  120. };
  121. BYTE* bSelectedGrid = bGridTable[table->dwSize];
  122.  
  123. m_pGrid->Clear();
  124. M2_DELETE(m_pGrid);
  125. m_pGrid = M2_NEW CGrid(bSelectedGrid[0], bSelectedGrid[1]);
  126. m_pGrid->Clear();
  127.  
  128. m_itemVector.resize(SHOP_HOST_ITEM_MAX_NUM);
  129. memset(&m_itemVector[0], 0, sizeof(SHOP_ITEM) * m_itemVector.size());
  130.  
  131. DWORD dwExpireDate = table->dwInstallTime + table->dwDuration;
  132. DWORD dwNowTimestamp = get_global_time();
  133. sys_log(0, "Create Offlineshop Install time: %u Expire time: %u Now: %u", table->dwInstallTime, dwExpireDate, dwNowTimestamp);
  134.  
  135. if (dwNowTimestamp > dwExpireDate)
  136. {
  137. sys_err("Create Offlineshop fail %s:%u cannot created. shop's time expired", table->szName, table->dwPID);
  138. return false;
  139. }
  140.  
  141. for (int i = 0; i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  142. {
  143. TPlayerItem* pkItemTable = &table->items[i];
  144. if (pkItemTable->id == 0)
  145. continue;
  146.  
  147. LPITEM pkItem = NULL;
  148. if ((pkItem = ITEM_MANAGER::instance().CreateItem(pkItemTable->vnum, pkItemTable->count, pkItemTable->id)) == NULL)
  149. {
  150. sys_err("Create Offlineshop fail %s item[id:%u] cannot created. item can not loaded", table->szName, pkItemTable->id);
  151. continue;
  152. }
  153.  
  154. pkItem->SetSkipSave(true);
  155. pkItem->SetSockets(pkItemTable->alSockets);
  156. pkItem->SetAttributes(pkItemTable->aAttr);
  157.  
  158. pkItem->SetLastOwnerPID(pkItemTable->owner);
  159.  
  160. pkItem->SetCell(NULL, i);
  161. pkItem->SetWindow(pkItemTable->window);
  162.  
  163. const TItemTable* pkItemProto = pkItem->GetProto();
  164. m_pGrid->Put(pkItemTable->pos, 1, pkItemProto->bSize);
  165.  
  166.  
  167. SHOP_ITEM & item = m_itemVector[pkItemTable->pos];
  168. item.pkItem = pkItem;
  169. item.itemid = pkItem->GetID();
  170. item.vnum = pkItem->GetVnum();
  171. item.count = pkItem->GetCount();
  172. item.price = table->price[i];
  173. item.price2 = table->price2[i];
  174. item.price3 = table->price3[i];
  175. item.price4 = table->price4[i];
  176.  
  177. char name[36];
  178. snprintf(name, sizeof(name), "%-20s(#%-5d) (x %d)", pkItemProto->szName, (int)item.vnum, item.count);
  179. sys_log(1, "OFFLINE_SHOP_ITEM: %-36s PRICE %-5d", name, item.price);
  180. }
  181.  
  182. m_Money = table->ullMoney;
  183. m_bColor = table->dwColor;
  184. m_bSize = table->dwSize;
  185. m_bIsLocked = false;
  186.  
  187. return true;
  188. }
  189. #endif
  190. #ifdef __OFFLINE_SHOP__
  191. void CShop::SetShopItems(LPCHARACTER pkOwner, TShopItemTable * pTable, BYTE bItemCount)
  192. #else
  193. void CShop::SetShopItems(TShopItemTable * pTable, BYTE bItemCount)
  194. #endif
  195. {
  196. #ifdef __OFFLINE_SHOP__
  197. if (!bItemCount) {
  198. sys_err("Offline shop init fail! Null item count.");
  199.  
  200. LPCHARACTER owner = (pkOwner ? pkOwner : m_pkPC);
  201. if (owner)
  202. sys_err("Owner: %s[%u]", owner->GetName(), owner->GetPlayerID());
  203. return;
  204. }
  205. #endif
  206.  
  207. if (bItemCount > SHOP_HOST_ITEM_MAX_NUM)
  208. return;
  209.  
  210. #ifdef __OFFLINE_SHOP__
  211. BYTE bGridTable[6][2] = {
  212. { 5, 8 },{ 5, 10 },{ 6, 10 },{ 7, 10, },{ 8, 10 },{ 9, 10 }
  213. };
  214.  
  215. if (m_pkPC)
  216. {
  217. BYTE* bSelectedGrid = bGridTable[m_bSize];
  218. if (bItemCount > bSelectedGrid[0] * bSelectedGrid[1]) {
  219. sys_err("maximum item count from allocated grid count. item count: %d grid count: %d", bItemCount, bSelectedGrid[0] * bSelectedGrid[1]);
  220. return;
  221. }
  222.  
  223. m_pGrid->Clear();
  224. M2_DELETE(m_pGrid);
  225. m_pGrid = M2_NEW CGrid(bSelectedGrid[0], bSelectedGrid[1]);
  226. m_pGrid->Clear();
  227. }
  228. else {
  229. if (bItemCount > 40)
  230. return;
  231. }
  232. #else
  233. m_pGrid->Clear();
  234. #endif
  235.  
  236. m_itemVector.resize(SHOP_HOST_ITEM_MAX_NUM);
  237. memset(&m_itemVector[0], 0, sizeof(SHOP_ITEM) * m_itemVector.size());
  238.  
  239. for (int i = 0; i < bItemCount; ++i)
  240. {
  241. LPITEM pkItem = NULL;
  242. const TItemTable * item_table;
  243.  
  244. if (m_pkPC)
  245. {
  246. #ifdef __OFFLINE_SHOP__
  247. pkItem = (pkOwner ? pkOwner : m_pkPC)->GetItem(pTable->pos);
  248. #else
  249. pkItem = m_pkPC->GetItem(pTable->pos);
  250. #endif
  251.  
  252. if (!pkItem)
  253. {
  254. #ifdef __OFFLINE_SHOP__
  255. sys_err("cannot find item on pos (%d, %d) (name: %s)", pTable->pos.window_type, pTable->pos.cell, (pkOwner ? pkOwner : m_pkPC)->GetName());
  256. #else
  257. sys_err("cannot find item on pos (%d, %d) (name: %s)", pTable->pos.window_type, pTable->pos.cell, m_pkPC->GetName());
  258. #endif
  259. continue;
  260. }
  261.  
  262. item_table = pkItem->GetProto();
  263. }
  264. else
  265. {
  266. if (!pTable->vnum)
  267. continue;
  268.  
  269. item_table = ITEM_MANAGER::instance().GetTable(pTable->vnum);
  270. }
  271.  
  272. if (!item_table)
  273. {
  274. sys_err("Shop: no item table by item vnum #%d", pTable->vnum);
  275. continue;
  276. }
  277.  
  278. int iPos;
  279.  
  280. if (IsPCShop())
  281. {
  282. sys_log(0, "MyShop: use position %d", pTable->display_pos);
  283. iPos = pTable->display_pos;
  284. }
  285. else
  286. iPos = m_pGrid->FindBlank(1, item_table->bSize);
  287.  
  288. if (iPos < 0)
  289. {
  290. sys_err("not enough shop window");
  291. continue;
  292. }
  293.  
  294. if (!m_pGrid->IsEmpty(iPos, 1, item_table->bSize))
  295. {
  296. if (IsPCShop())
  297. {
  298. #ifdef __OFFLINE_SHOP__
  299. sys_err("not empty position for pc shop %s[%d]", (pkOwner ? pkOwner : m_pkPC)->GetName(), (pkOwner ? pkOwner : m_pkPC)->GetPlayerID());
  300. #else
  301. sys_err("not empty position for pc shop %s[%d]", m_pkPC->GetName(), m_pkPC->GetPlayerID());
  302. #endif
  303. }
  304. else
  305. {
  306. sys_err("not empty position for npc shop");
  307. }
  308. continue;
  309. }
  310.  
  311. m_pGrid->Put(iPos, 1, item_table->bSize);
  312.  
  313. SHOP_ITEM & item = m_itemVector[iPos];
  314.  
  315. item.pkItem = pkItem;
  316. item.itemid = 0;
  317. #ifdef __OFFLINE_SHOP__
  318. if (pkItem)
  319. {
  320. if (pkOwner)
  321. {
  322. pkOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, pkItem->GetCell(), 255);
  323.  
  324. pkItem->SetSkipSave(true);
  325. pkItem->RemoveFromCharacter();
  326.  
  327. pkItem->SetCell(NULL, iPos);
  328. pkItem->SetWindow(OFFLINE_SHOP);
  329.  
  330. ITEM_MANAGER::instance().SaveSingleItem(pkItem);
  331. }
  332.  
  333. item.itemid = pkItem->GetID();
  334. item.vnum = pkItem->GetVnum();
  335. item.count = pkItem->GetCount();
  336. item.price = pTable->price;
  337. item.price2 = pTable->price2;
  338. item.price3 = pTable->price3;
  339. item.price4 = pTable->price4;
  340. }
  341. #else
  342. if (item.pkItem)
  343. {
  344. item.vnum = pkItem->GetVnum();
  345. item.count = pkItem->GetCount(); // PC ĽĄŔÇ °ćżě ľĆŔĚĹŰ °łĽö´Â ÁřÂĄ ľĆŔĚĹŰŔÇ °łĽöż©ľß ÇŃ´Ů.
  346. item.price = pTable->price; // °ˇ°Ýµµ »çżëŔÚ°ˇ Á¤ÇŃ´ë·Î..
  347. item.itemid = pkItem->GetID();
  348. }
  349. #endif
  350. else
  351. {
  352. item.vnum = pTable->vnum;
  353. item.count = pTable->count;
  354. #ifdef __OFFLINE_SHOP__
  355. item.price2 = pTable->price2;
  356. item.price3 = pTable->price3;
  357. item.price4 = pTable->price4;
  358. #endif
  359.  
  360. if (IS_SET(item_table->dwFlags, ITEM_FLAG_COUNT_PER_1GOLD))
  361. {
  362. if (item_table->dwGold == 0)
  363. item.price = item.count;
  364. else
  365. item.price = item.count / item_table->dwGold;
  366. }
  367. else
  368. item.price = item_table->dwGold * item.count;
  369. }
  370.  
  371. char name[36];
  372. snprintf(name, sizeof(name), "%-20s(#%-5d) (x %d)", item_table->szName, (int) item.vnum, item.count);
  373.  
  374. #ifdef __OFFLINE_SHOP__
  375. sys_log(0, "SHOP_ITEM: %-36s PRICE %-5d PRICE2: %d PRICE3: %d PRICE4: %d", name, item.price, item.price2, item.price3, item.price4);
  376. #else
  377. sys_log(0, "SHOP_ITEM: %-36s PRICE %-5d", name, item.price);
  378. #endif
  379. ++pTable;
  380. }
  381. }
  382.  
  383. int CShop::Buy(LPCHARACTER ch, BYTE pos)
  384. {
  385. #ifdef __OFFLINE_SHOP__
  386. if (m_bIsLocked == true)
  387. {
  388. sys_log(0, "Shop::Buy : locked shop: %s", ch->GetName());
  389. return SHOP_SUBHEADER_GC_INVALID_POS;
  390. }
  391.  
  392. if (IsPCShop() && ch && GetOwner() && ch->GetPlayerID() == GetOwner())
  393. {
  394. ch->ChatPacket(CHAT_TYPE_INFO, "You can not buy item from your offline shop!");
  395. sys_log(0, "Shop::Buy : itself offline shop: %s", ch->GetName());
  396. return SHOP_SUBHEADER_GC_INVALID_POS;
  397. }
  398. #endif
  399.  
  400. if (pos >= m_itemVector.size())
  401. {
  402. sys_log(0, "Shop::Buy : invalid position %d : %s", pos, ch->GetName());
  403. return SHOP_SUBHEADER_GC_INVALID_POS;
  404. }
  405.  
  406. sys_log(0, "Shop::Buy : name %s pos %d", ch->GetName(), pos);
  407.  
  408. GuestMapType::iterator it = m_map_guest.find(ch);
  409.  
  410. if (it == m_map_guest.end())
  411. return SHOP_SUBHEADER_GC_END;
  412.  
  413. SHOP_ITEM& r_item = m_itemVector[pos];
  414.  
  415. if (r_item.price <= 0)
  416. {
  417. LogManager::instance().HackLog("SHOP_BUY_GOLD_OVERFLOW", ch);
  418. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
  419. }
  420. #ifdef __OFFLINE_SHOP__
  421. if (r_item.price2 < 0)
  422. {
  423. LogManager::instance().HackLog("SHOP_BUY_COIN_OVERFLOW", ch);
  424. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_COIN;
  425. }
  426. if (r_item.price3 < 0)
  427. {
  428. LogManager::instance().HackLog("SHOP_BUY_GOLDBAR_OVERFLOW", ch);
  429. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_GOLDBAR;
  430. }
  431. if (r_item.price4 < 0)
  432. {
  433. LogManager::instance().HackLog("SHOP_BUY_WON_OVERFLOW", ch);
  434. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_WON;
  435. }
  436. #endif
  437.  
  438. DWORD dwPrice = r_item.price;
  439.  
  440. if (it->second) // if other empire, price is triple
  441. dwPrice *= 3;
  442.  
  443. if (ch->GetGold() < (int) dwPrice)
  444. {
  445. sys_log(1, "Shop::Buy : Not enough money : %s has %d, price %d", ch->GetName(), ch->GetGold(), dwPrice);
  446. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
  447. }
  448. #ifdef __OFFLINE_SHOP__
  449. DWORD dwPrice2 = r_item.price2; // coin
  450. if (ch->GetCoins() < (long)dwPrice2)
  451. {
  452. sys_log(1, "Shop::Buy : Not enough money price2 : %s has %d, price %d", ch->GetName(), ch->GetCoins(), dwPrice2);
  453. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_COIN;
  454. }
  455.  
  456. DWORD dwPrice3 = r_item.price3; // goldbar
  457. if (ch->CountSpecifyItem(80007) < (int)dwPrice3)
  458. {
  459. sys_log(1, "Shop::Buy : Not enough money price3 : %s has %d, price %d", ch->GetName(), ch->CountSpecifyItem(80007), dwPrice3);
  460. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_GOLDBAR;
  461. }
  462.  
  463. DWORD dwPrice4 = r_item.price4; // won
  464. #ifdef ENABLE_CHEQUE_SYSTEM
  465. if (ch->GetPoint(POINT_CHEQUE) < dwPrice4)
  466. {
  467. sys_log(1, "Shop::Buy : Not enough money price4 : %s has %d, price %d", ch->GetName(), ch->GetPoint(POINT_CHEQUE), dwPrice4);
  468. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_WON;
  469. }
  470. #endif
  471. #endif
  472.  
  473. LPITEM item;
  474.  
  475. if (m_pkPC) // ÇÇľľ°ˇ żîżµÇĎ´Â ĽĄŔş ÇÇľľ°ˇ ˝ÇÁ¦ ľĆŔĚĹŰŔ» °ˇÁö°íŔÖľîľß ÇŃ´Ů.
  476. item = r_item.pkItem;
  477. else
  478. item = ITEM_MANAGER::instance().CreateItem(r_item.vnum, r_item.count);
  479.  
  480. if (!item)
  481. return SHOP_SUBHEADER_GC_SOLD_OUT;
  482.  
  483. if (!m_pkPC)
  484. {
  485. if (quest::CQuestManager::instance().GetEventFlag("hivalue_item_sell") == 0)
  486. {
  487. //ĂŕşąŔÇ ±¸˝˝ && ¸¸łâÇŃö ŔĚşĄĆ®
  488. if (item->GetVnum() == 70024 || item->GetVnum() == 70035)
  489. {
  490. return SHOP_SUBHEADER_GC_END;
  491. }
  492. }
  493. }
  494.  
  495. int iEmptyPos;
  496. if (item->IsDragonSoul())
  497. {
  498. iEmptyPos = ch->GetEmptyDragonSoulInventory(item);
  499. }
  500. else
  501. {
  502. iEmptyPos = ch->GetEmptyInventory(item->GetSize());
  503. }
  504.  
  505. if (iEmptyPos < 0)
  506. {
  507. if (m_pkPC)
  508. {
  509. sys_log(1, "Shop::Buy at PC Shop : Inventory full : %s size %d", ch->GetName(), item->GetSize());
  510. return SHOP_SUBHEADER_GC_INVENTORY_FULL;
  511. }
  512. else
  513. {
  514. sys_log(1, "Shop::Buy : Inventory full : %s size %d", ch->GetName(), item->GetSize());
  515. M2_DESTROY_ITEM(item);
  516. return SHOP_SUBHEADER_GC_INVENTORY_FULL;
  517. }
  518. }
  519.  
  520. ch->PointChange(POINT_GOLD, -dwPrice, false);
  521. #ifdef __OFFLINE_SHOP__
  522. if (dwPrice2 > 0)
  523. ch->UpdateCoins(0, -dwPrice2);
  524. if (dwPrice3 > 0)
  525. ch->RemoveSpecifyItem(80007, dwPrice3);
  526. #ifdef ENABLE_CHEQUE_SYSTEM
  527. if (dwPrice4 > 0)
  528. ch->PointChange(POINT_CHEQUE, -dwPrice4, true);
  529. #endif
  530. #endif
  531.  
  532. //ĽĽ±Ý °č»ę
  533. DWORD dwTax = 0;
  534. int iVal = 0;
  535.  
  536. if (LC_IsYMIR() || LC_IsKorea())
  537. {
  538. if (0 < (iVal = quest::CQuestManager::instance().GetEventFlag("trade_tax")))
  539. {
  540. if (iVal > 100)
  541. iVal = 100;
  542.  
  543. dwTax = dwPrice * iVal / 100;
  544. dwPrice = dwPrice - dwTax;
  545. }
  546. else
  547. {
  548. iVal = 3;
  549. dwTax = dwPrice * iVal / 100;
  550. dwPrice = dwPrice - dwTax;
  551. }
  552. }
  553. else
  554. {
  555. iVal = quest::CQuestManager::instance().GetEventFlag("personal_shop");
  556.  
  557. if (0 < iVal)
  558. {
  559. if (iVal > 100)
  560. iVal = 100;
  561.  
  562. dwTax = dwPrice * iVal / 100;
  563. dwPrice = dwPrice - dwTax;
  564. }
  565. else
  566. {
  567. iVal = 0;
  568. dwTax = 0;
  569. }
  570. }
  571.  
  572. // »óÁˇżˇĽ­ »ě‹š ĽĽ±Ý 5%
  573. if (!m_pkPC)
  574. {
  575. CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch);
  576. }
  577.  
  578. #ifdef __OFFLINE_SHOP__
  579. DWORD dwGoldbarCosts = 2000000; /* Default: 2.000.000 */
  580. TItemTable* rItem = ITEM_MANAGER::instance().GetTable(80007);
  581. if (rItem && rItem->dwGold)
  582. dwGoldbarCosts = rItem->dwGold;
  583. if (m_pkPC)
  584. {
  585. m_Money += dwPrice;
  586. if (dwPrice3)
  587. m_Money += dwGoldbarCosts * dwPrice3;
  588.  
  589. GuestMapType::iterator it = m_map_guest.begin();
  590. GuestMapType::iterator it_end = m_map_guest.end();
  591. for (; it != it_end; ++it)
  592. {
  593. LPCHARACTER pkGuest = it->first;
  594. if (pkGuest->GetDesc() && pkGuest->GetPlayerID() == GetOwner())
  595. {
  596. TPacketGCShop pack;
  597.  
  598. pack.header = HEADER_GC_SHOP;
  599. pack.subheader = SHOP_SUBHEADER_GC_UPDATE_MONEY;
  600. pack.size = sizeof(pack) + sizeof(m_Money);
  601.  
  602. pkGuest->GetDesc()->BufferedPacket(&pack, sizeof(pack));
  603. pkGuest->GetDesc()->Packet(&m_Money, sizeof(m_Money));
  604. break;
  605. }
  606. }
  607. }
  608.  
  609. if (HasOwner())
  610. {
  611. {
  612. item->SetSkipSave(false);
  613. item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  614. item->SetWindow(SAFEBOX_OFFLINE_SHOP); // Get new item to extra safebox
  615. ITEM_MANAGER::instance().SaveSingleItem(item); // Save item to extra safebox
  616. item->SetWindow(INVENTORY); // Set inventory window as temporary window
  617. ITEM_MANAGER::instance().SaveSingleItem(item); // Register delayed save request for inventory window
  618.  
  619. char buf[512];
  620.  
  621. snprintf(buf, sizeof(buf), "%s %u %u %u", item->GetName(), m_dwOwnerPID, dwPrice, item->GetCount());
  622. LogManager::instance().ItemLog(ch, item, "SHOP_BUY2", buf);
  623.  
  624. snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), ch->GetPlayerID(), ch->GetName(), dwPrice, item->GetCount());
  625. LogManager::instance().ItemLog(m_dwOwnerPID, 0, 0, item->GetID(), "SHOP_SELL2", buf, "", item->GetVnum());
  626. }
  627.  
  628. r_item.pkItem = NULL;
  629.  
  630. SShopSoldData lpSoldData;
  631. lpSoldData.lpShop = this;
  632. lpSoldData.vnum = item->GetVnum();
  633. lpSoldData.Price = dwPrice;
  634. lpSoldData.Price2 = dwPrice2;
  635. lpSoldData.Price3 = dwPrice3;
  636. lpSoldData.Price4 = dwPrice4;
  637. lpSoldData.Count = item->GetCount();
  638. thecore_memcpy(lpSoldData.alSockets, item->GetSockets(), sizeof(lpSoldData.alSockets));
  639. thecore_memcpy(lpSoldData.aAttr, item->GetAttributes(), sizeof(lpSoldData.aAttr));
  640. #if 0
  641. strlcpy(lpSoldData.newOwner, ch->GetName(), sizeof(lpSoldData.newOwner));
  642. lpSoldData.soldDate = get_global_time();
  643. #endif
  644. m_SoldItems[pos] = lpSoldData;
  645.  
  646. BroadcastUpdateItem(pos);
  647.  
  648. TSafeboxMoney p;
  649. p.dwAID = m_dwOwnerAID;
  650. p.bType = 1;
  651. p.llAmount = dwPrice;
  652. db_clientdesc->DBPacket(HEADER_GD_SAFEBOX_MONEY, 0, &p, sizeof(p));
  653.  
  654. if (dwPrice2 > 0)
  655. ch->UpdateCoins(m_dwOwnerAID, dwPrice2);
  656.  
  657. if (dwPrice3 > 0) {
  658. TSafeboxMoney pBar;
  659. pBar.dwAID = m_dwOwnerAID;
  660. pBar.bType = 1;
  661. pBar.llAmount = dwPrice3 * dwGoldbarCosts;
  662. db_clientdesc->DBPacket(HEADER_GD_SAFEBOX_MONEY, 0, &pBar, sizeof(pBar));
  663. }
  664.  
  665. #ifdef ENABLE_CHEQUE_SYSTEM
  666. if (dwPrice4 > 0) {
  667. char szQuery[1024 + 1];
  668. sprintf(szQuery, "UPDATE player.player SET cheque = cheque + '%u' WHERE id = '%u'", dwPrice4, m_dwOwnerAID);
  669. std::auto_ptr<SQLMsg> msg(DBManager::instance().DirectQuery(szQuery));
  670. }
  671. }
  672. #endif
  673. }
  674. else if (m_pkPC)
  675. #else
  676. if (m_pkPC)
  677. #endif
  678. {
  679. m_pkPC->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
  680.  
  681. char buf[512];
  682.  
  683. if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
  684. {
  685. snprintf(buf, sizeof(buf), "%s FROM: %u TO: %u PRICE: %u", item->GetName(), ch->GetPlayerID(), m_pkPC->GetPlayerID(), dwPrice);
  686. LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), SHOP_BUY, buf);
  687. LogManager::instance().GoldBarLog(m_pkPC->GetPlayerID(), item->GetID(), SHOP_SELL, buf);
  688. }
  689.  
  690. item->RemoveFromCharacter();
  691. if (item->IsDragonSoul())
  692. item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
  693. else
  694. item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  695. ITEM_MANAGER::instance().FlushDelayedSave(item);
  696.  
  697. #ifdef __OFFLINE_SHOP__
  698. snprintf(buf, sizeof(buf), "%s %u(%s) %u %u %u %u %u", item->GetName(), m_pkPC->GetPlayerID(), m_pkPC->GetName(), dwPrice, dwPrice2, dwPrice3, dwPrice4, item->GetCount());
  699. #else
  700. snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), m_pkPC->GetPlayerID(), m_pkPC->GetName(), dwPrice, item->GetCount());
  701. #endif
  702. LogManager::instance().ItemLog(ch, item, "SHOP_BUY", buf);
  703.  
  704. #ifdef __OFFLINE_SHOP__
  705. snprintf(buf, sizeof(buf), "%s %u(%s) %u %u %u %u %u", item->GetName(), ch->GetPlayerID(), ch->GetName(), dwPrice, dwPrice2, dwPrice3, dwPrice4, item->GetCount());
  706. #else
  707. snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), ch->GetPlayerID(), ch->GetName(), dwPrice, item->GetCount());
  708. #endif
  709. LogManager::instance().ItemLog(m_pkPC, item, "SHOP_SELL", buf);
  710.  
  711.  
  712. r_item.pkItem = NULL;
  713. #ifdef __OFFLINE_SHOP__
  714. SShopSoldData lpSoldData;
  715. lpSoldData.lpShop = this;
  716. lpSoldData.vnum = item->GetVnum();
  717. lpSoldData.Price = dwPrice;
  718. lpSoldData.Price2 = dwPrice2;
  719. lpSoldData.Price3 = dwPrice3;
  720. lpSoldData.Price4 = dwPrice4;
  721. lpSoldData.Count = item->GetCount();
  722. thecore_memcpy(lpSoldData.alSockets, item->GetSockets(), sizeof(lpSoldData.alSockets));
  723. thecore_memcpy(lpSoldData.aAttr, item->GetAttributes(), sizeof(lpSoldData.aAttr));
  724. #if 0
  725. strlcpy(lpSoldData.newOwner, ch->GetName(), sizeof(lpSoldData.newOwner));
  726. lpSoldData.soldDate = get_global_time();
  727. #endif
  728. m_SoldItems[pos] = lpSoldData;
  729. #endif
  730.  
  731. BroadcastUpdateItem(pos);
  732.  
  733. m_pkPC->PointChange(POINT_GOLD, dwPrice, false);
  734.  
  735. #ifdef __OFFLINE_SHOP__
  736. if (dwPrice2 > 0)
  737. m_pkPC->UpdateCoins(0, dwPrice2);
  738.  
  739. if (dwPrice3 > 0) {
  740. DWORD dwGoldbarCosts = 2000000; /* Default: 2.000.000 */
  741. TItemTable* rItem = ITEM_MANAGER::instance().GetTable(80007);
  742. if (rItem && rItem->dwGold)
  743. dwGoldbarCosts = rItem->dwGold;
  744.  
  745. TSafeboxMoney pBar;
  746. pBar.dwAID = m_dwOwnerAID;
  747. pBar.bType = 1;
  748. pBar.llAmount = dwPrice3 * dwGoldbarCosts;
  749. db_clientdesc->DBPacket(HEADER_GD_SAFEBOX_MONEY, 0, &pBar, sizeof(pBar));
  750. }
  751.  
  752. #ifdef ENABLE_CHEQUE_SYSTEM
  753. if (dwPrice4 > 0)
  754. m_pkPC->PointChange(POINT_CHEQUE, dwPrice4);
  755. #endif
  756.  
  757. #endif
  758. }
  759. else
  760. {
  761. if (item->IsDragonSoul())
  762. item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
  763. else
  764. item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  765. ITEM_MANAGER::instance().FlushDelayedSave(item);
  766. LogManager::instance().ItemLog(ch, item, "BUY", item->GetName());
  767.  
  768. if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
  769. {
  770. LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), PERSONAL_SHOP_BUY, "");
  771. }
  772.  
  773. DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), -dwPrice);
  774. }
  775.  
  776. if (item)
  777. #ifdef __OFFLINE_SHOP__
  778. sys_log(0, "SHOP: BUY: name %s %s(x %d):%u price1 %u price2 %u price3 %u price4 %u", ch->GetName(), item->GetName(), item->GetCount(), item->GetID(), dwPrice, dwPrice2, dwPrice3, dwPrice4);
  779. #else
  780. sys_log(0, "SHOP: BUY: name %s %s(x %d):%u price %u", ch->GetName(), item->GetName(), item->GetCount(), item->GetID(), dwPrice);
  781. #endif
  782.  
  783. #ifdef __OFFLINE_SHOP__
  784. if (HasOwner())
  785. {
  786. char buf[1024] = { 0 };
  787. char itemlink[256];
  788. int len;
  789. int i;
  790.  
  791. len = snprintf(itemlink, sizeof(itemlink), "item:%x:%x", item->GetVnum(), item->GetFlag());
  792.  
  793. for (i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
  794. len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%d", item->GetSocket(i));
  795.  
  796. for (i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; i++) {
  797. if (i >= item->GetAttributeCount())
  798. len += snprintf(itemlink + len, sizeof(itemlink) - len, ":0:0");
  799. else
  800. len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%x:%d", item->GetAttributeType(i), item->GetAttributeValue(i));
  801. }
  802.  
  803. //if (item->GetAttributeCount() > 0)
  804. snprintf(buf, sizeof(buf), "|cffffc700|H%s|h[%s]|h|r", itemlink, item->GetName());
  805. //else
  806. // snprintf(buf, sizeof(buf), "|cfff1e6c0|H%s|h[%s]|h|r", itemlink, item->GetName());
  807.  
  808. LPCHARACTER ownerch = CHARACTER_MANAGER::instance().FindByPID(m_dwOwnerPID);
  809. if (ownerch)
  810. ownerch->ChatPacket(CHAT_TYPE_INFO, "<Buy notice> %s bought %s with %u yang %u coin %u goldbar %u won from your offline shop.", ch->GetName(), buf, dwPrice, dwPrice2, dwPrice3, dwPrice4);
  811. }
  812. #endif
  813.  
  814. ch->Save();
  815.  
  816. #ifdef __OFFLINE_SHOP__
  817. if (HasOwner())
  818. {
  819. for (DWORD i = 0; i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  820. {
  821. const SHOP_ITEM & item = m_itemVector[i];
  822.  
  823. if (item.pkItem)
  824. break;
  825.  
  826. if (i == SHOP_HOST_ITEM_MAX_NUM - 1)
  827. {
  828. Remove();
  829. M2_DESTROY_CHARACTER(m_pkPC);
  830. }
  831. }
  832. }
  833. #endif
  834.  
  835. return (SHOP_SUBHEADER_GC_OK);
  836. }
  837.  
  838. bool CShop::AddGuest(LPCHARACTER ch, DWORD owner_vid, bool bOtherEmpire)
  839. {
  840. if (!ch)
  841. return false;
  842.  
  843. if (ch->GetExchange())
  844. return false;
  845.  
  846. if (ch->GetShop())
  847. return false;
  848.  
  849. ch->SetShop(this);
  850.  
  851. m_map_guest.insert(GuestMapType::value_type(ch, bOtherEmpire));
  852.  
  853. TPacketGCShop pack;
  854.  
  855. pack.header = HEADER_GC_SHOP;
  856. pack.subheader = SHOP_SUBHEADER_GC_START;
  857.  
  858. TPacketGCShopStart pack2;
  859.  
  860. memset(&pack2, 0, sizeof(pack2));
  861. #ifdef __OFFLINE_SHOP__
  862. pack2.vid = owner_vid;
  863. #else
  864. pack2.owner_vid = owner_vid;
  865. #endif
  866. #ifdef __OFFLINE_SHOP__
  867. if (IsPCShop() || HasOwner())
  868. pack2.grid_type = m_bSize;
  869. else
  870. pack2.grid_type = 0;
  871.  
  872.  
  873. if (HasOwner())
  874. {
  875. if (ch->GetPlayerID() == m_dwOwnerPID)
  876. pack2.owner_vid = ch->GetVID();
  877. else
  878. pack2.owner_vid = -1;
  879. }
  880. #endif
  881. for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  882. {
  883. const SHOP_ITEM & item = m_itemVector[i];
  884.  
  885. //HIVALUE_ITEM_EVENT
  886. if (quest::CQuestManager::instance().GetEventFlag("hivalue_item_sell") == 0)
  887. {
  888. //ĂŕşąŔÇ ±¸˝˝ && ¸¸łâÇŃö ŔĚşĄĆ®
  889. if (item.vnum == 70024 || item.vnum == 70035)
  890. {
  891. continue;
  892. }
  893. }
  894. //END_HIVALUE_ITEM_EVENT
  895. if (m_pkPC && !item.pkItem)
  896. {
  897. #ifdef __OFFLINE_SHOP__
  898. DWORD dwVnum = GetSoldItemVnum(i);
  899. if (dwVnum)
  900. {
  901. pack2.items[i].vnum = dwVnum;
  902. long lGetPriceFromTempData = GetSoldPrice(i, 1);
  903.  
  904. if (bOtherEmpire) // no empire price penalty for pc shop
  905. pack2.items[i].price = lGetPriceFromTempData * 3;
  906. else
  907. pack2.items[i].price = lGetPriceFromTempData;
  908.  
  909. pack2.items[i].price2 = GetSoldPrice(i, 2);
  910. pack2.items[i].price3 = GetSoldPrice(i, 3);
  911. pack2.items[i].price4 = GetSoldPrice(i, 4);
  912.  
  913. pack2.items[i].count = GetSoldCount(i);
  914.  
  915. thecore_memcpy(pack2.items[i].alSockets, GetSoldSockets(i), sizeof(pack2.items[i].alSockets));
  916. thecore_memcpy(pack2.items[i].aAttr, GetSoldAttributes(i), sizeof(pack2.items[i].aAttr));
  917. pack2.items[i].isSold = 1;
  918. }
  919. else
  920. #endif
  921. continue;
  922. }
  923.  
  924. else {
  925. pack2.items[i].vnum = item.vnum;
  926.  
  927. if (bOtherEmpire) // no empire price penalty for pc shop
  928. pack2.items[i].price = item.price * 3;
  929. else
  930. pack2.items[i].price = item.price;
  931.  
  932. pack2.items[i].count = item.count;
  933. #ifdef __OFFLINE_SHOP__
  934. pack2.items[i].price2 = item.price2;
  935. pack2.items[i].price3 = item.price3;
  936. pack2.items[i].price4 = item.price4;
  937. #endif
  938. if (item.pkItem)
  939. {
  940. thecore_memcpy(pack2.items[i].alSockets, item.pkItem->GetSockets(), sizeof(pack2.items[i].alSockets));
  941. thecore_memcpy(pack2.items[i].aAttr, item.pkItem->GetAttributes(), sizeof(pack2.items[i].aAttr));
  942. }
  943. #ifdef __OFFLINE_SHOP__
  944. pack2.items[i].isSold = 0;
  945. #endif
  946. }
  947. }
  948.  
  949. pack.size = sizeof(pack) + sizeof(pack2);
  950.  
  951. ch->GetDesc()->BufferedPacket(&pack, sizeof(TPacketGCShop));
  952. ch->GetDesc()->Packet(&pack2, sizeof(TPacketGCShopStart));
  953.  
  954. #ifdef __OFFLINE_SHOP__
  955. LPCHARACTER ownerch = CHARACTER_MANAGER::instance().FindByPID(m_dwOwnerPID);
  956. if (IsPCShop() && ownerch && ownerch != ch && ownerch->IsPC())
  957. ownerch->ChatPacket(CHAT_TYPE_INFO, "%s oglada Twoj sklep!", ch->GetName());
  958.  
  959. if (ch->GetPlayerID() == m_dwOwnerPID)
  960. {
  961. pack.subheader = SHOP_SUBHEADER_GC_UPDATE_MONEY;
  962. pack.size = sizeof(pack) + sizeof(m_Money);
  963.  
  964. ch->GetDesc()->BufferedPacket(&pack, sizeof(pack));
  965. ch->GetDesc()->Packet(&m_Money, sizeof(m_Money));
  966. }
  967. #endif
  968.  
  969. return true;
  970. }
  971.  
  972. void CShop::RemoveGuest(LPCHARACTER ch)
  973. {
  974. if (ch->GetShop() != this)
  975. return;
  976. #ifdef __OFFLINE_SHOP__
  977. LPCHARACTER ownerch = CHARACTER_MANAGER::instance().FindByPID(ch->GetShop()->GetOwner());
  978. if (IsPCShop() && ownerch && ownerch != ch && ownerch->IsPC())
  979. ownerch->ChatPacket(CHAT_TYPE_INFO, "%s przestal ogladac Twoj sklep!", ch->GetName());
  980. #endif
  981. m_map_guest.erase(ch);
  982. ch->SetShop(NULL);
  983.  
  984. TPacketGCShop pack;
  985.  
  986. pack.header = HEADER_GC_SHOP;
  987. pack.subheader = SHOP_SUBHEADER_GC_END;
  988. pack.size = sizeof(TPacketGCShop);
  989.  
  990. ch->GetDesc()->Packet(&pack, sizeof(pack));
  991. }
  992.  
  993. void CShop::Broadcast(const void * data, int bytes)
  994. {
  995. sys_log(1, "Shop::Broadcast %p %d", data, bytes);
  996.  
  997. GuestMapType::iterator it;
  998.  
  999. it = m_map_guest.begin();
  1000.  
  1001. while (it != m_map_guest.end())
  1002. {
  1003. LPCHARACTER ch = it->first;
  1004.  
  1005. if (ch->GetDesc())
  1006. ch->GetDesc()->Packet(data, bytes);
  1007.  
  1008. ++it;
  1009. }
  1010. }
  1011.  
  1012. #ifdef __OFFLINE_SHOP__
  1013. DWORD CShop::GetSoldItemVnum(BYTE pos)
  1014. {
  1015. if (m_SoldItems.empty() || m_SoldItems.begin() == m_SoldItems.end())
  1016. return NULL;
  1017.  
  1018. std::map<BYTE, SShopSoldData>::iterator it;
  1019. for (it = m_SoldItems.begin(); it != m_SoldItems.end(); ++it)
  1020. {
  1021. if (it->first != pos)
  1022. continue;
  1023.  
  1024. if (it->second.lpShop != this)
  1025. continue;
  1026.  
  1027. if (it->second.vnum == NULL)
  1028. return NULL;
  1029.  
  1030. return it->second.vnum;
  1031. }
  1032. return NULL;
  1033. }
  1034.  
  1035. long CShop::GetSoldPrice(BYTE pos, BYTE type)
  1036. {
  1037. if (m_SoldItems.empty() || m_SoldItems.begin() == m_SoldItems.end())
  1038. return NULL;
  1039.  
  1040. std::map<BYTE, SShopSoldData>::iterator it;
  1041. for (it = m_SoldItems.begin(); it != m_SoldItems.end(); ++it)
  1042. {
  1043. if (it->first != pos)
  1044. continue;
  1045.  
  1046. if (it->second.lpShop != this)
  1047. continue;
  1048.  
  1049. if (type == 1 && it->second.Price == NULL)
  1050. return NULL;
  1051. if (type == 2 && it->second.Price2 == NULL)
  1052. return NULL;
  1053. if (type == 3 && it->second.Price3 == NULL)
  1054. return NULL;
  1055. if (type == 4 && it->second.Price4 == NULL)
  1056. return NULL;
  1057.  
  1058. if (type == 4)
  1059. return it->second.Price4;
  1060. if (type == 3)
  1061. return it->second.Price3;
  1062. if (type == 2)
  1063. return it->second.Price2;
  1064. return it->second.Price;
  1065. }
  1066. return NULL;
  1067. }
  1068. BYTE CShop::GetSoldCount(BYTE pos)
  1069. {
  1070. if (m_SoldItems.empty() || m_SoldItems.begin() == m_SoldItems.end())
  1071. return NULL;
  1072.  
  1073. std::map<BYTE, SShopSoldData>::iterator it;
  1074. for (it = m_SoldItems.begin(); it != m_SoldItems.end(); ++it)
  1075. {
  1076. if (it->first != pos)
  1077. continue;
  1078.  
  1079. if (it->second.lpShop != this)
  1080. continue;
  1081.  
  1082. if (it->second.Count == NULL)
  1083. return NULL;
  1084.  
  1085. return it->second.Count;
  1086. }
  1087. return NULL;
  1088. }
  1089. const long* CShop::GetSoldSockets(BYTE pos)
  1090. {
  1091. if (m_SoldItems.empty() || m_SoldItems.begin() == m_SoldItems.end())
  1092. return NULL;
  1093.  
  1094. std::map<BYTE, SShopSoldData>::iterator it;
  1095. for (it = m_SoldItems.begin(); it != m_SoldItems.end(); ++it)
  1096. {
  1097. if (it->first != pos)
  1098. continue;
  1099.  
  1100. if (it->second.lpShop != this)
  1101. continue;
  1102.  
  1103. if (it->second.alSockets == NULL)
  1104. return NULL;
  1105.  
  1106. return it->second.alSockets;
  1107. }
  1108. return NULL;
  1109. }
  1110. const TPlayerItemAttribute* CShop::GetSoldAttributes(BYTE pos)
  1111. {
  1112. if (m_SoldItems.empty() || m_SoldItems.begin() == m_SoldItems.end())
  1113. return NULL;
  1114.  
  1115. std::map<BYTE, SShopSoldData>::iterator it;
  1116. for (it = m_SoldItems.begin(); it != m_SoldItems.end(); ++it)
  1117. {
  1118. if (it->first != pos)
  1119. continue;
  1120.  
  1121. if (it->second.lpShop != this)
  1122. continue;
  1123.  
  1124. if (it->second.aAttr == NULL)
  1125. return NULL;
  1126.  
  1127. return it->second.aAttr;
  1128. }
  1129. return NULL;
  1130. }
  1131. #endif
  1132. void CShop::BroadcastUpdateItem(BYTE pos)
  1133. {
  1134. TPacketGCShop pack;
  1135. TPacketGCShopUpdateItem pack2;
  1136.  
  1137. pack.header = HEADER_GC_SHOP;
  1138. pack.subheader = SHOP_SUBHEADER_GC_UPDATE_ITEM;
  1139. pack.size = sizeof(pack) + sizeof(pack2);
  1140.  
  1141. pack2.pos = pos;
  1142.  
  1143. if (m_pkPC && !m_itemVector[pos].pkItem)
  1144. {
  1145. #ifdef __OFFLINE_SHOP__
  1146. DWORD dwVnum = GetSoldItemVnum(pos);
  1147. if (dwVnum)
  1148. {
  1149. pack2.item.vnum = dwVnum;
  1150. thecore_memcpy(pack2.item.alSockets, GetSoldSockets(pos), sizeof(pack2.item.alSockets));
  1151. thecore_memcpy(pack2.item.aAttr, GetSoldAttributes(pos), sizeof(pack2.item.aAttr));
  1152. pack2.item.isSold = 1;
  1153. }
  1154. else
  1155. #endif
  1156. pack2.item.vnum = m_itemVector[pos].vnum;
  1157. }
  1158. else
  1159. {
  1160. pack2.item.vnum = m_itemVector[pos].vnum;
  1161. if (m_itemVector[pos].pkItem)
  1162. {
  1163. thecore_memcpy(pack2.item.alSockets, m_itemVector[pos].pkItem->GetSockets(), sizeof(pack2.item.alSockets));
  1164. thecore_memcpy(pack2.item.aAttr, m_itemVector[pos].pkItem->GetAttributes(), sizeof(pack2.item.aAttr));
  1165. }
  1166. else
  1167. {
  1168. memset(pack2.item.alSockets, 0, sizeof(pack2.item.alSockets));
  1169. memset(pack2.item.aAttr, 0, sizeof(pack2.item.aAttr));
  1170. }
  1171. #ifdef __OFFLINE_SHOP__
  1172. pack2.item.isSold = 0;
  1173. #endif
  1174. }
  1175.  
  1176. pack2.item.price = m_itemVector[pos].price;
  1177. #ifdef __OFFLINE_SHOP__
  1178. pack2.item.price2 = m_itemVector[pos].price2;
  1179. pack2.item.price3 = m_itemVector[pos].price3;
  1180. pack2.item.price4 = m_itemVector[pos].price4;
  1181. #endif
  1182. pack2.item.count = m_itemVector[pos].count;
  1183.  
  1184. TEMP_BUFFER buf;
  1185. buf.write(&pack, sizeof(pack));
  1186. buf.write(&pack2, sizeof(pack2));
  1187.  
  1188. Broadcast(buf.read_peek(), buf.size());
  1189. }
  1190.  
  1191. int CShop::GetNumberByVnum(DWORD dwVnum)
  1192. {
  1193. int itemNumber = 0;
  1194.  
  1195. for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  1196. {
  1197. const SHOP_ITEM & item = m_itemVector[i];
  1198.  
  1199. if (item.vnum == dwVnum)
  1200. {
  1201. itemNumber += item.count;
  1202. }
  1203. }
  1204.  
  1205. return itemNumber;
  1206. }
  1207.  
  1208. bool CShop::IsSellingItem(DWORD itemID)
  1209. {
  1210. bool isSelling = false;
  1211.  
  1212. for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  1213. {
  1214. if (m_itemVector[i].itemid == itemID)
  1215. {
  1216. isSelling = true;
  1217. break;
  1218. }
  1219. }
  1220.  
  1221. return isSelling;
  1222.  
  1223. }
  1224. #ifdef __OFFLINE_SHOP__
  1225. void CShop::Apply()
  1226. {
  1227. if (!HasOwner())
  1228. return;
  1229.  
  1230. TOfflineShopTable p;
  1231. memset(&p, 0, sizeof(p));
  1232.  
  1233. p.dwAID = m_dwOwnerAID;
  1234. p.dwPID = m_dwOwnerPID;
  1235.  
  1236. p.dwX = m_pkPC->GetX();
  1237. p.dwY = m_pkPC->GetY();
  1238. p.dwMapIndex = m_pkPC->GetMapIndex();
  1239.  
  1240. p.dwChannel = g_bChannel;
  1241.  
  1242. p.dwDuration = event_time(m_pkPC->m_pkExpireOfflineShopEvent) / passes_per_sec;
  1243.  
  1244. p.ullMoney = m_Money;
  1245. p.dwSize = m_bSize;
  1246. p.dwColor = m_bColor;
  1247.  
  1248. strlcpy(p.szSign, m_pkPC->GetShopSign().c_str(), sizeof(p.szSign));
  1249.  
  1250. for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  1251. {
  1252. const SHOP_ITEM & item = m_itemVector[i];
  1253.  
  1254. if (item.pkItem == NULL)
  1255. continue;
  1256.  
  1257. p.items2[i] = item.itemid;
  1258. p.price[i] = item.price;
  1259. p.price2[i] = item.price2;
  1260. p.price3[i] = item.price3;
  1261. p.price4[i] = item.price4;
  1262. }
  1263.  
  1264. db_clientdesc->DBPacket(HEADER_GD_OFFLINE_SHOP_ENTRY, 0, &p, sizeof(p));
  1265. }
  1266.  
  1267. void CShop::Remove()
  1268. {
  1269. if (!HasOwner())
  1270. return;
  1271.  
  1272. m_bIsLocked = true;
  1273.  
  1274. TOfflineShopTable p;
  1275. memset(&p, 0, sizeof(p));
  1276.  
  1277. p.dwAID = m_dwOwnerAID;
  1278. p.dwPID = m_dwOwnerPID;
  1279.  
  1280. p.dwX = m_pkPC->GetX();
  1281. p.dwY = m_pkPC->GetY();
  1282. p.dwMapIndex = m_pkPC->GetMapIndex();
  1283.  
  1284. p.dwChannel = g_bChannel;
  1285.  
  1286. p.ullMoney = m_Money;
  1287. p.dwSize = m_bSize;
  1288. p.dwColor = m_bColor;
  1289.  
  1290. strlcpy(p.szSign, m_pkPC->GetShopSign().c_str(), sizeof(p.szSign));
  1291.  
  1292. for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  1293. {
  1294. SHOP_ITEM& item = m_itemVector[i];
  1295.  
  1296. if (item.pkItem == NULL)
  1297. continue;
  1298.  
  1299. p.items2[i] = item.itemid;
  1300. p.price[i] = item.price;
  1301. p.price2[i] = item.price2;
  1302. p.price3[i] = item.price3;
  1303. p.price4[i] = item.price4;
  1304.  
  1305. item.pkItem->SetWindow(SAFEBOX_OFFLINE_SHOP);
  1306. ITEM_MANAGER::instance().SaveSingleItem(item.pkItem);
  1307.  
  1308. item.pkItem->SetSkipSave(true);
  1309. if (item.pkItem)
  1310. M2_DESTROY_ITEM(item.pkItem);
  1311.  
  1312. memset(&item, 0, sizeof(item));
  1313. }
  1314.  
  1315. db_clientdesc->DBPacket(HEADER_GD_OFFLINE_SHOP_REMOVE, 0, &p, sizeof(p));
  1316. }
  1317. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement