Advertisement
Guest User

Untitled

a guest
Jan 24th, 2017
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.10 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.  
  22. /* ------------------------------------------------------------------------------------ */
  23. CShop::CShop()
  24. : m_dwVnum(0), m_dwNPCVnum(0), m_pkPC(NULL)
  25. {
  26. m_pGrid = M2_NEW CGrid(10, 9);
  27. }
  28.  
  29. CShop::~CShop()
  30. {
  31. TPacketGCShop pack;
  32.  
  33. pack.header = HEADER_GC_SHOP;
  34. pack.subheader = SHOP_SUBHEADER_GC_END;
  35. pack.size = sizeof(TPacketGCShop);
  36.  
  37. Broadcast(&pack, sizeof(pack));
  38.  
  39. GuestMapType::iterator it;
  40.  
  41. it = m_map_guest.begin();
  42.  
  43. while (it != m_map_guest.end())
  44. {
  45. LPCHARACTER ch = it->first;
  46. ch->SetShop(NULL);
  47. ++it;
  48. }
  49.  
  50. M2_DELETE(m_pGrid);
  51. }
  52.  
  53. void CShop::SetPCShop(LPCHARACTER ch)
  54. {
  55. m_pkPC = ch;
  56. }
  57.  
  58. bool CShop::Create(DWORD dwVnum, DWORD dwNPCVnum, TShopItemTable * pTable)
  59. {
  60. /*
  61. if (NULL == CMobManager::instance().Get(dwNPCVnum))
  62. {
  63. sys_err("No such a npc by vnum %d", dwNPCVnum);
  64. return false;
  65. }
  66. */
  67. sys_log(0, "SHOP #%d (Shopkeeper %d)", dwVnum, dwNPCVnum);
  68.  
  69. m_dwVnum = dwVnum;
  70. m_dwNPCVnum = dwNPCVnum;
  71.  
  72. BYTE bItemCount;
  73.  
  74. for (bItemCount = 0; bItemCount < SHOP_HOST_ITEM_MAX_NUM; ++bItemCount)
  75. if (0 == (pTable + bItemCount)->vnum)
  76. break;
  77.  
  78. SetShopItems(pTable, bItemCount);
  79. return true;
  80. }
  81.  
  82. void CShop::SetShopItems(TShopItemTable * pTable, BYTE bItemCount)
  83. {
  84. if (bItemCount > SHOP_HOST_ITEM_MAX_NUM)
  85. return;
  86.  
  87. m_pGrid->Clear();
  88.  
  89. m_itemVector.resize(SHOP_HOST_ITEM_MAX_NUM);
  90. memset(&m_itemVector[0], 0, sizeof(SHOP_ITEM) * m_itemVector.size());
  91.  
  92. for (int i = 0; i < bItemCount; ++i)
  93. {
  94. LPITEM pkItem = NULL;
  95. const TItemTable * item_table;
  96.  
  97. if (m_pkPC)
  98. {
  99. pkItem = m_pkPC->GetItem(pTable->pos);
  100.  
  101. if (!pkItem)
  102. {
  103. sys_err("cannot find item on pos (%d, %d) (name: %s)", pTable->pos.window_type, pTable->pos.cell, m_pkPC->GetName());
  104. continue;
  105. }
  106.  
  107. item_table = pkItem->GetProto();
  108. }
  109. else
  110. {
  111. if (!pTable->vnum)
  112. continue;
  113.  
  114. item_table = ITEM_MANAGER::instance().GetTable(pTable->vnum);
  115. }
  116.  
  117. if (!item_table)
  118. {
  119. sys_err("Shop: no item table by item vnum #%d", pTable->vnum);
  120. continue;
  121. }
  122.  
  123. int iPos;
  124.  
  125. if (IsPCShop())
  126. {
  127. sys_log(0, "MyShop: use position %d", pTable->display_pos);
  128. iPos = pTable->display_pos;
  129. }
  130. else
  131. iPos = m_pGrid->FindBlank(1, item_table->bSize);
  132.  
  133. if (iPos < 0)
  134. {
  135. sys_err("not enough shop window");
  136. continue;
  137. }
  138.  
  139. if (!m_pGrid->IsEmpty(iPos, 1, item_table->bSize))
  140. {
  141. if (IsPCShop())
  142. {
  143. sys_err("not empty position for pc shop %s[%d]", m_pkPC->GetName(), m_pkPC->GetPlayerID());
  144. }
  145. else
  146. {
  147. sys_err("not empty position for npc shop");
  148. }
  149. continue;
  150. }
  151.  
  152. m_pGrid->Put(iPos, 1, item_table->bSize);
  153.  
  154. SHOP_ITEM & item = m_itemVector[iPos];
  155.  
  156. item.pkItem = pkItem;
  157. item.itemid = 0;
  158.  
  159. if (item.pkItem)
  160. {
  161. item.vnum = pkItem->GetVnum();
  162. item.count = pkItem->GetCount(); // PC ¼¥ÀÇ °æ¿ì ¾ÆÀÌÅÛ °³¼ö´Â ÁøÂ¥ ¾ÆÀÌÅÛÀÇ °³¼ö¿©¾ß ÇÑ´Ù.
  163. item.price = pTable->price; // °¡°Ýµµ »ç¿ëÀÚ°¡ Á¤ÇÑ´ë·Î..
  164. item.itemid = pkItem->GetID();
  165. }
  166. else
  167. {
  168. item.vnum = pTable->vnum;
  169. item.count = pTable->count;
  170.  
  171. if (IS_SET(item_table->dwFlags, ITEM_FLAG_COUNT_PER_1GOLD))
  172. {
  173. if (item_table->dwGold == 0)
  174. item.price = item.count;
  175. else
  176. item.price = item.count / item_table->dwGold;
  177. }
  178. else
  179. item.price = item_table->dwGold * item.count;
  180. }
  181.  
  182. char name[36];
  183. snprintf(name, sizeof(name), "%-20s(#%-5d) (x %d)", item_table->szName, (int) item.vnum, item.count);
  184.  
  185. sys_log(0, "SHOP_ITEM: %-36s PRICE %-5d", name, item.price);
  186. ++pTable;
  187. }
  188. }
  189.  
  190. long long CShop::Buy(LPCHARACTER ch, BYTE pos)
  191. {
  192. if (pos >= m_itemVector.size())
  193. {
  194. sys_log(0, "Shop::Buy : invalid position %d : %s", pos, ch->GetName());
  195. return SHOP_SUBHEADER_GC_INVALID_POS;
  196. }
  197.  
  198. sys_log(0, "Shop::Buy : name %s pos %d", ch->GetName(), pos);
  199.  
  200. GuestMapType::iterator it = m_map_guest.find(ch);
  201.  
  202. if (it == m_map_guest.end())
  203. return SHOP_SUBHEADER_GC_END;
  204.  
  205. SHOP_ITEM& r_item = m_itemVector[pos];
  206.  
  207. if (r_item.price < 0)
  208. {
  209. LogManager::instance().HackLog("SHOP_BUY_GOLD_OVERFLOW", ch);
  210. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
  211. }
  212.  
  213. LPITEM pkSelectedItem = ITEM_MANAGER::instance().Find(r_item.itemid);
  214.  
  215. if (IsPCShop())
  216. {
  217. if (!pkSelectedItem)
  218. {
  219. sys_log(0, "Shop::Buy : Critical: This user seems to be a hacker : invalid pcshop item : BuyerPID:%d SellerPID:%d",
  220. ch->GetPlayerID(),
  221. m_pkPC->GetPlayerID());
  222.  
  223. return false;
  224. }
  225.  
  226. if ((pkSelectedItem->GetOwner() != m_pkPC))
  227. {
  228. sys_log(0, "Shop::Buy : Critical: This user seems to be a hacker : invalid pcshop item : BuyerPID:%d SellerPID:%d",
  229. ch->GetPlayerID(),
  230. m_pkPC->GetPlayerID());
  231.  
  232. return false;
  233. }
  234. }
  235.  
  236. long long dwPrice = r_item.price;
  237.  
  238. if (it->second) // if other empire, price is triple
  239. dwPrice *= 1;
  240.  
  241. if (ch->GetGold() < (long long) dwPrice)
  242. {
  243. sys_log(1, "Shop::Buy : Not enough money : %s has %lld, price %lld", ch->GetName(), ch->GetGold(), dwPrice);
  244. return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
  245. }
  246.  
  247. LPITEM item;
  248.  
  249. if (m_pkPC) // ÇǾ¾°¡ ¿î¿µÇÏ´Â ¼¥Àº ÇǾ¾°¡ ½ÇÁ¦ ¾ÆÀÌÅÛÀ» °¡Áö°íÀÖ¾î¾ß ÇÑ´Ù.
  250. item = r_item.pkItem;
  251. else
  252. item = ITEM_MANAGER::instance().CreateItem(r_item.vnum, r_item.count);
  253.  
  254. if (!item)
  255. return SHOP_SUBHEADER_GC_SOLD_OUT;
  256.  
  257. int iEmptyPos;
  258. if (item->IsDragonSoul())
  259. {
  260. iEmptyPos = ch->GetEmptyDragonSoulInventory(item);
  261. }
  262. else
  263. {
  264. iEmptyPos = ch->GetEmptyInventory(item->GetSize());
  265. }
  266.  
  267. if (iEmptyPos < 0)
  268. {
  269. if (m_pkPC)
  270. {
  271. sys_log(1, "Shop::Buy at PC Shop : Inventory full : %s size %d", ch->GetName(), item->GetSize());
  272. return SHOP_SUBHEADER_GC_INVENTORY_FULL;
  273. }
  274. else
  275. {
  276. sys_log(1, "Shop::Buy : Inventory full : %s size %d", ch->GetName(), item->GetSize());
  277. M2_DESTROY_ITEM(item);
  278. return SHOP_SUBHEADER_GC_INVENTORY_FULL;
  279. }
  280. }
  281.  
  282. ch->PointChange(POINT_GOLD, -dwPrice, false);
  283.  
  284. //¼¼±Ý °è»ê
  285. DWORD dwTax = 0;
  286. int iVal = 0;
  287.  
  288. if (LC_IsYMIR() || LC_IsKorea())
  289. {
  290. if (0 < (iVal = quest::CQuestManager::instance().GetEventFlag("trade_tax")))
  291. {
  292. if (iVal > 100)
  293. iVal = 100;
  294.  
  295. dwTax = dwPrice * iVal / 100;
  296. dwPrice = dwPrice - dwTax;
  297. }
  298. else
  299. {
  300. iVal = 0;
  301. dwTax = dwPrice * iVal / 100;
  302. dwPrice = dwPrice - dwTax;
  303. }
  304. }
  305. else
  306. {
  307. iVal = quest::CQuestManager::instance().GetEventFlag("personal_shop");
  308.  
  309. if (0 < iVal)
  310. {
  311. if (iVal > 100)
  312. iVal = 100;
  313.  
  314. dwTax = dwPrice * iVal / 100;
  315. dwPrice = dwPrice - dwTax;
  316. }
  317. else
  318. {
  319. iVal = 0;
  320. dwTax = 0;
  321. }
  322. }
  323.  
  324. // »óÁ¡¿¡¼­ »ì‹š ¼¼±Ý 5%
  325. if (!m_pkPC)
  326. {
  327. CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch);
  328. }
  329.  
  330. // ±ºÁÖ ½Ã½ºÅÛ : ¼¼±Ý ¡¼ö
  331. if (m_pkPC)
  332. {
  333. m_pkPC->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
  334.  
  335. if (item->GetVnum() == 90008 || item->GetVnum() == 90009) // VCARD
  336. {
  337. VCardUse(m_pkPC, ch, item);
  338. item = NULL;
  339. }
  340. else
  341. {
  342. char buf[512];
  343.  
  344. if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
  345. {
  346. snprintf(buf, sizeof(buf), "%s FROM: %u TO: %u PRICE: %u", item->GetName(), ch->GetPlayerID(), m_pkPC->GetPlayerID(), dwPrice);
  347. LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), SHOP_BUY, buf);
  348. LogManager::instance().GoldBarLog(m_pkPC->GetPlayerID(), item->GetID(), SHOP_SELL, buf);
  349. }
  350.  
  351. item->RemoveFromCharacter();
  352. if (item->IsDragonSoul())
  353. item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
  354. else
  355. item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  356. ITEM_MANAGER::instance().FlushDelayedSave(item);
  357.  
  358.  
  359. snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), m_pkPC->GetPlayerID(), m_pkPC->GetName(), dwPrice, item->GetCount());
  360. LogManager::instance().ItemLog(ch, item, "SHOP_BUY", buf);
  361.  
  362. snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), ch->GetPlayerID(), ch->GetName(), dwPrice, item->GetCount());
  363. LogManager::instance().ItemLog(m_pkPC, item, "SHOP_SELL", buf);
  364. }
  365.  
  366. r_item.pkItem = NULL;
  367. BroadcastUpdateItem(pos);
  368.  
  369. m_pkPC->PointChange(POINT_GOLD, dwPrice, false);
  370.  
  371. if (iVal > 0)
  372. m_pkPC->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÆǸűݾ×ÀÇ %d %% °¡ ¼¼±ÝÀ¸·Î ³ª°¡°ÔµË´Ï´Ù"), iVal);
  373.  
  374. CMonarch::instance().SendtoDBAddMoney(dwTax, m_pkPC->GetEmpire(), m_pkPC);
  375. }
  376. else
  377. {
  378. if (item->IsDragonSoul())
  379. item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
  380. else
  381. item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  382. ITEM_MANAGER::instance().FlushDelayedSave(item);
  383. LogManager::instance().ItemLog(ch, item, "BUY", item->GetName());
  384.  
  385. if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
  386. {
  387. LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), PERSONAL_SHOP_BUY, "");
  388. }
  389.  
  390. DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), -dwPrice);
  391. }
  392.  
  393. if (item)
  394. sys_log(0, "SHOP: BUY: name %s %s(x %d):%u price %u", ch->GetName(), item->GetName(), item->GetCount(), item->GetID(), dwPrice);
  395.  
  396. ch->Save();
  397.  
  398. return (SHOP_SUBHEADER_GC_OK);
  399. }
  400.  
  401. bool CShop::AddGuest(LPCHARACTER ch, DWORD owner_vid, bool bOtherEmpire)
  402. {
  403. if (!ch)
  404. return false;
  405.  
  406. if (ch->GetExchange())
  407. return false;
  408.  
  409. if (ch->GetShop())
  410. return false;
  411.  
  412. ch->SetShop(this);
  413.  
  414. m_map_guest.insert(GuestMapType::value_type(ch, bOtherEmpire));
  415.  
  416. TPacketGCShop pack;
  417.  
  418. pack.header = HEADER_GC_SHOP;
  419. pack.subheader = SHOP_SUBHEADER_GC_START;
  420.  
  421. TPacketGCShopStart pack2;
  422.  
  423. memset(&pack2, 0, sizeof(pack2));
  424. pack2.owner_vid = owner_vid;
  425.  
  426. for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  427. {
  428. const SHOP_ITEM & item = m_itemVector[i];
  429.  
  430. if (m_pkPC && !item.pkItem)
  431. continue;
  432.  
  433. pack2.items[i].vnum = item.vnum;
  434.  
  435. if (bOtherEmpire) // no empire price penalty for pc shop
  436. pack2.items[i].price = item.price * 1;
  437. else
  438. pack2.items[i].price = item.price;
  439.  
  440. pack2.items[i].count = item.count;
  441.  
  442. if (item.pkItem)
  443. {
  444. thecore_memcpy(pack2.items[i].alSockets, item.pkItem->GetSockets(), sizeof(pack2.items[i].alSockets));
  445. thecore_memcpy(pack2.items[i].aAttr, item.pkItem->GetAttributes(), sizeof(pack2.items[i].aAttr));
  446. }
  447. }
  448.  
  449. pack.size = sizeof(pack) + sizeof(pack2);
  450.  
  451. ch->GetDesc()->BufferedPacket(&pack, sizeof(TPacketGCShop));
  452. ch->GetDesc()->Packet(&pack2, sizeof(TPacketGCShopStart));
  453. return true;
  454. }
  455.  
  456. void CShop::RemoveGuest(LPCHARACTER ch)
  457. {
  458. if (ch->GetShop() != this)
  459. return;
  460.  
  461. m_map_guest.erase(ch);
  462. ch->SetShop(NULL);
  463.  
  464. TPacketGCShop pack;
  465.  
  466. pack.header = HEADER_GC_SHOP;
  467. pack.subheader = SHOP_SUBHEADER_GC_END;
  468. pack.size = sizeof(TPacketGCShop);
  469.  
  470. ch->GetDesc()->Packet(&pack, sizeof(pack));
  471. }
  472.  
  473. void CShop::Broadcast(const void * data, int bytes)
  474. {
  475. sys_log(1, "Shop::Broadcast %p %d", data, bytes);
  476.  
  477. GuestMapType::iterator it;
  478.  
  479. it = m_map_guest.begin();
  480.  
  481. while (it != m_map_guest.end())
  482. {
  483. LPCHARACTER ch = it->first;
  484.  
  485. if (ch->GetDesc())
  486. ch->GetDesc()->Packet(data, bytes);
  487.  
  488. ++it;
  489. }
  490. }
  491.  
  492. void CShop::BroadcastUpdateItem(BYTE pos)
  493. {
  494. TPacketGCShop pack;
  495. TPacketGCShopUpdateItem pack2;
  496.  
  497. TEMP_BUFFER buf;
  498.  
  499. pack.header = HEADER_GC_SHOP;
  500. pack.subheader = SHOP_SUBHEADER_GC_UPDATE_ITEM;
  501. pack.size = sizeof(pack) + sizeof(pack2);
  502.  
  503. pack2.pos = pos;
  504.  
  505. if (m_pkPC && !m_itemVector[pos].pkItem)
  506. pack2.item.vnum = 0;
  507. else
  508. {
  509. pack2.item.vnum = m_itemVector[pos].vnum;
  510. if (m_itemVector[pos].pkItem)
  511. {
  512. thecore_memcpy(pack2.item.alSockets, m_itemVector[pos].pkItem->GetSockets(), sizeof(pack2.item.alSockets));
  513. thecore_memcpy(pack2.item.aAttr, m_itemVector[pos].pkItem->GetAttributes(), sizeof(pack2.item.aAttr));
  514. }
  515. else
  516. {
  517. memset(pack2.item.alSockets, 0, sizeof(pack2.item.alSockets));
  518. memset(pack2.item.aAttr, 0, sizeof(pack2.item.aAttr));
  519. }
  520. }
  521.  
  522. pack2.item.price = m_itemVector[pos].price;
  523. pack2.item.count = m_itemVector[pos].count;
  524.  
  525. buf.write(&pack, sizeof(pack));
  526. buf.write(&pack2, sizeof(pack2));
  527.  
  528. Broadcast(buf.read_peek(), buf.size());
  529. }
  530.  
  531. int CShop::GetNumberByVnum(DWORD dwVnum)
  532. {
  533. int itemNumber = 0;
  534.  
  535. for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  536. {
  537. const SHOP_ITEM & item = m_itemVector[i];
  538.  
  539. if (item.vnum == dwVnum)
  540. {
  541. itemNumber += item.count;
  542. }
  543. }
  544.  
  545. return itemNumber;
  546. }
  547.  
  548. bool CShop::IsSellingItem(DWORD itemID)
  549. {
  550. bool isSelling = false;
  551.  
  552. for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
  553. {
  554. if (m_itemVector[i].itemid == itemID)
  555. {
  556. isSelling = true;
  557. break;
  558. }
  559. }
  560.  
  561. return isSelling;
  562.  
  563. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement