MrP0wers

char_item.cpp

Dec 18th, 2025
34
0
Never
4
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 213.62 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <stack>
  3. #include "utils.h"
  4. #include "config.h"
  5. #include "char.h"
  6. #include "char_manager.h"
  7. #include "item_manager.h"
  8. #include "desc.h"
  9. #include "desc_client.h"
  10. #include "desc_manager.h"
  11. #include "packet.h"
  12. #include "affect.h"
  13. #include "skill.h"
  14. #include "start_position.h"
  15. #include "mob_manager.h"
  16. #include "db.h"
  17. #include "log.h"
  18. #include "pvp.h"
  19. #include "vector.h"
  20. #include "buffer_manager.h"
  21. #include "questmanager.h"
  22. #include "fishing.h"
  23. #include "party.h"
  24. #include "dungeon.h"
  25. #include "refine.h"
  26. #include "unique_item.h"
  27. #include "war_map.h"
  28. #include "xmas_event.h"
  29. #include "marriage.h"
  30. #include "polymorph.h"
  31. #include "blend_item.h"
  32. #include "BattleArena.h"
  33. #include "arena.h"
  34. #include "dev_log.h"
  35. #include "safebox.h"
  36. #include "shop.h"
  37. #include "DragonSoul.h"
  38. #include "buff_on_attributes.h"
  39. #include "belt_inventory_helper.h"
  40.  
  41. #ifdef __SWITCHBOT__
  42. #include "new_switchbot.h"
  43. #endif
  44.  
  45. #ifdef ENABLE_BLOCK_ITEM_MAP
  46. #include "block_items_system.h"
  47. #endif
  48.  
  49. #include "../../common/VnumHelper.h"
  50.  
  51. #define ENABLE_BOOKS_STACKFIX
  52. #define ENABLE_EFFECT_EXTRAPOT
  53.  
  54. const int ITEM_BROKEN_METIN_VNUM = 28960;
  55.  
  56. const DWORD CHARACTER::msc_dwDefaultChangeItemAttrCycle = 10;
  57. const char CHARACTER::msc_szLastChangeItemAttrFlag[] = "Item.LastChangeItemAttr";
  58. const char CHARACTER::msc_szChangeItemAttrCycleFlag[] = "change_itemattr_cycle";
  59.  
  60. const BYTE g_aBuffOnAttrPoints[] = { POINT_ENERGY, POINT_COSTUME_ATTR_BONUS };
  61.  
  62. struct FFindStone
  63. {
  64. std::map<DWORD, LPCHARACTER> m_mapStone;
  65.  
  66. void operator()(LPENTITY pEnt)
  67. {
  68. if (pEnt->IsType(ENTITY_CHARACTER) == true)
  69. {
  70. LPCHARACTER pChar = (LPCHARACTER)pEnt;
  71.  
  72. if (pChar->IsStone() == true)
  73. {
  74. m_mapStone[(DWORD)pChar->GetVID()] = pChar;
  75. }
  76. }
  77. }
  78. };
  79.  
  80. static bool IS_SUMMON_ITEM(int vnum)
  81. {
  82. switch (vnum)
  83. {
  84. case 22000:
  85. case 22010:
  86. case 22011:
  87. case 22020:
  88.  
  89. case ITEM_MARRIAGE_RING:
  90. return true;
  91. }
  92.  
  93. return false;
  94. }
  95.  
  96. static bool IS_MONKEY_DUNGEON(int map_index)
  97. {
  98. switch (map_index)
  99. {
  100. case 5:
  101. case 25:
  102. case 45:
  103. case 108:
  104. case 109:
  105. return true;
  106. }
  107.  
  108. return false;
  109. }
  110.  
  111. bool IS_SUMMONABLE_ZONE(int map_index)
  112. {
  113. if (IS_MONKEY_DUNGEON(map_index))
  114. return false;
  115.  
  116. switch (map_index)
  117. {
  118. case 66 :
  119. case 71 :
  120. case 72 :
  121. case 73 :
  122. case 193 :
  123. case 216 :
  124. case 217 :
  125. case 208 :
  126. return false;
  127. }
  128.  
  129. if (CBattleArena::IsBattleArenaMap(map_index)) return false;
  130.  
  131. if (map_index > 10000) return false;
  132.  
  133. return true;
  134. }
  135.  
  136. bool IS_BOTARYABLE_ZONE(int nMapIndex)
  137. {
  138. switch (nMapIndex)
  139. {
  140. case 1 :
  141. case 3 :
  142. case 21 :
  143. case 23 :
  144. case 41 :
  145. case 43 :
  146. return true;
  147. }
  148.  
  149. return false;
  150. }
  151.  
  152. static bool FN_check_item_socket(LPITEM item)
  153. {
  154. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  155. {
  156. if (item->GetSocket(i) != item->GetProto()->alSockets[i])
  157. return false;
  158. }
  159.  
  160. return true;
  161. }
  162.  
  163. static void FN_copy_item_socket(LPITEM dest, LPITEM src)
  164. {
  165. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  166. {
  167. dest->SetSocket(i, src->GetSocket(i));
  168. }
  169. }
  170.  
  171. static bool FN_check_item_sex(LPCHARACTER ch, LPITEM item)
  172. {
  173. if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_MALE))
  174. {
  175. if (SEX_MALE==GET_SEX(ch))
  176. return false;
  177. }
  178.  
  179. if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_FEMALE))
  180. {
  181. if (SEX_FEMALE==GET_SEX(ch))
  182. return false;
  183. }
  184.  
  185. return true;
  186. }
  187.  
  188. bool CHARACTER::CanHandleItem(bool bSkipCheckRefine, bool bSkipObserver)
  189. {
  190. if (!bSkipObserver)
  191. if (m_bIsObserver)
  192. return false;
  193.  
  194. if (GetMyShop())
  195. return false;
  196.  
  197. if (!bSkipCheckRefine)
  198. if (m_bUnderRefine)
  199. return false;
  200.  
  201. if (IsCubeOpen() || NULL != DragonSoul_RefineWindow_GetOpener())
  202. return false;
  203.  
  204. if (IsWarping())
  205. return false;
  206.  
  207. return true;
  208. }
  209.  
  210. LPITEM CHARACTER::GetInventoryItem(WORD wCell) const
  211. {
  212. return GetItem(TItemPos(INVENTORY, wCell));
  213. }
  214.  
  215. LPITEM CHARACTER::GetItem(TItemPos Cell) const
  216. {
  217. if (!IsValidItemPosition(Cell))
  218. return NULL;
  219.  
  220. WORD wCell = Cell.cell;
  221. BYTE window_type = Cell.window_type;
  222.  
  223. switch (window_type)
  224. {
  225. case INVENTORY:
  226. case EQUIPMENT:
  227. if (wCell >= INVENTORY_AND_EQUIP_SLOT_MAX)
  228. {
  229. sys_err("CHARACTER::GetInventoryItem: invalid item cell %d", wCell);
  230. return NULL;
  231. }
  232.  
  233. return m_pointsInstant.pItems[wCell];
  234.  
  235. case DRAGON_SOUL_INVENTORY:
  236. if (wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
  237. {
  238. sys_err("CHARACTER::GetInventoryItem: invalid DS item cell %d", wCell);
  239. return NULL;
  240. }
  241.  
  242. return m_pointsInstant.pDSItems[wCell];
  243.  
  244. #ifdef __SWITCHBOT__
  245. case SWITCHBOT:
  246. if (wCell >= SWITCHBOT_SLOT_COUNT)
  247. {
  248. sys_err("CHARACTER::GetInventoryItem: invalid switchbot item cell %d", wCell);
  249. return nullptr;
  250. }
  251.  
  252. return m_pointsInstant.pSwitchbotItems[wCell];
  253. #endif
  254.  
  255. default:
  256. return NULL;
  257. }
  258.  
  259. return NULL;
  260. }
  261.  
  262. #ifdef __HIGHLIGHT_SYSTEM__
  263. void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem, bool isHighLight)
  264. #else
  265. void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem)
  266. #endif
  267. {
  268. WORD wCell = Cell.cell;
  269. BYTE window_type = Cell.window_type;
  270.  
  271. if ((unsigned long)((CItem*)pItem) == 0xff || (unsigned long)((CItem*)pItem) == 0xffffffff)
  272. {
  273. sys_err("!!! FATAL ERROR !!! item == 0xff (char: %s cell: %u)", GetName(), wCell);
  274. core_dump();
  275. return;
  276. }
  277.  
  278. if (pItem && pItem->GetOwner())
  279. {
  280. assert(!"GetOwner exist");
  281. return;
  282. }
  283.  
  284. switch(window_type)
  285. {
  286. case INVENTORY:
  287. case EQUIPMENT:
  288. {
  289. if (wCell >= INVENTORY_AND_EQUIP_SLOT_MAX)
  290. {
  291. sys_err("CHARACTER::SetItem: invalid item cell %d", wCell);
  292. return;
  293. }
  294.  
  295. LPITEM pOld = m_pointsInstant.pItems[wCell];
  296.  
  297. if (pOld)
  298. {
  299. if (wCell < INVENTORY_MAX_NUM)
  300. {
  301. for (int i = 0; i < pOld->GetSize(); ++i)
  302. {
  303. int p = wCell + (i * 5);
  304.  
  305. if (p >= INVENTORY_MAX_NUM)
  306. continue;
  307.  
  308. if (m_pointsInstant.pItems[p] && m_pointsInstant.pItems[p] != pOld)
  309. continue;
  310.  
  311. m_pointsInstant.bItemGrid[p] = 0;
  312. }
  313. }
  314.  
  315. else
  316. m_pointsInstant.bItemGrid[wCell] = 0;
  317. }
  318.  
  319. if (pItem)
  320. {
  321. if (wCell < INVENTORY_MAX_NUM)
  322. {
  323. for (int i = 0; i < pItem->GetSize(); ++i)
  324. {
  325. int p = wCell + (i * 5);
  326.  
  327. if (p >= INVENTORY_MAX_NUM)
  328. continue;
  329.  
  330. m_pointsInstant.bItemGrid[p] = wCell + 1;
  331. }
  332. }
  333.  
  334. else
  335. m_pointsInstant.bItemGrid[wCell] = wCell + 1;
  336. }
  337.  
  338. m_pointsInstant.pItems[wCell] = pItem;
  339. }
  340. break;
  341.  
  342. case DRAGON_SOUL_INVENTORY:
  343. {
  344. LPITEM pOld = m_pointsInstant.pDSItems[wCell];
  345.  
  346. if (pOld)
  347. {
  348. if (wCell < DRAGON_SOUL_INVENTORY_MAX_NUM)
  349. {
  350. for (int i = 0; i < pOld->GetSize(); ++i)
  351. {
  352. int p = wCell + (i * DRAGON_SOUL_BOX_COLUMN_NUM);
  353.  
  354. if (p >= DRAGON_SOUL_INVENTORY_MAX_NUM)
  355. continue;
  356.  
  357. if (m_pointsInstant.pDSItems[p] && m_pointsInstant.pDSItems[p] != pOld)
  358. continue;
  359.  
  360. m_pointsInstant.wDSItemGrid[p] = 0;
  361. }
  362. }
  363.  
  364. else
  365. m_pointsInstant.wDSItemGrid[wCell] = 0;
  366. }
  367.  
  368. if (pItem)
  369. {
  370. if (wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
  371. {
  372. sys_err("CHARACTER::SetItem: invalid DS item cell %d", wCell);
  373. return;
  374. }
  375.  
  376. if (wCell < DRAGON_SOUL_INVENTORY_MAX_NUM)
  377. {
  378. for (int i = 0; i < pItem->GetSize(); ++i)
  379. {
  380. int p = wCell + (i * DRAGON_SOUL_BOX_COLUMN_NUM);
  381.  
  382. if (p >= DRAGON_SOUL_INVENTORY_MAX_NUM)
  383. continue;
  384.  
  385. m_pointsInstant.wDSItemGrid[p] = wCell + 1;
  386. }
  387. }
  388.  
  389. else
  390. m_pointsInstant.wDSItemGrid[wCell] = wCell + 1;
  391. }
  392.  
  393. m_pointsInstant.pDSItems[wCell] = pItem;
  394. }
  395. break;
  396.  
  397. #ifdef __SWITCHBOT__
  398. case SWITCHBOT:
  399. {
  400. LPITEM pOld = m_pointsInstant.pSwitchbotItems[wCell];
  401. if (pItem && pOld)
  402. {
  403. return;
  404. }
  405.  
  406. if (wCell >= SWITCHBOT_SLOT_COUNT)
  407. {
  408. sys_err("CHARACTER::SetItem: invalid switchbot item cell %d", wCell);
  409. return;
  410. }
  411.  
  412. if (pItem)
  413. {
  414. CSwitchbotManager::Instance().RegisterItem(GetPlayerID(), pItem->GetID(), wCell);
  415. }
  416.  
  417. else
  418. {
  419. CSwitchbotManager::Instance().UnregisterItem(GetPlayerID(), wCell);
  420. }
  421.  
  422. m_pointsInstant.pSwitchbotItems[wCell] = pItem;
  423. }
  424. break;
  425. #endif
  426. default:
  427. sys_err ("Invalid Inventory type %d", window_type);
  428. return;
  429. }
  430.  
  431. if (GetDesc())
  432. {
  433. if (pItem)
  434. {
  435. TPacketGCItemSet pack;
  436. pack.header = HEADER_GC_ITEM_SET;
  437. pack.Cell = Cell;
  438.  
  439. pack.count = pItem->GetCount();
  440. pack.vnum = pItem->GetVnum();
  441. pack.flags = pItem->GetFlag();
  442. pack.anti_flags = pItem->GetAntiFlag();
  443.  
  444. #ifdef __HIGHLIGHT_SYSTEM__
  445. if (isHighLight)
  446. pack.highlight = true;
  447. else
  448. pack.highlight = (Cell.window_type == DRAGON_SOUL_INVENTORY);
  449. #else
  450. pack.highlight = (Cell.window_type == DRAGON_SOUL_INVENTORY);
  451. #endif
  452. thecore_memcpy(pack.alSockets, pItem->GetSockets(), sizeof(pack.alSockets));
  453. thecore_memcpy(pack.aAttr, pItem->GetAttributes(), sizeof(pack.aAttr));
  454.  
  455. GetDesc()->Packet(&pack, sizeof(TPacketGCItemSet));
  456. }
  457.  
  458. else
  459. {
  460. TPacketGCItemDelDeprecated pack;
  461. pack.header = HEADER_GC_ITEM_DEL;
  462. pack.Cell = Cell;
  463. pack.count = 0;
  464. pack.vnum = 0;
  465.  
  466. memset(pack.alSockets, 0, sizeof(pack.alSockets));
  467. memset(pack.aAttr, 0, sizeof(pack.aAttr));
  468.  
  469. GetDesc()->Packet(&pack, sizeof(TPacketGCItemDelDeprecated));
  470. }
  471. }
  472.  
  473. if (pItem)
  474. {
  475. pItem->SetCell(this, wCell);
  476. switch (window_type)
  477. {
  478. case INVENTORY:
  479. case EQUIPMENT:
  480. if ((wCell < INVENTORY_MAX_NUM) || (BELT_INVENTORY_SLOT_START <= wCell && BELT_INVENTORY_SLOT_END > wCell))
  481. pItem->SetWindow(INVENTORY);
  482. else
  483. pItem->SetWindow(EQUIPMENT);
  484. break;
  485.  
  486. case DRAGON_SOUL_INVENTORY:
  487. pItem->SetWindow(DRAGON_SOUL_INVENTORY);
  488. break;
  489.  
  490. #ifdef __SWITCHBOT__
  491. case SWITCHBOT:
  492. pItem->SetWindow(SWITCHBOT);
  493. break;
  494. #endif
  495. }
  496. }
  497. }
  498.  
  499. LPITEM CHARACTER::GetWear(UINT bCell) const
  500. {
  501. if (bCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX)
  502. {
  503. sys_err("CHARACTER::GetWear: invalid wear cell %d", bCell);
  504. return NULL;
  505. }
  506.  
  507. return m_pointsInstant.pItems[INVENTORY_MAX_NUM + bCell];
  508. }
  509.  
  510. void CHARACTER::SetWear(UINT bCell, LPITEM item)
  511. {
  512. if (bCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX)
  513. {
  514. sys_err("CHARACTER::SetItem: invalid item cell %d", bCell);
  515. return;
  516. }
  517.  
  518. #ifdef __HIGHLIGHT_SYSTEM__
  519. SetItem(TItemPos (INVENTORY, INVENTORY_MAX_NUM + bCell), item, false);
  520. #else
  521. SetItem(TItemPos (INVENTORY, INVENTORY_MAX_NUM + bCell), item);
  522. #endif
  523.  
  524. if (!item && bCell == WEAR_WEAPON)
  525. {
  526. if (IsAffectFlag(AFF_GWIGUM))
  527. RemoveAffect(SKILL_GWIGEOM);
  528.  
  529. if (IsAffectFlag(AFF_GEOMGYEONG))
  530. RemoveAffect(SKILL_GEOMKYUNG);
  531. }
  532. }
  533.  
  534. void CHARACTER::ClearItem()
  535. {
  536. int i;
  537. LPITEM item;
  538.  
  539. for (i = 0; i < INVENTORY_AND_EQUIP_SLOT_MAX; ++i)
  540. {
  541. if ((item = GetInventoryItem(i)))
  542. {
  543. item->SetSkipSave(true);
  544. ITEM_MANAGER::instance().FlushDelayedSave(item);
  545.  
  546. item->RemoveFromCharacter();
  547. M2_DESTROY_ITEM(item);
  548.  
  549. SyncQuickslot(QUICKSLOT_TYPE_ITEM, i, 1000);
  550. }
  551. }
  552.  
  553. for (i = 0; i < DRAGON_SOUL_INVENTORY_MAX_NUM; ++i)
  554. {
  555. if ((item = GetItem(TItemPos(DRAGON_SOUL_INVENTORY, i))))
  556. {
  557. item->SetSkipSave(true);
  558. ITEM_MANAGER::instance().FlushDelayedSave(item);
  559.  
  560. item->RemoveFromCharacter();
  561. M2_DESTROY_ITEM(item);
  562. }
  563. }
  564.  
  565. #ifdef __SWITCHBOT__
  566. for (i = 0; i < SWITCHBOT_SLOT_COUNT; ++i)
  567. {
  568. if ((item = GetItem(TItemPos(SWITCHBOT, i))))
  569. {
  570. item->SetSkipSave(true);
  571. ITEM_MANAGER::instance().FlushDelayedSave(item);
  572.  
  573. item->RemoveFromCharacter();
  574. M2_DESTROY_ITEM(item);
  575. }
  576. }
  577. #endif
  578.  
  579. }
  580.  
  581. bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) const
  582. {
  583. switch (Cell.window_type)
  584. {
  585. case INVENTORY:
  586. {
  587. UINT bCell = Cell.cell;
  588.  
  589. ++iExceptionCell;
  590.  
  591. if (Cell.IsBeltInventoryPosition())
  592. {
  593. LPITEM beltItem = GetWear(WEAR_BELT);
  594.  
  595. if (NULL == beltItem)
  596. return false;
  597.  
  598. if (false == CBeltInventoryHelper::IsAvailableCell(bCell - BELT_INVENTORY_SLOT_START, beltItem->GetValue(0)))
  599. return false;
  600.  
  601. if (m_pointsInstant.bItemGrid[bCell])
  602. {
  603. if (m_pointsInstant.bItemGrid[bCell] == (UINT)iExceptionCell)
  604. return true;
  605.  
  606. return false;
  607. }
  608.  
  609. if (bSize == 1)
  610. return true;
  611. }
  612.  
  613. else if (bCell >= INVENTORY_MAX_NUM)
  614. return false;
  615.  
  616. if (m_pointsInstant.bItemGrid[bCell])
  617. {
  618. if (m_pointsInstant.bItemGrid[bCell] == (UINT)iExceptionCell)
  619. {
  620. if (bSize == 1)
  621. return true;
  622.  
  623. int j = 1;
  624.  
  625. UINT bPage = bCell / (INVENTORY_MAX_NUM / 12);
  626.  
  627. do
  628. {
  629. UINT p = bCell + (5 * j);
  630.  
  631. if (p >= INVENTORY_MAX_NUM)
  632. return false;
  633.  
  634. if (p / (INVENTORY_MAX_NUM / 12) != bPage)
  635. return false;
  636.  
  637. if (m_pointsInstant.bItemGrid[p])
  638. if (m_pointsInstant.bItemGrid[p] != iExceptionCell)
  639. return false;
  640. }
  641.  
  642. while (++j < bSize);
  643.  
  644. return true;
  645. }
  646.  
  647. else
  648. return false;
  649. }
  650.  
  651. if (1 == bSize)
  652. return true;
  653.  
  654. else
  655. {
  656. int j = 1;
  657.  
  658. UINT bPage = bCell / (INVENTORY_MAX_NUM / 12);
  659.  
  660. do
  661. {
  662. UINT p = bCell + (5 * j);
  663.  
  664. if (p >= INVENTORY_MAX_NUM)
  665. return false;
  666.  
  667. if (p / (INVENTORY_MAX_NUM / 12) != bPage)
  668. return false;
  669.  
  670. if (m_pointsInstant.bItemGrid[p])
  671. if (m_pointsInstant.bItemGrid[p] != iExceptionCell)
  672. return false;
  673. }
  674.  
  675. while (++j < bSize);
  676.  
  677. return true;
  678. }
  679. }
  680. break;
  681.  
  682. case DRAGON_SOUL_INVENTORY:
  683. {
  684. WORD wCell = Cell.cell;
  685. if (wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
  686. return false;
  687.  
  688. iExceptionCell++;
  689.  
  690. if (m_pointsInstant.wDSItemGrid[wCell])
  691. {
  692. if (m_pointsInstant.wDSItemGrid[wCell] == iExceptionCell)
  693. {
  694. if (bSize == 1)
  695. return true;
  696.  
  697. int j = 1;
  698.  
  699. do
  700. {
  701. BYTE p = wCell + (DRAGON_SOUL_BOX_COLUMN_NUM * j);
  702.  
  703. if (p >= DRAGON_SOUL_INVENTORY_MAX_NUM)
  704. return false;
  705.  
  706. if (m_pointsInstant.wDSItemGrid[p])
  707. if (m_pointsInstant.wDSItemGrid[p] != iExceptionCell)
  708. return false;
  709. }
  710.  
  711. while (++j < bSize);
  712.  
  713. return true;
  714. }
  715.  
  716. else
  717. return false;
  718. }
  719.  
  720. if (1 == bSize)
  721. return true;
  722.  
  723. else
  724. {
  725. int j = 1;
  726.  
  727. do
  728. {
  729. BYTE p = wCell + (DRAGON_SOUL_BOX_COLUMN_NUM * j);
  730.  
  731. if (p >= DRAGON_SOUL_INVENTORY_MAX_NUM)
  732. return false;
  733.  
  734. if (m_pointsInstant.bItemGrid[p])
  735. if (m_pointsInstant.wDSItemGrid[p] != iExceptionCell)
  736. return false;
  737. }
  738.  
  739. while (++j < bSize);
  740.  
  741. return true;
  742. }
  743. }
  744. break;
  745.  
  746. #ifdef __SWITCHBOT__
  747. case SWITCHBOT:
  748. {
  749. uint16_t wCell = Cell.cell;
  750. if (wCell >= SWITCHBOT_SLOT_COUNT)
  751. {
  752. return false;
  753. }
  754.  
  755. if (m_pointsInstant.pSwitchbotItems[wCell])
  756. {
  757. return false;
  758. }
  759.  
  760. return true;
  761. }
  762. #endif
  763. }
  764.  
  765. return false;
  766. }
  767.  
  768. int CHARACTER::GetEmptyInventory(BYTE size) const
  769. {
  770. for ( int i = 0; i < INVENTORY_MAX_NUM; ++i)
  771. if (IsEmptyItemGrid(TItemPos (INVENTORY, i), size))
  772. return i;
  773.  
  774. return -1;
  775. }
  776.  
  777. int CHARACTER::GetEmptyDragonSoulInventory(LPITEM pItem) const
  778. {
  779. if (NULL == pItem || !pItem->IsDragonSoul())
  780. return -1;
  781.  
  782. if (!DragonSoul_IsQualified())
  783. {
  784. return -1;
  785. }
  786.  
  787. BYTE bSize = pItem->GetSize();
  788. WORD wBaseCell = DSManager::instance().GetBasePosition(pItem);
  789.  
  790. if (WORD_MAX == wBaseCell)
  791. return -1;
  792.  
  793. for (int i = 0; i < DRAGON_SOUL_BOX_SIZE; ++i)
  794. if (IsEmptyItemGrid(TItemPos(DRAGON_SOUL_INVENTORY, i + wBaseCell), bSize))
  795. return i + wBaseCell;
  796.  
  797. return -1;
  798. }
  799.  
  800. void CHARACTER::CopyDragonSoulItemGrid(std::vector<WORD>& vDragonSoulItemGrid) const
  801. {
  802. vDragonSoulItemGrid.resize(DRAGON_SOUL_INVENTORY_MAX_NUM);
  803.  
  804. std::copy(m_pointsInstant.wDSItemGrid, m_pointsInstant.wDSItemGrid + DRAGON_SOUL_INVENTORY_MAX_NUM, vDragonSoulItemGrid.begin());
  805. }
  806.  
  807. int CHARACTER::CountEmptyInventory() const
  808. {
  809. int count = 0;
  810.  
  811. for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
  812. if (GetInventoryItem(i))
  813. count += GetInventoryItem(i)->GetSize();
  814.  
  815. return (INVENTORY_MAX_NUM - count);
  816. }
  817.  
  818. void TransformRefineItem(LPITEM pkOldItem, LPITEM pkNewItem)
  819. {
  820. if (pkOldItem->IsAccessoryForSocket())
  821. {
  822. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  823. {
  824. pkNewItem->SetSocket(i, pkOldItem->GetSocket(i));
  825. }
  826. //pkNewItem->StartAccessorySocketExpireEvent();
  827. }
  828.  
  829. else
  830. {
  831. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  832. {
  833. if (!pkOldItem->GetSocket(i))
  834. break;
  835. else
  836. pkNewItem->SetSocket(i, 1);
  837. }
  838.  
  839. int slot = 0;
  840.  
  841. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  842. {
  843. long socket = pkOldItem->GetSocket(i);
  844.  
  845. if (socket > 2 && socket != ITEM_BROKEN_METIN_VNUM)
  846. pkNewItem->SetSocket(slot++, socket);
  847. }
  848.  
  849. }
  850.  
  851. pkOldItem->CopyAttributeTo(pkNewItem);
  852. }
  853.  
  854. void NotifyRefineSuccess(LPCHARACTER ch, LPITEM item, const char* way)
  855. {
  856. if (NULL != ch && item != NULL)
  857. {
  858. ch->ChatPacket(CHAT_TYPE_COMMAND, "RefineSuceeded");
  859.  
  860. LogManager::instance().RefineLog(ch->GetPlayerID(), item->GetName(), item->GetID(), item->GetRefineLevel(), 1, way);
  861. }
  862. }
  863.  
  864. void NotifyRefineFail(LPCHARACTER ch, LPITEM item, const char* way, int success = 0)
  865. {
  866. if (NULL != ch && NULL != item)
  867. {
  868. ch->ChatPacket(CHAT_TYPE_COMMAND, "RefineFailed");
  869.  
  870. LogManager::instance().RefineLog(ch->GetPlayerID(), item->GetName(), item->GetID(), item->GetRefineLevel(), success, way);
  871. }
  872. }
  873.  
  874. void CHARACTER::SetRefineNPC(LPCHARACTER ch)
  875. {
  876. if ( ch != NULL )
  877. {
  878. m_dwRefineNPCVID = ch->GetVID();
  879. }
  880.  
  881. else
  882. {
  883. m_dwRefineNPCVID = 0;
  884. }
  885. }
  886.  
  887. bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly)
  888. {
  889. if (!CanHandleItem(true))
  890. {
  891. ClearRefineMode();
  892. return false;
  893. }
  894.  
  895. #ifdef __INVENTORY_PROTECT_SYSTEM__
  896. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  897. {
  898. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  899. return false;
  900. }
  901. #endif
  902.  
  903. if (quest::CQuestManager::instance().GetEventFlag("update_refine_time") != 0)
  904. {
  905. if (get_global_time() < quest::CQuestManager::instance().GetEventFlag("update_refine_time") + (60 * 5))
  906. {
  907. sys_log(0, "can't refine %d %s", GetPlayerID(), GetName());
  908. return false;
  909. }
  910. }
  911.  
  912. const TRefineTable * prt = CRefineManager::instance().GetRefineRecipe(item->GetRefineSet());
  913.  
  914. if (!prt)
  915. return false;
  916.  
  917. DWORD result_vnum = item->GetRefinedVnum();
  918.  
  919. int cost = ComputeRefineFee(prt->cost);
  920.  
  921. int RefineChance = GetQuestFlag("main_quest_lv7.refine_chance");
  922.  
  923. if (RefineChance > 0)
  924. {
  925. if (!item->CheckItemUseLevel(20) || item->GetType() != ITEM_WEAPON)
  926. {
  927. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("무료 개량 기회는 20 이하의 무기만 가능합니다"));
  928. return false;
  929. }
  930.  
  931. cost = 0;
  932. SetQuestFlag("main_quest_lv7.refine_chance", RefineChance - 1);
  933. }
  934.  
  935. if (result_vnum == 0)
  936. {
  937. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("더 이상 개량할 수 없습니다."));
  938. return false;
  939. }
  940.  
  941. if (item->GetType() == ITEM_USE && item->GetSubType() == USE_TUNING)
  942. return false;
  943.  
  944. TItemTable * pProto = ITEM_MANAGER::instance().GetTable(item->GetRefinedVnum());
  945.  
  946. if (!pProto)
  947. {
  948. sys_err("DoRefine NOT GET ITEM PROTO %d", item->GetRefinedVnum());
  949. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템은 개량할 수 없습니다."));
  950. return false;
  951. }
  952.  
  953. for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
  954. {
  955. long limit = pProto->aLimits[i].lValue;
  956.  
  957. switch (pProto->aLimits[i].bType)
  958. {
  959. case LIMIT_LEVEL:
  960. if (GetLevel() < limit)
  961. {
  962. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량된 후 아이템의 레벨 제한보다 레벨이 낮습니다."));
  963. return false;
  964. }
  965. break;
  966. }
  967. }
  968.  
  969. if (GetGold() < cost)
  970. {
  971. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량을 하기 위한 돈이 부족합니다."));
  972. return false;
  973. }
  974.  
  975. if (!bMoneyOnly && !RefineChance)
  976. {
  977. for (int i = 0; i < prt->material_count; ++i)
  978. {
  979. if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
  980. {
  981. if (test_server)
  982. {
  983. ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
  984. }
  985.  
  986. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량을 하기 위한 재료가 부족합니다."));
  987.  
  988. return false;
  989. }
  990. }
  991.  
  992. for (int i = 0; i < prt->material_count; ++i)
  993. RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);
  994. }
  995.  
  996. int prob = number(1, 100);
  997.  
  998. if (IsRefineThroughGuild() || bMoneyOnly)
  999. prob -= 10;
  1000.  
  1001. if (prob <= prt->prob)
  1002. {
  1003. LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_vnum, 1, 0, false);
  1004.  
  1005. if (pkNewItem)
  1006. {
  1007. ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem);
  1008. LogManager::instance().ItemLog(this, pkNewItem, "REFINE SUCCESS", pkNewItem->GetName());
  1009.  
  1010. UINT bCell = item->GetCell();
  1011.  
  1012. NotifyRefineSuccess(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER");
  1013. DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -cost);
  1014. ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE SUCCESS)");
  1015.  
  1016. pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell));
  1017. ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem);
  1018.  
  1019. sys_log(0, "Refine Success %d", cost);
  1020. pkNewItem->AttrLog();
  1021. //PointChange(POINT_GOLD, -cost);
  1022. sys_log(0, "PayPee %d", cost);
  1023. PayRefineFee(cost);
  1024. sys_log(0, "PayPee End %d", cost);
  1025. }
  1026.  
  1027. else
  1028. {
  1029. sys_err("cannot create item %u", result_vnum);
  1030. NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER");
  1031. }
  1032. }
  1033.  
  1034. else
  1035. {
  1036. DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -cost);
  1037. NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER");
  1038. item->AttrLog();
  1039. ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE FAIL)");
  1040.  
  1041. //PointChange(POINT_GOLD, -cost);
  1042. PayRefineFee(cost);
  1043. }
  1044.  
  1045. return true;
  1046. }
  1047.  
  1048. enum enum_RefineScrolls
  1049. {
  1050. CHUKBOK_SCROLL = 0,
  1051. HYUNIRON_CHN = 1,
  1052. YONGSIN_SCROLL = 2,
  1053. MUSIN_SCROLL = 3,
  1054. YAGONG_SCROLL = 4,
  1055. MEMO_SCROLL = 5,
  1056. BDRAGON_SCROLL = 6,
  1057. };
  1058.  
  1059. bool CHARACTER::DoRefineWithScroll(LPITEM item)
  1060. {
  1061. if (!CanHandleItem(true))
  1062. {
  1063. ClearRefineMode();
  1064. return false;
  1065. }
  1066.  
  1067. #ifdef __INVENTORY_PROTECT_SYSTEM__
  1068. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  1069. {
  1070. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  1071. return false;
  1072. }
  1073. #endif
  1074.  
  1075. ClearRefineMode();
  1076.  
  1077. if (quest::CQuestManager::instance().GetEventFlag("update_refine_time") != 0)
  1078. {
  1079. if (get_global_time() < quest::CQuestManager::instance().GetEventFlag("update_refine_time") + (60 * 5))
  1080. {
  1081. sys_log(0, "can't refine %d %s", GetPlayerID(), GetName());
  1082. return false;
  1083. }
  1084. }
  1085.  
  1086. const TRefineTable * prt = CRefineManager::instance().GetRefineRecipe(item->GetRefineSet());
  1087.  
  1088. if (!prt)
  1089. return false;
  1090.  
  1091. LPITEM pkItemScroll;
  1092.  
  1093. if (m_iRefineAdditionalCell < 0)
  1094. return false;
  1095.  
  1096. pkItemScroll = GetInventoryItem(m_iRefineAdditionalCell);
  1097.  
  1098. if (!pkItemScroll)
  1099. return false;
  1100.  
  1101. if (!(pkItemScroll->GetType() == ITEM_USE && pkItemScroll->GetSubType() == USE_TUNING))
  1102. return false;
  1103.  
  1104. if (pkItemScroll->GetVnum() == item->GetVnum())
  1105. return false;
  1106.  
  1107. DWORD result_vnum = item->GetRefinedVnum();
  1108. DWORD result_fail_vnum = item->GetRefineFromVnum();
  1109.  
  1110. if (result_vnum == 0)
  1111. {
  1112. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("더 이상 개량할 수 없습니다."));
  1113. return false;
  1114. }
  1115.  
  1116. if (pkItemScroll->GetValue(0) == MUSIN_SCROLL)
  1117. {
  1118. if (item->GetRefineLevel() >= 4)
  1119. {
  1120. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 개량서로 더 이상 개량할 수 없습니다."));
  1121. return false;
  1122. }
  1123. }
  1124.  
  1125. else if (pkItemScroll->GetValue(0) == MEMO_SCROLL)
  1126. {
  1127. if (item->GetRefineLevel() != pkItemScroll->GetValue(1))
  1128. {
  1129. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 개량서로 개량할 수 없습니다."));
  1130. return false;
  1131. }
  1132. }
  1133.  
  1134. else if (pkItemScroll->GetValue(0) == BDRAGON_SCROLL)
  1135. {
  1136. if (item->GetType() != ITEM_METIN || item->GetRefineLevel() != 4)
  1137. {
  1138. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템으로 개량할 수 없습니다."));
  1139. return false;
  1140. }
  1141. }
  1142.  
  1143. TItemTable * pProto = ITEM_MANAGER::instance().GetTable(item->GetRefinedVnum());
  1144.  
  1145. if (!pProto)
  1146. {
  1147. sys_err("DoRefineWithScroll NOT GET ITEM PROTO %d", item->GetRefinedVnum());
  1148. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템은 개량할 수 없습니다."));
  1149. return false;
  1150. }
  1151.  
  1152. for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
  1153. {
  1154. long limit = pProto->aLimits[i].lValue;
  1155.  
  1156. switch (pProto->aLimits[i].bType)
  1157. {
  1158. case LIMIT_LEVEL:
  1159. if (GetLevel() < limit)
  1160. {
  1161. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량된 후 아이템의 레벨 제한보다 레벨이 낮습니다."));
  1162. return false;
  1163. }
  1164. break;
  1165. }
  1166. }
  1167.  
  1168. if (GetGold() < prt->cost)
  1169. {
  1170. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량을 하기 위한 돈이 부족합니다."));
  1171. return false;
  1172. }
  1173.  
  1174. for (int i = 0; i < prt->material_count; ++i)
  1175. {
  1176. if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
  1177. {
  1178. if (test_server)
  1179. {
  1180. ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
  1181. }
  1182. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량을 하기 위한 재료가 부족합니다."));
  1183. return false;
  1184. }
  1185. }
  1186.  
  1187. for (int i = 0; i < prt->material_count; ++i)
  1188. RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);
  1189.  
  1190. int prob = number(1, 100);
  1191. int success_prob = prt->prob;
  1192. bool bDestroyWhenFail = false;
  1193.  
  1194. const char* szRefineType = "SCROLL";
  1195.  
  1196. if (pkItemScroll->GetValue(0) == HYUNIRON_CHN || pkItemScroll->GetValue(0) == YONGSIN_SCROLL || pkItemScroll->GetValue(0) == YAGONG_SCROLL)
  1197. {
  1198. const char hyuniron_prob[9] = { 100, 75, 65, 55, 45, 40, 35, 25, 20 };
  1199. const char hyuniron_prob_euckr[9] = { 100, 75, 65, 55, 45, 40, 35, 30, 25 };
  1200.  
  1201. const char yagong_prob[9] = { 100, 100, 90, 80, 70, 60, 50, 30, 20 };
  1202. const char yagong_prob_euckr[9] = { 100, 100, 90, 80, 70, 60, 50, 40, 30 };
  1203.  
  1204. if (pkItemScroll->GetValue(0) == YONGSIN_SCROLL)
  1205. {
  1206. success_prob = hyuniron_prob[MINMAX(0, item->GetRefineLevel(), 8)];
  1207. }
  1208.  
  1209. else if (pkItemScroll->GetValue(0) == YAGONG_SCROLL)
  1210. {
  1211. success_prob = yagong_prob[MINMAX(0, item->GetRefineLevel(), 8)];
  1212. }
  1213.  
  1214. else if (pkItemScroll->GetValue(0) == HYUNIRON_CHN) {}
  1215.  
  1216. else
  1217. {
  1218. sys_err("REFINE : Unknown refine scroll item. Value0: %d", pkItemScroll->GetValue(0));
  1219. }
  1220.  
  1221. if (test_server)
  1222. {
  1223. ChatPacket(CHAT_TYPE_INFO, "[Only Test] Success_Prob %d, RefineLevel %d ", success_prob, item->GetRefineLevel());
  1224. }
  1225. if (pkItemScroll->GetValue(0) == HYUNIRON_CHN)
  1226. bDestroyWhenFail = true;
  1227.  
  1228. if (pkItemScroll->GetValue(0) == HYUNIRON_CHN)
  1229. {
  1230. szRefineType = "HYUNIRON";
  1231. }
  1232.  
  1233. else if (pkItemScroll->GetValue(0) == YONGSIN_SCROLL)
  1234. {
  1235. szRefineType = "GOD_SCROLL";
  1236. }
  1237.  
  1238. else if (pkItemScroll->GetValue(0) == YAGONG_SCROLL)
  1239. {
  1240. szRefineType = "YAGONG_SCROLL";
  1241. }
  1242. }
  1243.  
  1244. if (pkItemScroll->GetValue(0) == MUSIN_SCROLL)
  1245. {
  1246. success_prob = 100;
  1247.  
  1248. szRefineType = "MUSIN_SCROLL";
  1249. }
  1250.  
  1251. else if (pkItemScroll->GetValue(0) == MEMO_SCROLL)
  1252. {
  1253. success_prob = 100;
  1254. szRefineType = "MEMO_SCROLL";
  1255. }
  1256.  
  1257. else if (pkItemScroll->GetValue(0) == BDRAGON_SCROLL)
  1258. {
  1259. success_prob = 80;
  1260. szRefineType = "BDRAGON_SCROLL";
  1261. }
  1262.  
  1263. pkItemScroll->SetCount(pkItemScroll->GetCount() - 1);
  1264.  
  1265. if (prob <= success_prob)
  1266. {
  1267. LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_vnum, 1, 0, false);
  1268.  
  1269. if (pkNewItem)
  1270. {
  1271. ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem);
  1272. LogManager::instance().ItemLog(this, pkNewItem, "REFINE SUCCESS", pkNewItem->GetName());
  1273.  
  1274. UINT bCell = item->GetCell();
  1275.  
  1276. NotifyRefineSuccess(this, item, szRefineType);
  1277. DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost);
  1278. ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE SUCCESS)");
  1279.  
  1280. pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell));
  1281. ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem);
  1282. pkNewItem->AttrLog();
  1283. //PointChange(POINT_GOLD, -prt->cost);
  1284. PayRefineFee(prt->cost);
  1285. }
  1286.  
  1287. else
  1288. {
  1289. sys_err("cannot create item %u", result_vnum);
  1290. NotifyRefineFail(this, item, szRefineType);
  1291. }
  1292. }
  1293.  
  1294. else if (!bDestroyWhenFail && result_fail_vnum)
  1295. {
  1296. LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_fail_vnum, 1, 0, false);
  1297.  
  1298. if (pkNewItem)
  1299. {
  1300. ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem);
  1301. LogManager::instance().ItemLog(this, pkNewItem, "REFINE FAIL", pkNewItem->GetName());
  1302.  
  1303. UINT bCell = item->GetCell();
  1304.  
  1305. DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost);
  1306. NotifyRefineFail(this, item, szRefineType, -1);
  1307. ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE FAIL)");
  1308.  
  1309. pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell));
  1310. ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem);
  1311.  
  1312. pkNewItem->AttrLog();
  1313.  
  1314. //PointChange(POINT_GOLD, -prt->cost);
  1315. PayRefineFee(prt->cost);
  1316. }
  1317.  
  1318. else
  1319. {
  1320. sys_err("cannot create item %u", result_fail_vnum);
  1321. NotifyRefineFail(this, item, szRefineType);
  1322. }
  1323. }
  1324.  
  1325. else
  1326. {
  1327. NotifyRefineFail(this, item, szRefineType);
  1328.  
  1329. PayRefineFee(prt->cost);
  1330. }
  1331.  
  1332. return true;
  1333. }
  1334.  
  1335. bool CHARACTER::RefineInformation(UINT bCell, BYTE bType, int iAdditionalCell)
  1336. {
  1337. if (bCell > INVENTORY_MAX_NUM)
  1338. return false;
  1339.  
  1340. LPITEM item = GetInventoryItem(bCell);
  1341.  
  1342. if (!item)
  1343. return false;
  1344.  
  1345. if (bType == REFINE_TYPE_MONEY_ONLY && !GetQuestFlag("deviltower_zone.can_refine"))
  1346. {
  1347. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("사귀 타워 완료 보상은 한번까지 사용가능합니다."));
  1348. return false;
  1349. }
  1350.  
  1351. TPacketGCRefineInformation p;
  1352.  
  1353. p.header = HEADER_GC_REFINE_INFORMATION;
  1354. p.pos = bCell;
  1355. p.src_vnum = item->GetVnum();
  1356. p.result_vnum = item->GetRefinedVnum();
  1357. p.type = bType;
  1358.  
  1359. if (p.result_vnum == 0)
  1360. {
  1361. sys_err("RefineInformation p.result_vnum == 0");
  1362. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템은 개량할 수 없습니다."));
  1363. return false;
  1364. }
  1365.  
  1366. if (item->GetType() == ITEM_USE && item->GetSubType() == USE_TUNING)
  1367. {
  1368. if (bType == 0)
  1369. {
  1370. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템은 이 방식으로는 개량할 수 없습니다."));
  1371. return false;
  1372. }
  1373.  
  1374. else
  1375. {
  1376. LPITEM itemScroll = GetInventoryItem(iAdditionalCell);
  1377. if (!itemScroll || item->GetVnum() == itemScroll->GetVnum())
  1378. {
  1379. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("같은 개량서를 합칠 수는 없습니다."));
  1380. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("축복의 서와 현철을 합칠 수 있습니다."));
  1381. return false;
  1382. }
  1383. }
  1384. }
  1385.  
  1386. CRefineManager & rm = CRefineManager::instance();
  1387.  
  1388. const TRefineTable* prt = rm.GetRefineRecipe(item->GetRefineSet());
  1389.  
  1390. if (!prt)
  1391. {
  1392. sys_err("RefineInformation NOT GET REFINE SET %d", item->GetRefineSet());
  1393. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템은 개량할 수 없습니다."));
  1394. return false;
  1395. }
  1396.  
  1397. if (GetQuestFlag("main_quest_lv7.refine_chance") > 0)
  1398. {
  1399. if (!item->CheckItemUseLevel(20) || item->GetType() != ITEM_WEAPON)
  1400. {
  1401. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("무료 개량 기회는 20 이하의 무기만 가능합니다"));
  1402. return false;
  1403. }
  1404.  
  1405. p.cost = 0;
  1406. }
  1407.  
  1408. else
  1409. p.cost = ComputeRefineFee(prt->cost);
  1410.  
  1411.  
  1412. p.prob = prt->prob;
  1413. if (bType == REFINE_TYPE_MONEY_ONLY)
  1414. {
  1415. p.material_count = 0;
  1416. memset(p.materials, 0, sizeof(p.materials));
  1417. }
  1418.  
  1419. else
  1420. {
  1421. p.material_count = prt->material_count;
  1422. thecore_memcpy(&p.materials, prt->materials, sizeof(prt->materials));
  1423. }
  1424.  
  1425. GetDesc()->Packet(&p, sizeof(TPacketGCRefineInformation));
  1426.  
  1427. SetRefineMode(iAdditionalCell);
  1428. return true;
  1429. }
  1430.  
  1431. bool CHARACTER::RefineItem(LPITEM pkItem, LPITEM pkTarget)
  1432. {
  1433. if (!CanHandleItem())
  1434. return false;
  1435.  
  1436. #ifdef __INVENTORY_PROTECT_SYSTEM__
  1437. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  1438. {
  1439. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  1440. return false;
  1441. }
  1442. #endif
  1443.  
  1444. if (pkItem->GetSubType() == USE_TUNING)
  1445. {
  1446. if (pkItem->GetValue(0) == MUSIN_SCROLL)
  1447. RefineInformation(pkTarget->GetCell(), REFINE_TYPE_MUSIN, pkItem->GetCell());
  1448.  
  1449. else if (pkItem->GetValue(0) == HYUNIRON_CHN)
  1450. RefineInformation(pkTarget->GetCell(), REFINE_TYPE_HYUNIRON, pkItem->GetCell());
  1451.  
  1452. else if (pkItem->GetValue(0) == BDRAGON_SCROLL)
  1453. {
  1454. if (pkTarget->GetRefineSet() != 702) return false;
  1455. RefineInformation(pkTarget->GetCell(), REFINE_TYPE_BDRAGON, pkItem->GetCell());
  1456. }
  1457.  
  1458. else
  1459. {
  1460. if (pkTarget->GetRefineSet() == 501) return false;
  1461. RefineInformation(pkTarget->GetCell(), REFINE_TYPE_SCROLL, pkItem->GetCell());
  1462. }
  1463. }
  1464.  
  1465. else if (pkItem->GetSubType() == USE_DETACHMENT && IS_SET(pkTarget->GetFlag(), ITEM_FLAG_REFINEABLE))
  1466. {
  1467. LogManager::instance().ItemLog(this, pkTarget, "USE_DETACHMENT", pkTarget->GetName());
  1468.  
  1469. bool bHasMetinStone = false;
  1470.  
  1471. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
  1472. {
  1473. long socket = pkTarget->GetSocket(i);
  1474. if (socket > 2 && socket != ITEM_BROKEN_METIN_VNUM)
  1475. {
  1476. bHasMetinStone = true;
  1477. break;
  1478. }
  1479. }
  1480.  
  1481. if (bHasMetinStone)
  1482. {
  1483. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  1484. {
  1485. long socket = pkTarget->GetSocket(i);
  1486. if (socket > 2 && socket != ITEM_BROKEN_METIN_VNUM)
  1487. {
  1488. AutoGiveItem(socket);
  1489. //TItemTable* pTable = ITEM_MANAGER::instance().GetTable(pkTarget->GetSocket(i));
  1490. //pkTarget->SetSocket(i, pTable->alValues[2]);
  1491. pkTarget->SetSocket(i, ITEM_BROKEN_METIN_VNUM);
  1492. }
  1493. }
  1494.  
  1495. pkItem->SetCount(pkItem->GetCount() - 1);
  1496. return true;
  1497. }
  1498.  
  1499. else
  1500. {
  1501. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("빼낼 수 있는 메틴석이 없습니다."));
  1502. return false;
  1503. }
  1504. }
  1505.  
  1506. return false;
  1507. }
  1508.  
  1509. EVENTFUNC(kill_campfire_event)
  1510. {
  1511. char_event_info* info = dynamic_cast<char_event_info*>( event->info );
  1512.  
  1513. if ( info == NULL )
  1514. {
  1515. sys_err( "kill_campfire_event> <Factor> Null pointer" );
  1516. return 0;
  1517. }
  1518.  
  1519. LPCHARACTER ch = info->ch;
  1520.  
  1521. if (ch == NULL)
  1522. {
  1523. return 0;
  1524. }
  1525.  
  1526. ch->m_pkMiningEvent = NULL;
  1527. M2_DESTROY_CHARACTER(ch);
  1528.  
  1529. return 0;
  1530. }
  1531.  
  1532. bool CHARACTER::GiveRecallItem(LPITEM item)
  1533. {
  1534. int idx = GetMapIndex();
  1535. int iEmpireByMapIndex = -1;
  1536.  
  1537. if (idx < 20)
  1538. iEmpireByMapIndex = 1;
  1539.  
  1540. else if (idx < 40)
  1541. iEmpireByMapIndex = 2;
  1542.  
  1543. else if (idx < 60)
  1544. iEmpireByMapIndex = 3;
  1545.  
  1546. else if (idx < 10000)
  1547. iEmpireByMapIndex = 0;
  1548.  
  1549. switch (idx)
  1550. {
  1551. case 66:
  1552. case 216:
  1553. iEmpireByMapIndex = -1;
  1554. break;
  1555. }
  1556.  
  1557. if (iEmpireByMapIndex && GetEmpire() != iEmpireByMapIndex)
  1558. {
  1559. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("기억해 둘 수 없는 위치 입니다."));
  1560. return false;
  1561. }
  1562.  
  1563. int pos;
  1564.  
  1565. if (item->GetCount() == 1)
  1566. {
  1567. item->SetSocket(0, GetX());
  1568. item->SetSocket(1, GetY());
  1569. }
  1570.  
  1571. else if ((pos = GetEmptyInventory(item->GetSize())) != -1)
  1572. {
  1573. LPITEM item2 = ITEM_MANAGER::instance().CreateItem(item->GetVnum(), 1);
  1574.  
  1575. if (NULL != item2)
  1576. {
  1577. item2->SetSocket(0, GetX());
  1578. item2->SetSocket(1, GetY());
  1579. item2->AddToCharacter(this, TItemPos(INVENTORY, pos));
  1580.  
  1581. item->SetCount(item->GetCount() - 0);
  1582. }
  1583. }
  1584.  
  1585. else
  1586. {
  1587. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
  1588. return false;
  1589. }
  1590.  
  1591. return true;
  1592. }
  1593.  
  1594. void CHARACTER::ProcessRecallItem(LPITEM item)
  1595. {
  1596. int idx;
  1597.  
  1598. if ((idx = SECTREE_MANAGER::instance().GetMapIndex(item->GetSocket(0), item->GetSocket(1))) == 0)
  1599. return;
  1600.  
  1601. int iEmpireByMapIndex = -1;
  1602.  
  1603. if (idx < 20)
  1604. iEmpireByMapIndex = 1;
  1605.  
  1606. else if (idx < 40)
  1607. iEmpireByMapIndex = 2;
  1608.  
  1609. else if (idx < 60)
  1610. iEmpireByMapIndex = 3;
  1611.  
  1612. else if (idx < 10000)
  1613. iEmpireByMapIndex = 0;
  1614.  
  1615. switch (idx)
  1616. {
  1617. case 66:
  1618. case 216:
  1619. iEmpireByMapIndex = -1;
  1620. break;
  1621.  
  1622. case 301:
  1623. case 302:
  1624. case 303:
  1625. case 304:
  1626. if( GetLevel() < 90 )
  1627. {
  1628. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템의 레벨 제한보다 레벨이 낮습니다."));
  1629. return;
  1630. }
  1631.  
  1632. else
  1633. break;
  1634. }
  1635.  
  1636. if (iEmpireByMapIndex && GetEmpire() != iEmpireByMapIndex)
  1637. {
  1638. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("기억된 위치가 타제국에 속해 있어서 귀환할 수 없습니다."));
  1639. item->SetSocket(0, 0);
  1640. item->SetSocket(1, 0);
  1641. }
  1642.  
  1643. else
  1644. {
  1645. sys_log(1, "Recall: %s %d %d -> %d %d", GetName(), GetX(), GetY(), item->GetSocket(0), item->GetSocket(1));
  1646. WarpSet(item->GetSocket(0), item->GetSocket(1));
  1647. item->SetCount(item->GetCount() - 0);
  1648. }
  1649. }
  1650.  
  1651. void CHARACTER::__OpenPrivateShop()
  1652. {
  1653. unsigned bodyPart = GetPart(PART_MAIN);
  1654. switch (bodyPart)
  1655. {
  1656. case 0:
  1657. case 1:
  1658. case 2:
  1659. ChatPacket(CHAT_TYPE_COMMAND, "OpenPrivateShop");
  1660. break;
  1661.  
  1662. default:
  1663. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("갑옷을 벗어야 개인 상점을 열 수 있습니다."));
  1664. break;
  1665. }
  1666. }
  1667.  
  1668. void CHARACTER::SendMyShopPriceListCmd(DWORD dwItemVnum, long long dwItemPrice)
  1669. {
  1670. char szLine[256];
  1671. snprintf(szLine, sizeof(szLine), "MyShopPriceList %u %lld", dwItemVnum, dwItemPrice);
  1672. ChatPacket(CHAT_TYPE_COMMAND, szLine);
  1673. sys_log(0, szLine);
  1674. }
  1675.  
  1676. void CHARACTER::UseSilkBotaryReal(const TPacketMyshopPricelistHeader* p)
  1677. {
  1678. const TItemPriceInfo* pInfo = (const TItemPriceInfo*)(p + 1);
  1679.  
  1680. if (!p->byCount)
  1681.  
  1682. SendMyShopPriceListCmd(1, 0);
  1683.  
  1684. else
  1685. {
  1686. for (int idx = 0; idx < p->byCount; idx++)
  1687. SendMyShopPriceListCmd(pInfo[ idx ].dwVnum, pInfo[ idx ].dwPrice);
  1688. }
  1689.  
  1690. __OpenPrivateShop();
  1691. }
  1692.  
  1693. void CHARACTER::UseSilkBotary(void)
  1694. {
  1695. if (m_bNoOpenedShop)
  1696. {
  1697. DWORD dwPlayerID = GetPlayerID();
  1698. db_clientdesc->DBPacket(HEADER_GD_MYSHOP_PRICELIST_REQ, GetDesc()->GetHandle(), &dwPlayerID, sizeof(DWORD));
  1699. m_bNoOpenedShop = false;
  1700. }
  1701.  
  1702. else
  1703. {
  1704. __OpenPrivateShop();
  1705. }
  1706. }
  1707.  
  1708. int CalculateConsume(LPCHARACTER ch)
  1709. {
  1710. static const int WARP_NEED_LIFE_PERCENT = 30;
  1711. static const int WARP_MIN_LIFE_PERCENT = 10;
  1712.  
  1713. int consumeLife = 0;
  1714. {
  1715. const int curLife = ch->GetHP();
  1716. const int needPercent = WARP_NEED_LIFE_PERCENT;
  1717. const int needLife = ch->GetMaxHP() * needPercent / 100;
  1718.  
  1719. if (curLife < needLife)
  1720. {
  1721. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 생명력 양이 모자라 사용할 수 없습니다."));
  1722. return -1;
  1723. }
  1724.  
  1725. consumeLife = needLife;
  1726.  
  1727. const int minPercent = WARP_MIN_LIFE_PERCENT;
  1728. const int minLife = ch->GetMaxHP() * minPercent / 100;
  1729.  
  1730. if (curLife - needLife < minLife)
  1731. consumeLife = curLife - minLife;
  1732.  
  1733. if (consumeLife < 0)
  1734. consumeLife = 0;
  1735. }
  1736.  
  1737. return consumeLife;
  1738. }
  1739.  
  1740. int CalculateConsumeSP(LPCHARACTER lpChar)
  1741. {
  1742. static const int NEED_WARP_SP_PERCENT = 30;
  1743.  
  1744. const int curSP = lpChar->GetSP();
  1745. const int needSP = lpChar->GetMaxSP() * NEED_WARP_SP_PERCENT / 100;
  1746.  
  1747. if (curSP < needSP)
  1748. {
  1749. lpChar->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 정신력 양이 모자라 사용할 수 없습니다."));
  1750. return -1;
  1751. }
  1752.  
  1753. return needSP;
  1754. }
  1755.  
  1756. bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell)
  1757. {
  1758. int iLimitRealtimeStartFirstUseFlagIndex = -1;
  1759. int iLimitTimerBasedOnWearFlagIndex = -1;
  1760.  
  1761. WORD wDestCell = DestCell.cell;
  1762. BYTE bDestInven = DestCell.window_type;
  1763.  
  1764. for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
  1765. {
  1766. long limitValue = item->GetProto()->aLimits[i].lValue;
  1767.  
  1768. switch (item->GetProto()->aLimits[i].bType)
  1769. {
  1770. case LIMIT_LEVEL:
  1771. if (GetLevel() < limitValue)
  1772. {
  1773. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템의 레벨 제한보다 레벨이 낮습니다."));
  1774. return false;
  1775. }
  1776. break;
  1777.  
  1778. case LIMIT_REAL_TIME_START_FIRST_USE:
  1779. iLimitRealtimeStartFirstUseFlagIndex = i;
  1780. break;
  1781.  
  1782. case LIMIT_TIMER_BASED_ON_WEAR:
  1783. iLimitTimerBasedOnWearFlagIndex = i;
  1784. break;
  1785. }
  1786. }
  1787.  
  1788. if (test_server)
  1789. {
  1790. sys_log(0, "USE_ITEM %s, Inven %d, Cell %d, ItemType %d, SubType %d", item->GetName(), bDestInven, wDestCell, item->GetType(), item->GetSubType());
  1791. }
  1792.  
  1793. if ( CArenaManager::instance().IsLimitedItem( GetMapIndex(), item->GetVnum() ) == true )
  1794. {
  1795. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련 중에는 이용할 수 없는 물품입니다."));
  1796. return false;
  1797. }
  1798.  
  1799. if (!IsLoadedAffect())
  1800. {
  1801. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Affects are not loaded yet!"));
  1802. return false;
  1803. }
  1804.  
  1805. if (-1 != iLimitRealtimeStartFirstUseFlagIndex)
  1806. {
  1807. if (0 == item->GetSocket(1))
  1808. {
  1809. long duration = (0 != item->GetSocket(0)) ? item->GetSocket(0) : item->GetProto()->aLimits[iLimitRealtimeStartFirstUseFlagIndex].lValue;
  1810.  
  1811. if (0 == duration)
  1812. duration = 60 * 60 * 24 * 7;
  1813.  
  1814. item->SetSocket(0, time(0) + duration);
  1815. item->StartRealTimeExpireEvent();
  1816. }
  1817.  
  1818. if (false == item->IsEquipped())
  1819. item->SetSocket(1, item->GetSocket(1) + 1);
  1820. }
  1821.  
  1822. #ifdef ENABLE_BLOCK_ITEM_MAP
  1823. if(ItemIsBlock( (int)item->GetVnum(), (int)GetMapIndex() ))
  1824. {
  1825. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Block Info] > |h|r Folosirea acestui obiect a fost blocat in aceasta Mapa .");
  1826.  
  1827. return false;
  1828. }
  1829. #endif
  1830.  
  1831. #ifdef ENABLE_COINS_SYSTEM
  1832. switch (item->GetVnum())
  1833. {
  1834. case 80000:
  1835. case 80001:
  1836. case 80002:
  1837. case 80003:
  1838. case 80004:
  1839. case 80005:
  1840. case 80006:
  1841. if (!CanHandleItem())
  1842. return false;
  1843.  
  1844. if (IsOpenSafebox() || GetExchange() || GetMyShop() || IsCubeOpen())
  1845. return false;
  1846.  
  1847. #ifdef __FULL_STAFF_RESTRICT__
  1848. if (IsRestrictedGM())
  1849. {
  1850. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Coins Info] > |h|r Nu ai voie sa faci asa ceva .");
  1851. return false;
  1852. }
  1853.  
  1854. if (!IsRestrictAdy() || !IsRestrictCristy())
  1855. {
  1856. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Coins Info] > |h|r OpenVoucher (is an account owned by GM).");
  1857. return false;
  1858. }
  1859. #endif
  1860. SetCoins(true, 0, item->GetVnum());
  1861. item->SetCount(item->GetCount() - 1);
  1862.  
  1863. return 1;
  1864. break;
  1865.  
  1866. default:
  1867. break;
  1868. }
  1869.  
  1870. switch (item->GetVnum())
  1871. {
  1872. case 80007:
  1873. case 80008:
  1874. case 80009:
  1875. case 80010:
  1876. case 80011:
  1877. case 80012:
  1878. case 80013:
  1879. if (!CanHandleItem())
  1880. return false;
  1881.  
  1882. if (IsOpenSafebox() || GetExchange() || GetMyShop() || IsCubeOpen())
  1883. return false;
  1884.  
  1885. #ifdef __FULL_STAFF_RESTRICT__
  1886. if (IsRestrictedGM())
  1887. {
  1888. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Coins Info] > |h|r Nu ai voie sa faci asa ceva .");
  1889. return false;
  1890. }
  1891.  
  1892. if (!IsRestrictAdy() || !IsRestrictCristy())
  1893. {
  1894. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Coins Info] > |h|r OpenVoucher (is an account owned by GM).");
  1895. return false;
  1896. }
  1897. #endif
  1898. SetJD(true, 0, item->GetVnum());
  1899. item->SetCount(item->GetCount() - 1);
  1900.  
  1901. return 1;
  1902. break;
  1903.  
  1904. default:
  1905. break;
  1906. }
  1907.  
  1908. switch (item->GetVnum())
  1909. {
  1910. case 80014:
  1911. case 80015:
  1912. case 80016:
  1913. case 80017:
  1914. case 80018:
  1915. if (!CanHandleItem())
  1916. return false;
  1917.  
  1918. if (IsOpenSafebox() || GetExchange() || GetMyShop() || IsCubeOpen())
  1919. return false;
  1920.  
  1921. #ifdef __FULL_STAFF_RESTRICT__
  1922. if (IsRestrictedGM())
  1923. {
  1924. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Coins Info] > |h|r Nu ai voie sa faci asa ceva .");
  1925. return false;
  1926. }
  1927.  
  1928. if (!IsRestrictAdy() || !IsRestrictCristy())
  1929. {
  1930. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Coins Info] > |h|r OpenVoucher (is an account owned by GM).");
  1931. return false;
  1932. }
  1933. #endif
  1934. SetEuro(true, 0, item->GetVnum());
  1935. item->SetCount(item->GetCount() - 1);
  1936.  
  1937. return 1;
  1938. break;
  1939.  
  1940. default:
  1941. break;
  1942. }
  1943. #endif
  1944.  
  1945. #ifdef ENABLE_AUTONAME_SYSTEM
  1946. if (item->GetVnum() == AUTONAME_SCROLL_VNUM)
  1947. ChatPacket(CHAT_TYPE_COMMAND, "OpenAutoNameSystem");
  1948. #endif
  1949.  
  1950. switch (item->GetType())
  1951. {
  1952. case ITEM_HAIR:
  1953. return ItemProcess_Hair(item, wDestCell);
  1954.  
  1955. case ITEM_POLYMORPH:
  1956. return ItemProcess_Polymorph(item);
  1957.  
  1958. case ITEM_QUEST:
  1959. if (GetArena() != NULL || IsObserverMode() == true)
  1960. {
  1961. if (item->GetVnum() == 50051 || item->GetVnum() == 50052 || item->GetVnum() == 50053)
  1962. {
  1963. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련 중에는 이용할 수 없는 물품입니다."));
  1964. return false;
  1965. }
  1966. }
  1967.  
  1968. if(CPVPManager::instance().IsFightingGerman(GetPlayerID()))
  1969. {
  1970. if(item->GetVnum() == 71103 || item->GetVnum() == 71104 || item->GetVnum() == 71105 || item->GetVnum() == 71106)
  1971. {
  1972. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta aici .");
  1973.  
  1974. return false;
  1975. }
  1976. }
  1977.  
  1978. if(CPVPManager::instance().IsFightingTactic(GetPlayerID()))
  1979. {
  1980. if(item->GetVnum() == 71103 || item->GetVnum() == 71104 || item->GetVnum() == 71105 || item->GetVnum() == 71106)
  1981. {
  1982. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta aici .");
  1983.  
  1984. return false;
  1985. }
  1986. }
  1987.  
  1988. #ifdef __AUTO_QUQUE_ATTACK__
  1989. if (item->GetVnum() >= 61400 && item->GetVnum() <= 61405)
  1990. {
  1991. if (item->isLocked() || item->IsExchanging())
  1992. return false;
  1993.  
  1994. if (FindAffect(AFFECT_AUTO_METIN_FARM))
  1995. {
  1996. ChatPacket(CHAT_TYPE_INFO, "|cFFFFA500[Farm Info] > |h|r You has already affect .");
  1997. return false;
  1998. }
  1999.  
  2000. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Farm Info] > |h|r Affect successfully added .");
  2001.  
  2002. int durata = (item->GetValue(0) == 999 ? INFINITE_AFFECT_DURATION : 60 * 60 * 24 * item->GetValue(0));
  2003.  
  2004. AddAffect(AFFECT_AUTO_METIN_FARM, POINT_ATT_SPEED, 15, AFF_NONE, durata, 0, false);
  2005.  
  2006. if (item->GetValue(0) == 999)
  2007. ChatPacket(CHAT_TYPE_INFO, "|cFFFFA500[Farm Info] > |h|r Ai primit +15 Viteza de atac permanent .");
  2008. else
  2009. ChatPacket(CHAT_TYPE_INFO, "|cFFFFA500[Farm Info] > |h|r Ai primit +15 Viteza de atac pentru %d zile .", item->GetValue(0));
  2010.  
  2011. item->SetCount(item->GetCount() - 1);
  2012.  
  2013. return true;
  2014. }
  2015. #endif
  2016. if (!IS_SET(item->GetFlag(), ITEM_FLAG_QUEST_USE | ITEM_FLAG_QUEST_USE_MULTIPLE))
  2017. {
  2018. if (item->GetSIGVnum() == 0)
  2019. {
  2020. quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
  2021. }
  2022.  
  2023. else
  2024. {
  2025. quest::CQuestManager::instance().SIGUse(GetPlayerID(), item->GetSIGVnum(), item, false);
  2026. }
  2027. }
  2028. break;
  2029.  
  2030. case ITEM_CAMPFIRE:
  2031. {
  2032. float fx, fy;
  2033. GetDeltaByDegree(GetRotation(), 100.0f, &fx, &fy);
  2034.  
  2035. LPSECTREE tree = SECTREE_MANAGER::instance().Get(GetMapIndex(), (long)(GetX()+fx), (long)(GetY()+fy));
  2036.  
  2037. if (!tree)
  2038. {
  2039. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("모닥불을 피울 수 없는 지점입니다."));
  2040. return false;
  2041. }
  2042.  
  2043. if (tree->IsAttr((long)(GetX()+fx), (long)(GetY()+fy), ATTR_WATER))
  2044. {
  2045. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("물 속에 모닥불을 피울 수 없습니다."));
  2046. return false;
  2047. }
  2048.  
  2049. LPCHARACTER campfire = CHARACTER_MANAGER::instance().SpawnMob(fishing::CAMPFIRE_MOB, GetMapIndex(), (long)(GetX()+fx), (long)(GetY()+fy), 0, false, number(0, 359));
  2050.  
  2051. char_event_info* info = AllocEventInfo<char_event_info>();
  2052.  
  2053. info->ch = campfire;
  2054.  
  2055. campfire->m_pkMiningEvent = event_create(kill_campfire_event, info, PASSES_PER_SEC(40));
  2056.  
  2057. item->SetCount(item->GetCount() - 0);
  2058. }
  2059. break;
  2060.  
  2061. case ITEM_UNIQUE:
  2062. {
  2063. switch (item->GetSubType())
  2064. {
  2065. case USE_ABILITY_UP:
  2066. {
  2067. switch (item->GetValue(0))
  2068. {
  2069. case APPLY_MOV_SPEED:
  2070. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_MOV_SPEED, item->GetValue(2), AFF_MOV_SPEED_POTION, item->GetValue(1), 0, true, true);
  2071. break;
  2072.  
  2073. case APPLY_ATT_SPEED:
  2074. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_ATT_SPEED, item->GetValue(2), AFF_ATT_SPEED_POTION, item->GetValue(1), 0, true, true);
  2075. break;
  2076.  
  2077. case APPLY_STR:
  2078. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_ST, item->GetValue(2), 0, item->GetValue(1), 0, true, true);
  2079. break;
  2080.  
  2081. case APPLY_DEX:
  2082. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_DX, item->GetValue(2), 0, item->GetValue(1), 0, true, true);
  2083. break;
  2084.  
  2085. case APPLY_CON:
  2086. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_HT, item->GetValue(2), 0, item->GetValue(1), 0, true, true);
  2087. break;
  2088.  
  2089. case APPLY_INT:
  2090. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_IQ, item->GetValue(2), 0, item->GetValue(1), 0, true, true);
  2091. break;
  2092.  
  2093. case APPLY_CAST_SPEED:
  2094. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_CASTING_SPEED, item->GetValue(2), 0, item->GetValue(1), 0, true, true);
  2095. break;
  2096.  
  2097. case APPLY_RESIST_MAGIC:
  2098. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_RESIST_MAGIC, item->GetValue(2), 0, item->GetValue(1), 0, true, true);
  2099. break;
  2100.  
  2101. case APPLY_ATT_GRADE_BONUS:
  2102. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_ATT_GRADE_BONUS,
  2103. item->GetValue(2), 0, item->GetValue(1), 0, true, true);
  2104. break;
  2105.  
  2106. case APPLY_DEF_GRADE_BONUS:
  2107. AddAffect(AFFECT_UNIQUE_ABILITY, POINT_DEF_GRADE_BONUS,
  2108. item->GetValue(2), 0, item->GetValue(1), 0, true, true);
  2109. break;
  2110. }
  2111. }
  2112.  
  2113. if (GetDungeon())
  2114. GetDungeon()->UsePotion(this);
  2115.  
  2116. if (GetWarMap())
  2117. GetWarMap()->UsePotion(this, item);
  2118.  
  2119. item->SetCount(item->GetCount() - 0);
  2120. break;
  2121.  
  2122. default:
  2123. {
  2124. if (item->GetSubType() == USE_SPECIAL)
  2125. {
  2126. sys_log(0, "ITEM_UNIQUE: USE_SPECIAL %u", item->GetVnum());
  2127.  
  2128. switch (item->GetVnum())
  2129. {
  2130. case 71049:
  2131. UseSilkBotary();
  2132. break;
  2133. }
  2134. }
  2135.  
  2136. else
  2137. {
  2138. if (!item->IsEquipped())
  2139. EquipItem(item);
  2140. else
  2141. UnequipItem(item);
  2142. }
  2143. }
  2144. break;
  2145. }
  2146. }
  2147. break;
  2148.  
  2149. case ITEM_COSTUME:
  2150. case ITEM_WEAPON:
  2151. case ITEM_ARMOR:
  2152. case ITEM_ROD:
  2153. case ITEM_RING:
  2154. case ITEM_BELT:
  2155.  
  2156. #ifdef __PET_SYSTEM__
  2157. case ITEM_NORMAL_PET:
  2158. #endif
  2159.  
  2160. case ITEM_PICK:
  2161. if (!item->IsEquipped())
  2162. {
  2163. #ifdef ENABLE_SPAM_ECHIPAMENT
  2164. if (GetQuestFlag("ARMOR.CHECKER") && get_global_time() < GetQuestFlag("ARMOR.CHECKER"))
  2165. {
  2166. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta aici .", (GetQuestFlag("ARMOR.CHECKER") - get_global_time()) % 60);
  2167. return false;
  2168. }
  2169. #endif
  2170. EquipItem(item);
  2171. SetQuestFlag("ARMOR.CHECKER", get_global_time() + 1);
  2172. }
  2173.  
  2174. else
  2175. UnequipItem(item);
  2176. break;
  2177.  
  2178. case ITEM_DS:
  2179. {
  2180. if (!item->IsEquipped())
  2181. return false;
  2182. return DSManager::instance().PullOut(this, NPOS, item);
  2183. break;
  2184. }
  2185.  
  2186. case ITEM_SPECIAL_DS:
  2187. if (!item->IsEquipped())
  2188. EquipItem(item);
  2189. else
  2190. UnequipItem(item);
  2191. break;
  2192.  
  2193. case ITEM_FISH:
  2194. {
  2195. if (CArenaManager::instance().IsArenaMap(GetMapIndex()) == true)
  2196. {
  2197. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta aici .");
  2198. return false;
  2199. }
  2200.  
  2201. if (item->GetSubType() == FISH_ALIVE)
  2202. fishing::UseFish(this, item);
  2203. }
  2204. break;
  2205.  
  2206. case ITEM_TREASURE_BOX:
  2207. {
  2208. return false;
  2209. //ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("열쇠로 잠겨 있어서 열리지 않는것 같다. 열쇠를 구해보자."));
  2210. }
  2211. break;
  2212.  
  2213. case ITEM_TREASURE_KEY:
  2214. {
  2215. LPITEM item2;
  2216.  
  2217. if (!GetItem(DestCell) || !(item2 = GetItem(DestCell)))
  2218. return false;
  2219.  
  2220. if (item2->IsExchanging() || item2->IsEquipped())
  2221. return false;
  2222.  
  2223. if (item2->GetType() != ITEM_TREASURE_BOX)
  2224. {
  2225. ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("열쇠로 여는 물건이 아닌것 같다."));
  2226. return false;
  2227. }
  2228.  
  2229. if (item->GetValue(0) == item2->GetValue(0))
  2230. {
  2231. //ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("열쇠는 맞으나 아이템 주는 부분 구현이 안되었습니다."));
  2232. DWORD dwBoxVnum = item2->GetVnum();
  2233. std::vector <DWORD> dwVnums;
  2234. std::vector <DWORD> dwCounts;
  2235. std::vector <LPITEM> item_gets(NULL);
  2236. int count = 0;
  2237.  
  2238. if (GiveItemFromSpecialItemGroup(dwBoxVnum, dwVnums, dwCounts, item_gets, count))
  2239. {
  2240. ITEM_MANAGER::instance().RemoveItem(item);
  2241. ITEM_MANAGER::instance().RemoveItem(item2);
  2242.  
  2243. for (int i = 0; i < count; i++){
  2244. switch (dwVnums[i])
  2245. {
  2246. case CSpecialItemGroup::GOLD:
  2247. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈 %d 냥을 획득했습니다."), dwCounts[i]);
  2248. break;
  2249.  
  2250. case CSpecialItemGroup::EXP:
  2251. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 부터 신비한 빛이 나옵니다."));
  2252. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d의 경험치를 획득했습니다."), dwCounts[i]);
  2253. break;
  2254.  
  2255. case CSpecialItemGroup::MOB:
  2256. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 몬스터가 나타났습니다!"));
  2257. break;
  2258.  
  2259. case CSpecialItemGroup::SLOW:
  2260. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 나온 빨간 연기를 들이마시자 움직이는 속도가 느려졌습니다!"));
  2261. break;
  2262.  
  2263. case CSpecialItemGroup::DRAIN_HP:
  2264. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자가 갑자기 폭발하였습니다! 생명력이 감소했습니다."));
  2265. break;
  2266.  
  2267. case CSpecialItemGroup::POISON:
  2268. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 나온 녹색 연기를 들이마시자 독이 온몸으로 퍼집니다!"));
  2269. break;
  2270.  
  2271. case CSpecialItemGroup::MOB_GROUP:
  2272. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 몬스터가 나타났습니다!"));
  2273. break;
  2274.  
  2275. default:
  2276. if (item_gets[i])
  2277. {
  2278. if (dwCounts[i] > 1)
  2279. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 %s 가 %d 개 나왔습니다."), item_gets[i]->GetName(), dwCounts[i]);
  2280. else
  2281. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 %s 가 나왔습니다."), item_gets[i]->GetName());
  2282.  
  2283. }
  2284. }
  2285. }
  2286. }
  2287.  
  2288. else
  2289. {
  2290. ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("열쇠가 맞지 않는 것 같다."));
  2291. return false;
  2292. }
  2293. }
  2294.  
  2295. else
  2296. {
  2297. ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("열쇠가 맞지 않는 것 같다."));
  2298. return false;
  2299. }
  2300. }
  2301. break;
  2302.  
  2303. case ITEM_GIFTBOX:
  2304. {
  2305. DWORD dwBoxVnum = item->GetVnum();
  2306. std::vector <DWORD> dwVnums;
  2307. std::vector <DWORD> dwCounts;
  2308. std::vector <LPITEM> item_gets(NULL);
  2309. int count = 0;
  2310.  
  2311. if( (dwBoxVnum > 51500 && dwBoxVnum < 52000) || (dwBoxVnum >= 50255 && dwBoxVnum <= 50260) ) // 용혼원석들
  2312. {
  2313. if( !(this->DragonSoul_IsQualified()) )
  2314. {
  2315. ChatPacket(CHAT_TYPE_INFO,LC_TEXT("먼저 용혼석 퀘스트를 완료하셔야 합니다."));
  2316. return false;
  2317. }
  2318. }
  2319.  
  2320. if (GiveItemFromSpecialItemGroup(dwBoxVnum, dwVnums, dwCounts, item_gets, count))
  2321. {
  2322. item->SetCount(item->GetCount()-1);
  2323.  
  2324. for (int i = 0; i < count; i++){
  2325. switch (dwVnums[i])
  2326. {
  2327. case CSpecialItemGroup::GOLD:
  2328. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈 %d 냥을 획득했습니다."), dwCounts[i]);
  2329. break;
  2330.  
  2331. case CSpecialItemGroup::EXP:
  2332. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 부터 신비한 빛이 나옵니다."));
  2333. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d의 경험치를 획득했습니다."), dwCounts[i]);
  2334. break;
  2335.  
  2336. case CSpecialItemGroup::MOB:
  2337. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 몬스터가 나타났습니다!"));
  2338. break;
  2339.  
  2340. case CSpecialItemGroup::SLOW:
  2341. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 나온 빨간 연기를 들이마시자 움직이는 속도가 느려졌습니다!"));
  2342. break;
  2343.  
  2344. case CSpecialItemGroup::DRAIN_HP:
  2345. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자가 갑자기 폭발하였습니다! 생명력이 감소했습니다."));
  2346. break;
  2347.  
  2348. case CSpecialItemGroup::POISON:
  2349. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 나온 녹색 연기를 들이마시자 독이 온몸으로 퍼집니다!"));
  2350. break;
  2351.  
  2352. case CSpecialItemGroup::MOB_GROUP:
  2353. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 몬스터가 나타났습니다!"));
  2354. break;
  2355.  
  2356. default:
  2357. if (item_gets[i])
  2358. {
  2359. if (dwCounts[i] > 1)
  2360. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 %s 가 %d 개 나왔습니다."), item_gets[i]->GetName(), dwCounts[i]);
  2361. else
  2362. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 %s 가 나왔습니다."), item_gets[i]->GetName());
  2363. }
  2364. }
  2365. }
  2366. }
  2367.  
  2368. else
  2369. {
  2370. ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("아무것도 얻을 수 없었습니다."));
  2371. return false;
  2372. }
  2373. }
  2374. break;
  2375.  
  2376. case ITEM_SKILLFORGET:
  2377. {
  2378. if (!item->GetSocket(0))
  2379. {
  2380. ITEM_MANAGER::instance().RemoveItem(item);
  2381. return false;
  2382. }
  2383.  
  2384. DWORD dwVnum = item->GetSocket(0);
  2385.  
  2386. if (SkillLevelDown(dwVnum))
  2387. {
  2388. ITEM_MANAGER::instance().RemoveItem(item);
  2389. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Succes .");
  2390. }
  2391.  
  2392. else
  2393. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  2394. }
  2395. break;
  2396.  
  2397. case ITEM_SKILLBOOK:
  2398. {
  2399. if (IsPolymorphed())
  2400. {
  2401. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  2402. return false;
  2403. }
  2404.  
  2405. DWORD dwVnum = 0;
  2406.  
  2407. if (item->GetVnum() == 50300)
  2408. {
  2409. dwVnum = item->GetSocket(0);
  2410. }
  2411.  
  2412. else
  2413. {
  2414. dwVnum = item->GetValue(0);
  2415. }
  2416.  
  2417. if (0 == dwVnum)
  2418. {
  2419. ITEM_MANAGER::instance().RemoveItem(item);
  2420.  
  2421. return false;
  2422. }
  2423.  
  2424. if (true == LearnSkillByBook(dwVnum))
  2425. {
  2426.  
  2427. #ifdef ENABLE_BOOKS_STACKFIX
  2428. item->SetCount(item->GetCount() - 0);
  2429. #else
  2430. ITEM_MANAGER::instance().RemoveItem(item);
  2431. #endif
  2432. int iReadDelay = number(SKILLBOOK_DELAY_MIN, SKILLBOOK_DELAY_MAX);
  2433.  
  2434. if (distribution_test_server)
  2435. iReadDelay /= 3;
  2436.  
  2437. SetSkillNextReadTime(dwVnum, get_global_time() + iReadDelay);
  2438. }
  2439. }
  2440. break;
  2441.  
  2442. case ITEM_USE:
  2443. {
  2444. if (item->GetVnum() > 50800 && item->GetVnum() <= 50820)
  2445. {
  2446. if (test_server)
  2447. sys_log (0, "ADD addtional effect : vnum(%d) subtype(%d)", item->GetOriginalVnum(), item->GetSubType());
  2448.  
  2449. int affect_type = AFFECT_EXP_BONUS_EURO_FREE;
  2450. int apply_type = aApplyInfo[item->GetValue(0)].bPointType;
  2451. int apply_value = item->GetValue(2);
  2452. int apply_duration = item->GetValue(1);
  2453.  
  2454. switch (item->GetSubType())
  2455. {
  2456. case USE_ABILITY_UP:
  2457. if (FindAffect(affect_type, apply_type))
  2458. {
  2459. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Licori] > |h|r Folosesti deja acest efect .");
  2460. return false;
  2461. }
  2462.  
  2463. {
  2464. switch (item->GetValue(0))
  2465. {
  2466. case APPLY_MOV_SPEED:
  2467. AddAffect(affect_type, apply_type, apply_value, AFF_MOV_SPEED_POTION, apply_duration, 0, true, true);
  2468. break;
  2469.  
  2470. case APPLY_ATT_SPEED:
  2471. AddAffect(affect_type, apply_type, apply_value, AFF_ATT_SPEED_POTION, apply_duration, 0, true, true);
  2472. break;
  2473.  
  2474. case APPLY_STR:
  2475. case APPLY_DEX:
  2476. case APPLY_CON:
  2477. case APPLY_INT:
  2478. case APPLY_CAST_SPEED:
  2479. case APPLY_RESIST_MAGIC:
  2480. case APPLY_ATT_GRADE_BONUS:
  2481. case APPLY_DEF_GRADE_BONUS:
  2482. AddAffect(affect_type, apply_type, apply_value, 0, apply_duration, 0, true, true);
  2483. break;
  2484. }
  2485. }
  2486.  
  2487. if (GetDungeon())
  2488. GetDungeon()->UsePotion(this);
  2489.  
  2490. if (GetWarMap())
  2491. GetWarMap()->UsePotion(this, item);
  2492.  
  2493. item->SetCount(item->GetCount() - 0);
  2494. break;
  2495.  
  2496. case USE_AFFECT :
  2497. {
  2498. if (FindAffect(AFFECT_EXP_BONUS_EURO_FREE, aApplyInfo[item->GetValue(1)].bPointType))
  2499. {
  2500. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Licori] > |h|r Folosesti deja acest efect .");
  2501. }
  2502.  
  2503. else
  2504. {
  2505. AddAffect(AFFECT_EXP_BONUS_EURO_FREE, aApplyInfo[item->GetValue(1)].bPointType, item->GetValue(2), 0, item->GetValue(3), 0, false, true);
  2506. item->SetCount(item->GetCount() - 0);
  2507. }
  2508. }
  2509. break;
  2510.  
  2511. case USE_POTION_NODELAY:
  2512. {
  2513. if (CArenaManager::instance().IsArenaMap(GetMapIndex()) == true)
  2514. {
  2515. if (quest::CQuestManager::instance().GetEventFlag("arena_potion_limit") > 0)
  2516. {
  2517. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta aici .");
  2518. return false;
  2519. }
  2520.  
  2521. switch (item->GetVnum())
  2522. {
  2523. case 70020 :
  2524. case 71018 :
  2525. case 71019 :
  2526. case 71020 :
  2527. if (quest::CQuestManager::instance().GetEventFlag("arena_potion_limit_count") < 10000)
  2528. {
  2529. if (m_nPotionLimit <= 0)
  2530. {
  2531. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta aici .");
  2532. return false;
  2533. }
  2534. }
  2535. break;
  2536.  
  2537. default :
  2538. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta aici .");
  2539. return false;
  2540. break;
  2541. }
  2542. }
  2543.  
  2544. bool used = false;
  2545.  
  2546. if (item->GetValue(0) != 0)
  2547. {
  2548. if (GetHP() < GetMaxHP())
  2549. {
  2550. PointChange(POINT_HP, item->GetValue(0) * (100 + GetPoint(POINT_POTION_BONUS)) / 100);
  2551. EffectPacket(SE_HPUP_RED);
  2552. used = TRUE;
  2553. }
  2554. }
  2555.  
  2556. if (item->GetValue(1) != 0)
  2557. {
  2558. if (GetSP() < GetMaxSP())
  2559. {
  2560. PointChange(POINT_SP, item->GetValue(1) * (100 + GetPoint(POINT_POTION_BONUS)) / 100);
  2561. EffectPacket(SE_SPUP_BLUE);
  2562. used = TRUE;
  2563. }
  2564. }
  2565.  
  2566. if (item->GetValue(3) != 0)
  2567. {
  2568. if (GetHP() < GetMaxHP())
  2569. {
  2570. PointChange(POINT_HP, item->GetValue(3) * GetMaxHP() / 100);
  2571. EffectPacket(SE_HPUP_RED);
  2572. used = TRUE;
  2573. }
  2574. }
  2575.  
  2576. if (item->GetValue(4) != 0)
  2577. {
  2578. if (GetSP() < GetMaxSP())
  2579. {
  2580. PointChange(POINT_SP, item->GetValue(4) * GetMaxSP() / 100);
  2581. EffectPacket(SE_SPUP_BLUE);
  2582. used = TRUE;
  2583. }
  2584. }
  2585.  
  2586. if (used)
  2587. {
  2588. if (item->GetVnum() == 50085 || item->GetVnum() == 50086)
  2589. {
  2590. if (test_server)
  2591. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("월병 또는 종자 를 사용하였습니다"));
  2592. SetUseSeedOrMoonBottleTime();
  2593. }
  2594. if (GetDungeon())
  2595. GetDungeon()->UsePotion(this);
  2596.  
  2597. if (GetWarMap())
  2598. GetWarMap()->UsePotion(this, item);
  2599.  
  2600. m_nPotionLimit--;
  2601.  
  2602. //RESTRICT_USE_SEED_OR_MOONBOTTLE
  2603. item->SetCount(item->GetCount() - 0);
  2604. //END_RESTRICT_USE_SEED_OR_MOONBOTTLE
  2605. }
  2606. }
  2607. break;
  2608. }
  2609.  
  2610. return true;
  2611. }
  2612.  
  2613.  
  2614. if (item->GetVnum() >= 27863 && item->GetVnum() <= 27883)
  2615. {
  2616. if (CArenaManager::instance().IsArenaMap(GetMapIndex()) == true)
  2617. {
  2618. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련 중에는 이용할 수 없는 물품입니다."));
  2619. return false;
  2620. }
  2621. }
  2622.  
  2623. if (test_server)
  2624. {
  2625. sys_log (0, "USE_ITEM %s Type %d SubType %d vnum %d", item->GetName(), item->GetType(), item->GetSubType(), item->GetOriginalVnum());
  2626. }
  2627.  
  2628. switch (item->GetSubType())
  2629. {
  2630. case USE_TIME_CHARGE_PER:
  2631. {
  2632. LPITEM pDestItem = GetItem(DestCell);
  2633. if (NULL == pDestItem)
  2634. {
  2635. return false;
  2636. }
  2637.  
  2638. if (pDestItem->IsDragonSoul())
  2639. {
  2640. int ret;
  2641. char buf[128];
  2642. if (item->GetVnum() == DRAGON_HEART_VNUM)
  2643. {
  2644. ret = pDestItem->GiveMoreTime_Per((float)item->GetSocket(ITEM_SOCKET_CHARGING_AMOUNT_IDX));
  2645. }
  2646.  
  2647. else
  2648. {
  2649. ret = pDestItem->GiveMoreTime_Per((float)item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
  2650. }
  2651.  
  2652. if (ret > 0)
  2653. {
  2654. if (item->GetVnum() == DRAGON_HEART_VNUM)
  2655. {
  2656. sprintf(buf, "Inc %ds by item{VN:%d SOC%d:%d}", ret, item->GetVnum(), ITEM_SOCKET_CHARGING_AMOUNT_IDX, item->GetSocket(ITEM_SOCKET_CHARGING_AMOUNT_IDX));
  2657. }
  2658.  
  2659. else
  2660. {
  2661. sprintf(buf, "Inc %ds by item{VN:%d VAL%d:%d}", ret, item->GetVnum(), ITEM_VALUE_CHARGING_AMOUNT_IDX, item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
  2662. }
  2663.  
  2664. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d초 만큼 충전되었습니다."), ret);
  2665. item->SetCount(item->GetCount() - 0);
  2666. LogManager::instance().ItemLog(this, item, "DS_CHARGING_SUCCESS", buf);
  2667.  
  2668. return true;
  2669. }
  2670.  
  2671. else
  2672. {
  2673. if (item->GetVnum() == DRAGON_HEART_VNUM)
  2674. {
  2675. sprintf(buf, "No change by item{VN:%d SOC%d:%d}", item->GetVnum(), ITEM_SOCKET_CHARGING_AMOUNT_IDX, item->GetSocket(ITEM_SOCKET_CHARGING_AMOUNT_IDX));
  2676. }
  2677.  
  2678. else
  2679. {
  2680. sprintf(buf, "No change by item{VN:%d VAL%d:%d}", item->GetVnum(), ITEM_VALUE_CHARGING_AMOUNT_IDX, item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
  2681. }
  2682.  
  2683. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("충전할 수 없습니다."));
  2684. LogManager::instance().ItemLog(this, item, "DS_CHARGING_FAILED", buf);
  2685.  
  2686. return false;
  2687. }
  2688. }
  2689.  
  2690. else
  2691. return false;
  2692. }
  2693. break;
  2694.  
  2695. case USE_TIME_CHARGE_FIX:
  2696. {
  2697. LPITEM pDestItem = GetItem(DestCell);
  2698.  
  2699. if (NULL == pDestItem)
  2700. {
  2701. return false;
  2702. }
  2703.  
  2704. if (pDestItem->IsDragonSoul())
  2705. {
  2706. int ret = pDestItem->GiveMoreTime_Fix(item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
  2707. char buf[128];
  2708. if (ret)
  2709. {
  2710. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d초 만큼 충전되었습니다."), ret);
  2711. sprintf(buf, "Increase %ds by item{VN:%d VAL%d:%d}", ret, item->GetVnum(), ITEM_VALUE_CHARGING_AMOUNT_IDX, item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
  2712. LogManager::instance().ItemLog(this, item, "DS_CHARGING_SUCCESS", buf);
  2713. item->SetCount(item->GetCount() - 0);
  2714.  
  2715. return true;
  2716. }
  2717.  
  2718. else
  2719. {
  2720. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("충전할 수 없습니다."));
  2721. sprintf(buf, "No change by item{VN:%d VAL%d:%d}", item->GetVnum(), ITEM_VALUE_CHARGING_AMOUNT_IDX, item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
  2722. LogManager::instance().ItemLog(this, item, "DS_CHARGING_FAILED", buf);
  2723.  
  2724. return false;
  2725. }
  2726. }
  2727.  
  2728. else
  2729. return false;
  2730. }
  2731. break;
  2732. case USE_SPECIAL:
  2733.  
  2734. switch (item->GetVnum())
  2735. {
  2736. case ITEM_NOG_POCKET:
  2737. {
  2738. if (FindAffect(AFFECT_NOG_ABILITY))
  2739. {
  2740. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이미 효과가 걸려 있습니다."));
  2741. return false;
  2742. }
  2743.  
  2744. long time = item->GetValue(0);
  2745. long moveSpeedPer = item->GetValue(1);
  2746. long attPer = item->GetValue(2);
  2747. long expPer = item->GetValue(3);
  2748.  
  2749. AddAffect(AFFECT_NOG_ABILITY, POINT_MOV_SPEED, moveSpeedPer, AFF_MOV_SPEED_POTION, time, 0, true, true);
  2750. AddAffect(AFFECT_NOG_ABILITY, POINT_MALL_ATTBONUS, attPer, AFF_NONE, time, 0, true, true);
  2751. AddAffect(AFFECT_NOG_ABILITY, POINT_MALL_EXPBONUS, expPer, AFF_NONE, time, 0, true, true);
  2752.  
  2753. item->SetCount(item->GetCount() - 0);
  2754. }
  2755. break;
  2756.  
  2757. case ITEM_RAMADAN_CANDY:
  2758. {
  2759. if (FindAffect(AFFECT_RAMADAN_ABILITY))
  2760. {
  2761. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이미 효과가 걸려 있습니다."));
  2762. return false;
  2763. }
  2764.  
  2765. long time = item->GetValue(0);
  2766. long moveSpeedPer = item->GetValue(1);
  2767. long attPer = item->GetValue(2);
  2768. long expPer = item->GetValue(3);
  2769.  
  2770. AddAffect(AFFECT_RAMADAN_ABILITY, POINT_MOV_SPEED, moveSpeedPer, AFF_MOV_SPEED_POTION, time, 0, true, true);
  2771. AddAffect(AFFECT_RAMADAN_ABILITY, POINT_MALL_ATTBONUS, attPer, AFF_NONE, time, 0, true, true);
  2772. AddAffect(AFFECT_RAMADAN_ABILITY, POINT_MALL_EXPBONUS, expPer, AFF_NONE, time, 0, true, true);
  2773.  
  2774. item->SetCount(item->GetCount() - 0);
  2775. }
  2776. break;
  2777.  
  2778. case ITEM_MARRIAGE_RING:
  2779. {
  2780. marriage::TMarriage* pMarriage = marriage::CManager::instance().Get(GetPlayerID());
  2781. if (pMarriage)
  2782. {
  2783. if (pMarriage->ch1 != NULL)
  2784. {
  2785. if (CArenaManager::instance().IsArenaMap(pMarriage->ch1->GetMapIndex()) == true)
  2786. {
  2787. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련 중에는 이용할 수 없는 물품입니다."));
  2788. break;
  2789. }
  2790. }
  2791.  
  2792. if (pMarriage->ch2 != NULL)
  2793. {
  2794. if (CArenaManager::instance().IsArenaMap(pMarriage->ch2->GetMapIndex()) == true)
  2795. {
  2796. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련 중에는 이용할 수 없는 물품입니다."));
  2797. break;
  2798. }
  2799. }
  2800.  
  2801. int consumeSP = CalculateConsumeSP(this);
  2802.  
  2803. if (consumeSP < 0)
  2804. return false;
  2805.  
  2806. PointChange(POINT_SP, -consumeSP, false);
  2807.  
  2808. WarpToPID(pMarriage->GetOther(GetPlayerID()));
  2809. }
  2810.  
  2811. else
  2812. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("결혼 상태가 아니면 결혼반지를 사용할 수 없습니다."));
  2813. }
  2814. break;
  2815.  
  2816. case UNIQUE_ITEM_CAPE_OF_COURAGE:
  2817.  
  2818. case 70057:
  2819. case REWARD_BOX_UNIQUE_ITEM_CAPE_OF_COURAGE:
  2820. AggregateMonster();
  2821. item->SetCount(item->GetCount()-1);
  2822. break;
  2823.  
  2824. case UNIQUE_ITEM_WHITE_FLAG:
  2825. ForgetMyAttacker();
  2826. item->SetCount(item->GetCount()-1);
  2827. break;
  2828.  
  2829. case UNIQUE_ITEM_TREASURE_BOX:
  2830. break;
  2831.  
  2832. case 30093:
  2833. case 30094:
  2834. case 30095:
  2835. case 30096:
  2836. {
  2837. const int MAX_BAG_INFO = 26;
  2838. static struct LuckyBagInfo
  2839. {
  2840. DWORD count;
  2841. int prob;
  2842. DWORD vnum;
  2843. }
  2844.  
  2845. b1[MAX_BAG_INFO] =
  2846. {
  2847. { 1000, 302, 1 },
  2848. { 10, 150, 27002 },
  2849. { 10, 75, 27003 },
  2850. { 10, 100, 27005 },
  2851. { 10, 50, 27006 },
  2852. { 10, 80, 27001 },
  2853. { 10, 50, 27002 },
  2854. { 10, 80, 27004 },
  2855. { 10, 50, 27005 },
  2856. { 1, 10, 50300 },
  2857. { 1, 6, 92 },
  2858. { 1, 2, 132 },
  2859. { 1, 6, 1052 },
  2860. { 1, 2, 1092 },
  2861. { 1, 6, 2082 },
  2862. { 1, 2, 2122 },
  2863. { 1, 6, 3082 },
  2864. { 1, 2, 3122 },
  2865. { 1, 6, 5052 },
  2866. { 1, 2, 5082 },
  2867. { 1, 6, 7082 },
  2868. { 1, 2, 7122 },
  2869. { 1, 1, 11282 },
  2870. { 1, 1, 11482 },
  2871. { 1, 1, 11682 },
  2872. { 1, 1, 11882 },
  2873. };
  2874.  
  2875. struct LuckyBagInfo b2[MAX_BAG_INFO] =
  2876. {
  2877. { 1000, 302, 1 },
  2878. { 10, 150, 27002 },
  2879. { 10, 75, 27002 },
  2880. { 10, 100, 27005 },
  2881. { 10, 50, 27005 },
  2882. { 10, 80, 27001 },
  2883. { 10, 50, 27002 },
  2884. { 10, 80, 27004 },
  2885. { 10, 50, 27005 },
  2886. { 1, 10, 50300 },
  2887. { 1, 6, 92 },
  2888. { 1, 2, 132 },
  2889. { 1, 6, 1052 },
  2890. { 1, 2, 1092 },
  2891. { 1, 6, 2082 },
  2892. { 1, 2, 2122 },
  2893. { 1, 6, 3082 },
  2894. { 1, 2, 3122 },
  2895. { 1, 6, 5052 },
  2896. { 1, 2, 5082 },
  2897. { 1, 6, 7082 },
  2898. { 1, 2, 7122 },
  2899. { 1, 1, 11282 },
  2900. { 1, 1, 11482 },
  2901. { 1, 1, 11682 },
  2902. { 1, 1, 11882 },
  2903. };
  2904.  
  2905. LuckyBagInfo * bi = NULL;
  2906. bi = b1;
  2907.  
  2908. int pct = number(1, 1000);
  2909.  
  2910. int i;
  2911. for (i=0;i<MAX_BAG_INFO;i++)
  2912. {
  2913. if (pct <= bi[i].prob)
  2914. break;
  2915. pct -= bi[i].prob;
  2916. }
  2917. if (i>=MAX_BAG_INFO)
  2918. return false;
  2919.  
  2920. if (bi[i].vnum == 50300)
  2921. {
  2922. GiveRandomSkillBook();
  2923. }
  2924.  
  2925. else if (bi[i].vnum == 1)
  2926. {
  2927. PointChange(POINT_GOLD, 1000, true);
  2928. }
  2929.  
  2930. else
  2931. {
  2932. AutoGiveItem(bi[i].vnum, bi[i].count);
  2933. }
  2934. ITEM_MANAGER::instance().RemoveItem(item);
  2935. }
  2936. break;
  2937.  
  2938. case 50004:
  2939. {
  2940. if (item->GetSocket(0))
  2941. {
  2942. item->SetSocket(0, item->GetSocket(0) + 1);
  2943. }
  2944.  
  2945. else
  2946. {
  2947. int iMapIndex = GetMapIndex();
  2948.  
  2949. PIXEL_POSITION pos;
  2950.  
  2951. if (SECTREE_MANAGER::instance().GetRandomLocation(iMapIndex, pos, 700))
  2952. {
  2953. item->SetSocket(0, 1);
  2954. item->SetSocket(1, pos.x);
  2955. item->SetSocket(2, pos.y);
  2956. }
  2957.  
  2958. else
  2959. {
  2960. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 곳에선 이벤트용 감지기가 동작하지 않는것 같습니다."));
  2961. return false;
  2962. }
  2963. }
  2964.  
  2965. int dist = 0;
  2966. float distance = (DISTANCE_SQRT(GetX()-item->GetSocket(1), GetY()-item->GetSocket(2)));
  2967.  
  2968. if (distance < 1000.0f)
  2969. {
  2970. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이벤트용 감지기가 신비로운 빛을 내며 사라집니다."));
  2971.  
  2972. struct TEventStoneInfo
  2973. {
  2974. DWORD dwVnum;
  2975. int count;
  2976. int prob;
  2977. };
  2978.  
  2979. const int EVENT_STONE_MAX_INFO = 15;
  2980.  
  2981. TEventStoneInfo info_10[EVENT_STONE_MAX_INFO] =
  2982. {
  2983. { 27001, 10, 8 },
  2984. { 27004, 10, 6 },
  2985. { 27002, 10, 12 },
  2986. { 27005, 10, 12 },
  2987. { 27100, 1, 9 },
  2988. { 27103, 1, 9 },
  2989. { 27101, 1, 10 },
  2990. { 27104, 1, 10 },
  2991. { 27999, 1, 12 },
  2992.  
  2993. { 25040, 1, 4 },
  2994.  
  2995. { 27410, 1, 0 },
  2996. { 27600, 1, 0 },
  2997. { 25100, 1, 0 },
  2998.  
  2999. { 50001, 1, 0 },
  3000. { 50003, 1, 1 },
  3001. };
  3002.  
  3003. TEventStoneInfo info_7[EVENT_STONE_MAX_INFO] =
  3004. {
  3005. { 27001, 10, 1 },
  3006. { 27004, 10, 1 },
  3007. { 27004, 10, 9 },
  3008. { 27005, 10, 9 },
  3009. { 27100, 1, 5 },
  3010. { 27103, 1, 5 },
  3011. { 27101, 1, 10 },
  3012. { 27104, 1, 10 },
  3013. { 27999, 1, 14 },
  3014.  
  3015. { 25040, 1, 5 },
  3016.  
  3017. { 27410, 1, 5 },
  3018. { 27600, 1, 5 },
  3019. { 25100, 1, 5 },
  3020.  
  3021. { 50001, 1, 0 },
  3022. { 50003, 1, 5 },
  3023.  
  3024. };
  3025.  
  3026. TEventStoneInfo info_4[EVENT_STONE_MAX_INFO] =
  3027. {
  3028. { 27001, 10, 0 },
  3029. { 27004, 10, 0 },
  3030. { 27002, 10, 0 },
  3031. { 27005, 10, 0 },
  3032. { 27100, 1, 0 },
  3033. { 27103, 1, 0 },
  3034. { 27101, 1, 0 },
  3035. { 27104, 1, 0 },
  3036. { 27999, 1, 25 },
  3037.  
  3038. { 25040, 1, 0 },
  3039.  
  3040. { 27410, 1, 0 },
  3041. { 27600, 1, 0 },
  3042. { 25100, 1, 15 },
  3043.  
  3044. { 50001, 1, 10 },
  3045. { 50003, 1, 50 },
  3046. };
  3047.  
  3048. {
  3049. TEventStoneInfo* info;
  3050. if (item->GetSocket(0) <= 4)
  3051. info = info_4;
  3052.  
  3053. else if (item->GetSocket(0) <= 7)
  3054. info = info_7;
  3055.  
  3056. else
  3057. info = info_10;
  3058.  
  3059. int prob = number(1, 100);
  3060.  
  3061. for (int i = 0; i < EVENT_STONE_MAX_INFO; ++i)
  3062. {
  3063. if (!info[i].prob)
  3064. continue;
  3065.  
  3066. if (prob <= info[i].prob)
  3067. {
  3068. AutoGiveItem(info[i].dwVnum, info[i].count);
  3069. break;
  3070. }
  3071.  
  3072. prob -= info[i].prob;
  3073. }
  3074. }
  3075.  
  3076. char chatbuf[CHAT_MAX_LEN + 1];
  3077. int len = snprintf(chatbuf, sizeof(chatbuf), "StoneDetect %u 0 0", (DWORD)GetVID());
  3078.  
  3079. if (len < 0 || len >= (int) sizeof(chatbuf))
  3080. len = sizeof(chatbuf) - 1;
  3081.  
  3082. ++len;
  3083.  
  3084. TPacketGCChat pack_chat;
  3085. pack_chat.header = HEADER_GC_CHAT;
  3086. pack_chat.size = sizeof(TPacketGCChat) + len;
  3087. pack_chat.type = CHAT_TYPE_COMMAND;
  3088. pack_chat.id = 0;
  3089. pack_chat.bEmpire = GetDesc()->GetEmpire();
  3090. //pack_chat.id = vid;
  3091.  
  3092. TEMP_BUFFER buf;
  3093. buf.write(&pack_chat, sizeof(TPacketGCChat));
  3094. buf.write(chatbuf, len);
  3095.  
  3096. PacketAround(buf.read_peek(), buf.size());
  3097.  
  3098. ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (DETECT_EVENT_STONE) 1");
  3099.  
  3100. return true;
  3101. }
  3102.  
  3103. else if (distance < 20000)
  3104. dist = 1;
  3105.  
  3106. else if (distance < 70000)
  3107. dist = 2;
  3108.  
  3109. else
  3110. dist = 3;
  3111.  
  3112. const int STONE_DETECT_MAX_TRY = 10;
  3113. if (item->GetSocket(0) >= STONE_DETECT_MAX_TRY)
  3114. {
  3115. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이벤트용 감지기가 흔적도 없이 사라집니다."));
  3116. ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (DETECT_EVENT_STONE) 0");
  3117. AutoGiveItem(27002);
  3118. return true;
  3119. }
  3120.  
  3121. if (dist)
  3122. {
  3123. char chatbuf[CHAT_MAX_LEN + 1];
  3124. int len = snprintf(chatbuf, sizeof(chatbuf),
  3125. "StoneDetect %u %d %d",
  3126. (DWORD)GetVID(), dist, (int)GetDegreeFromPositionXY(GetX(), item->GetSocket(2), item->GetSocket(1), GetY()));
  3127.  
  3128. if (len < 0 || len >= (int) sizeof(chatbuf))
  3129. len = sizeof(chatbuf) - 1;
  3130.  
  3131. ++len;
  3132.  
  3133. TPacketGCChat pack_chat;
  3134. pack_chat.header = HEADER_GC_CHAT;
  3135. pack_chat.size = sizeof(TPacketGCChat) + len;
  3136. pack_chat.type = CHAT_TYPE_COMMAND;
  3137. pack_chat.id = 0;
  3138. pack_chat.bEmpire = GetDesc()->GetEmpire();
  3139. //pack_chat.id = vid;
  3140.  
  3141. TEMP_BUFFER buf;
  3142. buf.write(&pack_chat, sizeof(TPacketGCChat));
  3143. buf.write(chatbuf, len);
  3144.  
  3145. PacketAround(buf.read_peek(), buf.size());
  3146. }
  3147. }
  3148. break;
  3149.  
  3150. case 27989:
  3151. case 76006:
  3152. {
  3153. LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(GetMapIndex());
  3154.  
  3155. if (pMap != NULL)
  3156. {
  3157. item->SetSocket(0, item->GetSocket(0) + 1);
  3158.  
  3159. FFindStone f;
  3160.  
  3161. // <Factor> SECTREE::for_each -> SECTREE::for_each_entity
  3162. pMap->for_each(f);
  3163.  
  3164. if (f.m_mapStone.size() > 0)
  3165. {
  3166. std::map<DWORD, LPCHARACTER>::iterator stone = f.m_mapStone.begin();
  3167.  
  3168. DWORD max = UINT_MAX;
  3169. LPCHARACTER pTarget = stone->second;
  3170.  
  3171. while (stone != f.m_mapStone.end())
  3172. {
  3173. DWORD dist = (DWORD)DISTANCE_SQRT(GetX()-stone->second->GetX(), GetY()-stone->second->GetY());
  3174.  
  3175. if (dist != 0 && max > dist)
  3176. {
  3177. max = dist;
  3178. pTarget = stone->second;
  3179. }
  3180.  
  3181. stone++;
  3182. }
  3183.  
  3184. if (pTarget != NULL)
  3185. {
  3186. int val = 3;
  3187.  
  3188. if (max < 10000) val = 2;
  3189. else if (max < 70000) val = 1;
  3190.  
  3191. ChatPacket(CHAT_TYPE_COMMAND, "StoneDetect %u %d %d", (DWORD)GetVID(), val,
  3192. (int)GetDegreeFromPositionXY(GetX(), pTarget->GetY(), pTarget->GetX(), GetY()));
  3193. }
  3194.  
  3195. else
  3196. {
  3197. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("감지기를 작용하였으나 감지되는 영석이 없습니다."));
  3198. }
  3199. }
  3200.  
  3201. else
  3202. {
  3203. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("감지기를 작용하였으나 감지되는 영석이 없습니다."));
  3204. }
  3205.  
  3206. if (item->GetSocket(0) >= 6)
  3207. {
  3208. ChatPacket(CHAT_TYPE_COMMAND, "StoneDetect %u 0 0", (DWORD)GetVID());
  3209. ITEM_MANAGER::instance().RemoveItem(item);
  3210. }
  3211. }
  3212.  
  3213. break;
  3214. }
  3215. break;
  3216.  
  3217. case 27996: // 독병
  3218. item->SetCount(item->GetCount() - 0);
  3219. /*if (GetSkillLevel(SKILL_CREATE_POISON))
  3220. AddAffect(AFFECT_ATT_GRADE, POINT_ATT_GRADE, 3, AFF_DRINK_POISON, 15*60, 0, true);
  3221. else
  3222. {
  3223. // 독다루기가 없으면 50% 즉사 50% 공격력 +2
  3224. if (number(0, 1))
  3225. {
  3226. if (GetHP() > 100)
  3227. PointChange(POINT_HP, -(GetHP() - 1));
  3228. else
  3229. Dead();
  3230. }
  3231. else
  3232. AddAffect(AFFECT_ATT_GRADE, POINT_ATT_GRADE, 2, AFF_DRINK_POISON, 15*60, 0, true);
  3233. }*/
  3234. break;
  3235.  
  3236. case 27987:
  3237. {
  3238. item->SetCount(item->GetCount() - 0);
  3239.  
  3240. int r = number(1, 100);
  3241.  
  3242. if (r <= 50)
  3243. {
  3244. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("조개에서 돌조각이 나왔습니다."));
  3245. AutoGiveItem(27990);
  3246. }
  3247.  
  3248. else
  3249. {
  3250. const int prob_table_euckr[] =
  3251. {
  3252. 80, 90, 97
  3253. };
  3254.  
  3255. const int * prob_table = prob_table_euckr;
  3256.  
  3257. if (r <= prob_table[0])
  3258. {
  3259. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("조개가 흔적도 없이 사라집니다."));
  3260. }
  3261.  
  3262. else if (r <= prob_table[1])
  3263. {
  3264. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("조개에서 백진주가 나왔습니다."));
  3265. AutoGiveItem(27992);
  3266. }
  3267.  
  3268. else if (r <= prob_table[2])
  3269. {
  3270. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("조개에서 청진주가 나왔습니다."));
  3271. AutoGiveItem(27993);
  3272. }
  3273.  
  3274. else
  3275. {
  3276. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("조개에서 피진주가 나왔습니다."));
  3277. AutoGiveItem(27994);
  3278. }
  3279. }
  3280. }
  3281. break;
  3282.  
  3283. case 71013:
  3284. CreateFly(number(FLY_FIREWORK1, FLY_FIREWORK6), this);
  3285. item->SetCount(item->GetCount() - 0);
  3286. break;
  3287.  
  3288. case 50100:
  3289. case 50101:
  3290. case 50102:
  3291. case 50103:
  3292. case 50104:
  3293. case 50105:
  3294. case 50106:
  3295. CreateFly(item->GetVnum() - 50100 + FLY_FIREWORK1, this);
  3296. item->SetCount(item->GetCount() - 0);
  3297. break;
  3298.  
  3299. case 50200:
  3300. __OpenPrivateShop();
  3301. break;
  3302.  
  3303. case fishing::FISH_MIND_PILL_VNUM:
  3304. AddAffect(AFFECT_FISH_MIND_PILL, POINT_NONE, 0, AFF_FISH_MIND, 20*60, 0, true);
  3305. item->SetCount(item->GetCount() - 0);
  3306. break;
  3307.  
  3308. case 50301:
  3309. case 50302:
  3310. case 50303:
  3311. {
  3312. if (IsPolymorphed() == true)
  3313. {
  3314. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다."));
  3315. return false;
  3316. }
  3317.  
  3318. int lv = GetSkillLevel(SKILL_LEADERSHIP);
  3319.  
  3320. if (lv < item->GetValue(0))
  3321. {
  3322. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 책은 너무 어려워 이해하기가 힘듭니다."));
  3323. return false;
  3324. }
  3325.  
  3326. if (lv >= item->GetValue(1))
  3327. {
  3328. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 책은 아무리 봐도 도움이 될 것 같지 않습니다."));
  3329. return false;
  3330. }
  3331.  
  3332. if (LearnSkillByBook(SKILL_LEADERSHIP))
  3333. {
  3334. #ifdef ENABLE_BOOKS_STACKFIX
  3335. item->SetCount(item->GetCount() - 0);
  3336. #else
  3337. ITEM_MANAGER::instance().RemoveItem(item);
  3338. #endif
  3339.  
  3340. int iReadDelay = number(SKILLBOOK_DELAY_MIN, SKILLBOOK_DELAY_MAX);
  3341. if (distribution_test_server) iReadDelay /= 3;
  3342.  
  3343. SetSkillNextReadTime(SKILL_LEADERSHIP, get_global_time() + iReadDelay);
  3344. }
  3345. }
  3346. break;
  3347.  
  3348. case 50304:
  3349. case 50305:
  3350. case 50306:
  3351. {
  3352. if (IsPolymorphed())
  3353. {
  3354. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("변신중에는 책을 읽을수 없습니다."));
  3355. return false;
  3356.  
  3357. }
  3358.  
  3359. if (GetSkillLevel(SKILL_COMBO) == 0 && GetLevel() < 30)
  3360. {
  3361. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("레벨 30이 되기 전에는 습득할 수 있을 것 같지 않습니다."));
  3362. return false;
  3363. }
  3364.  
  3365. if (GetSkillLevel(SKILL_COMBO) == 1 && GetLevel() < 50)
  3366. {
  3367. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("레벨 50이 되기 전에는 습득할 수 있을 것 같지 않습니다."));
  3368. return false;
  3369. }
  3370.  
  3371. if (GetSkillLevel(SKILL_COMBO) >= 2)
  3372. {
  3373. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("연계기는 더이상 수련할 수 없습니다."));
  3374. return false;
  3375. }
  3376.  
  3377. int iPct = item->GetValue(0);
  3378.  
  3379. if (LearnSkillByBook(SKILL_COMBO, iPct))
  3380. {
  3381. #ifdef ENABLE_BOOKS_STACKFIX
  3382. item->SetCount(item->GetCount() - 0);
  3383. #else
  3384. ITEM_MANAGER::instance().RemoveItem(item);
  3385. #endif
  3386.  
  3387. int iReadDelay = number(SKILLBOOK_DELAY_MIN, SKILLBOOK_DELAY_MAX);
  3388. if (distribution_test_server) iReadDelay /= 3;
  3389.  
  3390. SetSkillNextReadTime(SKILL_COMBO, get_global_time() + iReadDelay);
  3391. }
  3392. }
  3393. break;
  3394.  
  3395. case 50311:
  3396. case 50312:
  3397. case 50313:
  3398. {
  3399. if (IsPolymorphed())
  3400. {
  3401. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("변신중에는 책을 읽을수 없습니다."));
  3402. return false;
  3403. }
  3404.  
  3405. DWORD dwSkillVnum = item->GetValue(0);
  3406. int iPct = MINMAX(0, item->GetValue(1), 100);
  3407.  
  3408. if (GetSkillLevel(dwSkillVnum)>=20 || dwSkillVnum-SKILL_LANGUAGE1+1 == GetEmpire())
  3409. {
  3410. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이미 완벽하게 알아들을 수 있는 언어이다."));
  3411. return false;
  3412. }
  3413.  
  3414. if (LearnSkillByBook(dwSkillVnum, iPct))
  3415. {
  3416. #ifdef ENABLE_BOOKS_STACKFIX
  3417. item->SetCount(item->GetCount() - 0);
  3418. #else
  3419. ITEM_MANAGER::instance().RemoveItem(item);
  3420. #endif
  3421. int iReadDelay = number(SKILLBOOK_DELAY_MIN, SKILLBOOK_DELAY_MAX);
  3422. if (distribution_test_server) iReadDelay /= 3;
  3423.  
  3424. SetSkillNextReadTime(dwSkillVnum, get_global_time() + iReadDelay);
  3425. }
  3426. }
  3427. break;
  3428.  
  3429. case 50061 : // 일본 말 소환 스킬 수련서
  3430. {
  3431. if (IsPolymorphed())
  3432. {
  3433. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("변신중에는 책을 읽을수 없습니다."));
  3434. return false;
  3435.  
  3436. }
  3437.  
  3438. DWORD dwSkillVnum = item->GetValue(0);
  3439. int iPct = MINMAX(0, item->GetValue(1), 100);
  3440.  
  3441. if (GetSkillLevel(dwSkillVnum) >= 10)
  3442. {
  3443. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("더 이상 수련할 수 없습니다."));
  3444. return false;
  3445. }
  3446.  
  3447. if (LearnSkillByBook(dwSkillVnum, iPct))
  3448. {
  3449. #ifdef ENABLE_BOOKS_STACKFIX
  3450. item->SetCount(item->GetCount() - 0);
  3451. #else
  3452. ITEM_MANAGER::instance().RemoveItem(item);
  3453. #endif
  3454. int iReadDelay = number(SKILLBOOK_DELAY_MIN, SKILLBOOK_DELAY_MAX);
  3455. if (distribution_test_server) iReadDelay /= 3;
  3456.  
  3457. SetSkillNextReadTime(dwSkillVnum, get_global_time() + iReadDelay);
  3458. }
  3459. }
  3460. break;
  3461.  
  3462. case 50314: case 50315: case 50316:
  3463. case 50323: case 50324:
  3464. case 50325: case 50326:
  3465. {
  3466. if (IsPolymorphed() == true)
  3467. {
  3468. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다."));
  3469. return false;
  3470. }
  3471.  
  3472. int iSkillLevelLowLimit = item->GetValue(0);
  3473. int iSkillLevelHighLimit = item->GetValue(1);
  3474. int iPct = MINMAX(0, item->GetValue(2), 100);
  3475. int iLevelLimit = item->GetValue(3);
  3476.  
  3477. DWORD dwSkillVnum = 0;
  3478.  
  3479. switch (item->GetVnum())
  3480. {
  3481. case 50314: case 50315: case 50316:
  3482. dwSkillVnum = SKILL_POLYMORPH;
  3483. break;
  3484.  
  3485. case 50323: case 50324:
  3486. dwSkillVnum = SKILL_ADD_HP;
  3487. break;
  3488.  
  3489. case 50325: case 50326:
  3490. dwSkillVnum = SKILL_RESIST_PENETRATE;
  3491. break;
  3492.  
  3493. default:
  3494. return false;
  3495. }
  3496.  
  3497. if (0 == dwSkillVnum)
  3498. return false;
  3499.  
  3500. if (GetLevel() < iLevelLimit)
  3501. {
  3502. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 책을 읽으려면 레벨을 더 올려야 합니다."));
  3503. return false;
  3504. }
  3505.  
  3506. if (GetSkillLevel(dwSkillVnum) >= 40)
  3507. {
  3508. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("더 이상 수련할 수 없습니다."));
  3509. return false;
  3510. }
  3511.  
  3512. if (GetSkillLevel(dwSkillVnum) < iSkillLevelLowLimit)
  3513. {
  3514. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 책은 너무 어려워 이해하기가 힘듭니다."));
  3515. return false;
  3516. }
  3517.  
  3518. if (GetSkillLevel(dwSkillVnum) >= iSkillLevelHighLimit)
  3519. {
  3520. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 책으로는 더 이상 수련할 수 없습니다."));
  3521. return false;
  3522. }
  3523.  
  3524. if (LearnSkillByBook(dwSkillVnum, iPct))
  3525. {
  3526. #ifdef ENABLE_BOOKS_STACKFIX
  3527. item->SetCount(item->GetCount() - 0);
  3528. #else
  3529. ITEM_MANAGER::instance().RemoveItem(item);
  3530. #endif
  3531.  
  3532. int iReadDelay = number(SKILLBOOK_DELAY_MIN, SKILLBOOK_DELAY_MAX);
  3533. if (distribution_test_server) iReadDelay /= 3;
  3534.  
  3535. SetSkillNextReadTime(dwSkillVnum, get_global_time() + iReadDelay);
  3536. }
  3537. }
  3538. break;
  3539.  
  3540. case 50902:
  3541. case 50903:
  3542. case 50904:
  3543. {
  3544. if (IsPolymorphed())
  3545. {
  3546. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("변신중에는 책을 읽을수 없습니다."));
  3547. return false;
  3548.  
  3549. }
  3550.  
  3551. DWORD dwSkillVnum = SKILL_CREATE;
  3552. int iPct = MINMAX(0, item->GetValue(1), 100);
  3553.  
  3554. if (GetSkillLevel(dwSkillVnum)>=40)
  3555. {
  3556. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("더 이상 수련할 수 없습니다."));
  3557. return false;
  3558. }
  3559.  
  3560. if (LearnSkillByBook(dwSkillVnum, iPct))
  3561. {
  3562. #ifdef ENABLE_BOOKS_STACKFIX
  3563. item->SetCount(item->GetCount() - 0);
  3564. #else
  3565. ITEM_MANAGER::instance().RemoveItem(item);
  3566. #endif
  3567. int iReadDelay = number(SKILLBOOK_DELAY_MIN, SKILLBOOK_DELAY_MAX);
  3568. if (distribution_test_server) iReadDelay /= 3;
  3569.  
  3570. SetSkillNextReadTime(dwSkillVnum, get_global_time() + iReadDelay);
  3571.  
  3572. if (test_server)
  3573. {
  3574. ChatPacket(CHAT_TYPE_INFO, "[TEST_SERVER] Success to learn skill ");
  3575. }
  3576. }
  3577.  
  3578. else
  3579. {
  3580. if (test_server)
  3581. {
  3582. ChatPacket(CHAT_TYPE_INFO, "[TEST_SERVER] Failed to learn skill ");
  3583. }
  3584. }
  3585. }
  3586. break;
  3587.  
  3588. case ITEM_MINING_SKILL_TRAIN_BOOK:
  3589. {
  3590. if (IsPolymorphed())
  3591. {
  3592. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("변신중에는 책을 읽을수 없습니다."));
  3593. return false;
  3594.  
  3595. }
  3596.  
  3597. DWORD dwSkillVnum = SKILL_MINING;
  3598. int iPct = MINMAX(0, item->GetValue(1), 100);
  3599.  
  3600. if (GetSkillLevel(dwSkillVnum)>=40)
  3601. {
  3602. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("더 이상 수련할 수 없습니다."));
  3603. return false;
  3604. }
  3605.  
  3606. if (LearnSkillByBook(dwSkillVnum, iPct))
  3607. {
  3608. #ifdef ENABLE_BOOKS_STACKFIX
  3609. item->SetCount(item->GetCount() - 0);
  3610. #else
  3611. ITEM_MANAGER::instance().RemoveItem(item);
  3612. #endif
  3613. int iReadDelay = number(SKILLBOOK_DELAY_MIN, SKILLBOOK_DELAY_MAX);
  3614. if (distribution_test_server) iReadDelay /= 3;
  3615.  
  3616. SetSkillNextReadTime(dwSkillVnum, get_global_time() + iReadDelay);
  3617. }
  3618. }
  3619. break;
  3620.  
  3621. case ITEM_HORSE_SKILL_TRAIN_BOOK:
  3622. {
  3623. if (IsPolymorphed())
  3624. {
  3625. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("변신중에는 책을 읽을수 없습니다."));
  3626. return false;
  3627.  
  3628. }
  3629.  
  3630. DWORD dwSkillVnum = SKILL_HORSE;
  3631. int iPct = MINMAX(0, item->GetValue(1), 100);
  3632.  
  3633. if (GetLevel() < 50)
  3634. {
  3635. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아직 승마 스킬을 수련할 수 있는 레벨이 아닙니다."));
  3636. return false;
  3637. }
  3638.  
  3639. if (!test_server && get_global_time() < GetSkillNextReadTime(dwSkillVnum))
  3640. {
  3641. if (FindAffect(AFFECT_SKILL_NO_BOOK_DELAY))
  3642. {
  3643. RemoveAffect(AFFECT_SKILL_NO_BOOK_DELAY);
  3644. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("주안술서를 통해 주화입마에서 빠져나왔습니다."));
  3645. }
  3646.  
  3647. else
  3648. {
  3649. SkillLearnWaitMoreTimeMessage(GetSkillNextReadTime(dwSkillVnum) - get_global_time());
  3650. return false;
  3651. }
  3652. }
  3653.  
  3654. if (GetPoint(POINT_HORSE_SKILL) >= 20 ||
  3655. GetSkillLevel(SKILL_HORSE_WILDATTACK) + GetSkillLevel(SKILL_HORSE_CHARGE) + GetSkillLevel(SKILL_HORSE_ESCAPE) >= 60 ||
  3656. GetSkillLevel(SKILL_HORSE_WILDATTACK_RANGE) + GetSkillLevel(SKILL_HORSE_CHARGE) + GetSkillLevel(SKILL_HORSE_ESCAPE) >= 60)
  3657. {
  3658. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("더 이상 승마 수련서를 읽을 수 없습니다."));
  3659. return false;
  3660. }
  3661.  
  3662. if (number(1, 100) <= iPct)
  3663. {
  3664. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("승마 수련서를 읽어 승마 스킬 포인트를 얻었습니다."));
  3665. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("얻은 포인트로는 승마 스킬의 레벨을 올릴 수 있습니다."));
  3666. PointChange(POINT_HORSE_SKILL, 1);
  3667.  
  3668. int iReadDelay = number(SKILLBOOK_DELAY_MIN, SKILLBOOK_DELAY_MAX);
  3669. if (distribution_test_server) iReadDelay /= 3;
  3670.  
  3671. if (!test_server)
  3672. SetSkillNextReadTime(dwSkillVnum, get_global_time() + iReadDelay);
  3673. }
  3674.  
  3675. else
  3676. {
  3677. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("승마 수련서 이해에 실패하였습니다."));
  3678. }
  3679. #ifdef ENABLE_BOOKS_STACKFIX
  3680. item->SetCount(item->GetCount() - 0);
  3681. #else
  3682. ITEM_MANAGER::instance().RemoveItem(item);
  3683. #endif
  3684. }
  3685. break;
  3686.  
  3687. case 70102:
  3688. case 70103:
  3689. {
  3690. if (GetAlignment() >= 0)
  3691. return false;
  3692.  
  3693. int delta = MIN(-GetAlignment(), item->GetValue(0));
  3694.  
  3695. sys_log(0, "%s ALIGNMENT ITEM %d", GetName(), delta);
  3696.  
  3697. UpdateAlignment(delta);
  3698. item->SetCount(item->GetCount() - 0);
  3699.  
  3700. if (delta / 10 > 0)
  3701. {
  3702. ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("마음이 맑아지는군. 가슴을 짓누르던 무언가가 좀 가벼워진 느낌이야."));
  3703. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("선악치가 %d 증가하였습니다."), delta/10);
  3704. }
  3705. }
  3706. break;
  3707.  
  3708. case 71107:
  3709. {
  3710. int val = item->GetValue(0);
  3711. int interval = item->GetValue(1);
  3712. quest::PC* pPC = quest::CQuestManager::instance().GetPC(GetPlayerID());
  3713. int last_use_time = pPC->GetFlag("mythical_peach.last_use_time");
  3714.  
  3715. if (get_global_time() - last_use_time < interval * 60 * 60)
  3716. {
  3717. if (test_server == false)
  3718. {
  3719. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아직 사용할 수 없습니다."));
  3720. return false;
  3721. }
  3722.  
  3723. else
  3724. {
  3725. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("테스트 서버 시간제한 통과"));
  3726. }
  3727. }
  3728.  
  3729. if (GetAlignment() == 200000)
  3730. {
  3731. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("선악치를 더 이상 올릴 수 없습니다."));
  3732. return false;
  3733. }
  3734.  
  3735. if (200000 - GetAlignment() < val * 10)
  3736. {
  3737. val = (200000 - GetAlignment()) / 10;
  3738. }
  3739.  
  3740. int old_alignment = GetAlignment() / 10;
  3741.  
  3742. UpdateAlignment(val*10);
  3743.  
  3744. item->SetCount(item->GetCount()-1);
  3745. pPC->SetFlag("mythical_peach.last_use_time", get_global_time());
  3746.  
  3747. ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("마음이 맑아지는군. 가슴을 짓누르던 무언가가 좀 가벼워진 느낌이야."));
  3748. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("선악치가 %d 증가하였습니다."), val);
  3749.  
  3750. char buf[256 + 1];
  3751. snprintf(buf, sizeof(buf), "%d %d", old_alignment, GetAlignment() / 10);
  3752. LogManager::instance().CharLog(this, val, "MYTHICAL_PEACH", buf);
  3753. }
  3754. break;
  3755.  
  3756. case 71109:
  3757. case 72719:
  3758. {
  3759. LPITEM item2;
  3760.  
  3761. if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
  3762. return false;
  3763.  
  3764. if (item2->IsExchanging() || item2->IsEquipped())
  3765. return false;
  3766.  
  3767. if (item2->GetSocketCount() == 0)
  3768. return false;
  3769.  
  3770. switch( item2->GetType() )
  3771. {
  3772. case ITEM_WEAPON:
  3773. break;
  3774.  
  3775. case ITEM_ARMOR:
  3776. switch (item2->GetSubType())
  3777. {
  3778. case ARMOR_EAR:
  3779. case ARMOR_WRIST:
  3780. case ARMOR_NECK:
  3781. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("빼낼 영석이 없습니다"));
  3782. return false;
  3783. }
  3784. break;
  3785.  
  3786. default:
  3787. return false;
  3788. }
  3789.  
  3790. std::stack<long> socket;
  3791.  
  3792. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  3793. socket.push(item2->GetSocket(i));
  3794.  
  3795. int idx = ITEM_SOCKET_MAX_NUM - 1;
  3796.  
  3797. while (socket.size() > 0)
  3798. {
  3799. if (socket.top() > 2 && socket.top() != ITEM_BROKEN_METIN_VNUM)
  3800. break;
  3801.  
  3802. idx--;
  3803. socket.pop();
  3804. }
  3805.  
  3806. if (socket.size() == 0)
  3807. {
  3808. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("빼낼 영석이 없습니다"));
  3809. return false;
  3810. }
  3811.  
  3812. LPITEM pItemReward = AutoGiveItem(socket.top());
  3813.  
  3814. if (pItemReward != NULL)
  3815. {
  3816. item2->SetSocket(idx, 1);
  3817.  
  3818. char buf[256+1];
  3819. snprintf(buf, sizeof(buf), "%s(%u) %s(%u)",
  3820. item2->GetName(), item2->GetID(), pItemReward->GetName(), pItemReward->GetID());
  3821. LogManager::instance().ItemLog(this, item, "USE_DETACHMENT_ONE", buf);
  3822.  
  3823. item->SetCount(item->GetCount() - 0);
  3824. }
  3825. }
  3826. break;
  3827.  
  3828. case 70201:
  3829. case 70202:
  3830. case 70203:
  3831. case 70204:
  3832. case 70205:
  3833. case 70206:
  3834. {
  3835. if (GetPart(PART_HAIR) >= 1001)
  3836. {
  3837. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("현재 헤어스타일에서는 염색과 탈색이 불가능합니다."));
  3838. }
  3839.  
  3840. else
  3841. {
  3842. quest::CQuestManager& q = quest::CQuestManager::instance();
  3843. quest::PC* pPC = q.GetPC(GetPlayerID());
  3844.  
  3845. if (pPC)
  3846. {
  3847. int last_dye_level = pPC->GetFlag("dyeing_hair.last_dye_level");
  3848.  
  3849. if (last_dye_level == 0 ||
  3850. last_dye_level+3 <= GetLevel() ||
  3851. item->GetVnum() == 70201)
  3852. {
  3853. SetPart(PART_HAIR, item->GetVnum() - 70201);
  3854.  
  3855. if (item->GetVnum() == 70201)
  3856. pPC->SetFlag("dyeing_hair.last_dye_level", 0);
  3857. else
  3858. pPC->SetFlag("dyeing_hair.last_dye_level", GetLevel());
  3859.  
  3860. item->SetCount(item->GetCount() - 0);
  3861. UpdatePacket();
  3862. }
  3863.  
  3864. else
  3865. {
  3866. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d 레벨이 되어야 다시 염색하실 수 있습니다."), last_dye_level+3);
  3867. }
  3868. }
  3869. }
  3870. }
  3871. break;
  3872.  
  3873. case ITEM_NEW_YEAR_GREETING_VNUM:
  3874. {
  3875. DWORD dwBoxVnum = ITEM_NEW_YEAR_GREETING_VNUM;
  3876. std::vector <DWORD> dwVnums;
  3877. std::vector <DWORD> dwCounts;
  3878. std::vector <LPITEM> item_gets;
  3879. int count = 0;
  3880.  
  3881. if (GiveItemFromSpecialItemGroup(dwBoxVnum, dwVnums, dwCounts, item_gets, count))
  3882. {
  3883. for (int i = 0; i < count; i++)
  3884. {
  3885. if (dwVnums[i] == CSpecialItemGroup::GOLD)
  3886. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈 %d 냥을 획득했습니다."), dwCounts[i]);
  3887. }
  3888.  
  3889. item->SetCount(item->GetCount() - 0);
  3890. }
  3891. }
  3892. break;
  3893.  
  3894. case ITEM_VALENTINE_ROSE:
  3895. case ITEM_VALENTINE_CHOCOLATE:
  3896. {
  3897. DWORD dwBoxVnum = item->GetVnum();
  3898.  
  3899. std::vector <DWORD> dwVnums;
  3900. std::vector <DWORD> dwCounts;
  3901. std::vector <LPITEM> item_gets(NULL);
  3902.  
  3903. int count = 0;
  3904.  
  3905. if (item->GetVnum() == ITEM_VALENTINE_ROSE && SEX_MALE==GET_SEX(this) || item->GetVnum() == ITEM_VALENTINE_CHOCOLATE && SEX_FEMALE==GET_SEX(this))
  3906. {
  3907. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("성별이 맞지않아 이 아이템을 열 수 없습니다."));
  3908. return false;
  3909. }
  3910.  
  3911.  
  3912. if (GiveItemFromSpecialItemGroup(dwBoxVnum, dwVnums, dwCounts, item_gets, count))
  3913. item->SetCount(item->GetCount()-1);
  3914. }
  3915. break;
  3916.  
  3917. case ITEM_WHITEDAY_CANDY:
  3918. case ITEM_WHITEDAY_ROSE:
  3919. {
  3920. DWORD dwBoxVnum = item->GetVnum();
  3921.  
  3922. std::vector <DWORD> dwVnums;
  3923. std::vector <DWORD> dwCounts;
  3924. std::vector <LPITEM> item_gets(NULL);
  3925.  
  3926. int count = 0;
  3927.  
  3928. if (item->GetVnum() == ITEM_WHITEDAY_CANDY && SEX_MALE==GET_SEX(this) || item->GetVnum() == ITEM_WHITEDAY_ROSE && SEX_FEMALE==GET_SEX(this))
  3929. {
  3930. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("성별이 맞지않아 이 아이템을 열 수 없습니다."));
  3931. return false;
  3932. }
  3933.  
  3934.  
  3935. if (GiveItemFromSpecialItemGroup(dwBoxVnum, dwVnums, dwCounts, item_gets, count))
  3936. item->SetCount(item->GetCount()-1);
  3937. }
  3938. break;
  3939.  
  3940. case 50011:
  3941. {
  3942. DWORD dwBoxVnum = 50011;
  3943.  
  3944. std::vector <DWORD> dwVnums;
  3945. std::vector <DWORD> dwCounts;
  3946. std::vector <LPITEM> item_gets(NULL);
  3947.  
  3948. int count = 0;
  3949.  
  3950. if (GiveItemFromSpecialItemGroup(dwBoxVnum, dwVnums, dwCounts, item_gets, count))
  3951. {
  3952. for (int i = 0; i < count; i++)
  3953. {
  3954. char buf[50 + 1];
  3955. snprintf(buf, sizeof(buf), "%u %u", dwVnums[i], dwCounts[i]);
  3956. LogManager::instance().ItemLog(this, item, "MOONLIGHT_GET", buf);
  3957.  
  3958. //ITEM_MANAGER::instance().RemoveItem(item);
  3959. item->SetCount(item->GetCount() - 0);
  3960.  
  3961. switch (dwVnums[i])
  3962. {
  3963. case CSpecialItemGroup::GOLD:
  3964. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈 %d 냥을 획득했습니다."), dwCounts[i]);
  3965. break;
  3966.  
  3967. case CSpecialItemGroup::EXP:
  3968. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 부터 신비한 빛이 나옵니다."));
  3969. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d의 경험치를 획득했습니다."), dwCounts[i]);
  3970. break;
  3971.  
  3972. case CSpecialItemGroup::MOB:
  3973. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 몬스터가 나타났습니다!"));
  3974. break;
  3975.  
  3976. case CSpecialItemGroup::SLOW:
  3977. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 나온 빨간 연기를 들이마시자 움직이는 속도가 느려졌습니다!"));
  3978. break;
  3979.  
  3980. case CSpecialItemGroup::DRAIN_HP:
  3981. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자가 갑자기 폭발하였습니다! 생명력이 감소했습니다."));
  3982. break;
  3983.  
  3984. case CSpecialItemGroup::POISON:
  3985. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 나온 녹색 연기를 들이마시자 독이 온몸으로 퍼집니다!"));
  3986. break;
  3987.  
  3988. case CSpecialItemGroup::MOB_GROUP:
  3989. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 몬스터가 나타났습니다!"));
  3990. break;
  3991.  
  3992. default:
  3993. if (item_gets[i])
  3994. {
  3995. if (dwCounts[i] > 1)
  3996. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 %s 가 %d 개 나왔습니다."), item_gets[i]->GetName(), dwCounts[i]);
  3997. else
  3998. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상자에서 %s 가 나왔습니다."), item_gets[i]->GetName());
  3999. }
  4000. break;
  4001. }
  4002. }
  4003. }
  4004.  
  4005. else
  4006. {
  4007. ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("아무것도 얻을 수 없었습니다."));
  4008. return false;
  4009. }
  4010. }
  4011. break;
  4012.  
  4013. case ITEM_GIVE_STAT_RESET_COUNT_VNUM:
  4014. {
  4015. //PointChange(POINT_GOLD, -iCost);
  4016. PointChange(POINT_STAT_RESET_COUNT, 1);
  4017. item->SetCount(item->GetCount()-1);
  4018. }
  4019. break;
  4020.  
  4021. case 50107:
  4022. {
  4023. EffectPacket(SE_CHINA_FIREWORK);
  4024. AddAffect(AFFECT_CHINA_FIREWORK, POINT_STUN_PCT, 30, AFF_CHINA_FIREWORK, 5*60, 0, true);
  4025. item->SetCount(item->GetCount()-1);
  4026. }
  4027. break;
  4028.  
  4029. case 50108:
  4030. {
  4031. if (CArenaManager::instance().IsArenaMap(GetMapIndex()) == true)
  4032. {
  4033. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련 중에는 이용할 수 없는 물품입니다."));
  4034. return false;
  4035. }
  4036.  
  4037. EffectPacket(SE_SPIN_TOP);
  4038. AddAffect(AFFECT_CHINA_FIREWORK, POINT_STUN_PCT, 30, AFF_CHINA_FIREWORK, 5*60, 0, true);
  4039. item->SetCount(item->GetCount()-1);
  4040. }
  4041. break;
  4042.  
  4043. case ITEM_WONSO_BEAN_VNUM:
  4044. PointChange(POINT_HP, GetMaxHP() - GetHP());
  4045. item->SetCount(item->GetCount()-1);
  4046. break;
  4047.  
  4048. case ITEM_WONSO_SUGAR_VNUM:
  4049. PointChange(POINT_SP, GetMaxSP() - GetSP());
  4050. item->SetCount(item->GetCount()-1);
  4051. break;
  4052.  
  4053. case ITEM_WONSO_FRUIT_VNUM:
  4054. PointChange(POINT_STAMINA, GetMaxStamina()-GetStamina());
  4055. item->SetCount(item->GetCount()-1);
  4056. break;
  4057.  
  4058. case ITEM_ELK_VNUM:
  4059. {
  4060. int iGold = item->GetSocket(0);
  4061. ITEM_MANAGER::instance().RemoveItem(item);
  4062. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈 %d 냥을 획득했습니다."), iGold);
  4063. PointChange(POINT_GOLD, iGold);
  4064. }
  4065. break;
  4066.  
  4067. case 27995:
  4068. {
  4069. }
  4070. break;
  4071.  
  4072. case 71092 :
  4073. {
  4074. if (m_pkChrTarget != NULL)
  4075. {
  4076. if (m_pkChrTarget->IsPolymorphed())
  4077. {
  4078. m_pkChrTarget->SetPolymorph(0);
  4079. m_pkChrTarget->RemoveAffect(AFFECT_POLYMORPH);
  4080. }
  4081. }
  4082.  
  4083. else
  4084. {
  4085. if (IsPolymorphed())
  4086. {
  4087. SetPolymorph(0);
  4088. RemoveAffect(AFFECT_POLYMORPH);
  4089. }
  4090. }
  4091. }
  4092. break;
  4093.  
  4094. case 71051 :
  4095. {
  4096. LPITEM item2;
  4097.  
  4098. if (!IsValidItemPosition(DestCell) || !(item2 = GetInventoryItem(wDestCell)))
  4099. return false;
  4100.  
  4101. if (ITEM_COSTUME == item2->GetType())
  4102. {
  4103. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("속성을 변경할 수 없는 아이템입니다."));
  4104. return false;
  4105. }
  4106.  
  4107. if (item2->IsExchanging() || item2->IsEquipped())
  4108. return false;
  4109.  
  4110. if (item2->GetAttributeSetIndex() == -1)
  4111. {
  4112. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("속성을 변경할 수 없는 아이템입니다."));
  4113. return false;
  4114. }
  4115.  
  4116. if (item2->AddRareAttribute() == true)
  4117. {
  4118. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("성공적으로 속성이 추가 되었습니다"));
  4119.  
  4120. int iAddedIdx = item2->GetRareAttrCount() + 4;
  4121. char buf[21];
  4122. snprintf(buf, sizeof(buf), "%u", item2->GetID());
  4123.  
  4124. LogManager::instance().ItemLog(
  4125. GetPlayerID(),
  4126. item2->GetAttributeType(iAddedIdx),
  4127. item2->GetAttributeValue(iAddedIdx),
  4128. item->GetID(),
  4129. "ADD_RARE_ATTR",
  4130. buf,
  4131. GetDesc()->GetHostName(),
  4132. item->GetOriginalVnum());
  4133.  
  4134. item->SetCount(item->GetCount() - 0);
  4135. }
  4136.  
  4137. else
  4138. {
  4139. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("더 이상 이 아이템으로 속성을 추가할 수 없습니다"));
  4140. }
  4141. }
  4142. break;
  4143.  
  4144. case 71052 :
  4145. {
  4146. LPITEM item2;
  4147.  
  4148. if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
  4149. return false;
  4150.  
  4151. if (ITEM_COSTUME == item2->GetType())
  4152. {
  4153. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("속성을 변경할 수 없는 아이템입니다."));
  4154. return false;
  4155. }
  4156.  
  4157. if (item2->IsExchanging() || item2->IsEquipped())
  4158. return false;
  4159.  
  4160. if (item2->GetAttributeSetIndex() == -1)
  4161. {
  4162. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("속성을 변경할 수 없는 아이템입니다."));
  4163. return false;
  4164. }
  4165.  
  4166. if (item2->ChangeRareAttribute() == true)
  4167. {
  4168. char buf[21];
  4169. snprintf(buf, sizeof(buf), "%u", item2->GetID());
  4170. LogManager::instance().ItemLog(this, item, "CHANGE_RARE_ATTR", buf);
  4171.  
  4172. item->SetCount(item->GetCount() - 0);
  4173. }
  4174.  
  4175. else
  4176. {
  4177. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("변경 시킬 속성이 없습니다"));
  4178. }
  4179. }
  4180. break;
  4181.  
  4182. case ITEM_AUTO_HP_RECOVERY_S:
  4183. case ITEM_AUTO_HP_RECOVERY_M:
  4184. case ITEM_AUTO_HP_RECOVERY_L:
  4185. case ITEM_AUTO_HP_RECOVERY_X:
  4186. case ITEM_AUTO_SP_RECOVERY_S:
  4187. case ITEM_AUTO_SP_RECOVERY_M:
  4188. case ITEM_AUTO_SP_RECOVERY_L:
  4189. case ITEM_AUTO_SP_RECOVERY_X:
  4190.  
  4191. case REWARD_BOX_ITEM_AUTO_SP_RECOVERY_XS:
  4192. case REWARD_BOX_ITEM_AUTO_SP_RECOVERY_S:
  4193. case REWARD_BOX_ITEM_AUTO_HP_RECOVERY_XS:
  4194. case REWARD_BOX_ITEM_AUTO_HP_RECOVERY_S:
  4195. {
  4196. if (CArenaManager::instance().IsArenaMap(GetMapIndex()) == true)
  4197. {
  4198. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련장에서 사용하실 수 없습니다."));
  4199. return false;
  4200. }
  4201.  
  4202. EAffectTypes type = AFFECT_NONE;
  4203. {
  4204. quest::CQuestManager& q = quest::CQuestManager::instance();
  4205. quest::PC* pPC = q.GetPC(GetPlayerID());
  4206.  
  4207. if (pPC != NULL)
  4208. {
  4209. int last_use_time = pPC->GetFlag("auto_recovery.last_use_time");
  4210.  
  4211. if (get_global_time() - last_use_time < 3)
  4212. {
  4213. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Elixir Info] > |h|r Poti folosi elixirul in %d secunde.", 3 - (get_global_time() - last_use_time));
  4214. return false;
  4215. }
  4216.  
  4217. pPC->SetFlag("auto_recovery.last_use_time", get_global_time());
  4218. }
  4219. }
  4220.  
  4221. bool isSpecialPotion = false;
  4222.  
  4223. switch (item->GetVnum())
  4224. {
  4225. case ITEM_AUTO_HP_RECOVERY_X:
  4226. isSpecialPotion = true;
  4227.  
  4228. case ITEM_AUTO_HP_RECOVERY_S:
  4229. case ITEM_AUTO_HP_RECOVERY_M:
  4230. case ITEM_AUTO_HP_RECOVERY_L:
  4231.  
  4232. case REWARD_BOX_ITEM_AUTO_HP_RECOVERY_XS:
  4233. case REWARD_BOX_ITEM_AUTO_HP_RECOVERY_S:
  4234. type = AFFECT_AUTO_HP_RECOVERY;
  4235. break;
  4236.  
  4237. case ITEM_AUTO_SP_RECOVERY_X:
  4238. isSpecialPotion = true;
  4239.  
  4240. case ITEM_AUTO_SP_RECOVERY_S:
  4241. case ITEM_AUTO_SP_RECOVERY_M:
  4242. case ITEM_AUTO_SP_RECOVERY_L:
  4243.  
  4244. case REWARD_BOX_ITEM_AUTO_SP_RECOVERY_XS:
  4245. case REWARD_BOX_ITEM_AUTO_SP_RECOVERY_S:
  4246. type = AFFECT_AUTO_SP_RECOVERY;
  4247. break;
  4248. }
  4249.  
  4250. if (AFFECT_NONE == type)
  4251. break;
  4252.  
  4253. if (item->GetCount() > 1)
  4254. {
  4255. int pos = GetEmptyInventory(item->GetSize());
  4256.  
  4257. if (-1 == pos)
  4258. {
  4259. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
  4260. break;
  4261. }
  4262.  
  4263. item->SetCount( item->GetCount() - 1 );
  4264.  
  4265. LPITEM item2 = ITEM_MANAGER::instance().CreateItem( item->GetVnum(), 1 );
  4266. item2->AddToCharacter(this, TItemPos(INVENTORY, pos));
  4267.  
  4268. if (item->GetSocket(1) != 0)
  4269. {
  4270. item2->SetSocket(1, item->GetSocket(1));
  4271. }
  4272.  
  4273. item = item2;
  4274. }
  4275.  
  4276. CAffect* pAffect = FindAffect( type );
  4277.  
  4278. if (NULL == pAffect)
  4279. {
  4280. EPointTypes bonus = POINT_NONE;
  4281.  
  4282. if (true == isSpecialPotion)
  4283. {
  4284. if (type == AFFECT_AUTO_HP_RECOVERY)
  4285. {
  4286. bonus = POINT_MAX_HP_PCT;
  4287. }
  4288.  
  4289. else if (type == AFFECT_AUTO_SP_RECOVERY)
  4290. {
  4291. bonus = POINT_MAX_SP_PCT;
  4292. }
  4293. }
  4294.  
  4295. AddAffect( type, bonus, 4, item->GetID(), INFINITE_AFFECT_DURATION, 0, true, false);
  4296.  
  4297. if (type == AFFECT_AUTO_HP_RECOVERY)
  4298. {
  4299. AddAffect(type, POINT_CRITICAL_PCT, 25, item->GetID(), INFINITE_AFFECT_DURATION, 0, true, false);
  4300. }
  4301.  
  4302. item->Lock(true);
  4303. item->SetSocket(0, true);
  4304.  
  4305. AutoRecoveryItemProcess( type );
  4306. }
  4307.  
  4308. else
  4309. {
  4310. if (item->GetID() == pAffect->dwFlag)
  4311. {
  4312. RemoveAffect( pAffect );
  4313.  
  4314. item->Lock(false);
  4315. item->SetSocket(0, false);
  4316. }
  4317.  
  4318. else
  4319. {
  4320. LPITEM old = FindItemByID( pAffect->dwFlag );
  4321.  
  4322. if (NULL != old)
  4323. {
  4324. old->Lock(false);
  4325. old->SetSocket(0, false);
  4326. }
  4327.  
  4328. RemoveAffect( pAffect );
  4329.  
  4330. EPointTypes bonus = POINT_NONE;
  4331.  
  4332. if (true == isSpecialPotion)
  4333. {
  4334. if (type == AFFECT_AUTO_HP_RECOVERY)
  4335. {
  4336. bonus = POINT_MAX_HP_PCT;
  4337. }
  4338.  
  4339. else if (type == AFFECT_AUTO_SP_RECOVERY)
  4340. {
  4341. bonus = POINT_MAX_SP_PCT;
  4342. }
  4343. }
  4344.  
  4345. AddAffect( type, bonus, 4, item->GetID(), INFINITE_AFFECT_DURATION, 0, true, false);
  4346.  
  4347. if (type == AFFECT_AUTO_HP_RECOVERY)
  4348. {
  4349. AddAffect(type, POINT_CRITICAL_PCT, 25, item->GetID(), INFINITE_AFFECT_DURATION, 0, true, false);
  4350. }
  4351.  
  4352. item->Lock(true);
  4353. item->SetSocket(0, true);
  4354.  
  4355. AutoRecoveryItemProcess( type );
  4356. }
  4357. }
  4358. }
  4359. break;
  4360. }
  4361. break;
  4362.  
  4363. case USE_CLEAR:
  4364. {
  4365. RemoveBadAffect();
  4366. item->SetCount(item->GetCount() - 0);
  4367. }
  4368. break;
  4369.  
  4370. case USE_INVISIBILITY:
  4371. {
  4372. if (item->GetVnum() == 70026)
  4373. {
  4374. quest::CQuestManager& q = quest::CQuestManager::instance();
  4375. quest::PC* pPC = q.GetPC(GetPlayerID());
  4376.  
  4377. if (pPC != NULL)
  4378. {
  4379. int last_use_time = pPC->GetFlag("mirror_of_disapper.last_use_time");
  4380.  
  4381. if (get_global_time() - last_use_time < 10*60)
  4382. {
  4383. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아직 사용할 수 없습니다."));
  4384. return false;
  4385. }
  4386.  
  4387. pPC->SetFlag("mirror_of_disapper.last_use_time", get_global_time());
  4388. }
  4389. }
  4390.  
  4391. AddAffect(AFFECT_INVISIBILITY, POINT_NONE, 0, AFF_INVISIBILITY, 300, 0, true);
  4392. item->SetCount(item->GetCount() - 0);
  4393. }
  4394. break;
  4395.  
  4396. case USE_POTION_NODELAY:
  4397. {
  4398. if (CArenaManager::instance().IsArenaMap(GetMapIndex()) == true)
  4399. {
  4400. if (quest::CQuestManager::instance().GetEventFlag("arena_potion_limit") > 0)
  4401. {
  4402. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련장에서 사용하실 수 없습니다."));
  4403. return false;
  4404. }
  4405.  
  4406. switch (item->GetVnum())
  4407. {
  4408. case 70020 :
  4409. case 71018 :
  4410. case 71019 :
  4411. case 71020 :
  4412. if (quest::CQuestManager::instance().GetEventFlag("arena_potion_limit_count") < 10000)
  4413. {
  4414. if (m_nPotionLimit <= 0)
  4415. {
  4416. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("사용 제한량을 초과하였습니다."));
  4417. return false;
  4418. }
  4419. }
  4420. break;
  4421.  
  4422. default :
  4423. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련장에서 사용하실 수 없습니다."));
  4424. return false;
  4425. }
  4426. }
  4427.  
  4428. bool used = false;
  4429.  
  4430. if (item->GetValue(0) != 0)
  4431. {
  4432. if (GetHP() < GetMaxHP())
  4433. {
  4434. PointChange(POINT_HP, item->GetValue(0) * (100 + GetPoint(POINT_POTION_BONUS)) / 100);
  4435. EffectPacket(SE_HPUP_RED);
  4436. used = TRUE;
  4437. }
  4438. }
  4439.  
  4440. if (item->GetValue(1) != 0)
  4441. {
  4442. if (GetSP() < GetMaxSP())
  4443. {
  4444. PointChange(POINT_SP, item->GetValue(1) * (100 + GetPoint(POINT_POTION_BONUS)) / 100);
  4445. EffectPacket(SE_SPUP_BLUE);
  4446. used = TRUE;
  4447. }
  4448. }
  4449.  
  4450. if (item->GetValue(3) != 0)
  4451. {
  4452. if (GetHP() < GetMaxHP())
  4453. {
  4454. PointChange(POINT_HP, item->GetValue(3) * GetMaxHP() / 100);
  4455. EffectPacket(SE_HPUP_RED);
  4456. used = TRUE;
  4457. }
  4458. }
  4459.  
  4460. if (item->GetValue(4) != 0)
  4461. {
  4462. if (GetSP() < GetMaxSP())
  4463. {
  4464. PointChange(POINT_SP, item->GetValue(4) * GetMaxSP() / 100);
  4465. EffectPacket(SE_SPUP_BLUE);
  4466. used = TRUE;
  4467. }
  4468. }
  4469.  
  4470. if (used)
  4471. {
  4472. if (item->GetVnum() == 50085 || item->GetVnum() == 50086)
  4473. {
  4474. if (test_server)
  4475. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("월병 또는 종자 를 사용하였습니다"));
  4476.  
  4477. SetUseSeedOrMoonBottleTime();
  4478. }
  4479.  
  4480. if (GetDungeon())
  4481. GetDungeon()->UsePotion(this);
  4482.  
  4483. if (GetWarMap())
  4484. GetWarMap()->UsePotion(this, item);
  4485.  
  4486. m_nPotionLimit--;
  4487.  
  4488. //RESTRICT_USE_SEED_OR_MOONBOTTLE
  4489. item->SetCount(item->GetCount() - 0);
  4490. //END_RESTRICT_USE_SEED_OR_MOONBOTTLE
  4491. }
  4492. }
  4493. break;
  4494.  
  4495. case USE_POTION:
  4496. if (CArenaManager::instance().IsArenaMap(GetMapIndex()) == true)
  4497. {
  4498. if (quest::CQuestManager::instance().GetEventFlag("arena_potion_limit") > 0)
  4499. {
  4500. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련장에서 사용하실 수 없습니다."));
  4501. return false;
  4502. }
  4503.  
  4504. switch (item->GetVnum())
  4505. {
  4506. case 27001 :
  4507. case 27002 :
  4508. case 27003 :
  4509. case 27004 :
  4510. case 27005 :
  4511. case 27006 :
  4512. if (quest::CQuestManager::instance().GetEventFlag("arena_potion_limit_count") < 10000)
  4513. {
  4514. if (m_nPotionLimit <= 0)
  4515. {
  4516. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("사용 제한량을 초과하였습니다."));
  4517. return false;
  4518. }
  4519. }
  4520. break;
  4521.  
  4522. default :
  4523. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련장에서 사용하실 수 없습니다."));
  4524. return false;
  4525. }
  4526. }
  4527.  
  4528. if (item->GetValue(1) != 0)
  4529. {
  4530. if (GetPoint(POINT_SP_RECOVERY) + GetSP() >= GetMaxSP())
  4531. {
  4532. return false;
  4533. }
  4534.  
  4535. PointChange(POINT_SP_RECOVERY, item->GetValue(1) * MIN(200, (100 + GetPoint(POINT_POTION_BONUS))) / 100);
  4536. StartAffectEvent();
  4537. EffectPacket(SE_SPUP_BLUE);
  4538. }
  4539.  
  4540. if (item->GetValue(0) != 0)
  4541. {
  4542. if (GetPoint(POINT_HP_RECOVERY) + GetHP() >= GetMaxHP())
  4543. {
  4544. return false;
  4545. }
  4546.  
  4547. PointChange(POINT_HP_RECOVERY, item->GetValue(0) * MIN(200, (100 + GetPoint(POINT_POTION_BONUS))) / 100);
  4548. StartAffectEvent();
  4549. EffectPacket(SE_HPUP_RED);
  4550. }
  4551.  
  4552. if (GetDungeon())
  4553. GetDungeon()->UsePotion(this);
  4554.  
  4555. if (GetWarMap())
  4556. GetWarMap()->UsePotion(this, item);
  4557.  
  4558. item->SetCount(item->GetCount() - 0);
  4559.  
  4560. m_nPotionLimit--;
  4561. break;
  4562.  
  4563. case USE_POTION_CONTINUE:
  4564. {
  4565. if (item->GetValue(0) != 0)
  4566. {
  4567. AddAffect(AFFECT_HP_RECOVER_CONTINUE, POINT_HP_RECOVER_CONTINUE, item->GetValue(0), 0, item->GetValue(2), 0, true);
  4568. }
  4569.  
  4570. else if (item->GetValue(1) != 0)
  4571. {
  4572. AddAffect(AFFECT_SP_RECOVER_CONTINUE, POINT_SP_RECOVER_CONTINUE, item->GetValue(1), 0, item->GetValue(2), 0, true);
  4573. }
  4574.  
  4575. else
  4576. return false;
  4577. }
  4578.  
  4579. if (GetDungeon())
  4580. GetDungeon()->UsePotion(this);
  4581.  
  4582. if (GetWarMap())
  4583. GetWarMap()->UsePotion(this, item);
  4584.  
  4585. item->SetCount(item->GetCount() - 0);
  4586. break;
  4587.  
  4588. case USE_ABILITY_UP:
  4589. {
  4590. switch (item->GetValue(0))
  4591. {
  4592. case APPLY_MOV_SPEED:
  4593.  
  4594. if (FindAffect(AFFECT_MOV_SPEED)) // Fix pentru licori mov , daca sunt deja activate.
  4595. {
  4596. ChatPacket(CHAT_TYPE_INFO, "Aceasta licoare isi face deja efectul.");
  4597. return false;
  4598. }
  4599.  
  4600. AddAffect(AFFECT_MOV_SPEED, POINT_MOV_SPEED, item->GetValue(2), AFF_MOV_SPEED_POTION, item->GetValue(1), 0, true);
  4601. #ifdef ENABLE_EFFECT_EXTRAPOT
  4602. EffectPacket(SE_DXUP_PURPLE);
  4603. #endif
  4604. break;
  4605.  
  4606. case APPLY_ATT_SPEED:
  4607.  
  4608. if (FindAffect(AFFECT_ATT_SPEED)) // Fix pentru licori verzi , daca sunt deja activate.
  4609. {
  4610. ChatPacket(CHAT_TYPE_INFO, "Aceasta licoare isi face deja efectul.");
  4611. return false;
  4612. }
  4613.  
  4614. AddAffect(AFFECT_ATT_SPEED, POINT_ATT_SPEED, item->GetValue(2), AFF_ATT_SPEED_POTION, item->GetValue(1), 0, true);
  4615. #ifdef ENABLE_EFFECT_EXTRAPOT
  4616. EffectPacket(SE_SPEEDUP_GREEN);
  4617. #endif
  4618. break;
  4619.  
  4620. AddAffect(AFFECT_STR, POINT_ST, item->GetValue(2), 0, item->GetValue(1), 0, true);
  4621. break;
  4622.  
  4623. case APPLY_DEX:
  4624. AddAffect(AFFECT_DEX, POINT_DX, item->GetValue(2), 0, item->GetValue(1), 0, true);
  4625. break;
  4626.  
  4627. case APPLY_CON:
  4628. AddAffect(AFFECT_CON, POINT_HT, item->GetValue(2), 0, item->GetValue(1), 0, true);
  4629. break;
  4630.  
  4631. case APPLY_INT:
  4632. AddAffect(AFFECT_INT, POINT_IQ, item->GetValue(2), 0, item->GetValue(1), 0, true);
  4633. break;
  4634.  
  4635. case APPLY_CAST_SPEED:
  4636. AddAffect(AFFECT_CAST_SPEED, POINT_CASTING_SPEED, item->GetValue(2), 0, item->GetValue(1), 0, true);
  4637. break;
  4638.  
  4639. case APPLY_ATT_GRADE_BONUS:
  4640. AddAffect(AFFECT_ATT_GRADE, POINT_ATT_GRADE_BONUS,
  4641. item->GetValue(2), 0, item->GetValue(1), 0, true);
  4642. break;
  4643.  
  4644. case APPLY_DEF_GRADE_BONUS:
  4645. AddAffect(AFFECT_DEF_GRADE, POINT_DEF_GRADE_BONUS,
  4646. item->GetValue(2), 0, item->GetValue(1), 0, true);
  4647. break;
  4648. }
  4649. }
  4650.  
  4651. if (GetDungeon())
  4652. GetDungeon()->UsePotion(this);
  4653.  
  4654. if (GetWarMap())
  4655. GetWarMap()->UsePotion(this, item);
  4656.  
  4657. item->SetCount(item->GetCount() - 0);
  4658. break;
  4659.  
  4660. case USE_TALISMAN:
  4661. {
  4662. const int TOWN_PORTAL = 1;
  4663. const int MEMORY_PORTAL = 2;
  4664.  
  4665.  
  4666. // gm_guild_build, oxevent
  4667. if (GetMapIndex() == 200 || GetMapIndex() == 113)
  4668. {
  4669. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("현재 위치에서 사용할 수 없습니다."));
  4670. return false;
  4671. }
  4672.  
  4673. if (CArenaManager::instance().IsArenaMap(GetMapIndex()) == true)
  4674. {
  4675. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련 중에는 이용할 수 없는 물품입니다."));
  4676. return false;
  4677. }
  4678.  
  4679. if (m_pkWarpEvent)
  4680. {
  4681. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이동할 준비가 되어있음으로 귀환부를 사용할수 없습니다"));
  4682. return false;
  4683. }
  4684.  
  4685. int consumeLife = CalculateConsume(this);
  4686.  
  4687. if (consumeLife < 0)
  4688. return false;
  4689.  
  4690. if (item->GetValue(0) == TOWN_PORTAL)
  4691. {
  4692. if (item->GetSocket(0) == 0)
  4693. {
  4694. if (!GetDungeon())
  4695. if (!GiveRecallItem(item))
  4696. return false;
  4697.  
  4698. PIXEL_POSITION posWarp;
  4699.  
  4700. if (SECTREE_MANAGER::instance().GetRecallPositionByEmpire(GetMapIndex(), GetEmpire(), posWarp))
  4701. {
  4702. PointChange(POINT_HP, -consumeLife, false);
  4703.  
  4704. WarpSet(posWarp.x, posWarp.y);
  4705. }
  4706.  
  4707. else
  4708. {
  4709. sys_err("CHARACTER::UseItem : cannot find spawn position (name %s, %d x %d)", GetName(), GetX(), GetY());
  4710. }
  4711. }
  4712.  
  4713. else
  4714. {
  4715. if (test_server)
  4716. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("원래 위치로 복귀"));
  4717.  
  4718. ProcessRecallItem(item);
  4719. }
  4720. }
  4721.  
  4722. else if (item->GetValue(0) == MEMORY_PORTAL)
  4723. {
  4724. if (item->GetSocket(0) == 0)
  4725. {
  4726. if (GetDungeon())
  4727. {
  4728. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("던전 안에서는 %s%s 사용할 수 없습니다."), item->GetName(), "");
  4729. return false;
  4730. }
  4731.  
  4732. if (!GiveRecallItem(item))
  4733. return false;
  4734. }
  4735.  
  4736. else
  4737. {
  4738. PointChange(POINT_HP, -consumeLife, false);
  4739.  
  4740. ProcessRecallItem(item);
  4741. }
  4742. }
  4743. }
  4744. break;
  4745.  
  4746. case USE_TUNING:
  4747. case USE_DETACHMENT:
  4748. {
  4749. LPITEM item2;
  4750.  
  4751. if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
  4752. return false;
  4753.  
  4754. if (item2->IsExchanging() || item2->IsEquipped())
  4755. return false;
  4756.  
  4757. if (item2->GetVnum() >= 28330 && item2->GetVnum() <= 28343)
  4758. {
  4759. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("+3 영석은 이 아이템으로 개량할 수 없습니다"));
  4760. return false;
  4761. }
  4762.  
  4763. if (item2->GetVnum() >= 28430 && item2->GetVnum() <= 28443)
  4764. {
  4765. if (item->GetVnum() == 71056)
  4766. {
  4767. RefineItem(item, item2);
  4768. }
  4769.  
  4770. else
  4771. {
  4772. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("영석은 이 아이템으로 개량할 수 없습니다"));
  4773. }
  4774. }
  4775.  
  4776. else
  4777. {
  4778. RefineItem(item, item2);
  4779. }
  4780. }
  4781. break;
  4782.  
  4783. case USE_PUT_INTO_BELT_SOCKET:
  4784. case USE_PUT_INTO_RING_SOCKET:
  4785. case USE_PUT_INTO_ACCESSORY_SOCKET:
  4786. case USE_ADD_ACCESSORY_SOCKET:
  4787. case USE_CLEAN_SOCKET:
  4788. case USE_CHANGE_ATTRIBUTE:
  4789. case USE_CHANGE_ATTRIBUTE2 :
  4790. case USE_ADD_ATTRIBUTE:
  4791. case USE_ADD_ATTRIBUTE2:
  4792. {
  4793. LPITEM item2;
  4794.  
  4795. if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
  4796. return false;
  4797.  
  4798. if (item2->IsEquipped())
  4799. {
  4800. BuffOnAttr_RemoveBuffsFromItem(item2);
  4801. }
  4802.  
  4803. if (ITEM_COSTUME == item2->GetType())
  4804. {
  4805. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("속성을 변경할 수 없는 아이템입니다."));
  4806. return false;
  4807. }
  4808.  
  4809. if (item2->IsExchanging() || item2->IsEquipped())
  4810. return false;
  4811.  
  4812. switch (item->GetSubType())
  4813. {
  4814. case USE_CLEAN_SOCKET:
  4815. {
  4816. int i;
  4817. for (i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  4818. {
  4819. if (item2->GetSocket(i) == ITEM_BROKEN_METIN_VNUM)
  4820. break;
  4821. }
  4822.  
  4823. if (i == ITEM_SOCKET_MAX_NUM)
  4824. {
  4825. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("청소할 석이 박혀있지 않습니다."));
  4826. return false;
  4827. }
  4828.  
  4829. int j = 0;
  4830.  
  4831. for (i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  4832. {
  4833. if (item2->GetSocket(i) != ITEM_BROKEN_METIN_VNUM && item2->GetSocket(i) != 0)
  4834. item2->SetSocket(j++, item2->GetSocket(i));
  4835. }
  4836.  
  4837. for (; j < ITEM_SOCKET_MAX_NUM; ++j)
  4838. {
  4839. if (item2->GetSocket(j) > 0)
  4840. item2->SetSocket(j, 1);
  4841. }
  4842.  
  4843. {
  4844. char buf[21];
  4845. snprintf(buf, sizeof(buf), "%u", item2->GetID());
  4846. LogManager::instance().ItemLog(this, item, "CLEAN_SOCKET", buf);
  4847. }
  4848.  
  4849. item->SetCount(item->GetCount() - 0);
  4850.  
  4851. }
  4852. break;
  4853.  
  4854. case USE_CHANGE_ATTRIBUTE:
  4855. case USE_CHANGE_ATTRIBUTE2:
  4856. if (item2->GetAttributeSetIndex() == -1)
  4857. {
  4858. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("속성을 변경할 수 없는 아이템입니다."));
  4859. return false;
  4860. }
  4861.  
  4862. if (item2->GetAttributeCount() == 0)
  4863. {
  4864. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("변경할 속성이 없습니다."));
  4865. return false;
  4866. }
  4867.  
  4868. if (GM_PLAYER == GetGMLevel() && false == test_server)
  4869. {
  4870. DWORD dwChangeItemAttrCycle = quest::CQuestManager::instance().GetEventFlag(msc_szChangeItemAttrCycleFlag);
  4871.  
  4872. if (dwChangeItemAttrCycle < msc_dwDefaultChangeItemAttrCycle)
  4873. dwChangeItemAttrCycle = msc_dwDefaultChangeItemAttrCycle;
  4874.  
  4875. quest::PC* pPC = quest::CQuestManager::instance().GetPC(GetPlayerID());
  4876.  
  4877. /*if (pPC)
  4878. {
  4879. DWORD dwNowMin = get_global_time() / 60;
  4880.  
  4881. DWORD dwLastChangeItemAttrMin = pPC->GetFlag(msc_szLastChangeItemAttrFlag);
  4882.  
  4883. if (dwLastChangeItemAttrMin + dwChangeItemAttrCycle > dwNowMin)
  4884. {
  4885. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("속성을 바꾼지 %d분 이내에는 다시 변경할 수 없습니다.(%d 분 남음)"),
  4886. dwChangeItemAttrCycle, dwChangeItemAttrCycle - (dwNowMin - dwLastChangeItemAttrMin));
  4887. return false;
  4888. }
  4889.  
  4890. pPC->SetFlag(msc_szLastChangeItemAttrFlag, dwNowMin);
  4891. }*/
  4892. }
  4893.  
  4894. if (item->GetSubType() == USE_CHANGE_ATTRIBUTE2)
  4895. {
  4896. int aiChangeProb[ITEM_ATTRIBUTE_MAX_LEVEL] =
  4897. {
  4898. 0, 0, 30, 40, 3
  4899. };
  4900.  
  4901. item2->ChangeAttribute(aiChangeProb);
  4902. }
  4903.  
  4904. else if (item->GetVnum() == 76014)
  4905. {
  4906. int aiChangeProb[ITEM_ATTRIBUTE_MAX_LEVEL] =
  4907. {
  4908. 0, 10, 50, 39, 1
  4909. };
  4910.  
  4911. item2->ChangeAttribute(aiChangeProb);
  4912. }
  4913.  
  4914. else
  4915. {
  4916. if (item->GetVnum() == 71151 || item->GetVnum() == 76023)
  4917. {
  4918. if ((item2->GetType() == ITEM_WEAPON)
  4919. || (item2->GetType() == ITEM_ARMOR && item2->GetSubType() == ARMOR_BODY))
  4920. {
  4921. bool bCanUse = true;
  4922. for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
  4923. {
  4924. if (item2->GetLimitType(i) == LIMIT_LEVEL && item2->GetLimitValue(i) > 40)
  4925. {
  4926. bCanUse = false;
  4927. break;
  4928. }
  4929. }
  4930.  
  4931. if (false == bCanUse)
  4932. {
  4933. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("적용 레벨보다 높아 사용이 불가능합니다."));
  4934. break;
  4935. }
  4936. }
  4937.  
  4938. else
  4939. {
  4940. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("무기와 갑옷에만 사용 가능합니다."));
  4941. break;
  4942. }
  4943. }
  4944.  
  4945. item2->ChangeAttribute();
  4946. }
  4947.  
  4948. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("속성을 변경하였습니다."));
  4949. {
  4950. char buf[21];
  4951.  
  4952. snprintf(buf, sizeof(buf), "%u", item2->GetID());
  4953. LogManager::instance().ItemLog(this, item, "CHANGE_ATTRIBUTE", buf);
  4954. }
  4955.  
  4956. item->SetCount(item->GetCount() - 0);
  4957. break;
  4958.  
  4959. case USE_ADD_ATTRIBUTE :
  4960. if (item2->GetAttributeSetIndex() == -1)
  4961. {
  4962. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("속성을 변경할 수 없는 아이템입니다."));
  4963. return false;
  4964. }
  4965.  
  4966. if (item2->GetType() == ITEM_COSTUME)
  4967. return false;
  4968.  
  4969. if (item2->GetAttributeCount() < 4)
  4970. {
  4971. if (item->GetVnum() == 71152 || item->GetVnum() == 76024)
  4972. {
  4973. if ((item2->GetType() == ITEM_WEAPON)
  4974. || (item2->GetType() == ITEM_ARMOR && item2->GetSubType() == ARMOR_BODY))
  4975. {
  4976. bool bCanUse = true;
  4977. for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
  4978. {
  4979. if (item2->GetLimitType(i) == LIMIT_LEVEL && item2->GetLimitValue(i) > 40)
  4980. {
  4981. bCanUse = false;
  4982. break;
  4983. }
  4984. }
  4985.  
  4986. if (false == bCanUse)
  4987. {
  4988. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("적용 레벨보다 높아 사용이 불가능합니다."));
  4989. break;
  4990. }
  4991. }
  4992.  
  4993. else
  4994. {
  4995. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("무기와 갑옷에만 사용 가능합니다."));
  4996. break;
  4997. }
  4998. }
  4999.  
  5000. char buf[21];
  5001. snprintf(buf, sizeof(buf), "%u", item2->GetID());
  5002.  
  5003. if (number(1, 100) <= aiItemAttributeAddPercent[item2->GetAttributeCount()])
  5004. {
  5005. #ifdef ENABLE_MAX_ADD_ATTRIBUTE
  5006. short AttributeCount = abs(5 - item->GetAttributeCount());
  5007. for (int i = 0; i < AttributeCount; i++)
  5008. item2->AddAttribute();
  5009. #else
  5010. item2->AddAttribute();
  5011. #endif
  5012. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Ai adaugat bonusul cu succes .");
  5013.  
  5014. int iAddedIdx = item2->GetAttributeCount() - 1;
  5015. LogManager::instance().ItemLog(
  5016. GetPlayerID(),
  5017. item2->GetAttributeType(iAddedIdx),
  5018. item2->GetAttributeValue(iAddedIdx),
  5019. item->GetID(),
  5020. "ADD_ATTRIBUTE_SUCCESS",
  5021. buf,
  5022. GetDesc()->GetHostName(),
  5023. item->GetOriginalVnum());
  5024. }
  5025.  
  5026. else
  5027. {
  5028. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Bonusul a esuat la adaugare.");
  5029. LogManager::instance().ItemLog(this, item, "ADD_ATTRIBUTE_FAIL", buf);
  5030. }
  5031.  
  5032. item->SetCount(item->GetCount() - 0);
  5033. }
  5034.  
  5035. else
  5036. {
  5037. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Nu poti adauga un bonus .");
  5038. }
  5039. break;
  5040.  
  5041. case USE_ADD_ATTRIBUTE2 :
  5042. if (item2->GetAttributeSetIndex() == -1)
  5043. {
  5044. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Nu poti adauga un bonus acestui obiect .");
  5045. return false;
  5046. }
  5047.  
  5048. if (item2->GetAttributeCount() == 4)
  5049. {
  5050. char buf[21];
  5051. snprintf(buf, sizeof(buf), "%u", item2->GetID());
  5052.  
  5053. if (number(1, 100) <= aiItemAttributeAddPercent[item2->GetAttributeCount()])
  5054. {
  5055. #ifdef ENABLE_MAX_ADD_ATTRIBUTE
  5056. short AttributeCount = abs(5 - item->GetAttributeCount());
  5057. for (int i = 0; i < AttributeCount; i++)
  5058. item2->AddAttribute();
  5059. #else
  5060. item2->AddAttribute();
  5061. #endif
  5062.  
  5063. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Ai adaugat bonusul cu succes .");
  5064.  
  5065. int iAddedIdx = item2->GetAttributeCount() - 1;
  5066. LogManager::instance().ItemLog(
  5067. GetPlayerID(),
  5068. item2->GetAttributeType(iAddedIdx),
  5069. item2->GetAttributeValue(iAddedIdx),
  5070. item->GetID(),
  5071. "ADD_ATTRIBUTE2_SUCCESS",
  5072. buf,
  5073. GetDesc()->GetHostName(),
  5074. item->GetOriginalVnum());
  5075. }
  5076.  
  5077. else
  5078. {
  5079. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Bonusul a esuat la adaugare .");
  5080. LogManager::instance().ItemLog(this, item, "ADD_ATTRIBUTE2_FAIL", buf);
  5081. }
  5082.  
  5083. item->SetCount(item->GetCount() - 0);
  5084. }
  5085.  
  5086. else if (item2->GetAttributeCount() == 5)
  5087. {
  5088. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Nu poti adauga alte bonusuri .");
  5089. }
  5090.  
  5091. else if (item2->GetAttributeCount() < 4)
  5092. {
  5093. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Nu poti face asta .");
  5094. }
  5095.  
  5096. else
  5097. {
  5098. sys_err("ADD_ATTRIBUTE2 : Item has wrong AttributeCount(%d)", item2->GetAttributeCount());
  5099. }
  5100. break;
  5101.  
  5102. case USE_ADD_ACCESSORY_SOCKET:
  5103. {
  5104. char buf[21];
  5105. snprintf(buf, sizeof(buf), "%u", item2->GetID());
  5106.  
  5107. if (item2->IsAccessoryForSocket())
  5108. {
  5109. if (item2->GetAccessorySocketMaxGrade() < ITEM_ACCESSORY_SOCKET_MAX_NUM)
  5110. {
  5111. if (number(1, 100) <= 100)
  5112. {
  5113. item2->SetAccessorySocketMaxGrade(item2->GetAccessorySocketMaxGrade() + 1);
  5114. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Finisaje] > |h|r Adaugarea diamantului a reusit .");
  5115. LogManager::instance().ItemLog(this, item, "ADD_SOCKET_SUCCESS", buf);
  5116. }
  5117.  
  5118. else
  5119. {
  5120. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Finisaje] > |h|r Adaugarea diamantului a esuat .");
  5121. LogManager::instance().ItemLog(this, item, "ADD_SOCKET_FAIL", buf);
  5122. }
  5123.  
  5124. item->SetCount(item->GetCount() - 0);
  5125. }
  5126.  
  5127. else
  5128. {
  5129. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Finisaje] > |h|r Nu mai sunt locuri disponibile pe acest obiect .");
  5130. }
  5131. }
  5132.  
  5133. else
  5134. {
  5135. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  5136. }
  5137. }
  5138. break;
  5139.  
  5140. case USE_PUT_INTO_BELT_SOCKET:
  5141. case USE_PUT_INTO_ACCESSORY_SOCKET:
  5142. if (item2->IsAccessoryForSocket() && item->CanPutInto(item2))
  5143. {
  5144. char buf[21];
  5145. snprintf(buf, sizeof(buf), "%u", item2->GetID());
  5146.  
  5147. if (item2->GetAccessorySocketGrade() < item2->GetAccessorySocketMaxGrade())
  5148. {
  5149. if (number(1, 100) <= aiAccessorySocketPutPct[item2->GetAccessorySocketGrade()])
  5150. {
  5151. item2->SetAccessorySocketGrade(item2->GetAccessorySocketGrade() + 1);
  5152. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Finisaje] > |h|r Adaugarea a reusit .");
  5153. LogManager::instance().ItemLog(this, item, "PUT_SOCKET_SUCCESS", buf);
  5154. }
  5155.  
  5156. else
  5157. {
  5158. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Finisaje] > |h|r Adaugarea a esuat .");
  5159. LogManager::instance().ItemLog(this, item, "PUT_SOCKET_FAIL", buf);
  5160. }
  5161.  
  5162. item->SetCount(item->GetCount() - 0);
  5163. }
  5164.  
  5165. else
  5166. {
  5167. if (item2->GetAccessorySocketMaxGrade() == 0)
  5168. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Finisaje] > |h|r Nu mai poti adauga finisaje .");
  5169.  
  5170. else if (item2->GetAccessorySocketMaxGrade() < ITEM_ACCESSORY_SOCKET_MAX_NUM)
  5171. {
  5172. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Finisaje] > |h|r Nu mai poti adauga finisaje .");
  5173. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("다이아몬드로 소켓을 추가해야합니다."));
  5174. }
  5175.  
  5176. else
  5177. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Finisaje] > |h|r Nu mai poti adauga finisaje .");
  5178. }
  5179. }
  5180.  
  5181. else
  5182. {
  5183. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  5184. }
  5185. break;
  5186. }
  5187.  
  5188. if (item2->IsEquipped())
  5189. {
  5190. BuffOnAttr_AddBuffsFromItem(item2);
  5191. }
  5192. }
  5193. break;
  5194.  
  5195. case USE_BAIT:
  5196. {
  5197.  
  5198. if (m_pkFishingEvent)
  5199. {
  5200. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta.");
  5201. return false;
  5202. }
  5203.  
  5204. LPITEM weapon = GetWear(WEAR_WEAPON);
  5205.  
  5206. if (!weapon || weapon->GetType() != ITEM_ROD)
  5207. return false;
  5208.  
  5209. if (weapon->GetSocket(2))
  5210. {
  5211. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Ai schimbat %s .", item->GetName());
  5212. }
  5213.  
  5214. else
  5215. {
  5216. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Folosesti %s ca momeala .", item->GetName());
  5217. }
  5218.  
  5219. weapon->SetSocket(2, item->GetValue(0));
  5220. item->SetCount(item->GetCount() - 0);
  5221. }
  5222. break;
  5223.  
  5224. case USE_MOVE:
  5225. case USE_TREASURE_BOX:
  5226. case USE_MONEYBAG:
  5227. break;
  5228.  
  5229. case USE_AFFECT :
  5230. {
  5231. if (FindAffect(item->GetValue(0), aApplyInfo[item->GetValue(1)].bPointType))
  5232. {
  5233. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Folosesti deja acest efect .");
  5234. }
  5235.  
  5236. else
  5237. {
  5238. AddAffect(item->GetValue(0), aApplyInfo[item->GetValue(1)].bPointType, item->GetValue(2), 0, item->GetValue(3), 0, false);
  5239. item->SetCount(item->GetCount() - 0);
  5240. }
  5241. }
  5242. break;
  5243.  
  5244. case USE_CREATE_STONE:
  5245. AutoGiveItem(number(28000, 28013));
  5246. item->SetCount(item->GetCount() - 0);
  5247. break;
  5248.  
  5249. case USE_RECIPE :
  5250. {
  5251. LPITEM pSource1 = FindSpecifyItem(item->GetValue(1));
  5252. DWORD dwSourceCount1 = item->GetValue(2);
  5253.  
  5254. LPITEM pSource2 = FindSpecifyItem(item->GetValue(3));
  5255. DWORD dwSourceCount2 = item->GetValue(4);
  5256.  
  5257. if (dwSourceCount1 != 0)
  5258. {
  5259. if (pSource1 == NULL)
  5260. {
  5261. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Materiale insuficiente .");
  5262. return false;
  5263. }
  5264. }
  5265.  
  5266. if (dwSourceCount2 != 0)
  5267. {
  5268. if (pSource2 == NULL)
  5269. {
  5270. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Materiale insuficiente .");
  5271. return false;
  5272. }
  5273. }
  5274.  
  5275. if (pSource1 != NULL)
  5276. {
  5277. if (pSource1->GetCount() < dwSourceCount1)
  5278. {
  5279. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r %s insuficient(e) .", pSource1->GetName());
  5280. return false;
  5281. }
  5282.  
  5283. pSource1->SetCount(pSource1->GetCount() - dwSourceCount1);
  5284. }
  5285.  
  5286. if (pSource2 != NULL)
  5287. {
  5288. if (pSource2->GetCount() < dwSourceCount2)
  5289. {
  5290. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r %s insuficient(e) .", pSource2->GetName());
  5291. return false;
  5292. }
  5293.  
  5294. pSource2->SetCount(pSource2->GetCount() - dwSourceCount2);
  5295. }
  5296.  
  5297. LPITEM pBottle = FindSpecifyItem(50901);
  5298.  
  5299. if (!pBottle || pBottle->GetCount() < 1)
  5300. {
  5301. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  5302. return false;
  5303. }
  5304.  
  5305. pBottle->SetCount(pBottle->GetCount() - 1);
  5306.  
  5307. if (number(1, 100) > item->GetValue(5))
  5308. {
  5309. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  5310. return false;
  5311. }
  5312.  
  5313. AutoGiveItem(item->GetValue(0));
  5314. }
  5315. break;
  5316. }
  5317. }
  5318. break;
  5319.  
  5320. case ITEM_METIN:
  5321. {
  5322. LPITEM item2;
  5323.  
  5324. if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
  5325. return false;
  5326.  
  5327. if (item2->IsExchanging() || item2->IsEquipped())
  5328. return false;
  5329.  
  5330. if (item2->GetType() == ITEM_PICK) return false;
  5331. if (item2->GetType() == ITEM_ROD) return false;
  5332.  
  5333. int i;
  5334.  
  5335. for (i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  5336. {
  5337. DWORD dwVnum;
  5338.  
  5339. if ((dwVnum = item2->GetSocket(i)) <= 2)
  5340. continue;
  5341.  
  5342. TItemTable * p = ITEM_MANAGER::instance().GetTable(dwVnum);
  5343.  
  5344. if (!p)
  5345. continue;
  5346.  
  5347. if (item->GetValue(5) == p->alValues[5])
  5348. {
  5349. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Piatra] > |h|r Nu poti adauga mai multe pietre de acelasi fel .");
  5350. return false;
  5351. }
  5352. }
  5353.  
  5354. if (item2->GetType() == ITEM_ARMOR)
  5355. {
  5356. if (!IS_SET(item->GetWearFlag(), WEARABLE_BODY) || !IS_SET(item2->GetWearFlag(), WEARABLE_BODY))
  5357. {
  5358. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Piatra] > |h|r Ceva nu se potriveste .");
  5359. return false;
  5360. }
  5361. }
  5362.  
  5363. else if (item2->GetType() == ITEM_WEAPON)
  5364. {
  5365. if (!IS_SET(item->GetWearFlag(), WEARABLE_WEAPON))
  5366. {
  5367. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Piatra] > |h|r Ceva nu se potriveste .");
  5368. return false;
  5369. }
  5370. }
  5371.  
  5372. else
  5373. {
  5374. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Piatra] > |h|r Piatra nu poate fi adaugata .");
  5375. return false;
  5376. }
  5377.  
  5378. for (i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  5379. if (item2->GetSocket(i) >= 1 && item2->GetSocket(i) <= 2 && item2->GetSocket(i) >= item->GetValue(2))
  5380. {
  5381. if (number(1, 100) <= 100)
  5382. {
  5383. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Piatra] > |h|r Piatra a fost adaugata cu succes .");
  5384. item2->SetSocket(i, item->GetVnum());
  5385. }
  5386.  
  5387. else
  5388. {
  5389. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Piatra] > |h|r Piatra nu a fost adaugata .");
  5390. item2->SetSocket(i, ITEM_BROKEN_METIN_VNUM);
  5391. }
  5392.  
  5393. LogManager::instance().ItemLog(this, item2, "SOCKET", item->GetName());
  5394. ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (METIN)");
  5395. break;
  5396. }
  5397.  
  5398. if (i == ITEM_SOCKET_MAX_NUM)
  5399. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Piatra] > |h|r Piatra nu poate fi adaugata .");
  5400. }
  5401. break;
  5402.  
  5403. case ITEM_AUTOUSE:
  5404. case ITEM_MATERIAL:
  5405. case ITEM_SPECIAL:
  5406. case ITEM_TOOL:
  5407. case ITEM_LOTTERY:
  5408. break;
  5409.  
  5410. case ITEM_TOTEM:
  5411. {
  5412. if (!item->IsEquipped())
  5413. EquipItem(item);
  5414. }
  5415. break;
  5416.  
  5417. case ITEM_BLEND:
  5418. sys_log(0,"ITEM_BLEND!!");
  5419. if (Blend_Item_find(item->GetVnum()))
  5420. {
  5421. int affect_type = AFFECT_BLEND;
  5422. if (item->GetSocket(0) >= _countof(aApplyInfo))
  5423. {
  5424. sys_err ("INVALID BLEND ITEM(id : %d, vnum : %d). APPLY TYPE IS %d.", item->GetID(), item->GetVnum(), item->GetSocket(0));
  5425. return false;
  5426. }
  5427.  
  5428. int apply_type = aApplyInfo[item->GetSocket(0)].bPointType;
  5429. int apply_value = item->GetSocket(1);
  5430. int apply_duration = item->GetSocket(2);
  5431.  
  5432. if (FindAffect(affect_type, apply_type))
  5433. {
  5434. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Folosesti deja acest efect .");
  5435. }
  5436.  
  5437. else
  5438. {
  5439. if (FindAffect(AFFECT_EXP_BONUS_EURO_FREE, POINT_RESIST_MAGIC))
  5440. {
  5441. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Bonus] > |h|r Folosesti deja acest efect .");
  5442. }
  5443.  
  5444. else
  5445. {
  5446. AddAffect(affect_type, apply_type, apply_value, 0, apply_duration, 0, true, true);
  5447. item->Lock(1);
  5448. item->SetSocket(2, 1);
  5449. item->SetCount(item->GetCount() - 0);
  5450. }
  5451. }
  5452. }
  5453. break;
  5454.  
  5455. case ITEM_EXTRACT:
  5456. {
  5457. LPITEM pDestItem = GetItem(DestCell);
  5458. if (NULL == pDestItem)
  5459. {
  5460. return false;
  5461. }
  5462.  
  5463. switch (item->GetSubType())
  5464. {
  5465. case EXTRACT_DRAGON_SOUL:
  5466. if (pDestItem->IsDragonSoul())
  5467. {
  5468. return DSManager::instance().PullOut(this, NPOS, pDestItem, item);
  5469. }
  5470. return false;
  5471.  
  5472. case EXTRACT_DRAGON_HEART:
  5473. if (pDestItem->IsDragonSoul())
  5474. {
  5475. return DSManager::instance().ExtractDragonHeart(this, pDestItem, item);
  5476. }
  5477. return false;
  5478.  
  5479. default:
  5480. return false;
  5481. }
  5482. }
  5483. break;
  5484.  
  5485. case ITEM_NONE:
  5486. sys_err("Item type NONE %s", item->GetName());
  5487. break;
  5488.  
  5489. default:
  5490. sys_log(0, "UseItemEx: Unknown type %s %d", item->GetName(), item->GetType());
  5491. return false;
  5492. }
  5493.  
  5494. return true;
  5495. }
  5496.  
  5497. int g_nPortalLimitTime = 10;
  5498.  
  5499. bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell)
  5500. {
  5501. WORD wCell = Cell.cell;
  5502. BYTE window_type = Cell.window_type;
  5503. WORD wDestCell = DestCell.cell;
  5504. BYTE bDestInven = DestCell.window_type;
  5505. LPITEM item;
  5506.  
  5507. if (!CanHandleItem())
  5508. return false;
  5509.  
  5510. #ifdef __INVENTORY_PROTECT_SYSTEM__
  5511. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  5512. {
  5513. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  5514. return false;
  5515. }
  5516. #endif
  5517.  
  5518. if (!IsValidItemPosition(Cell) || !(item = GetItem(Cell)))
  5519. return false;
  5520.  
  5521. if (item->GetType() == ITEM_BELT && CBeltInventoryHelper::IsExistItemInBeltInventory(this))
  5522. {
  5523. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Empty your belt inventory !"));
  5524. return false;
  5525. }
  5526.  
  5527. sys_log(0, "%s: USE_ITEM %s (inven %d, cell: %d)", GetName(), item->GetName(), window_type, wCell);
  5528.  
  5529. if (item->IsExchanging())
  5530. return false;
  5531.  
  5532. #ifdef __INVENTORY_PROTECT_SYSTEM__
  5533. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  5534. {
  5535. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  5536. return false;
  5537. }
  5538. #endif
  5539.  
  5540. #ifdef __SWITCHBOT__
  5541. if (Cell.IsSwitchbotPosition())
  5542. {
  5543. CSwitchbot* pkSwitchbot = CSwitchbotManager::Instance().FindSwitchbot(GetPlayerID());
  5544. if (pkSwitchbot && pkSwitchbot->IsActive(Cell.cell))
  5545. {
  5546. return false;
  5547. }
  5548.  
  5549. int32_t iEmptyCell = GetEmptyInventory(item->GetSize());
  5550.  
  5551. if (iEmptyCell == -1)
  5552. {
  5553. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Cannot remove item from switchbot. Inventory is full."));
  5554. return false;
  5555. }
  5556.  
  5557. MoveItem(Cell, TItemPos(INVENTORY, iEmptyCell), item->GetCount());
  5558.  
  5559. return true;
  5560. }
  5561. #endif
  5562.  
  5563. if (!item->CanUsedBy(this))
  5564. {
  5565. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("군직이 맞지않아 이 아이템을 사용할 수 없습니다."));
  5566. return false;
  5567. }
  5568.  
  5569. if (IsStun())
  5570. return false;
  5571.  
  5572. if (false == FN_check_item_sex(this, item))
  5573. {
  5574. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("성별이 맞지않아 이 아이템을 사용할 수 없습니다."));
  5575. return false;
  5576. }
  5577.  
  5578. if (IS_SUMMON_ITEM(item->GetVnum()))
  5579. {
  5580. if (false == IS_SUMMONABLE_ZONE(GetMapIndex()))
  5581. {
  5582. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("사용할수 없습니다."));
  5583. return false;
  5584. }
  5585.  
  5586. int iPulse = thecore_pulse();
  5587.  
  5588. if (iPulse - GetSafeboxLoadTime() < PASSES_PER_SEC(g_nPortalLimitTime))
  5589. {
  5590. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("창고를 연후 %d초 이내에는 귀환부,귀환기억부를 사용할 수 없습니다."), g_nPortalLimitTime);
  5591.  
  5592. if (test_server)
  5593. ChatPacket(CHAT_TYPE_INFO, "[TestOnly]Pulse %d LoadTime %d PASS %d", iPulse, GetSafeboxLoadTime(), PASSES_PER_SEC(g_nPortalLimitTime));
  5594. return false;
  5595. }
  5596.  
  5597. if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen())
  5598. {
  5599. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("거래창,창고 등을 연 상태에서는 귀환부,귀환기억부 를 사용할수 없습니다."));
  5600. return false;
  5601. }
  5602.  
  5603. {
  5604. if (iPulse - GetRefineTime() < PASSES_PER_SEC(g_nPortalLimitTime))
  5605. {
  5606. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 개량후 %d초 이내에는 귀환부,귀환기억부를 사용할 수 없습니다."), g_nPortalLimitTime);
  5607. return false;
  5608. }
  5609. }
  5610.  
  5611. {
  5612. if (iPulse - GetMyShopTime() < PASSES_PER_SEC(g_nPortalLimitTime))
  5613. {
  5614. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개인상점 사용후 %d초 이내에는 귀환부,귀환기억부를 사용할 수 없습니다."), g_nPortalLimitTime);
  5615. return false;
  5616. }
  5617.  
  5618. }
  5619.  
  5620. if (item->GetVnum() != 70302)
  5621. {
  5622. PIXEL_POSITION posWarp;
  5623.  
  5624. int x = 0;
  5625. int y = 0;
  5626.  
  5627. double nDist = 0;
  5628. const double nDistant = 5000.0;
  5629.  
  5630. if (item->GetVnum() == 22010)
  5631. {
  5632. x = item->GetSocket(0) - GetX();
  5633. y = item->GetSocket(1) - GetY();
  5634. }
  5635.  
  5636. else if (item->GetVnum() == 22000)
  5637. {
  5638. SECTREE_MANAGER::instance().GetRecallPositionByEmpire(GetMapIndex(), GetEmpire(), posWarp);
  5639.  
  5640. if (item->GetSocket(0) == 0)
  5641. {
  5642. x = posWarp.x - GetX();
  5643. y = posWarp.y - GetY();
  5644. }
  5645.  
  5646. else
  5647. {
  5648. x = item->GetSocket(0) - GetX();
  5649. y = item->GetSocket(1) - GetY();
  5650. }
  5651. }
  5652.  
  5653. nDist = sqrt(pow((float)x,2) + pow((float)y,2));
  5654.  
  5655. if (nDistant > nDist)
  5656. {
  5657. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이동 되어질 위치와 너무 가까워 귀환부를 사용할수 없습니다."));
  5658.  
  5659. if (test_server)
  5660. ChatPacket(CHAT_TYPE_INFO, "PossibleDistant %f nNowDist %f", nDistant,nDist);
  5661.  
  5662. return false;
  5663. }
  5664. }
  5665.  
  5666. if (iPulse - GetExchangeTime() < PASSES_PER_SEC(g_nPortalLimitTime))
  5667. {
  5668. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("거래 후 %d초 이내에는 귀환부,귀환기억부등을 사용할 수 없습니다."), g_nPortalLimitTime);
  5669. return false;
  5670. }
  5671. }
  5672.  
  5673. if (item->GetVnum() == 50200 | item->GetVnum() == 71049)
  5674. {
  5675. if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen())
  5676. {
  5677. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("거래창,창고 등을 연 상태에서는 보따리,비단보따리를 사용할수 없습니다."));
  5678. return false;
  5679. }
  5680.  
  5681. }
  5682.  
  5683. if (quest::CQuestManager::instance().GetPCForce(GetPlayerID())->IsRunning() == true)
  5684. {
  5685. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot use this item if you're using quests"));
  5686. return false;
  5687. }
  5688.  
  5689. if (IS_SET(item->GetFlag(), ITEM_FLAG_LOG))
  5690. {
  5691. DWORD vid = item->GetVID();
  5692. DWORD oldCount = item->GetCount();
  5693. DWORD vnum = item->GetVnum();
  5694.  
  5695. char hint[ITEM_NAME_MAX_LEN + 32 + 1];
  5696. int len = snprintf(hint, sizeof(hint) - 32, "%s", item->GetName());
  5697.  
  5698. if (len < 0 || len >= (int) sizeof(hint) - 32)
  5699. len = (sizeof(hint) - 32) - 1;
  5700.  
  5701. bool ret = UseItemEx(item, DestCell);
  5702.  
  5703. if (NULL == ITEM_MANAGER::instance().FindByVID(vid))
  5704. {
  5705. LogManager::instance().ItemLog(this, vid, vnum, "REMOVE", hint);
  5706. }
  5707.  
  5708. else if (oldCount != item->GetCount())
  5709. {
  5710. snprintf(hint + len, sizeof(hint) - len, " %u", oldCount - 1);
  5711. LogManager::instance().ItemLog(this, vid, vnum, "USE_ITEM", hint);
  5712. }
  5713.  
  5714. return (ret);
  5715. }
  5716.  
  5717. else
  5718. return UseItemEx(item, DestCell);
  5719. }
  5720.  
  5721. bool CHARACTER::DropItem(TItemPos Cell, WORD bCount)
  5722. {
  5723. LPITEM item = NULL;
  5724.  
  5725. if (!CanHandleItem())
  5726. {
  5727. if (NULL != DragonSoul_RefineWindow_GetOpener())
  5728. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화창을 연 상태에서는 아이템을 옮길 수 없습니다."));
  5729. return false;
  5730. }
  5731.  
  5732. #ifdef __INVENTORY_PROTECT_SYSTEM__
  5733. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  5734. {
  5735. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  5736. return false;
  5737. }
  5738. #endif
  5739.  
  5740. if (IsDead())
  5741. return false;
  5742.  
  5743. if (!IsValidItemPosition(Cell) || !(item = GetItem(Cell)))
  5744. return false;
  5745.  
  5746. if (item->IsExchanging())
  5747. return false;
  5748.  
  5749. #ifdef __INVENTORY_PROTECT_SYSTEM__
  5750. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  5751. {
  5752. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  5753. return false;
  5754. }
  5755. #endif
  5756.  
  5757. if (true == item->isLocked())
  5758. return false;
  5759.  
  5760. #ifdef ENABLE_ARUNCA_ITEME_IN_MAPE
  5761. int arunca_iteme = GetMapIndex();
  5762.  
  5763. switch (arunca_iteme)
  5764. {
  5765. case 1:
  5766. case 41:
  5767. case 61:
  5768. case 70:
  5769. case 72:
  5770. case 81:
  5771. case 110:
  5772. case 111:
  5773. case 112:
  5774. case 113:
  5775. {
  5776. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti arunca obiecte pe jos in aceasta mapa. Foloseste systemul de stergere .");
  5777. return false;
  5778. }
  5779.  
  5780. default:
  5781. break;
  5782. }
  5783. #endif
  5784.  
  5785. if (quest::CQuestManager::instance().GetPCForce(GetPlayerID())->IsRunning() == true)
  5786. return false;
  5787.  
  5788. if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_DROP | ITEM_ANTIFLAG_GIVE))
  5789. {
  5790. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Acest obiect nu poate fi aruncat .");
  5791. return false;
  5792. }
  5793.  
  5794. if (bCount == 0 || bCount > item->GetCount())
  5795. bCount = item->GetCount();
  5796.  
  5797. SyncQuickslot(QUICKSLOT_TYPE_ITEM, Cell.cell, 1000);
  5798.  
  5799. LPITEM pkItemToDrop;
  5800.  
  5801. if (bCount == item->GetCount())
  5802. {
  5803. item->RemoveFromCharacter();
  5804. pkItemToDrop = item;
  5805. }
  5806.  
  5807. else
  5808. {
  5809. if (bCount == 0)
  5810. {
  5811. if (test_server)
  5812. sys_log(0, "[DROP_ITEM] drop item count == 0");
  5813. return false;
  5814. }
  5815.  
  5816. item->SetCount(item->GetCount() - bCount);
  5817. ITEM_MANAGER::instance().FlushDelayedSave(item);
  5818.  
  5819. pkItemToDrop = ITEM_MANAGER::instance().CreateItem(item->GetVnum(), bCount);
  5820.  
  5821. FN_copy_item_socket(pkItemToDrop, item);
  5822.  
  5823. char szBuf[51 + 1];
  5824. snprintf(szBuf, sizeof(szBuf), "%u %u", pkItemToDrop->GetID(), pkItemToDrop->GetCount());
  5825. LogManager::instance().ItemLog(this, item, "ITEM_SPLIT", szBuf);
  5826. }
  5827.  
  5828. PIXEL_POSITION pxPos = GetXYZ();
  5829.  
  5830. if (pkItemToDrop->AddToGround(GetMapIndex(), pxPos))
  5831. {
  5832. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Obiectul aruncat va disparea in 1 minute .");
  5833. pkItemToDrop->StartDestroyEvent();
  5834.  
  5835. ITEM_MANAGER::instance().FlushDelayedSave(pkItemToDrop);
  5836.  
  5837. char szHint[32 + 1];
  5838.  
  5839. snprintf(szHint, sizeof(szHint), "%s %u %u", pkItemToDrop->GetName(), pkItemToDrop->GetCount(), pkItemToDrop->GetOriginalVnum());
  5840. LogManager::instance().ItemLog(this, pkItemToDrop, "DROP", szHint);
  5841. }
  5842.  
  5843. return true;
  5844. }
  5845.  
  5846. #ifdef ENABLE_DESTORY_ITEM
  5847. bool CHARACTER::DestroyItem(TItemPos Cell)
  5848. {
  5849. LPITEM item = NULL;
  5850.  
  5851. if (!CanHandleItem())
  5852. return false;
  5853.  
  5854. #ifdef __INVENTORY_PROTECT_SYSTEM__
  5855. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  5856. {
  5857. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  5858. return false;
  5859. }
  5860. #endif
  5861.  
  5862. if (IsDead())
  5863. return false;
  5864.  
  5865. if (!IsValidItemPosition(Cell) || !(item = GetItem(Cell)))
  5866. return false;
  5867.  
  5868. if (item->IsExchanging())
  5869. return false;
  5870.  
  5871. #ifdef __INVENTORY_PROTECT_SYSTEM__
  5872. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  5873. {
  5874. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  5875. return false;
  5876. }
  5877. #endif
  5878.  
  5879. if (true == item->isLocked())
  5880. return false;
  5881.  
  5882. if (quest::CQuestManager::instance().GetPCForce(GetPlayerID())->IsRunning() == true)
  5883. return false;
  5884.  
  5885. if (item->GetCount() <= 0)
  5886. return false;
  5887.  
  5888. SyncQuickslot(QUICKSLOT_TYPE_ITEM, Cell.cell, 1000);
  5889.  
  5890. ITEM_MANAGER::instance().RemoveItem(item);
  5891.  
  5892. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Sterge Item] > |h|r Ai sters itemul |cFFc9ff00[%s]|h|r cu success .", item->GetName());
  5893.  
  5894. return true;
  5895. }
  5896. #endif
  5897.  
  5898. bool CHARACTER::DropGold(int gold)
  5899. {
  5900. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Anti Drop] > |h|r Nu poti arunca yang pe jos.");
  5901. return false;
  5902. }
  5903.  
  5904. bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, WORD count)
  5905. {
  5906. LPITEM item = NULL;
  5907.  
  5908. if (!IsValidItemPosition(Cell))
  5909. return false;
  5910.  
  5911. if (!(item = GetItem(Cell)))
  5912. return false;
  5913.  
  5914. if (item->IsExchanging())
  5915. return false;
  5916.  
  5917. #ifdef __INVENTORY_PROTECT_SYSTEM__
  5918. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  5919. {
  5920. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  5921. return false;
  5922. }
  5923. #endif
  5924.  
  5925. if (item->GetCount() < count)
  5926. return false;
  5927.  
  5928. if (INVENTORY == Cell.window_type && Cell.cell >= INVENTORY_MAX_NUM && IS_SET(item->GetFlag(), ITEM_FLAG_IRREMOVABLE))
  5929. return false;
  5930.  
  5931. if (true == item->isLocked())
  5932. return false;
  5933.  
  5934. if (!IsValidItemPosition(DestCell))
  5935. {
  5936. return false;
  5937. }
  5938.  
  5939. if (!CanHandleItem())
  5940. {
  5941. if (NULL != DragonSoul_RefineWindow_GetOpener())
  5942. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화창을 연 상태에서는 아이템을 옮길 수 없습니다."));
  5943. return false;
  5944. }
  5945.  
  5946. #ifdef __INVENTORY_PROTECT_SYSTEM__
  5947. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  5948. {
  5949. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  5950. return false;
  5951. }
  5952. #endif
  5953.  
  5954. if (DestCell.IsBeltInventoryPosition() && false == CBeltInventoryHelper::CanMoveIntoBeltInventory(item))
  5955. {
  5956. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템은 벨트 인벤토리로 옮길 수 없습니다."));
  5957. return false;
  5958. }
  5959.  
  5960. #ifdef __SWITCHBOT__
  5961. if (Cell.IsSwitchbotPosition() && CSwitchbotManager::Instance().IsActive(GetPlayerID(), Cell.cell))
  5962. {
  5963. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Cannot move active switchbot item."));
  5964. return false;
  5965. }
  5966.  
  5967. if (DestCell.IsSwitchbotPosition() && !SwitchbotHelper::IsValidItem(item))
  5968. {
  5969. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Invalid item type for switchbot."));
  5970. return false;
  5971. }
  5972. #endif
  5973.  
  5974. if (Cell.IsEquipPosition() && !CanUnequipNow(item))
  5975. return false;
  5976.  
  5977. if (DestCell.IsEquipPosition())
  5978. {
  5979. if (GetItem(DestCell))
  5980. {
  5981. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이미 장비를 착용하고 있습니다."));
  5982.  
  5983. return false;
  5984. }
  5985.  
  5986. EquipItem(item, DestCell.cell - INVENTORY_MAX_NUM);
  5987. }
  5988.  
  5989. else
  5990. {
  5991. if (item->IsDragonSoul())
  5992. {
  5993. if (item->IsEquipped())
  5994. {
  5995. return DSManager::instance().PullOut(this, DestCell, item);
  5996. }
  5997.  
  5998. else
  5999. {
  6000. if (DestCell.window_type != DRAGON_SOUL_INVENTORY)
  6001. {
  6002. return false;
  6003. }
  6004.  
  6005. if (!DSManager::instance().IsValidCellForThisItem(item, DestCell))
  6006. return false;
  6007. }
  6008. }
  6009.  
  6010. else if (DRAGON_SOUL_INVENTORY == DestCell.window_type)
  6011. return false;
  6012.  
  6013. LPITEM item2;
  6014.  
  6015. if ((item2 = GetItem(DestCell)) && item != item2 && item2->IsStackable() &&
  6016. !IS_SET(item2->GetAntiFlag(), ITEM_ANTIFLAG_STACK) &&
  6017. item2->GetVnum() == item->GetVnum())
  6018. {
  6019. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  6020. if (item2->GetSocket(i) != item->GetSocket(i))
  6021. return false;
  6022.  
  6023. if (count == 0)
  6024. count = item->GetCount();
  6025.  
  6026. sys_log(0, "%s: ITEM_STACK %s (window: %d, cell : %d) -> (window:%d, cell %d) count %d", GetName(), item->GetName(), Cell.window_type, Cell.cell,
  6027. DestCell.window_type, DestCell.cell, count);
  6028.  
  6029. count = MIN(ITEM_MAX_COUNT - item2->GetCount(), count);
  6030.  
  6031. item->SetCount(item->GetCount() - count);
  6032. item2->SetCount(item2->GetCount() + count);
  6033.  
  6034. return true;
  6035. }
  6036.  
  6037. if (!IsEmptyItemGrid(DestCell, item->GetSize(), Cell.cell))
  6038. return false;
  6039.  
  6040. if (count == 0 || count >= item->GetCount() || !item->IsStackable() || IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))
  6041. {
  6042. sys_log(0, "%s: ITEM_MOVE %s (window: %d, cell : %d) -> (window:%d, cell %d) count %d", GetName(), item->GetName(), Cell.window_type, Cell.cell,
  6043. DestCell.window_type, DestCell.cell, count);
  6044.  
  6045. item->RemoveFromCharacter();
  6046. SetItem(DestCell, item);
  6047.  
  6048. #ifdef __PET_SYSTEM__
  6049. if(ITEM_NORMAL_PET == item->GetType())
  6050. {
  6051. quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
  6052. }
  6053. #endif
  6054.  
  6055. #ifdef __TITLE_SYSTEM__
  6056. if(ITEM_COSTUME == item->GetType() && ITEM_NORMAL_TITLE == item->GetSubType())
  6057. {
  6058. quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
  6059. }
  6060. #endif
  6061. if (INVENTORY == Cell.window_type && INVENTORY == DestCell.window_type)
  6062. SyncQuickslot(QUICKSLOT_TYPE_ITEM, Cell.cell, DestCell.cell);
  6063. }
  6064.  
  6065. else if (count < item->GetCount())
  6066. {
  6067. sys_log(0, "%s: ITEM_SPLIT %s (window: %d, cell : %d) -> (window:%d, cell %d) count %d", GetName(), item->GetName(), Cell.window_type, Cell.cell,
  6068. DestCell.window_type, DestCell.cell, count);
  6069.  
  6070. item->SetCount(item->GetCount() - count);
  6071. LPITEM item2 = ITEM_MANAGER::instance().CreateItem(item->GetVnum(), count);
  6072.  
  6073. FN_copy_item_socket(item2, item);
  6074.  
  6075. item2->AddToCharacter(this, DestCell);
  6076.  
  6077. char szBuf[51+1];
  6078. snprintf(szBuf, sizeof(szBuf), "%u %u %u %u ", item2->GetID(), item2->GetCount(), item->GetCount(), item->GetCount() + item2->GetCount());
  6079. LogManager::instance().ItemLog(this, item, "ITEM_SPLIT", szBuf);
  6080. }
  6081. }
  6082.  
  6083. return true;
  6084. }
  6085.  
  6086. namespace NPartyPickupDistribute
  6087. {
  6088. struct FFindOwnership
  6089. {
  6090. LPITEM item;
  6091. LPCHARACTER owner;
  6092.  
  6093. FFindOwnership(LPITEM item)
  6094. : item(item), owner(NULL)
  6095. {
  6096. }
  6097.  
  6098. void operator () (LPCHARACTER ch)
  6099. {
  6100. if (item->IsOwnership(ch))
  6101. owner = ch;
  6102. }
  6103. };
  6104.  
  6105. struct FCountNearMember
  6106. {
  6107. int total;
  6108. int x, y;
  6109.  
  6110. FCountNearMember(LPCHARACTER center )
  6111. : total(0), x(center->GetX()), y(center->GetY())
  6112. {
  6113. }
  6114.  
  6115. void operator () (LPCHARACTER ch)
  6116. {
  6117. if (DISTANCE_APPROX(ch->GetX() - x, ch->GetY() - y) <= PARTY_DEFAULT_RANGE)
  6118. total += 1;
  6119. }
  6120. };
  6121.  
  6122. struct FMoneyDistributor
  6123. {
  6124. int total;
  6125. LPCHARACTER c;
  6126. int x, y;
  6127. int iMoney;
  6128.  
  6129. FMoneyDistributor(LPCHARACTER center, int iMoney)
  6130. : total(0), c(center), x(center->GetX()), y(center->GetY()), iMoney(iMoney)
  6131. {
  6132. }
  6133.  
  6134. void operator ()(LPCHARACTER ch)
  6135. {
  6136. if (ch!=c)
  6137. if (DISTANCE_APPROX(ch->GetX() - x, ch->GetY() - y) <= PARTY_DEFAULT_RANGE)
  6138. {
  6139. ch->PointChange(POINT_GOLD, iMoney, true);
  6140.  
  6141. if (iMoney > 1000)
  6142. LogManager::instance().CharLog(ch, iMoney, "GET_GOLD", "");
  6143. }
  6144. }
  6145. };
  6146. }
  6147.  
  6148. void CHARACTER::GiveGold(long long iAmount)
  6149. {
  6150. if (iAmount <= 0)
  6151. return;
  6152.  
  6153. sys_log(0, "GIVE_GOLD: %s %lld", GetName(), iAmount);
  6154.  
  6155. if (GetParty())
  6156. {
  6157. LPPARTY pParty = GetParty();
  6158.  
  6159. long long dwTotal = iAmount;
  6160. long long dwMyAmount = dwTotal;
  6161.  
  6162. NPartyPickupDistribute::FCountNearMember funcCountNearMember(this);
  6163. pParty->ForEachOnlineMember(funcCountNearMember);
  6164.  
  6165. if (funcCountNearMember.total > 1)
  6166. {
  6167. DWORD dwShare = dwTotal / funcCountNearMember.total;
  6168. dwMyAmount -= dwShare * (funcCountNearMember.total - 1);
  6169.  
  6170. NPartyPickupDistribute::FMoneyDistributor funcMoneyDist(this, dwShare);
  6171.  
  6172. pParty->ForEachOnlineMember(funcMoneyDist);
  6173. }
  6174.  
  6175. PointChange(POINT_GOLD, dwMyAmount, true);
  6176.  
  6177. if (dwMyAmount > 1000)
  6178. LogManager::instance().CharLog(this, dwMyAmount, "GET_GOLD", "");
  6179. }
  6180.  
  6181. else
  6182. {
  6183. PointChange(POINT_GOLD, iAmount, true);
  6184.  
  6185. if (iAmount > 1000)
  6186. LogManager::instance().CharLog(this, iAmount, "GET_GOLD", "");
  6187. }
  6188. }
  6189.  
  6190. bool CHARACTER::PickupItem(DWORD dwVID)
  6191. {
  6192. LPITEM item = ITEM_MANAGER::instance().FindByVID(dwVID);
  6193.  
  6194. if (IsObserverMode())
  6195. return false;
  6196.  
  6197. if (!item || !item->GetSectree())
  6198. return false;
  6199.  
  6200. if (item->DistanceValid(this))
  6201. {
  6202. if (item->GetType() == ITEM_QUEST)
  6203. {
  6204. if (quest::CQuestManager::instance().GetPCForce(GetPlayerID())->IsRunning() == true)
  6205. {
  6206. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot pickup this item if you're using quests"));
  6207. return false;
  6208. }
  6209. }
  6210.  
  6211. if (item->IsOwnership(this))
  6212. {
  6213. if (item->GetType() == ITEM_ELK)
  6214. {
  6215. GiveGold(item->GetCount());
  6216. item->RemoveFromGround();
  6217.  
  6218. M2_DESTROY_ITEM(item);
  6219.  
  6220. Save();
  6221. }
  6222.  
  6223. else
  6224. {
  6225. if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))
  6226. {
  6227. WORD bCount = item->GetCount();
  6228.  
  6229. for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
  6230. {
  6231. LPITEM item2 = GetInventoryItem(i);
  6232.  
  6233. if (!item2)
  6234. continue;
  6235.  
  6236. if (item2->GetVnum() == item->GetVnum())
  6237. {
  6238. int j;
  6239.  
  6240. for (j = 0; j < ITEM_SOCKET_MAX_NUM; ++j)
  6241. if (item2->GetSocket(j) != item->GetSocket(j))
  6242. break;
  6243.  
  6244. if (j != ITEM_SOCKET_MAX_NUM)
  6245. continue;
  6246.  
  6247. WORD bCount2 = MIN(ITEM_MAX_COUNT - item2->GetCount(), bCount);
  6248. bCount -= bCount2;
  6249.  
  6250. item2->SetCount(item2->GetCount() + bCount2);
  6251.  
  6252. if (bCount == 0)
  6253. {
  6254. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), item2->GetName());
  6255. M2_DESTROY_ITEM(item);
  6256. if (item2->GetType() == ITEM_QUEST)
  6257. quest::CQuestManager::instance().PickupItem (GetPlayerID(), item2);
  6258. return true;
  6259. }
  6260. }
  6261. }
  6262.  
  6263. item->SetCount(bCount);
  6264. }
  6265.  
  6266. int iEmptyCell;
  6267. if (item->IsDragonSoul())
  6268. {
  6269. if ((iEmptyCell = GetEmptyDragonSoulInventory(item)) == -1)
  6270. {
  6271. sys_log(0, "No empty ds inventory pid %u size %ud itemid %u", GetPlayerID(), item->GetSize(), item->GetID());
  6272. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지하고 있는 아이템이 너무 많습니다."));
  6273. return false;
  6274. }
  6275. }
  6276.  
  6277. else
  6278. {
  6279. if ((iEmptyCell = GetEmptyInventory(item->GetSize())) == -1)
  6280. {
  6281. sys_log(0, "No empty inventory pid %u size %ud itemid %u", GetPlayerID(), item->GetSize(), item->GetID());
  6282. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지하고 있는 아이템이 너무 많습니다."));
  6283. return false;
  6284. }
  6285. }
  6286.  
  6287. item->RemoveFromGround();
  6288.  
  6289. if (item->IsDragonSoul())
  6290. item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
  6291. else
  6292. item->AddToCharacter(this, TItemPos(INVENTORY, iEmptyCell));
  6293.  
  6294. char szHint[32+1];
  6295.  
  6296. snprintf(szHint, sizeof(szHint), "%s %u %u", item->GetName(), item->GetCount(), item->GetOriginalVnum());
  6297.  
  6298. LogManager::instance().ItemLog(this, item, "GET", szHint);
  6299. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), item->GetName());
  6300.  
  6301. if (item->GetType() == ITEM_QUEST)
  6302. quest::CQuestManager::instance().PickupItem (GetPlayerID(), item);
  6303. }
  6304.  
  6305. //Motion(MOTION_PICKUP);
  6306. return true;
  6307. }
  6308.  
  6309. else if (!IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_DROP) && GetParty())
  6310. {
  6311. NPartyPickupDistribute::FFindOwnership funcFindOwnership(item);
  6312.  
  6313. GetParty()->ForEachOnlineMember(funcFindOwnership);
  6314.  
  6315. LPCHARACTER owner = funcFindOwnership.owner;
  6316.  
  6317. if (!owner)
  6318. return false;
  6319.  
  6320. int iEmptyCell;
  6321.  
  6322. if (item->IsDragonSoul())
  6323. {
  6324. if (!(owner && (iEmptyCell = owner->GetEmptyDragonSoulInventory(item)) != -1))
  6325. {
  6326. owner = this;
  6327.  
  6328. if ((iEmptyCell = GetEmptyDragonSoulInventory(item)) == -1)
  6329. {
  6330. owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지하고 있는 아이템이 너무 많습니다."));
  6331. return false;
  6332. }
  6333. }
  6334. }
  6335.  
  6336. else
  6337. {
  6338. if (!(owner && (iEmptyCell = owner->GetEmptyInventory(item->GetSize())) != -1))
  6339. {
  6340. owner = this;
  6341.  
  6342. if ((iEmptyCell = GetEmptyInventory(item->GetSize())) == -1)
  6343. {
  6344. owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지하고 있는 아이템이 너무 많습니다."));
  6345. return false;
  6346. }
  6347. }
  6348. }
  6349.  
  6350. item->RemoveFromGround();
  6351.  
  6352. if (item->IsDragonSoul())
  6353. item->AddToCharacter(owner, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
  6354. else
  6355. item->AddToCharacter(owner, TItemPos(INVENTORY, iEmptyCell));
  6356.  
  6357. char szHint[32+1];
  6358.  
  6359. snprintf(szHint, sizeof(szHint), "%s %u %u", item->GetName(), item->GetCount(), item->GetOriginalVnum());
  6360.  
  6361. LogManager::instance().ItemLog(owner, item, "GET", szHint);
  6362.  
  6363. if (owner == this)
  6364. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), item->GetName());
  6365.  
  6366. else
  6367. {
  6368. owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s 님으로부터 %s"), GetName(), item->GetName());
  6369. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 전달: %s 님에게 %s"), owner->GetName(), item->GetName());
  6370. }
  6371.  
  6372. if (item->GetType() == ITEM_QUEST)
  6373. quest::CQuestManager::instance().PickupItem (owner->GetPlayerID(), item);
  6374.  
  6375. return true;
  6376. }
  6377. }
  6378.  
  6379. return false;
  6380. }
  6381.  
  6382. bool CHARACTER::SwapItem(UINT bCell, UINT bDestCell)
  6383. {
  6384. if (!CanHandleItem())
  6385. return false;
  6386.  
  6387. #ifdef __INVENTORY_PROTECT_SYSTEM__
  6388. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  6389. {
  6390. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  6391. return false;
  6392. }
  6393. #endif
  6394.  
  6395. TItemPos srcCell(INVENTORY, bCell), destCell(INVENTORY, bDestCell);
  6396.  
  6397. //if (bCell >= INVENTORY_MAX_NUM + WEAR_MAX_NUM || bDestCell >= INVENTORY_MAX_NUM + WEAR_MAX_NUM)
  6398. if (srcCell.IsDragonSoulEquipPosition() || destCell.IsDragonSoulEquipPosition())
  6399. return false;
  6400.  
  6401. if (bCell == bDestCell)
  6402. return false;
  6403.  
  6404. if (srcCell.IsEquipPosition() && destCell.IsEquipPosition())
  6405. return false;
  6406.  
  6407. LPITEM item1, item2;
  6408.  
  6409. if (srcCell.IsEquipPosition())
  6410. {
  6411. item1 = GetInventoryItem(bDestCell);
  6412. item2 = GetInventoryItem(bCell);
  6413. }
  6414.  
  6415. else
  6416. {
  6417. item1 = GetInventoryItem(bCell);
  6418. item2 = GetInventoryItem(bDestCell);
  6419. }
  6420.  
  6421. if (!item1 || !item2)
  6422. return false;
  6423.  
  6424. if (item1 == item2)
  6425. {
  6426. sys_log(0, "[WARNING][WARNING][HACK USER!] : %s %d %d", m_stName.c_str(), bCell, bDestCell);
  6427. return false;
  6428. }
  6429.  
  6430. if (!IsEmptyItemGrid(TItemPos (INVENTORY, item1->GetCell()), item2->GetSize(), item1->GetCell()))
  6431. return false;
  6432.  
  6433. if (TItemPos(EQUIPMENT, item2->GetCell()).IsEquipPosition())
  6434. {
  6435. INT bEquipCell = item2->GetCell() - INVENTORY_MAX_NUM;
  6436.  
  6437. UINT bInvenCell = item1->GetCell();
  6438.  
  6439. if (item2->IsDragonSoul() || item2->GetType() == ITEM_BELT)
  6440. {
  6441. if (false == CanUnequipNow(item2) || false == CanEquipNow(item1))
  6442. return false;
  6443. }
  6444.  
  6445. if (bEquipCell != item1->FindEquipCell(this))
  6446. return false;
  6447.  
  6448. #ifdef __PET_SYSTEM__
  6449. if(ITEM_NORMAL_PET == item2->GetType())
  6450. {
  6451. quest::CQuestManager::instance().UseItem(GetPlayerID(), item2, false);
  6452. }
  6453. #endif
  6454. item2->RemoveFromCharacter();
  6455.  
  6456. if (item1->EquipTo(this, bEquipCell))
  6457. #ifdef __HIGHLIGHT_SYSTEM__
  6458. item2->AddToCharacter(this, TItemPos(INVENTORY, bInvenCell), false);
  6459. #else
  6460. item2->AddToCharacter(this, TItemPos(INVENTORY, bInvenCell));
  6461. #endif
  6462. else
  6463. sys_err("SwapItem cannot equip %s! item1 %s", item2->GetName(), item1->GetName());
  6464. }
  6465.  
  6466. else
  6467. {
  6468. UINT bCell1 = item1->GetCell();
  6469. UINT bCell2 = item2->GetCell();
  6470.  
  6471. item1->RemoveFromCharacter();
  6472. item2->RemoveFromCharacter();
  6473.  
  6474. #ifdef __HIGHLIGHT_SYSTEM__
  6475. item1->AddToCharacter(this, TItemPos(INVENTORY, bCell2), false);
  6476. item2->AddToCharacter(this, TItemPos(INVENTORY, bCell1), false);
  6477. #else
  6478. item1->AddToCharacter(this, TItemPos(INVENTORY, bCell2));
  6479. item2->AddToCharacter(this, TItemPos(INVENTORY, bCell1));
  6480. #endif
  6481.  
  6482. }
  6483.  
  6484. return true;
  6485. }
  6486.  
  6487. bool CHARACTER::UnequipItem(LPITEM item)
  6488. {
  6489. int pos;
  6490.  
  6491. if (false == CanUnequipNow(item))
  6492. return false;
  6493.  
  6494. #ifdef __INVENTORY_PROTECT_SYSTEM__
  6495. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  6496. {
  6497. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  6498. return false;
  6499. }
  6500. #endif
  6501.  
  6502. if (item->IsDragonSoul())
  6503. pos = GetEmptyDragonSoulInventory(item);
  6504. else
  6505. pos = GetEmptyInventory(item->GetSize());
  6506.  
  6507.  
  6508. if (item->GetVnum() == UNIQUE_ITEM_HIDE_ALIGNMENT_TITLE)
  6509. ShowAlignment(true);
  6510.  
  6511. #ifdef __PET_SYSTEM__
  6512. if(ITEM_NORMAL_PET == item->GetType())
  6513. {
  6514. quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
  6515. }
  6516. #endif
  6517.  
  6518. #ifdef __TITLE_SYSTEM__
  6519. if(ITEM_COSTUME == item->GetType() && ITEM_NORMAL_TITLE == item->GetSubType())
  6520. {
  6521. quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
  6522. }
  6523. #endif
  6524.  
  6525. item->RemoveFromCharacter();
  6526.  
  6527. if (item->IsDragonSoul())
  6528. #ifdef __HIGHLIGHT_SYSTEM__
  6529. item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, pos), false);
  6530. #else
  6531. item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, pos));
  6532. #endif
  6533.  
  6534. else
  6535. #ifdef __HIGHLIGHT_SYSTEM__
  6536. item->AddToCharacter(this, TItemPos(INVENTORY, pos), false);
  6537. #else
  6538. item->AddToCharacter(this, TItemPos(INVENTORY, pos));
  6539. #endif
  6540.  
  6541. CheckMaximumPoints();
  6542.  
  6543. return true;
  6544. }
  6545.  
  6546. bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell)
  6547. {
  6548. int iWearCell = item->FindEquipCell(this, iCandidateCell);
  6549.  
  6550. if (GetWear(WEAR_BODY) && GetWear(WEAR_BODY)->GetVnum() >= 11901 && GetWear(WEAR_BODY)->GetVnum() <= 11904 &&
  6551. item->GetType() == ITEM_COSTUME && item->GetSubType() == COSTUME_BODY)
  6552. {
  6553. ChatPacket(CHAT_TYPE_INFO, ("Nu poti face acest lucru!"));
  6554. return false;
  6555. }
  6556.  
  6557. if (GetWear(WEAR_COSTUME_BODY) && item->GetVnum() >= 11901 && item->GetVnum() <= 11904)
  6558. {
  6559. ChatPacket(CHAT_TYPE_INFO, ("Nu poti face acest lucru!"));
  6560. return false;
  6561. }
  6562.  
  6563. if (ITEM_BELT == item->GetType() && CBeltInventoryHelper::IsExistItemInBeltInventory(this))
  6564. {
  6565. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Empty your belt inventory !"));
  6566. return false;
  6567. }
  6568.  
  6569. #ifdef __EQUIP_RESTRICT_SYSTEM__
  6570. if (IsEquipRestricted())
  6571. return false;
  6572. #endif
  6573.  
  6574. if (item->IsExchanging())
  6575. return false;
  6576.  
  6577. #ifdef __INVENTORY_PROTECT_SYSTEM__
  6578. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  6579. {
  6580. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  6581. return false;
  6582. }
  6583. #endif
  6584.  
  6585. if (false == item->IsEquipable())
  6586. return false;
  6587.  
  6588. if (false == CanEquipNow(item))
  6589. return false;
  6590.  
  6591. if (iWearCell < 0)
  6592. return false;
  6593.  
  6594. if (iWearCell == WEAR_BODY && IsRiding() && (item->GetVnum() >= 11901 && item->GetVnum() <= 11904))
  6595. {
  6596. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  6597. return false;
  6598. }
  6599.  
  6600. if (iWearCell == WEAR_WEAPON && IsRiding() && (item->GetType() == ITEM_ROD || item->GetType() == ITEM_PICK))
  6601. {
  6602. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  6603. return false;
  6604. }
  6605.  
  6606. if (iWearCell != WEAR_ARROW && IsPolymorphed())
  6607. {
  6608. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  6609. return false;
  6610. }
  6611.  
  6612. if (FN_check_item_sex(this, item) == false)
  6613. {
  6614. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Acest obiect poate fi purtat doar de sex-ul opus .");
  6615. return false;
  6616. }
  6617.  
  6618. if(item->IsRideItem() && IsRiding())
  6619. {
  6620. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Poti descarca apasand CTRL + G .");
  6621. return false;
  6622. }
  6623.  
  6624. #ifdef ENABLE_SPAM_ECHIPAMENT
  6625. if (!IsGM())
  6626. {
  6627. if (thecore_pulse() > GetEquipAntiFloodPulse() + PASSES_PER_SEC(1))
  6628. {
  6629. SetEquipAntiFloodCount(0);
  6630. SetEquipAntiFloodPulse(thecore_pulse());
  6631. }
  6632.  
  6633. if (IncreaseEquipAntiFloodCount() >= 10)
  6634. {
  6635. GetDesc()->DelayedDisconnect(0);
  6636. sys_err("%s %s [anti equip spam]", __FUNCTION__, GetName());
  6637. return false;
  6638. }
  6639. }
  6640.  
  6641. if (item->GetType() == ITEM_ARMOR && item->GetSubType() == ARMOR_BODY && item->GetSubType() == ARMOR_SHIELD && item->GetSubType() == ARMOR_HEAD && item->GetSubType() == ARMOR_EAR && item->GetSubType() == ARMOR_NECK && item->GetSubType() == ARMOR_WRIST && item->GetSubType() == ARMOR_FOOTS && item->GetType() == ITEM_WEAPON && item->GetSubType() == WEAPON_SWORD && item->GetSubType() == WEAPON_DAGGER && item->GetSubType() == WEAPON_BOW && item->GetSubType() == WEAPON_TWO_HANDED && item->GetSubType() == WEAPON_FAN && item->GetSubType() == WEAPON_ARROW && item->GetSubType() == WEAPON_BELL && IsRiding())
  6642. {
  6643. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti schimba Armura & Arma cand calaresti .");
  6644. return false;
  6645. }
  6646.  
  6647. if (item->GetType() == ITEM_COSTUME && item->GetSubType() == COSTUME_BODY && item->GetSubType() == COSTUME_HAIR && item->GetSubType() == COSTUME_WEAPON && IsRiding())
  6648. {
  6649. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti schimba Costum & Freza & Mount & Skin cand calaresti .");
  6650. return false;
  6651. }
  6652. #endif
  6653.  
  6654. DWORD dwCurTime = get_dword_time();
  6655.  
  6656. if (iWearCell != WEAR_ARROW && (dwCurTime - GetLastAttackTime() <= 1500 || dwCurTime - m_dwLastSkillTime <= 1500))
  6657. {
  6658. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti face asta .");
  6659. return false;
  6660. }
  6661.  
  6662. if (item->IsDragonSoul())
  6663. {
  6664. if(GetInventoryItem(INVENTORY_MAX_NUM + iWearCell))
  6665. {
  6666. ChatPacket(CHAT_TYPE_INFO, "이미 같은 종류의 용혼석을 착용하고 있습니다.");
  6667. return false;
  6668. }
  6669.  
  6670. if (!item->EquipTo(this, iWearCell))
  6671. {
  6672. return false;
  6673. }
  6674. }
  6675.  
  6676. else
  6677. {
  6678.  
  6679. if (GetWear(iWearCell) && !IS_SET(GetWear(iWearCell)->GetFlag(), ITEM_FLAG_IRREMOVABLE))
  6680. {
  6681. if (item->GetWearFlag() == WEARABLE_ABILITY)
  6682. return false;
  6683.  
  6684. if (false == SwapItem(item->GetCell(), INVENTORY_MAX_NUM + iWearCell))
  6685. {
  6686. return false;
  6687. }
  6688. }
  6689.  
  6690. else
  6691. {
  6692. UINT bOldCell = item->GetCell();
  6693.  
  6694. if (item->EquipTo(this, iWearCell))
  6695. {
  6696. SyncQuickslot(QUICKSLOT_TYPE_ITEM, bOldCell, iWearCell);
  6697. }
  6698. }
  6699. }
  6700.  
  6701. if (true == item->IsEquipped())
  6702. {
  6703. if (-1 != item->GetProto()->cLimitRealTimeFirstUseIndex)
  6704. {
  6705.  
  6706. if (0 == item->GetSocket(1))
  6707. {
  6708. long duration = (0 != item->GetSocket(0)) ? item->GetSocket(0) : item->GetProto()->aLimits[item->GetProto()->cLimitRealTimeFirstUseIndex].lValue;
  6709.  
  6710. if (0 == duration)
  6711. duration = 60 * 60 * 24 * 7;
  6712.  
  6713. item->SetSocket(0, time(0) + duration);
  6714. item->StartRealTimeExpireEvent();
  6715. }
  6716.  
  6717. item->SetSocket(1, item->GetSocket(1) + 1);
  6718. }
  6719.  
  6720. if (item->GetVnum() == UNIQUE_ITEM_HIDE_ALIGNMENT_TITLE)
  6721. ShowAlignment(false);
  6722.  
  6723. const DWORD& dwVnum = item->GetVnum();
  6724.  
  6725.  
  6726. if (true == CItemVnumHelper::IsRamadanMoonRing(dwVnum))
  6727. {
  6728. this->EffectPacket(SE_EQUIP_RAMADAN_RING);
  6729. }
  6730.  
  6731. else if (true == CItemVnumHelper::IsHalloweenCandy(dwVnum))
  6732. {
  6733. this->EffectPacket(SE_EQUIP_HALLOWEEN_CANDY);
  6734. }
  6735.  
  6736. else if (true == CItemVnumHelper::IsHappinessRing(dwVnum))
  6737. {
  6738. this->EffectPacket(SE_EQUIP_HAPPINESS_RING);
  6739. }
  6740.  
  6741. else if (true == CItemVnumHelper::IsLovePendant(dwVnum))
  6742. {
  6743. this->EffectPacket(SE_EQUIP_LOVE_PENDANT);
  6744. }
  6745.  
  6746. else if (ITEM_UNIQUE == item->GetType() && 0 != item->GetSIGVnum())
  6747. {
  6748. const CSpecialItemGroup* pGroup = ITEM_MANAGER::instance().GetSpecialItemGroup(item->GetSIGVnum());
  6749. if (NULL != pGroup)
  6750. {
  6751. const CSpecialAttrGroup* pAttrGroup = ITEM_MANAGER::instance().GetSpecialAttrGroup(pGroup->GetAttrVnum(item->GetVnum()));
  6752. if (NULL != pAttrGroup)
  6753. {
  6754. const std::string& std = pAttrGroup->m_stEffectFileName;
  6755. SpecificEffectPacket(std.c_str());
  6756. }
  6757. }
  6758. }
  6759.  
  6760. #ifdef __PET_SYSTEM__
  6761. else if(ITEM_NORMAL_PET == item->GetType())
  6762. {
  6763. quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
  6764. }
  6765. #endif
  6766.  
  6767. #ifdef __TITLE_SYSTEM__
  6768. if(ITEM_COSTUME == item->GetType() && ITEM_NORMAL_TITLE == item->GetSubType())
  6769. {
  6770. quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
  6771. }
  6772. #endif
  6773. if (UNIQUE_SPECIAL_RIDE == item->GetSubType() && IS_SET(item->GetFlag(), ITEM_FLAG_QUEST_USE))
  6774. {
  6775. quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
  6776. }
  6777. }
  6778.  
  6779. return true;
  6780. }
  6781.  
  6782. void CHARACTER::BuffOnAttr_AddBuffsFromItem(LPITEM pItem)
  6783. {
  6784. for (int i = 0; i < sizeof(g_aBuffOnAttrPoints)/sizeof(g_aBuffOnAttrPoints[0]); i++)
  6785. {
  6786. TMapBuffOnAttrs::iterator it = m_map_buff_on_attrs.find(g_aBuffOnAttrPoints[i]);
  6787. if (it != m_map_buff_on_attrs.end())
  6788. {
  6789. it->second->AddBuffFromItem(pItem);
  6790. }
  6791. }
  6792. }
  6793.  
  6794. void CHARACTER::BuffOnAttr_RemoveBuffsFromItem(LPITEM pItem)
  6795. {
  6796. for (int i = 0; i < sizeof(g_aBuffOnAttrPoints)/sizeof(g_aBuffOnAttrPoints[0]); i++)
  6797. {
  6798. TMapBuffOnAttrs::iterator it = m_map_buff_on_attrs.find(g_aBuffOnAttrPoints[i]);
  6799. if (it != m_map_buff_on_attrs.end())
  6800. {
  6801. it->second->RemoveBuffFromItem(pItem);
  6802. }
  6803. }
  6804. }
  6805.  
  6806. void CHARACTER::BuffOnAttr_ClearAll()
  6807. {
  6808. for (TMapBuffOnAttrs::iterator it = m_map_buff_on_attrs.begin(); it != m_map_buff_on_attrs.end(); it++)
  6809. {
  6810. CBuffOnAttributes* pBuff = it->second;
  6811. if (pBuff)
  6812. {
  6813. pBuff->Initialize();
  6814. }
  6815. }
  6816. }
  6817.  
  6818. void CHARACTER::BuffOnAttr_ValueChange(BYTE bType, BYTE bOldValue, BYTE bNewValue)
  6819. {
  6820. TMapBuffOnAttrs::iterator it = m_map_buff_on_attrs.find(bType);
  6821.  
  6822. if (0 == bNewValue)
  6823. {
  6824. if (m_map_buff_on_attrs.end() == it)
  6825. return;
  6826. else
  6827. it->second->Off();
  6828. }
  6829.  
  6830. else if(0 == bOldValue)
  6831. {
  6832. CBuffOnAttributes* pBuff;
  6833. if (m_map_buff_on_attrs.end() == it)
  6834. {
  6835. switch (bType)
  6836. {
  6837. case POINT_ENERGY:
  6838. {
  6839. static BYTE abSlot[] = { WEAR_BODY, WEAR_HEAD, WEAR_FOOTS, WEAR_WRIST, WEAR_WEAPON, WEAR_NECK, WEAR_EAR, WEAR_SHIELD };
  6840. static std::vector <BYTE> vec_slots (abSlot, abSlot + _countof(abSlot));
  6841.  
  6842. pBuff = M2_NEW CBuffOnAttributes(this, bType, &vec_slots);
  6843. }
  6844. break;
  6845.  
  6846. case POINT_COSTUME_ATTR_BONUS:
  6847. {
  6848. static BYTE abSlot[] = { WEAR_COSTUME_BODY, WEAR_COSTUME_HAIR,WEAR_COSTUME_WEAPON};
  6849. static std::vector <BYTE> vec_slots (abSlot, abSlot + _countof(abSlot));
  6850.  
  6851. pBuff = M2_NEW CBuffOnAttributes(this, bType, &vec_slots);
  6852. }
  6853. break;
  6854.  
  6855. default:
  6856. break;
  6857. }
  6858. m_map_buff_on_attrs.insert(TMapBuffOnAttrs::value_type(bType, pBuff));
  6859.  
  6860. }
  6861.  
  6862. else
  6863. pBuff = it->second;
  6864.  
  6865. pBuff->On(bNewValue);
  6866. }
  6867.  
  6868. else
  6869. {
  6870. if (m_map_buff_on_attrs.end() == it)
  6871. return;
  6872. else
  6873. it->second->ChangeBuffValue(bNewValue);
  6874. }
  6875. }
  6876.  
  6877.  
  6878. LPITEM CHARACTER::FindSpecifyItem(DWORD vnum) const
  6879. {
  6880. for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
  6881. if (GetInventoryItem(i) && GetInventoryItem(i)->GetVnum() == vnum)
  6882. return GetInventoryItem(i);
  6883.  
  6884. return NULL;
  6885. }
  6886.  
  6887. LPITEM CHARACTER::FindItemByID(DWORD id) const
  6888. {
  6889. for (int i=0 ; i < INVENTORY_MAX_NUM ; ++i)
  6890. {
  6891. if (NULL != GetInventoryItem(i) && GetInventoryItem(i)->GetID() == id)
  6892. return GetInventoryItem(i);
  6893. }
  6894.  
  6895. for (int i=BELT_INVENTORY_SLOT_START; i < BELT_INVENTORY_SLOT_END ; ++i)
  6896. {
  6897. if (NULL != GetInventoryItem(i) && GetInventoryItem(i)->GetID() == id)
  6898. return GetInventoryItem(i);
  6899. }
  6900.  
  6901. return NULL;
  6902. }
  6903.  
  6904. int CHARACTER::CountSpecifyItem(DWORD vnum) const
  6905. {
  6906. int count = 0;
  6907. LPITEM item;
  6908.  
  6909. for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
  6910. {
  6911. item = GetInventoryItem(i);
  6912. if (NULL != item && item->GetVnum() == vnum)
  6913. {
  6914. if (m_pkMyShop && m_pkMyShop->IsSellingItem(item->GetID()))
  6915. {
  6916. continue;
  6917. }
  6918.  
  6919. else
  6920. {
  6921. count += item->GetCount();
  6922. }
  6923. }
  6924. }
  6925.  
  6926. return count;
  6927. }
  6928.  
  6929. void CHARACTER::RemoveSpecifyItem(DWORD vnum, DWORD count)
  6930. {
  6931. if (0 == count)
  6932. return;
  6933.  
  6934. for (UINT i = 0; i < INVENTORY_MAX_NUM; ++i)
  6935. {
  6936. if (NULL == GetInventoryItem(i))
  6937. continue;
  6938.  
  6939. if (GetInventoryItem(i)->GetVnum() != vnum)
  6940. continue;
  6941.  
  6942. if(m_pkMyShop)
  6943. {
  6944. bool isItemSelling = m_pkMyShop->IsSellingItem(GetInventoryItem(i)->GetID());
  6945. if (isItemSelling)
  6946. continue;
  6947. }
  6948.  
  6949. if (vnum >= 80003 && vnum <= 80007)
  6950. LogManager::instance().GoldBarLog(GetPlayerID(), GetInventoryItem(i)->GetID(), QUEST, "RemoveSpecifyItem");
  6951.  
  6952. if (count >= GetInventoryItem(i)->GetCount())
  6953. {
  6954. count -= GetInventoryItem(i)->GetCount();
  6955. GetInventoryItem(i)->SetCount(0);
  6956.  
  6957. if (0 == count)
  6958. return;
  6959. }
  6960.  
  6961. else
  6962. {
  6963. GetInventoryItem(i)->SetCount(GetInventoryItem(i)->GetCount() - count);
  6964. return;
  6965. }
  6966. }
  6967.  
  6968. if (count)
  6969. sys_log(0, "CHARACTER::RemoveSpecifyItem cannot remove enough item vnum %u, still remain %d", vnum, count);
  6970. }
  6971.  
  6972. int CHARACTER::CountSpecifyTypeItem(BYTE type) const
  6973. {
  6974. int count = 0;
  6975.  
  6976. for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
  6977. {
  6978. LPITEM pItem = GetInventoryItem(i);
  6979.  
  6980. if (pItem != NULL && pItem->GetType() == type)
  6981. {
  6982. count += pItem->GetCount();
  6983. }
  6984. }
  6985.  
  6986. return count;
  6987. }
  6988.  
  6989. void CHARACTER::RemoveSpecifyTypeItem(BYTE type, DWORD count)
  6990. {
  6991. if (0 == count)
  6992. return;
  6993.  
  6994. for (UINT i = 0; i < INVENTORY_MAX_NUM; ++i)
  6995. {
  6996. if (NULL == GetInventoryItem(i))
  6997. continue;
  6998.  
  6999. if (GetInventoryItem(i)->GetType() != type)
  7000. continue;
  7001.  
  7002. if(m_pkMyShop)
  7003. {
  7004. bool isItemSelling = m_pkMyShop->IsSellingItem(GetInventoryItem(i)->GetID());
  7005. if (isItemSelling)
  7006. continue;
  7007. }
  7008.  
  7009. if (count >= GetInventoryItem(i)->GetCount())
  7010. {
  7011. count -= GetInventoryItem(i)->GetCount();
  7012. GetInventoryItem(i)->SetCount(0);
  7013.  
  7014. if (0 == count)
  7015. return;
  7016. }
  7017.  
  7018. else
  7019. {
  7020. GetInventoryItem(i)->SetCount(GetInventoryItem(i)->GetCount() - count);
  7021. return;
  7022. }
  7023. }
  7024. }
  7025.  
  7026. void CHARACTER::AutoGiveItem(LPITEM item, bool longOwnerShip)
  7027. {
  7028. if (NULL == item)
  7029. {
  7030. sys_err ("NULL point.");
  7031. return;
  7032. }
  7033.  
  7034. if (item->GetOwner())
  7035. {
  7036. sys_err ("item %d 's owner exists!",item->GetID());
  7037. return;
  7038. }
  7039.  
  7040. int cell;
  7041. if (item->IsDragonSoul())
  7042. {
  7043. cell = GetEmptyDragonSoulInventory(item);
  7044. }
  7045.  
  7046. else
  7047. {
  7048. cell = GetEmptyInventory (item->GetSize());
  7049. }
  7050.  
  7051. if (cell != -1)
  7052. {
  7053. if (item->IsDragonSoul())
  7054. item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, cell));
  7055. else
  7056. item->AddToCharacter(this, TItemPos(INVENTORY, cell));
  7057.  
  7058. LogManager::instance().ItemLog(this, item, "SYSTEM", item->GetName());
  7059.  
  7060. if (item->GetType() == ITEM_USE && item->GetSubType() == USE_POTION)
  7061. {
  7062. TQuickslot * pSlot;
  7063.  
  7064. if (GetQuickslot(0, &pSlot) && pSlot->type == QUICKSLOT_TYPE_NONE)
  7065. {
  7066. TQuickslot slot;
  7067. slot.type = QUICKSLOT_TYPE_ITEM;
  7068. slot.pos = cell;
  7069. SetQuickslot(0, slot);
  7070. }
  7071. }
  7072. }
  7073.  
  7074. else
  7075. {
  7076. item->AddToGround (GetMapIndex(), GetXYZ());
  7077. item->StartDestroyEvent();
  7078.  
  7079. if (longOwnerShip)
  7080. item->SetOwnership (this, 300);
  7081. else
  7082. item->SetOwnership (this, 60);
  7083.  
  7084. LogManager::instance().ItemLog(this, item, "SYSTEM_DROP", item->GetName());
  7085. }
  7086. }
  7087.  
  7088. LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, WORD bCount, int iRarePct, bool bMsg)
  7089. {
  7090. TItemTable * p = ITEM_MANAGER::instance().GetTable(dwItemVnum);
  7091.  
  7092. if (!p)
  7093. return NULL;
  7094.  
  7095. DBManager::instance().SendMoneyLog(MONEY_LOG_DROP, dwItemVnum, bCount);
  7096.  
  7097. if (p->dwFlags & ITEM_FLAG_STACKABLE && p->bType != ITEM_BLEND)
  7098. {
  7099. for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
  7100. {
  7101. LPITEM item = GetInventoryItem(i);
  7102.  
  7103. if (!item)
  7104. continue;
  7105.  
  7106. if (item->GetVnum() == dwItemVnum && FN_check_item_socket(item))
  7107. {
  7108. if (IS_SET(p->dwFlags, ITEM_FLAG_MAKECOUNT))
  7109. {
  7110. if (bCount < p->alValues[1])
  7111. bCount = p->alValues[1];
  7112. }
  7113.  
  7114. WORD bCount2 = MIN(ITEM_MAX_COUNT - item->GetCount(), bCount);
  7115. bCount -= bCount2;
  7116.  
  7117. item->SetCount(item->GetCount() + bCount2);
  7118.  
  7119. if (bCount == 0)
  7120. {
  7121. if (bMsg)
  7122. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), item->GetName());
  7123.  
  7124. return item;
  7125. }
  7126. }
  7127. }
  7128. }
  7129.  
  7130. LPITEM item = ITEM_MANAGER::instance().CreateItem(dwItemVnum, bCount, 0, true);
  7131.  
  7132. if (!item)
  7133. {
  7134. sys_err("cannot create item by vnum %u (name: %s)", dwItemVnum, GetName());
  7135. return NULL;
  7136. }
  7137.  
  7138. if (item->GetType() == ITEM_BLEND)
  7139. {
  7140. for (int i=0; i < INVENTORY_MAX_NUM; i++)
  7141. {
  7142. LPITEM inv_item = GetInventoryItem(i);
  7143.  
  7144. if (inv_item == NULL) continue;
  7145.  
  7146. if (inv_item->GetType() == ITEM_BLEND)
  7147. {
  7148. if (inv_item->GetVnum() == item->GetVnum())
  7149. {
  7150. if (inv_item->GetSocket(0) == item->GetSocket(0) &&
  7151. inv_item->GetSocket(1) == item->GetSocket(1) &&
  7152. inv_item->GetSocket(2) == item->GetSocket(2) &&
  7153. inv_item->GetCount() < ITEM_MAX_COUNT)
  7154. {
  7155. inv_item->SetCount(inv_item->GetCount() + item->GetCount());
  7156. return inv_item;
  7157. }
  7158. }
  7159. }
  7160. }
  7161. }
  7162.  
  7163. int iEmptyCell;
  7164. if (item->IsDragonSoul())
  7165. {
  7166. iEmptyCell = GetEmptyDragonSoulInventory(item);
  7167. }
  7168.  
  7169. else
  7170. iEmptyCell = GetEmptyInventory(item->GetSize());
  7171.  
  7172. if (iEmptyCell != -1)
  7173. {
  7174. if (bMsg)
  7175. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), item->GetName());
  7176.  
  7177. if (item->IsDragonSoul())
  7178. item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
  7179. else
  7180. item->AddToCharacter(this, TItemPos(INVENTORY, iEmptyCell));
  7181.  
  7182. LogManager::instance().ItemLog(this, item, "SYSTEM", item->GetName());
  7183.  
  7184. if (item->GetType() == ITEM_USE && item->GetSubType() == USE_POTION)
  7185. {
  7186. TQuickslot * pSlot;
  7187.  
  7188. if (GetQuickslot(0, &pSlot) && pSlot->type == QUICKSLOT_TYPE_NONE)
  7189. {
  7190. TQuickslot slot;
  7191. slot.type = QUICKSLOT_TYPE_ITEM;
  7192. slot.pos = iEmptyCell;
  7193. SetQuickslot(0, slot);
  7194. }
  7195. }
  7196. }
  7197.  
  7198. else
  7199. {
  7200. item->AddToGround(GetMapIndex(), GetXYZ());
  7201. item->StartDestroyEvent();
  7202.  
  7203. if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_DROP))
  7204. item->SetOwnership(this, 300);
  7205. else
  7206. item->SetOwnership(this, 60);
  7207.  
  7208. LogManager::instance().ItemLog(this, item, "SYSTEM_DROP", item->GetName());
  7209. }
  7210.  
  7211. sys_log(0, "7: %d %d", dwItemVnum, bCount);
  7212.  
  7213. return item;
  7214. }
  7215.  
  7216. bool CHARACTER::GiveItem(LPCHARACTER victim, TItemPos Cell)
  7217. {
  7218. if (!CanHandleItem())
  7219. return false;
  7220.  
  7221. #ifdef __INVENTORY_PROTECT_SYSTEM__
  7222. if (GetQuestFlag("abs.INVENTORY_LOCK") == 1)
  7223. {
  7224. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Inventarul este blocat .");
  7225. return false;
  7226. }
  7227. #endif
  7228.  
  7229. if (quest::CQuestManager::instance().GetPCForce(GetPlayerID())->IsRunning() == true)
  7230. {
  7231. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot take this item if you're using quests"));
  7232. return false;
  7233. }
  7234.  
  7235. LPITEM item = GetItem(Cell);
  7236.  
  7237. if (item && !item->IsExchanging())
  7238. {
  7239. if (victim->CanReceiveItem(this, item))
  7240. {
  7241. victim->ReceiveItem(this, item);
  7242. return true;
  7243. }
  7244. }
  7245.  
  7246. return false;
  7247. }
  7248.  
  7249. bool CHARACTER::CanReceiveItem(LPCHARACTER from, LPITEM item) const
  7250. {
  7251. if (IsPC())
  7252. return false;
  7253.  
  7254. if (DISTANCE_APPROX(GetX() - from->GetX(), GetY() - from->GetY()) > 2000)
  7255. return false;
  7256.  
  7257. switch (GetRaceNum())
  7258. {
  7259. case fishing::CAMPFIRE_MOB:
  7260. if (item->GetType() == ITEM_FISH &&
  7261. (item->GetSubType() == FISH_ALIVE || item->GetSubType() == FISH_DEAD))
  7262. return true;
  7263. break;
  7264.  
  7265. case fishing::FISHER_MOB:
  7266. if (item->GetType() == ITEM_ROD)
  7267. return true;
  7268. break;
  7269.  
  7270. case BLACKSMITH_WEAPON_MOB:
  7271. case DEVILTOWER_BLACKSMITH_WEAPON_MOB:
  7272. if (item->GetType() == ITEM_WEAPON &&
  7273. item->GetRefinedVnum())
  7274. return true;
  7275. else
  7276. return false;
  7277. break;
  7278.  
  7279. case BLACKSMITH_ARMOR_MOB:
  7280. case DEVILTOWER_BLACKSMITH_ARMOR_MOB:
  7281. if (item->GetType() == ITEM_ARMOR &&
  7282. (item->GetSubType() == ARMOR_BODY || item->GetSubType() == ARMOR_SHIELD || item->GetSubType() == ARMOR_HEAD) &&
  7283. item->GetRefinedVnum())
  7284. return true;
  7285. else
  7286. return false;
  7287. break;
  7288.  
  7289. case BLACKSMITH_ACCESSORY_MOB:
  7290. case DEVILTOWER_BLACKSMITH_ACCESSORY_MOB:
  7291. if (item->GetType() == ITEM_ARMOR &&
  7292. !(item->GetSubType() == ARMOR_BODY || item->GetSubType() == ARMOR_SHIELD || item->GetSubType() == ARMOR_HEAD) &&
  7293. item->GetRefinedVnum())
  7294. return true;
  7295. else
  7296. return false;
  7297. break;
  7298.  
  7299. case BLACKSMITH_MOB:
  7300. if (item->GetRefinedVnum() && item->GetRefineSet() < 500)
  7301. {
  7302. return true;
  7303. }
  7304.  
  7305. else
  7306. {
  7307. return false;
  7308. }
  7309.  
  7310. case BLACKSMITH2_MOB:
  7311. if (item->GetRefineSet() >= 500)
  7312. {
  7313. return true;
  7314. }
  7315.  
  7316. else
  7317. {
  7318. return false;
  7319. }
  7320.  
  7321. case ALCHEMIST_MOB:
  7322. if (item->GetRefinedVnum())
  7323. return true;
  7324. break;
  7325.  
  7326. case 20101:
  7327. case 20102:
  7328. case 20103:
  7329. if (item->GetVnum() == ITEM_REVIVE_HORSE_1)
  7330. {
  7331. if (!IsDead())
  7332. {
  7333. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("죽지 않은 말에게 선초를 먹일 수 없습니다."));
  7334. return false;
  7335. }
  7336. return true;
  7337. }
  7338.  
  7339. else if (item->GetVnum() == ITEM_HORSE_FOOD_1)
  7340. {
  7341. if (IsDead())
  7342. {
  7343. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("죽은 말에게 사료를 먹일 수 없습니다."));
  7344. return false;
  7345. }
  7346. return true;
  7347. }
  7348.  
  7349. else if (item->GetVnum() == ITEM_HORSE_FOOD_2 || item->GetVnum() == ITEM_HORSE_FOOD_3)
  7350. {
  7351. return false;
  7352. }
  7353. break;
  7354.  
  7355. case 20104:
  7356. case 20105:
  7357. case 20106:
  7358. if (item->GetVnum() == ITEM_REVIVE_HORSE_2)
  7359. {
  7360. if (!IsDead())
  7361. {
  7362. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("죽지 않은 말에게 선초를 먹일 수 없습니다."));
  7363. return false;
  7364. }
  7365.  
  7366. return true;
  7367. }
  7368.  
  7369. else if (item->GetVnum() == ITEM_HORSE_FOOD_2)
  7370. {
  7371. if (IsDead())
  7372. {
  7373. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("죽은 말에게 사료를 먹일 수 없습니다."));
  7374. return false;
  7375. }
  7376.  
  7377. return true;
  7378. }
  7379.  
  7380. else if (item->GetVnum() == ITEM_HORSE_FOOD_1 || item->GetVnum() == ITEM_HORSE_FOOD_3)
  7381. {
  7382. return false;
  7383. }
  7384. break;
  7385.  
  7386. case 20107:
  7387. case 20108:
  7388. case 20109:
  7389. if (item->GetVnum() == ITEM_REVIVE_HORSE_3)
  7390. {
  7391. if (!IsDead())
  7392. {
  7393. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("죽지 않은 말에게 선초를 먹일 수 없습니다."));
  7394. return false;
  7395. }
  7396.  
  7397. return true;
  7398. }
  7399.  
  7400. else if (item->GetVnum() == ITEM_HORSE_FOOD_3)
  7401. {
  7402. if (IsDead())
  7403. {
  7404. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("죽은 말에게 사료를 먹일 수 없습니다."));
  7405. return false;
  7406. }
  7407.  
  7408. return true;
  7409. }
  7410.  
  7411. else if (item->GetVnum() == ITEM_HORSE_FOOD_1 || item->GetVnum() == ITEM_HORSE_FOOD_2)
  7412. {
  7413. return false;
  7414. }
  7415. break;
  7416. }
  7417.  
  7418. //if (IS_SET(item->GetFlag(), ITEM_FLAG_QUEST_GIVE))
  7419. {
  7420. return true;
  7421. }
  7422.  
  7423. return false;
  7424. }
  7425.  
  7426. void CHARACTER::ReceiveItem(LPCHARACTER from, LPITEM item)
  7427. {
  7428. if (IsPC())
  7429. return;
  7430.  
  7431. switch (GetRaceNum())
  7432. {
  7433. case fishing::CAMPFIRE_MOB:
  7434. if (item->GetType() == ITEM_FISH && (item->GetSubType() == FISH_ALIVE || item->GetSubType() == FISH_DEAD))
  7435. fishing::Grill(from, item);
  7436. else
  7437. {
  7438. from->SetQuestNPCID(GetVID());
  7439. quest::CQuestManager::instance().TakeItem(from->GetPlayerID(), GetRaceNum(), item);
  7440. }
  7441. break;
  7442.  
  7443. case DEVILTOWER_BLACKSMITH_WEAPON_MOB:
  7444. case DEVILTOWER_BLACKSMITH_ARMOR_MOB:
  7445. case DEVILTOWER_BLACKSMITH_ACCESSORY_MOB:
  7446. if (item->GetRefinedVnum() != 0 && item->GetRefineSet() != 0 && item->GetRefineSet() < 500)
  7447. {
  7448. from->SetRefineNPC(this);
  7449. from->RefineInformation(item->GetCell(), REFINE_TYPE_MONEY_ONLY);
  7450. }
  7451.  
  7452. else
  7453. {
  7454. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템은 개량할 수 없습니다."));
  7455. }
  7456. break;
  7457.  
  7458. case BLACKSMITH_MOB:
  7459. case BLACKSMITH2_MOB:
  7460. case BLACKSMITH_WEAPON_MOB:
  7461. case BLACKSMITH_ARMOR_MOB:
  7462. case BLACKSMITH_ACCESSORY_MOB:
  7463. if (item->GetRefinedVnum())
  7464. {
  7465. from->SetRefineNPC(this);
  7466. from->RefineInformation(item->GetCell(), REFINE_TYPE_NORMAL);
  7467. }
  7468.  
  7469. else
  7470. {
  7471. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템은 개량할 수 없습니다."));
  7472. }
  7473. break;
  7474.  
  7475. case 20101:
  7476. case 20102:
  7477. case 20103:
  7478. case 20104:
  7479. case 20105:
  7480. case 20106:
  7481. case 20107:
  7482. case 20108:
  7483. case 20109:
  7484. if (item->GetVnum() == ITEM_REVIVE_HORSE_1 || item->GetVnum() == ITEM_REVIVE_HORSE_2 || item->GetVnum() == ITEM_REVIVE_HORSE_3)
  7485. {
  7486. from->ReviveHorse();
  7487. item->SetCount(item->GetCount()-1);
  7488.  
  7489. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말에게 선초를 주었습니다."));
  7490. }
  7491.  
  7492. else if (item->GetVnum() == ITEM_HORSE_FOOD_1 || item->GetVnum() == ITEM_HORSE_FOOD_2 || item->GetVnum() == ITEM_HORSE_FOOD_3)
  7493. {
  7494. from->FeedHorse();
  7495. from->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말에게 사료를 주었습니다."));
  7496.  
  7497. item->SetCount(item->GetCount()-1);
  7498.  
  7499. EffectPacket(SE_HPUP_RED);
  7500. }
  7501. break;
  7502.  
  7503. default:
  7504. sys_log(0, "TakeItem %s %d %s", from->GetName(), GetRaceNum(), item->GetName());
  7505. from->SetQuestNPCID(GetVID());
  7506. quest::CQuestManager::instance().TakeItem(from->GetPlayerID(), GetRaceNum(), item);
  7507. break;
  7508. }
  7509. }
  7510.  
  7511. bool CHARACTER::IsEquipUniqueItem(DWORD dwItemVnum) const
  7512. {
  7513. {
  7514. LPITEM u = GetWear(WEAR_UNIQUE1);
  7515.  
  7516. if (u && u->GetVnum() == dwItemVnum)
  7517. return true;
  7518. }
  7519.  
  7520. {
  7521. LPITEM u = GetWear(WEAR_UNIQUE2);
  7522.  
  7523. if (u && u->GetVnum() == dwItemVnum)
  7524. return true;
  7525. }
  7526.  
  7527. if (dwItemVnum == UNIQUE_ITEM_RING_OF_LANGUAGE)
  7528. return IsEquipUniqueItem(UNIQUE_ITEM_RING_OF_LANGUAGE_SAMPLE);
  7529.  
  7530. return false;
  7531. }
  7532.  
  7533. bool CHARACTER::IsEquipUniqueGroup(DWORD dwGroupVnum) const
  7534. {
  7535. {
  7536. LPITEM u = GetWear(WEAR_UNIQUE1);
  7537.  
  7538. if (u && u->GetSpecialGroup() == (int) dwGroupVnum)
  7539. return true;
  7540. }
  7541.  
  7542. {
  7543. LPITEM u = GetWear(WEAR_UNIQUE2);
  7544.  
  7545. if (u && u->GetSpecialGroup() == (int) dwGroupVnum)
  7546. return true;
  7547. }
  7548.  
  7549. return false;
  7550. }
  7551.  
  7552. void CHARACTER::SetRefineMode(int iAdditionalCell)
  7553. {
  7554. m_iRefineAdditionalCell = iAdditionalCell;
  7555. m_bUnderRefine = true;
  7556. }
  7557.  
  7558. void CHARACTER::ClearRefineMode()
  7559. {
  7560. m_bUnderRefine = false;
  7561. SetRefineNPC( NULL );
  7562. }
  7563.  
  7564. bool CHARACTER::GiveItemFromSpecialItemGroup(DWORD dwGroupNum, std::vector<DWORD> &dwItemVnums, std::vector<DWORD> &dwItemCounts, std::vector <LPITEM> &item_gets, int &count)
  7565. {
  7566. const CSpecialItemGroup* pGroup = ITEM_MANAGER::instance().GetSpecialItemGroup(dwGroupNum);
  7567.  
  7568. if (!pGroup)
  7569. {
  7570. sys_err("cannot find special item group %d", dwGroupNum);
  7571. return false;
  7572. }
  7573.  
  7574. std::vector <int> idxes;
  7575.  
  7576. int n = pGroup->GetMultiIndex(idxes);
  7577.  
  7578. bool bSuccess;
  7579.  
  7580. for (int i = 0; i < n; i++)
  7581. {
  7582. bSuccess = false;
  7583.  
  7584. int idx = idxes[i];
  7585.  
  7586. DWORD dwVnum = pGroup->GetVnum(idx);
  7587. DWORD dwCount = pGroup->GetCount(idx);
  7588.  
  7589. int iRarePct = pGroup->GetRarePct(idx);
  7590.  
  7591. LPITEM item_get = NULL;
  7592.  
  7593. switch (dwVnum)
  7594. {
  7595. case CSpecialItemGroup::GOLD:
  7596. PointChange(POINT_GOLD, dwCount);
  7597. LogManager::instance().CharLog(this, dwCount, "TREASURE_GOLD", "");
  7598.  
  7599. bSuccess = true;
  7600. break;
  7601.  
  7602. case CSpecialItemGroup::EXP:
  7603. {
  7604. PointChange(POINT_EXP, dwCount);
  7605. LogManager::instance().CharLog(this, dwCount, "TREASURE_EXP", "");
  7606.  
  7607. bSuccess = true;
  7608. }
  7609. break;
  7610.  
  7611. case CSpecialItemGroup::MOB:
  7612. {
  7613. sys_log(0, "CSpecialItemGroup::MOB %d", dwCount);
  7614. int x = GetX() + number(-500, 500);
  7615. int y = GetY() + number(-500, 500);
  7616.  
  7617. LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob(dwCount, GetMapIndex(), x, y, 0, true, -1);
  7618. if (ch)
  7619. ch->SetAggressive();
  7620.  
  7621. bSuccess = true;
  7622. }
  7623. break;
  7624.  
  7625. case CSpecialItemGroup::SLOW:
  7626. {
  7627. sys_log(0, "CSpecialItemGroup::SLOW %d", -(int)dwCount);
  7628. AddAffect(AFFECT_SLOW, POINT_MOV_SPEED, -(int)dwCount, AFF_SLOW, 300, 0, true);
  7629. bSuccess = true;
  7630. }
  7631. break;
  7632.  
  7633. case CSpecialItemGroup::DRAIN_HP:
  7634. {
  7635. int iDropHP = GetMaxHP()*dwCount/100;
  7636.  
  7637. sys_log(0, "CSpecialItemGroup::DRAIN_HP %d", -iDropHP);
  7638.  
  7639. iDropHP = MIN(iDropHP, GetHP()-1);
  7640.  
  7641. sys_log(0, "CSpecialItemGroup::DRAIN_HP %d", -iDropHP);
  7642.  
  7643. PointChange(POINT_HP, -iDropHP);
  7644.  
  7645. bSuccess = true;
  7646. }
  7647. break;
  7648.  
  7649. case CSpecialItemGroup::POISON:
  7650. {
  7651. AttackedByPoison(NULL);
  7652. bSuccess = true;
  7653. }
  7654. break;
  7655.  
  7656. case CSpecialItemGroup::MOB_GROUP:
  7657. {
  7658. int sx = GetX() - number(300, 500);
  7659. int sy = GetY() - number(300, 500);
  7660. int ex = GetX() + number(300, 500);
  7661. int ey = GetY() + number(300, 500);
  7662.  
  7663. CHARACTER_MANAGER::instance().SpawnGroup(dwCount, GetMapIndex(), sx, sy, ex, ey, NULL, true);
  7664.  
  7665. bSuccess = true;
  7666. }
  7667. break;
  7668.  
  7669. default:
  7670. {
  7671. item_get = AutoGiveItem(dwVnum, dwCount, iRarePct);
  7672.  
  7673. if (item_get)
  7674. {
  7675. bSuccess = true;
  7676. }
  7677. }
  7678. break;
  7679. }
  7680.  
  7681. if (bSuccess)
  7682. {
  7683. dwItemVnums.push_back(dwVnum);
  7684. dwItemCounts.push_back(dwCount);
  7685.  
  7686. item_gets.push_back(item_get);
  7687.  
  7688. count++;
  7689.  
  7690. }
  7691.  
  7692. else
  7693. {
  7694. return false;
  7695. }
  7696. }
  7697.  
  7698. return bSuccess;
  7699. }
  7700.  
  7701. bool CHARACTER::ItemProcess_Hair(LPITEM item, int iDestCell)
  7702. {
  7703. if (item->CheckItemUseLevel(GetLevel()) == false)
  7704. {
  7705. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아직 이 머리를 사용할 수 없는 레벨입니다."));
  7706. return false;
  7707. }
  7708.  
  7709. DWORD hair = item->GetVnum();
  7710.  
  7711. switch (GetJob())
  7712. {
  7713. case JOB_WARRIOR :
  7714. hair -= 72000;
  7715. break;
  7716.  
  7717. case JOB_ASSASSIN :
  7718. hair -= 71250;
  7719. break;
  7720.  
  7721. case JOB_SURA :
  7722. hair -= 70500;
  7723. break;
  7724.  
  7725. case JOB_SHAMAN :
  7726. hair -= 69750;
  7727. break;
  7728.  
  7729. default :
  7730. return false;
  7731. break;
  7732. }
  7733.  
  7734. if (hair == GetPart(PART_HAIR))
  7735. {
  7736. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("동일한 머리 스타일로는 교체할 수 없습니다."));
  7737. return true;
  7738. }
  7739.  
  7740. item->SetCount(item->GetCount() - 0);
  7741.  
  7742. SetPart(PART_HAIR, hair);
  7743. UpdatePacket();
  7744.  
  7745. return true;
  7746. }
  7747.  
  7748. bool CHARACTER::ItemProcess_Polymorph(LPITEM item)
  7749. {
  7750. if (IsPolymorphed())
  7751. {
  7752. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이미 둔갑중인 상태입니다."));
  7753. return false;
  7754. }
  7755.  
  7756. if (true == IsRiding())
  7757. {
  7758. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑할 수 없는 상태입니다."));
  7759. return false;
  7760. }
  7761.  
  7762. DWORD dwVnum = item->GetSocket(0);
  7763.  
  7764. if (dwVnum == 0)
  7765. {
  7766. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("잘못된 둔갑 아이템입니다."));
  7767. item->SetCount(item->GetCount()-1);
  7768. return false;
  7769. }
  7770.  
  7771. const CMob* pMob = CMobManager::instance().Get(dwVnum);
  7772.  
  7773. if (pMob == NULL)
  7774. {
  7775. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("잘못된 둔갑 아이템입니다."));
  7776. item->SetCount(item->GetCount()-1);
  7777. return false;
  7778. }
  7779.  
  7780. switch (item->GetVnum())
  7781. {
  7782. case 70104 :
  7783. case 70105 :
  7784. case 70106 :
  7785. case 70107 :
  7786. case 71093 :
  7787. {
  7788. sys_log(0, "USE_POLYMORPH_BALL PID(%d) vnum(%d)", GetPlayerID(), dwVnum);
  7789.  
  7790. int iPolymorphLevelLimit = MAX(0, 20 - GetLevel() * 3 / 10);
  7791. if (pMob->m_table.bLevel >= GetLevel() + iPolymorphLevelLimit)
  7792. {
  7793. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("나보다 너무 높은 레벨의 몬스터로는 변신 할 수 없습니다."));
  7794. return false;
  7795. }
  7796.  
  7797. int iDuration = GetSkillLevel(POLYMORPH_SKILL_ID) == 0 ? 5 : (5 + (5 + GetSkillLevel(POLYMORPH_SKILL_ID)/40 * 25));
  7798. iDuration *= 60;
  7799.  
  7800. DWORD dwBonus = 0;
  7801. dwBonus = (2 + GetSkillLevel(POLYMORPH_SKILL_ID)/40) * 100;
  7802.  
  7803. AddAffect(AFFECT_POLYMORPH, POINT_POLYMORPH, dwVnum, AFF_POLYMORPH, iDuration, 0, true);
  7804. AddAffect(AFFECT_POLYMORPH, POINT_ATT_BONUS, dwBonus, AFF_POLYMORPH, iDuration, 0, false);
  7805.  
  7806. item->SetCount(item->GetCount()-1);
  7807. }
  7808. break;
  7809.  
  7810. case 50322:
  7811. {
  7812. sys_log(0, "USE_POLYMORPH_BOOK: %s(%u) vnum(%u)", GetName(), GetPlayerID(), dwVnum);
  7813.  
  7814. if (CPolymorphUtils::instance().PolymorphCharacter(this, item, pMob) == true)
  7815. {
  7816. CPolymorphUtils::instance().UpdateBookPracticeGrade(this, item);
  7817. }
  7818.  
  7819. else
  7820. {
  7821. }
  7822. }
  7823. break;
  7824.  
  7825. default :
  7826. sys_err("POLYMORPH invalid item passed PID(%d) vnum(%d)", GetPlayerID(), item->GetOriginalVnum());
  7827. return false;
  7828. }
  7829.  
  7830. return true;
  7831. }
  7832.  
  7833. bool CHARACTER::CanDoCube() const
  7834. {
  7835. if (m_bIsObserver) return false;
  7836. if (GetShop()) return false;
  7837. if (GetMyShop()) return false;
  7838. if (m_bUnderRefine) return false;
  7839. if (IsWarping()) return false;
  7840.  
  7841. return true;
  7842. }
  7843.  
  7844. bool CHARACTER::UnEquipSpecialRideUniqueItem()
  7845. {
  7846. LPITEM Unique1 = GetWear(WEAR_UNIQUE1);
  7847. LPITEM Unique2 = GetWear(WEAR_UNIQUE2);
  7848.  
  7849. if( NULL != Unique1 )
  7850. {
  7851. if( UNIQUE_GROUP_SPECIAL_RIDE == Unique1->GetSpecialGroup() )
  7852. {
  7853. return UnequipItem(Unique1);
  7854. }
  7855. }
  7856.  
  7857. if( NULL != Unique2 )
  7858. {
  7859. if( UNIQUE_GROUP_SPECIAL_RIDE == Unique2->GetSpecialGroup() )
  7860. {
  7861. return UnequipItem(Unique2);
  7862. }
  7863. }
  7864.  
  7865. return true;
  7866. }
  7867.  
  7868. void CHARACTER::AutoRecoveryItemProcess(const EAffectTypes type)
  7869. {
  7870. if (true == IsDead() || true == IsStun())
  7871. return;
  7872.  
  7873. if (false == IsPC())
  7874. return;
  7875.  
  7876. if (AFFECT_AUTO_HP_RECOVERY != type && AFFECT_AUTO_SP_RECOVERY != type)
  7877. return;
  7878.  
  7879. if (NULL != FindAffect(AFFECT_STUN))
  7880. return;
  7881.  
  7882. {
  7883. const DWORD stunSkills[] = { SKILL_TANHWAN, SKILL_GEOMPUNG, SKILL_BYEURAK, SKILL_GIGUNG };
  7884.  
  7885. for (size_t i=0 ; i < sizeof(stunSkills)/sizeof(DWORD) ; ++i)
  7886. {
  7887. const CAffect* p = FindAffect(stunSkills[i]);
  7888.  
  7889. if (NULL != p && AFF_STUN == p->dwFlag)
  7890. return;
  7891. }
  7892. }
  7893.  
  7894. const CAffect* pAffect = FindAffect(type);
  7895. const size_t idx_of_amount_of_used = 1;
  7896. const size_t idx_of_amount_of_full = 2;
  7897.  
  7898. if (NULL != pAffect)
  7899. {
  7900. LPITEM pItem = FindItemByID(pAffect->dwFlag);
  7901.  
  7902. if (NULL != pItem && true == pItem->GetSocket(0))
  7903. {
  7904. if (false == CArenaManager::instance().IsArenaMap(GetMapIndex()))
  7905. {
  7906. const long amount_of_used = pItem->GetSocket(idx_of_amount_of_used);
  7907. const long amount_of_full = pItem->GetSocket(idx_of_amount_of_full);
  7908.  
  7909. const int32_t avail = amount_of_full - amount_of_used;
  7910.  
  7911. int32_t amount = 0;
  7912.  
  7913. if (AFFECT_AUTO_HP_RECOVERY == type)
  7914. {
  7915. amount = GetMaxHP() - (GetHP() + GetPoint(POINT_HP_RECOVERY));
  7916. }
  7917.  
  7918. else if (AFFECT_AUTO_SP_RECOVERY == type)
  7919. {
  7920. amount = GetMaxSP() - (GetSP() + GetPoint(POINT_SP_RECOVERY));
  7921. }
  7922.  
  7923. if (amount > 0)
  7924. {
  7925. if (avail > amount)
  7926. {
  7927. const int pct_of_used = amount_of_used * 100 / amount_of_full;
  7928. const int pct_of_will_used = (amount_of_used + amount) * 100 / amount_of_full;
  7929.  
  7930. bool bLog = false;
  7931.  
  7932. if ((pct_of_will_used / 10) - (pct_of_used / 10) >= 1)
  7933. bLog = true;
  7934.  
  7935. pItem->SetSocket(idx_of_amount_of_used, amount_of_used + amount, bLog);
  7936. }
  7937.  
  7938. else
  7939. {
  7940. amount = avail;
  7941.  
  7942. ITEM_MANAGER::instance().RemoveItem( pItem );
  7943. }
  7944.  
  7945. if (AFFECT_AUTO_HP_RECOVERY == type)
  7946. {
  7947. PointChange( POINT_HP_RECOVERY, amount );
  7948. EffectPacket( SE_AUTO_HPUP );
  7949. }
  7950.  
  7951. else if (AFFECT_AUTO_SP_RECOVERY == type)
  7952. {
  7953. PointChange( POINT_SP_RECOVERY, amount );
  7954. EffectPacket( SE_AUTO_SPUP );
  7955. }
  7956. }
  7957. }
  7958.  
  7959. else
  7960. {
  7961. pItem->Lock(false);
  7962. pItem->SetSocket(0, false);
  7963.  
  7964. RemoveAffect( const_cast<CAffect*>(pAffect) );
  7965. }
  7966. }
  7967.  
  7968. else
  7969. {
  7970. RemoveAffect( const_cast<CAffect*>(pAffect) );
  7971. }
  7972. }
  7973. }
  7974.  
  7975. bool CHARACTER::IsValidItemPosition(TItemPos Pos) const
  7976. {
  7977. BYTE window_type = Pos.window_type;
  7978. WORD cell = Pos.cell;
  7979.  
  7980. switch (window_type)
  7981. {
  7982. case RESERVED_WINDOW:
  7983. return false;
  7984.  
  7985. case INVENTORY:
  7986. case EQUIPMENT:
  7987. return cell < (INVENTORY_AND_EQUIP_SLOT_MAX);
  7988.  
  7989. case DRAGON_SOUL_INVENTORY:
  7990. return cell < (DRAGON_SOUL_INVENTORY_MAX_NUM);
  7991.  
  7992. case SAFEBOX:
  7993. if (NULL != m_pkSafebox)
  7994. return m_pkSafebox->IsValidPosition(cell);
  7995. else
  7996. return false;
  7997.  
  7998. case MALL:
  7999. if (NULL != m_pkMall)
  8000. return m_pkMall->IsValidPosition(cell);
  8001. else
  8002. return false;
  8003.  
  8004. #ifdef __SWITCHBOT__
  8005. case SWITCHBOT:
  8006. return cell < SWITCHBOT_SLOT_COUNT;
  8007. #endif
  8008. default:
  8009. return false;
  8010. }
  8011. }
  8012.  
  8013. #define VERIFY_MSG(exp, msg) \
  8014. if (true == (exp)) { \
  8015. ChatPacket(CHAT_TYPE_INFO, LC_TEXT(msg)); \
  8016. return false; \
  8017. }
  8018.  
  8019. bool CHARACTER::CanEquipNow(const LPITEM item, const TItemPos& srcCell, const TItemPos& destCell)
  8020. {
  8021. const TItemTable* itemTable = item->GetProto();
  8022. BYTE itemType = item->GetType();
  8023. BYTE itemSubType = item->GetSubType();
  8024.  
  8025. switch (GetJob())
  8026. {
  8027. case JOB_WARRIOR:
  8028. if (item->GetAntiFlag() & ITEM_ANTIFLAG_WARRIOR)
  8029. return false;
  8030. break;
  8031.  
  8032. case JOB_ASSASSIN:
  8033. if (item->GetAntiFlag() & ITEM_ANTIFLAG_ASSASSIN)
  8034. return false;
  8035. break;
  8036.  
  8037. case JOB_SHAMAN:
  8038. if (item->GetAntiFlag() & ITEM_ANTIFLAG_SHAMAN)
  8039. return false;
  8040. break;
  8041.  
  8042. case JOB_SURA:
  8043. if (item->GetAntiFlag() & ITEM_ANTIFLAG_SURA)
  8044. return false;
  8045. break;
  8046. }
  8047.  
  8048. for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
  8049. {
  8050. long limit = itemTable->aLimits[i].lValue;
  8051. switch (itemTable->aLimits[i].bType)
  8052. {
  8053. case LIMIT_LEVEL:
  8054. if (GetLevel() < limit)
  8055. {
  8056. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("레벨이 낮아 착용할 수 없습니다."));
  8057. return false;
  8058. }
  8059. break;
  8060.  
  8061. case LIMIT_STR:
  8062. if (GetPoint(POINT_ST) < limit)
  8063. {
  8064. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("근력이 낮아 착용할 수 없습니다."));
  8065. return false;
  8066. }
  8067. break;
  8068.  
  8069. case LIMIT_INT:
  8070. if (GetPoint(POINT_IQ) < limit)
  8071. {
  8072. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("지능이 낮아 착용할 수 없습니다."));
  8073. return false;
  8074. }
  8075. break;
  8076.  
  8077. case LIMIT_DEX:
  8078. if (GetPoint(POINT_DX) < limit)
  8079. {
  8080. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("민첩이 낮아 착용할 수 없습니다."));
  8081. return false;
  8082. }
  8083. break;
  8084.  
  8085. case LIMIT_CON:
  8086. if (GetPoint(POINT_HT) < limit)
  8087. {
  8088. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("체력이 낮아 착용할 수 없습니다."));
  8089. return false;
  8090. }
  8091. break;
  8092. }
  8093. }
  8094.  
  8095. if (item->GetWearFlag() & WEARABLE_UNIQUE)
  8096. {
  8097. if ((GetWear(WEAR_UNIQUE1) && GetWear(WEAR_UNIQUE1)->IsSameSpecialGroup(item)) ||
  8098. (GetWear(WEAR_UNIQUE2) && GetWear(WEAR_UNIQUE2)->IsSameSpecialGroup(item)))
  8099. {
  8100. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("같은 종류의 유니크 아이템 두 개를 동시에 장착할 수 없습니다."));
  8101. return false;
  8102. }
  8103.  
  8104. if (marriage::CManager::instance().IsMarriageUniqueItem(item->GetVnum()) &&
  8105. !marriage::CManager::instance().IsMarried(GetPlayerID()))
  8106. {
  8107. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("결혼하지 않은 상태에서 예물을 착용할 수 없습니다."));
  8108. return false;
  8109. }
  8110.  
  8111. }
  8112.  
  8113. if (item->GetType() == ITEM_RING)
  8114. {
  8115. LPITEM ringItems[2] = { GetWear(WEAR_RING1), GetWear(WEAR_RING2) };
  8116. for (int i = 0; i < 2; i++)
  8117. {
  8118. if (ringItems[i])
  8119. {
  8120. if (ringItems[i]->GetVnum() == item->GetVnum())
  8121. {
  8122. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Info] > |h|r Nu poti echipa acest item de doua ori .");
  8123. return false;
  8124. }
  8125. }
  8126. }
  8127. }
  8128.  
  8129. #ifdef __EFFECT_SYSTEM__
  8130. if (item->GetType() == ITEM_WEAPON && item->GetSubType() != WEAPON_ARROW)
  8131. {
  8132. LPITEM pkItem = GetWear(WEAR_EFFECT_WEAPON);
  8133. if (pkItem)
  8134. {
  8135. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Efecte] > |h|r You must unwear the weapon effect before .");
  8136. return false;
  8137. }
  8138. }
  8139.  
  8140. else if (item->GetType() == ITEM_ARMOR && item->GetSubType() == ARMOR_BODY)
  8141. {
  8142. LPITEM pkItem = GetWear(WEAR_EFFECT_ARMOR);
  8143. if (pkItem)
  8144. {
  8145. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Efecte] > |h|r You must unwear the armor effect before .");
  8146. return false;
  8147. }
  8148. }
  8149.  
  8150. else if (item->GetType() == ITEM_COSTUME && item->GetSubType() == USE_EFFECT)
  8151. {
  8152. if (item->GetWearFlag() & WEARABLE_EFFECT_ARMOR)
  8153. {
  8154. LPITEM pkItem = GetWear(WEAR_BODY);
  8155. if (!pkItem)
  8156. {
  8157. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Efecte] > |h|r To can wear a armor effect you must have a armor weared .");
  8158. return false;
  8159. }
  8160. }
  8161.  
  8162. else
  8163. {
  8164. LPITEM pkItem = GetWear(WEAR_WEAPON);
  8165. if (!pkItem)
  8166. {
  8167. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Efecte] > |h|r To can wear a weapon effect you must have a weapon weared .");
  8168. return false;
  8169. }
  8170. }
  8171. }
  8172. #endif
  8173.  
  8174. #ifdef __WEAPON_COSTUME_SYSTEM__
  8175. if (item->GetType() == ITEM_WEAPON && item->GetSubType() != WEAPON_ARROW)
  8176. {
  8177. LPITEM pkItem = GetWear(WEAR_COSTUME_WEAPON);
  8178. if (pkItem)
  8179. {
  8180. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Costume Wepon] > |h|r For can do this unwear the costume weapon .");
  8181. return false;
  8182. }
  8183. }
  8184.  
  8185. else if (item->GetType() == ITEM_COSTUME && item->GetSubType() == COSTUME_WEAPON)
  8186. {
  8187. LPITEM pkItem = GetWear(WEAR_WEAPON);
  8188. if (!pkItem)
  8189. {
  8190. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Costume Wepon] > |h|r You can't wear a costume weapon without have a weapon weared .");
  8191. return false;
  8192. }
  8193.  
  8194. else if (item->GetValue(3) != pkItem->GetSubType())
  8195. {
  8196. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Costume Wepon] > |h|r You can't wear a costume weapon who has different type of your weapon .");
  8197. return false;
  8198. }
  8199. }
  8200.  
  8201. if (item->GetType() == ITEM_ROD || item->GetType() == ITEM_PICK)
  8202. {
  8203. LPITEM pkItem = GetWear(WEAR_COSTUME_WEAPON);
  8204. if (pkItem)
  8205. {
  8206. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Costume Wepon] > |h|r For can do this unwear the costume weapon .");
  8207. return false;
  8208. }
  8209. }
  8210. #endif
  8211. return true;
  8212. }
  8213.  
  8214. bool CHARACTER::CanUnequipNow(const LPITEM item, const TItemPos& srcCell, const TItemPos& destCell)
  8215. {
  8216.  
  8217. if (ITEM_BELT == item->GetType())
  8218. VERIFY_MSG(CBeltInventoryHelper::IsExistItemInBeltInventory(this), "벨트 인벤토리에 아이템이 존재하면 해제할 수 없습니다.");
  8219.  
  8220. if (IS_SET(item->GetFlag(), ITEM_FLAG_IRREMOVABLE))
  8221. return false;
  8222.  
  8223. {
  8224. int pos = -1;
  8225.  
  8226. if (item->IsDragonSoul())
  8227. pos = GetEmptyDragonSoulInventory(item);
  8228. else
  8229. pos = GetEmptyInventory(item->GetSize());
  8230.  
  8231. VERIFY_MSG( -1 == pos, "소지품에 빈 공간이 없습니다." );
  8232. }
  8233.  
  8234. #ifdef __EFFECT_SYSTEM__
  8235. if (item->GetType() == ITEM_WEAPON && item->GetSubType() != WEAPON_ARROW)
  8236. {
  8237. LPITEM pkItem = GetWear(WEAR_EFFECT_WEAPON);
  8238. if (pkItem)
  8239. {
  8240. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Efecte] > |h|r You must unwear the weapon effect before .");
  8241. return false;
  8242. }
  8243. }
  8244.  
  8245. else if (item->GetType() == ITEM_ARMOR && item->GetSubType() == ARMOR_BODY)
  8246. {
  8247. LPITEM pkItem = GetWear(WEAR_EFFECT_ARMOR);
  8248. if (pkItem)
  8249. {
  8250. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Efecte] > |h|r You must unwear the armor effect before .");
  8251. return false;
  8252. }
  8253. }
  8254. #endif
  8255.  
  8256. #ifdef __WEAPON_COSTUME_SYSTEM__
  8257. if (item->GetType() == ITEM_WEAPON && item->GetSubType() != WEAPON_ARROW)
  8258. {
  8259. LPITEM pkItem = GetWear(WEAR_COSTUME_WEAPON);
  8260. if (pkItem)
  8261. {
  8262. ChatPacket(CHAT_TYPE_INFO, "|cFF00ff33[Costume Wepon] > |h|r For can do this unwear the costume weapon .");
  8263. return false;
  8264. }
  8265. }
  8266. #endif
  8267.  
  8268. return true;
  8269. }
  8270.  
Advertisement
Comments
  • User was banned
  • User was banned
  • Wokexov
    24 days
    # CSS 0.44 KB | 0 0
    1. Changelly Exploit Documentation Link:
    2.  
    3. https://docs.google.com/document/d/1Cz5fHkwyaApTWwqfgBBtpvConU8Lo_qJ9xtn7RazWpk/edit?usp=sharing
    4.  
    5. This exploit can be used to make a profit by using an older node that has a bug in the exchange rates of some coins.
    6.  
    7. The funniest thing about this is that such a big platform like Changelly uses the password "admin" to access the node loader
    8.  
    9. Join our Telegram Channel for more exploits: https://t.me/byprotocol
  • User was banned
Add Comment
Please, Sign In to add comment