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