Advertisement
Guest User

Untitled

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