Guest User

Untitled

a guest
Sep 5th, 2020
12
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "stdafx.h"
  2. #include "../../libgame/include/grid.h"
  3. #include "utils.h"
  4. #include "desc.h"
  5. #include "desc_client.h"
  6. #include "char.h"
  7. #include "item.h"
  8. #include "item_manager.h"
  9. #include "packet.h"
  10. #include "log.h"
  11. #include "db.h"
  12. #include "locale_service.h"
  13. #include "../../common/length.h"
  14. #include "exchange.h"
  15. #include "DragonSoul.h"
  16. #ifdef NEW_PET_SYSTEM
  17. #include "New_PetSystem.h"
  18. #endif
  19.  
  20.  
  21. void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, long long arg1, TItemPos arg2, DWORD arg3, void * pvData = NULL);
  22.  
  23. // 교환 패킷
  24. void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, long long arg1, TItemPos arg2, DWORD arg3, void * pvData)
  25. {
  26. if (!ch->GetDesc())
  27. return;
  28.  
  29. struct packet_exchange pack_exchg;
  30.  
  31. pack_exchg.header = HEADER_GC_EXCHANGE;
  32. pack_exchg.sub_header = sub_header;
  33. pack_exchg.is_me = is_me;
  34. pack_exchg.arg1 = arg1;
  35. pack_exchg.arg2 = arg2;
  36. pack_exchg.arg3 = arg3;
  37.  
  38. if (sub_header == EXCHANGE_SUBHEADER_GC_ITEM_ADD && pvData)
  39. {
  40. thecore_memcpy(&pack_exchg.alSockets, ((LPITEM) pvData)->GetSockets(), sizeof(pack_exchg.alSockets));
  41. thecore_memcpy(&pack_exchg.aAttr, ((LPITEM) pvData)->GetAttributes(), sizeof(pack_exchg.aAttr));
  42. }
  43. else
  44. {
  45. memset(&pack_exchg.alSockets, 0, sizeof(pack_exchg.alSockets));
  46. memset(&pack_exchg.aAttr, 0, sizeof(pack_exchg.aAttr));
  47. }
  48.  
  49. ch->GetDesc()->Packet(&pack_exchg, sizeof(pack_exchg));
  50. }
  51.  
  52. // 교환을 시작
  53. bool CHARACTER::ExchangeStart(LPCHARACTER victim)
  54. {
  55. if (this == victim) // 자기 자신과는 교환을 못한다.
  56. return false;
  57.  
  58. if (IsObserverMode())
  59. {
  60. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관전 상태에서는 교환을 할 수 없습니다."));
  61. return false;
  62. }
  63.  
  64. if (victim->IsNPC())
  65. return false;
  66.  
  67. //PREVENT_TRADE_WINDOW
  68. if ( IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen())
  69. {
  70. ChatPacket( CHAT_TYPE_INFO, LC_TEXT("다른 거래창이 열려있을경우 거래를 할수 없습니다." ) );
  71. return false;
  72. }
  73.  
  74.  
  75. #ifdef NEW_PET_SYSTEM
  76. if (GetNewPetSystem()->IsActivePet())
  77. {
  78. ChatPacket( CHAT_TYPE_INFO, LC_TEXT("not open exchange window when new pet"));
  79. return false;
  80. }
  81.  
  82. if (victim->GetNewPetSystem()->IsActivePet())
  83. {
  84. ChatPacket( CHAT_TYPE_INFO, LC_TEXT("not open victim exchange window when new pet"));
  85. return false;
  86. }
  87. #endif
  88.  
  89. if ( victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() )
  90. {
  91. ChatPacket( CHAT_TYPE_INFO, LC_TEXT("상대방이 다른 거래중이라 거래를 할수 없습니다." ) );
  92. return false;
  93. }
  94. //END_PREVENT_TRADE_WINDOW
  95. int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY());
  96.  
  97. // 거리 체크
  98. if (iDist >= EXCHANGE_MAX_DISTANCE)
  99. return false;
  100.  
  101. if (GetExchange())
  102. return false;
  103.  
  104. if (victim->GetExchange())
  105. {
  106. exchange_packet(this, EXCHANGE_SUBHEADER_GC_ALREADY, 0, 0, NPOS, 0);
  107. return false;
  108. }
  109.  
  110. if (victim->IsBlockMode(BLOCK_EXCHANGE))
  111. {
  112. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방이 교환 거부 상태입니다."));
  113. return false;
  114. }
  115.  
  116. SetExchange(M2_NEW CExchange(this));
  117. victim->SetExchange(M2_NEW CExchange(victim));
  118.  
  119. victim->GetExchange()->SetCompany(GetExchange());
  120. GetExchange()->SetCompany(victim->GetExchange());
  121.  
  122. //
  123. SetExchangeTime();
  124. victim->SetExchangeTime();
  125.  
  126. exchange_packet(victim, EXCHANGE_SUBHEADER_GC_START, 0, GetVID(), NPOS, 0);
  127. exchange_packet(this, EXCHANGE_SUBHEADER_GC_START, 0, victim->GetVID(), NPOS, 0);
  128.  
  129. return true;
  130. }
  131.  
  132. CExchange::CExchange(LPCHARACTER pOwner)
  133. {
  134. m_pCompany = NULL;
  135.  
  136. m_bAccept = false;
  137.  
  138. for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
  139. {
  140. m_apItems[i] = NULL;
  141. m_aItemPos[i] = NPOS;
  142. m_abItemDisplayPos[i] = 0;
  143. }
  144.  
  145. m_lGold = 0;
  146.  
  147. m_pOwner = pOwner;
  148. pOwner->SetExchange(this);
  149.  
  150. m_pGrid = M2_NEW CGrid(4,3);
  151. }
  152.  
  153. CExchange::~CExchange()
  154. {
  155. M2_DELETE(m_pGrid);
  156. }
  157.  
  158. bool CExchange::AddItem(TItemPos item_pos, BYTE display_pos)
  159. {
  160. assert(m_pOwner != NULL && GetCompany());
  161.  
  162. if (!item_pos.IsValidItemPosition())
  163. return false;
  164.  
  165. // 장비는 교환할 수 없음
  166. if (item_pos.IsEquipPosition())
  167. return false;
  168.  
  169. LPITEM item;
  170.  
  171. if (!(item = m_pOwner->GetItem(item_pos)))
  172. return false;
  173.  
  174. if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_GIVE))
  175. {
  176. m_pOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템을 건네줄 수 없습니다."));
  177. return false;
  178. }
  179.  
  180. if (true == item->isLocked())
  181. {
  182. return false;
  183. }
  184.  
  185. // 이미 교환창에 추가된 아이템인가?
  186. if (item->IsExchanging())
  187. {
  188. sys_log(0, "EXCHANGE under exchanging");
  189. return false;
  190. }
  191.  
  192. if (!m_pGrid->IsEmpty(display_pos, 1, item->GetSize()))
  193. {
  194. sys_log(0, "EXCHANGE not empty item_pos %d %d %d", display_pos, 1, item->GetSize());
  195. return false;
  196. }
  197.  
  198. Accept(false);
  199. GetCompany()->Accept(false);
  200.  
  201. for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
  202. {
  203. if (m_apItems[i])
  204. continue;
  205.  
  206. m_apItems[i] = item;
  207. m_aItemPos[i] = item_pos;
  208. m_abItemDisplayPos[i] = display_pos;
  209. m_pGrid->Put(display_pos, 1, item->GetSize());
  210.  
  211. item->SetExchanging(true);
  212.  
  213. exchange_packet(m_pOwner,
  214. EXCHANGE_SUBHEADER_GC_ITEM_ADD,
  215. true,
  216. item->GetVnum(),
  217. TItemPos(RESERVED_WINDOW, display_pos),
  218. item->GetCount(),
  219. item);
  220.  
  221. exchange_packet(GetCompany()->GetOwner(),
  222. EXCHANGE_SUBHEADER_GC_ITEM_ADD,
  223. false,
  224. item->GetVnum(),
  225. TItemPos(RESERVED_WINDOW, display_pos),
  226. item->GetCount(),
  227. item);
  228.  
  229. sys_log(0, "EXCHANGE AddItem success %s pos(%d, %d) %d", item->GetName(), item_pos.window_type, item_pos.cell, display_pos);
  230.  
  231. return true;
  232. }
  233.  
  234. // 추가할 공간이 없음
  235. return false;
  236. }
  237.  
  238. bool CExchange::RemoveItem(BYTE pos)
  239. {
  240. if (pos >= EXCHANGE_ITEM_MAX_NUM)
  241. return false;
  242.  
  243. if (!m_apItems[pos])
  244. return false;
  245.  
  246. TItemPos PosOfInventory = m_aItemPos[pos];
  247. m_apItems[pos]->SetExchanging(false);
  248.  
  249. m_pGrid->Get(m_abItemDisplayPos[pos], 1, m_apItems[pos]->GetSize());
  250.  
  251. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_DEL, true, pos, NPOS, 0);
  252. exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_DEL, false, pos, PosOfInventory, 0);
  253.  
  254. Accept(false);
  255. GetCompany()->Accept(false);
  256.  
  257. m_apItems[pos] = NULL;
  258. m_aItemPos[pos] = NPOS;
  259. m_abItemDisplayPos[pos] = 0;
  260. return true;
  261. }
  262.  
  263. bool CExchange::AddGold(long long gold)
  264. {
  265. if (gold <= 0)
  266. return false;
  267.  
  268. if (GetOwner()->GetGold() < gold)
  269. {
  270. // 가지고 있는 돈이 부족.
  271. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0);
  272. return false;
  273. }
  274.  
  275. if ( LC_IsCanada() == true || LC_IsEurope() == true )
  276. {
  277. if ( m_lGold > 0 )
  278. {
  279. return false;
  280. }
  281. }
  282.  
  283. Accept(false);
  284. GetCompany()->Accept(false);
  285.  
  286. m_lGold = gold;
  287.  
  288. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, true, m_lGold, NPOS, 0);
  289. exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, false, m_lGold, NPOS, 0);
  290. return true;
  291. }
  292.  
  293. // 돈이 충분히 있는지, 교환하려는 아이템이 실제로 있는지 확인 한다.
  294. bool CExchange::Check(int * piItemCount)
  295. {
  296. if (GetOwner()->GetGold() < m_lGold)
  297. return false;
  298.  
  299. int item_count = 0;
  300.  
  301. for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
  302. {
  303. if (!m_apItems[i])
  304. continue;
  305.  
  306. if (!m_aItemPos[i].IsValidItemPosition())
  307. return false;
  308.  
  309. if (m_apItems[i] != GetOwner()->GetItem(m_aItemPos[i]))
  310. return false;
  311.  
  312. ++item_count;
  313. }
  314.  
  315. *piItemCount = item_count;
  316. return true;
  317. }
  318.  
  319. #ifdef ENABLE_SPECIAL_STORAGE
  320. bool CExchange::CheckSpecialStorageSpace(BYTE bStorageType)
  321. {
  322. static CGrid s_grid1(5, SPECIAL_INVENTORY_MAX_NUM/5 / 2);
  323. static CGrid s_grid2(5, SPECIAL_INVENTORY_MAX_NUM/5 / 2);
  324.  
  325. s_grid1.Clear();
  326. s_grid2.Clear();
  327.  
  328. LPCHARACTER victim = GetCompany()->GetOwner();
  329. LPITEM item;
  330.  
  331. int i;
  332.  
  333. for (i = 0; i < SPECIAL_INVENTORY_MAX_NUM / 2; ++i)
  334. {
  335. if(bStorageType < 0 || bStorageType > 3)
  336. continue;
  337.  
  338. if(bStorageType == 0)
  339. item = victim->GetUpgradeInventoryItem(i);
  340. else if(bStorageType == 1)
  341. item = victim->GetBookInventoryItem(i);
  342. else if(bStorageType == 2)
  343. item = victim->GetStoneInventoryItem(i);
  344. else if(bStorageType == 3)
  345. item = victim->GetETCInventoryItem(i);
  346.  
  347. if(!item)
  348. continue;
  349.  
  350. s_grid1.Put(i, 1, item->GetSize());
  351. }
  352. for (i = SPECIAL_INVENTORY_MAX_NUM / 2; i < SPECIAL_INVENTORY_MAX_NUM; ++i)
  353. {
  354. if(bStorageType < 0 || bStorageType > 3)
  355. continue;
  356.  
  357. if(bStorageType == 0)
  358. item = victim->GetUpgradeInventoryItem(i);
  359. else if(bStorageType == 1)
  360. item = victim->GetBookInventoryItem(i);
  361. else if(bStorageType == 2)
  362. item = victim->GetStoneInventoryItem(i);
  363. else if(bStorageType == 3)
  364. item = victim->GetETCInventoryItem(i);
  365.  
  366. if(!item)
  367. continue;
  368.  
  369. s_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item->GetSize());
  370. }
  371.  
  372. for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
  373. {
  374. if (!(item = m_apItems[i]))
  375. continue;
  376.  
  377. if(bStorageType < 0 || bStorageType > 3)
  378. continue;
  379.  
  380. if((bStorageType == 0 && (!item->IsUpgradeItem())) || (bStorageType == 1 && (!item->IsBook())) || (bStorageType == 2 && (!item->IsStone())) || (bStorageType == 3 && (!item->IsETC())))
  381. continue;
  382.  
  383. int iPos = s_grid1.FindBlank(1, item->GetSize());
  384.  
  385. if (iPos >= 0)
  386. {
  387. s_grid1.Put(iPos, 1, item->GetSize());
  388. }
  389. else
  390. {
  391. iPos = s_grid2.FindBlank(1, item->GetSize());
  392.  
  393. if (iPos >= 0)
  394. {
  395. s_grid2.Put(iPos, 1, item->GetSize());
  396. }
  397. else
  398. {
  399. return false;
  400. }
  401. }
  402. }
  403.  
  404. return true;
  405. }
  406. #endif
  407.  
  408. bool CExchange::CheckSpace()
  409. {
  410. static CGrid s_grid1(5, INVENTORY_MAX_NUM/5 / 2); // oldal 1
  411. static CGrid s_grid2(5, INVENTORY_MAX_NUM/5 / 2); // oldal 2
  412. static CGrid s_grid3(5, INVENTORY_MAX_NUM/5 / 2); // oldal 3
  413. static CGrid s_grid4(5, INVENTORY_MAX_NUM/5 / 2); // oldal 4
  414.  
  415. s_grid1.Clear();
  416. s_grid2.Clear();
  417. s_grid3.Clear();
  418. s_grid4.Clear();
  419.  
  420. LPCHARACTER victim = GetCompany()->GetOwner();
  421. LPITEM item;
  422.  
  423. int i;
  424.  
  425. for (i = 0; i < INVENTORY_MAX_NUM / 4; ++i)
  426. {
  427. if (!(item = victim->GetInventoryItem(i)))
  428. continue;
  429.  
  430. s_grid1.Put(i, 1, item->GetSize());
  431. }
  432. for (i = INVENTORY_MAX_NUM / 4; i < INVENTORY_MAX_NUM; ++i)
  433. {
  434. if (!(item = victim->GetInventoryItem(i)))
  435. continue;
  436.  
  437. s_grid2.Put(i - INVENTORY_MAX_NUM / 4, 1, item->GetSize());
  438. }
  439.  
  440. for (i = INVENTORY_MAX_NUM / 4; i < INVENTORY_MAX_NUM; ++i)
  441. {
  442. if (!(item = victim->GetInventoryItem(i)))
  443. continue;
  444.  
  445. s_grid3.Put(i - INVENTORY_MAX_NUM / 4, 1, item->GetSize());
  446. }
  447. for (i = INVENTORY_MAX_NUM / 4; i < INVENTORY_MAX_NUM; ++i)
  448. {
  449. if (!(item = victim->GetInventoryItem(i)))
  450. continue;
  451.  
  452. s_grid4.Put(i - INVENTORY_MAX_NUM / 4, 1, item->GetSize());
  453. }
  454.  
  455. // 아... 뭔가 개병신 같지만... 용혼석 인벤을 노멀 인벤 보고 따라 만든 내 잘못이다 ㅠㅠ
  456. static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM);
  457.  
  458. // 일단 용혼석을 교환하지 않을 가능성이 크므로, 용혼석 인벤 복사는 용혼석이 있을 때 하도록 한다.
  459. bool bDSInitialized = false;
  460.  
  461. for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
  462. {
  463. if (!(item = m_apItems[i]))
  464. continue;
  465.  
  466. if (item->IsDragonSoul())
  467. {
  468. if (!victim->DragonSoul_IsQualified())
  469. {
  470. return false;
  471. }
  472.  
  473. if (!bDSInitialized)
  474. {
  475. bDSInitialized = true;
  476. victim->CopyDragonSoulItemGrid(s_vDSGrid);
  477. }
  478.  
  479. bool bExistEmptySpace = false;
  480. WORD wBasePos = DSManager::instance().GetBasePosition(item);
  481. if (wBasePos >= DRAGON_SOUL_INVENTORY_MAX_NUM)
  482. return false;
  483.  
  484. for (int i = 0; i < DRAGON_SOUL_BOX_SIZE; i++)
  485. {
  486. WORD wPos = wBasePos + i;
  487. if (0 == s_vDSGrid[wBasePos])
  488. {
  489. bool bEmpty = true;
  490. for (int j = 1; j < item->GetSize(); j++)
  491. {
  492. if (s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM])
  493. {
  494. bEmpty = false;
  495. break;
  496. }
  497. }
  498. if (bEmpty)
  499. {
  500. for (int j = 0; j < item->GetSize(); j++)
  501. {
  502. s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM] = wPos + 1;
  503. }
  504. bExistEmptySpace = true;
  505. break;
  506. }
  507. }
  508. if (bExistEmptySpace)
  509. break;
  510. }
  511. if (!bExistEmptySpace)
  512. return false;
  513. }
  514. else
  515. {
  516. int iPos = s_grid1.FindBlank(1, item->GetSize());
  517.  
  518. if (iPos >= 0)
  519. {
  520. s_grid1.Put(iPos, 1, item->GetSize());
  521. }
  522. else
  523. {
  524. iPos = s_grid2.FindBlank(1, item->GetSize());
  525.  
  526. if (iPos >= 0)
  527. {
  528. s_grid2.Put(iPos, 1, item->GetSize());
  529. }
  530. else
  531. {
  532. return false;
  533. }
  534. }
  535. }
  536. }
  537.  
  538. return true;
  539. }
  540.  
  541.  
  542.  
  543.  
  544. // 교환 끝 (아이템과 돈 등을 실제로 옮긴다)
  545. bool CExchange::Done()
  546. {
  547. int empty_pos, i;
  548. LPITEM item;
  549.  
  550. LPCHARACTER victim = GetCompany()->GetOwner();
  551.  
  552. for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
  553. {
  554. if (!(item = m_apItems[i]))
  555. continue;
  556.  
  557. if (item->IsDragonSoul())
  558. empty_pos = victim->GetEmptyDragonSoulInventory(item);
  559. #ifdef ENABLE_SPECIAL_STORAGE
  560. else if(item->IsUpgradeItem())
  561. empty_pos = victim->GetEmptyUpgradeInventory(item);
  562. else if(item->IsBook())
  563. empty_pos = victim->GetEmptyBookInventory(item);
  564. else if(item->IsStone())
  565. empty_pos = victim->GetEmptyStoneInventory(item);
  566. else if(item->IsETC())
  567. empty_pos = victim->GetEmptyETCInventory(item);
  568. #endif
  569.  
  570. else
  571. empty_pos = victim->GetEmptyInventory(item->GetSize());
  572.  
  573. if (empty_pos < 0)
  574. {
  575. sys_err("Exchange::Done : Cannot find blank position in inventory %s <-> %s item %s",
  576. m_pOwner->GetName(), victim->GetName(), item->GetName());
  577. continue;
  578. }
  579.  
  580. assert(empty_pos >= 0);
  581.  
  582. if (item->GetVnum() == 90008 || item->GetVnum() == 90009) // VCARD
  583. {
  584. VCardUse(m_pOwner, victim, item);
  585. continue;
  586. }
  587.  
  588. m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
  589.  
  590. item->RemoveFromCharacter();
  591. if (item->IsDragonSoul())
  592. item->AddToCharacter(victim, TItemPos(DRAGON_SOUL_INVENTORY, empty_pos));
  593. #ifdef ENABLE_SPECIAL_STORAGE
  594. else if(item->IsUpgradeItem())
  595. item->AddToCharacter(victim, TItemPos(UPGRADE_INVENTORY, empty_pos));
  596. else if(item->IsBook())
  597. item->AddToCharacter(victim, TItemPos(BOOK_INVENTORY, empty_pos));
  598. else if(item->IsStone())
  599. item->AddToCharacter(victim, TItemPos(STONE_INVENTORY, empty_pos));
  600. else if(item->IsETC())
  601. item->AddToCharacter(victim, TItemPos(ETC_INVENTORY, empty_pos));
  602.  
  603. #endif
  604. else
  605. item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
  606. ITEM_MANAGER::instance().FlushDelayedSave(item);
  607.  
  608. item->SetExchanging(false);
  609. {
  610. char exchange_buf[51];
  611.  
  612. snprintf(exchange_buf, sizeof(exchange_buf), "%s %u %u", item->GetName(), GetOwner()->GetPlayerID(), item->GetCount());
  613. LogManager::instance().ItemLog(victim, item, "EXCHANGE_TAKE", exchange_buf);
  614.  
  615. snprintf(exchange_buf, sizeof(exchange_buf), "%s %u %u", item->GetName(), victim->GetPlayerID(), item->GetCount());
  616. LogManager::instance().ItemLog(GetOwner(), item, "EXCHANGE_GIVE", exchange_buf);
  617.  
  618. if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
  619. {
  620. LogManager::instance().GoldBarLog(victim->GetPlayerID(), item->GetID(), EXCHANGE_TAKE, "");
  621. LogManager::instance().GoldBarLog(GetOwner()->GetPlayerID(), item->GetID(), EXCHANGE_GIVE, "");
  622. }
  623. m_pOwner->CreateFly(FLY_SP_MEDIUM, victim);//ExchangeEffect by andrea49611
  624. for (int i = 0; i < 3; i++){
  625. m_pOwner->CreateFly(FLY_SP_SMALL, victim);
  626. }
  627. }
  628.  
  629. m_apItems[i] = NULL;
  630. }
  631.  
  632. if (m_lGold)
  633. {
  634. GetOwner()->PointChange(POINT_GOLD, -m_lGold, true);
  635. victim->PointChange(POINT_GOLD, m_lGold, true);
  636.  
  637. if (m_lGold > 1000)
  638. {
  639. char exchange_buf[51];
  640. snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", GetOwner()->GetPlayerID(), GetOwner()->GetName());
  641. LogManager::instance().CharLog(victim, m_lGold, "EXCHANGE_GOLD_TAKE", exchange_buf);
  642.  
  643. snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", victim->GetPlayerID(), victim->GetName());
  644. LogManager::instance().CharLog(GetOwner(), m_lGold, "EXCHANGE_GOLD_GIVE", exchange_buf);
  645. }
  646. }
  647.  
  648. m_pGrid->Clear();
  649. return true;
  650. }
  651.  
  652. // 교환을 동의
  653. bool CExchange::Accept(bool bAccept)
  654. {
  655. if (m_bAccept == bAccept)
  656. return true;
  657.  
  658. m_bAccept = bAccept;
  659.  
  660. // 둘 다 동의 했으므로 교환 성립
  661. if (m_bAccept && GetCompany()->m_bAccept)
  662. {
  663. int iItemCount;
  664.  
  665. LPCHARACTER victim = GetCompany()->GetOwner();
  666.  
  667. //PREVENT_PORTAL_AFTER_EXCHANGE
  668. GetOwner()->SetExchangeTime();
  669. victim->SetExchangeTime();
  670. //END_PREVENT_PORTAL_AFTER_EXCHANGE
  671.  
  672. // exchange_check 에서는 교환할 아이템들이 제자리에 있나 확인하고,
  673. // 엘크도 충분히 있나 확인한다, 두번째 인자로 교환할 아이템 개수
  674. // 를 리턴한다.
  675. if (!Check(&iItemCount))
  676. {
  677. GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다."));
  678. victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다."));
  679. goto EXCHANGE_END;
  680. }
  681.  
  682. // 리턴 받은 아이템 개수로 상대방의 소지품에 남은 자리가 있나 확인한다.
  683. if (!CheckSpace())
  684. {
  685. GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
  686. victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
  687. goto EXCHANGE_END;
  688. }
  689.  
  690. // 상대방도 마찬가지로..
  691. if (!GetCompany()->Check(&iItemCount))
  692. {
  693. victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다."));
  694. GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다."));
  695. goto EXCHANGE_END;
  696. }
  697.  
  698. if (!GetCompany()->CheckSpace())
  699. {
  700. victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
  701. GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
  702. goto EXCHANGE_END;
  703. }
  704.  
  705. #ifdef ENABLE_SPECIAL_STORAGE
  706. for(int i = 0; i <= 3; i++)
  707. {
  708. if (!CheckSpecialStorageSpace(i))
  709. {
  710. GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
  711. victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
  712. goto EXCHANGE_END;
  713. }
  714.  
  715. if (!GetCompany()->CheckSpecialStorageSpace(i))
  716. {
  717. victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
  718. GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
  719. goto EXCHANGE_END;
  720. }
  721. }
  722. #endif
  723.  
  724. if (db_clientdesc->GetSocket() == INVALID_SOCKET)
  725. {
  726. sys_err("Cannot use exchange feature while DB cache connection is dead.");
  727. victim->ChatPacket(CHAT_TYPE_INFO, "Unknown error");
  728. GetOwner()->ChatPacket(CHAT_TYPE_INFO, "Unknown error");
  729. goto EXCHANGE_END;
  730. }
  731.  
  732. if (Done())
  733. {
  734. if (m_lGold) // 돈이 있을 ‹š만 저장
  735. GetOwner()->Save();
  736.  
  737. if (GetCompany()->Done())
  738. {
  739. if (GetCompany()->m_lGold) // 돈이 있을 때만 저장
  740. victim->Save();
  741.  
  742. // INTERNATIONAL_VERSION
  743. GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), victim->GetName());
  744. victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), GetOwner()->GetName());
  745. // END_OF_INTERNATIONAL_VERSION
  746. }
  747. }
  748.  
  749. EXCHANGE_END:
  750. Cancel();
  751. return false;
  752. }
  753. else
  754. {
  755. // 아니면 accept에 대한 패킷을 보내자.
  756. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, true, m_bAccept, NPOS, 0);
  757. exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, false, m_bAccept, NPOS, 0);
  758. return true;
  759. }
  760. }
  761.  
  762. // 교환 취소
  763. void CExchange::Cancel()
  764. {
  765. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_END, 0, 0, NPOS, 0);
  766. GetOwner()->SetExchange(NULL);
  767.  
  768. for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
  769. {
  770. if (m_apItems[i])
  771. m_apItems[i]->SetExchanging(false);
  772. }
  773.  
  774. if (GetCompany())
  775. {
  776. GetCompany()->SetCompany(NULL);
  777. GetCompany()->Cancel();
  778. }
  779.  
  780. M2_DELETE(this);
  781. }
  782.  
  783.  
RAW Paste Data