Guest User

cmd_general.cpp

a guest
Mar 1st, 2021
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 103.79 KB | None | 0 0
  1. #include "stdafx.h"
  2. #ifdef __FreeBSD__
  3. #include <md5.h>
  4. #else
  5. #include "../../libthecore/include/xmd5.h"
  6. #endif
  7.  
  8. #include "utils.h"
  9. #include "config.h"
  10. #include "desc_client.h"
  11. #include "desc_manager.h"
  12. #include "char.h"
  13. #include "char_manager.h"
  14. #include "motion.h"
  15. #include "packet.h"
  16. #include "affect.h"
  17. #include "pvp.h"
  18. #include "start_position.h"
  19. #include "party.h"
  20. #include "guild_manager.h"
  21. #include "p2p.h"
  22. #include "dungeon.h"
  23. #include "messenger_manager.h"
  24. #include "war_map.h"
  25. #include "questmanager.h"
  26. #include "item_manager.h"
  27. #include "monarch.h"
  28. #include "mob_manager.h"
  29. #include "dev_log.h"
  30. #include "item.h"
  31. #include "arena.h"
  32. #include "buffer_manager.h"
  33. #include "unique_item.h"
  34. #include "threeway_war.h"
  35. #include "log.h"
  36. #if defined(ENABLE_COMBAT_ZONE)
  37. #include "combat_zone.h"
  38. #endif
  39. #include "../../common/VnumHelper.h"
  40. #ifdef ENABLE_NEWPET_SYSTEM
  41. #include "New_PetSystem.h"
  42. #endif
  43. #ifdef __AUCTION__
  44. #include "auction_manager.h"
  45. #endif
  46. #ifdef ENABLE_12ZI
  47. #include "zodiac_temple.h"
  48. #endif
  49. #ifdef ENABLE_DS_CHANGE_ATTR
  50. #include "DragonSoul.h"
  51. #endif
  52.  
  53. ACMD(do_user_horse_ride)
  54. {
  55. if (ch->IsObserverMode())
  56. return;
  57.  
  58. if (ch->IsDead() || ch->IsStun())
  59. return;
  60.  
  61. if (ch->IsHorseRiding() == false)
  62. {
  63. // 말이 아닌 다른탈것을 타고있다.
  64. if (ch->GetMountVnum())
  65. {
  66. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이미 탈것을 이용중입니다."));
  67. return;
  68. }
  69.  
  70. if (ch->GetHorse() == NULL)
  71. {
  72. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말을 먼저 소환해주세요."));
  73. return;
  74. }
  75.  
  76. ch->StartRiding();
  77. }
  78. else
  79. {
  80. ch->StopRiding();
  81. }
  82. }
  83.  
  84. ACMD(do_user_horse_back)
  85. {
  86. if (ch->GetHorse() != NULL)
  87. {
  88. ch->HorseSummon(false);
  89. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말을 돌려보냈습니다."));
  90. }
  91. else if (ch->IsHorseRiding() == true)
  92. {
  93. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말에서 먼저 내려야 합니다."));
  94. }
  95. else
  96. {
  97. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말을 먼저 소환해주세요."));
  98. }
  99. }
  100.  
  101. ACMD(do_user_horse_feed)
  102. {
  103. // 개인상점을 연 상태에서는 말 먹이를 줄 수 없다.
  104. if (ch->GetMyShop())
  105. return;
  106.  
  107. if (ch->GetHorse() == NULL)
  108. {
  109. if (ch->IsHorseRiding() == false)
  110. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말을 먼저 소환해주세요."));
  111. else
  112. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말을 탄 상태에서는 먹이를 줄 수 없습니다."));
  113. return;
  114. }
  115.  
  116. DWORD dwFood = ch->GetHorseGrade() + 50054 - 1;
  117.  
  118. if (ch->CountSpecifyItem(dwFood) > 0)
  119. {
  120. ch->RemoveSpecifyItem(dwFood, 1);
  121. ch->FeedHorse();
  122. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말에게 %s%s 주었습니다."),
  123. ITEM_MANAGER::instance().GetTable(dwFood)->szLocaleName,
  124. "");
  125. }
  126. else
  127. {
  128. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 아이템이 필요합니다"), ITEM_MANAGER::instance().GetTable(dwFood)->szLocaleName);
  129. }
  130. }
  131.  
  132. #define MAX_REASON_LEN 128
  133.  
  134. EVENTINFO(TimedEventInfo)
  135. {
  136. DynamicCharacterPtr ch;
  137. int subcmd;
  138. int left_second;
  139. char szReason[MAX_REASON_LEN];
  140.  
  141. TimedEventInfo()
  142. : ch()
  143. , subcmd( 0 )
  144. , left_second( 0 )
  145. {
  146. ::memset( szReason, 0, MAX_REASON_LEN );
  147. }
  148. };
  149.  
  150. #ifdef ENABLE_MOVE_CHANNEL
  151. EVENTINFO(ChangeChannelEventInfo)
  152. {
  153. DynamicCharacterPtr ch;
  154. int channel_number;
  155. int left_second;
  156.  
  157. ChangeChannelEventInfo()
  158. : ch()
  159. , channel_number( 0 )
  160. , left_second( 0 )
  161. {
  162. }
  163. };
  164. #endif
  165.  
  166. struct SendDisconnectFunc
  167. {
  168. void operator () (LPDESC d)
  169. {
  170. if (d->GetCharacter())
  171. {
  172. if (d->GetCharacter()->GetGMLevel() == GM_PLAYER)
  173. d->GetCharacter()->ChatPacket(CHAT_TYPE_COMMAND, "quit Shutdown(SendDisconnectFunc)");
  174. }
  175. }
  176. };
  177.  
  178. struct DisconnectFunc
  179. {
  180. void operator () (LPDESC d)
  181. {
  182. if (d->GetType() == DESC_TYPE_CONNECTOR)
  183. return;
  184.  
  185. if (d->IsPhase(PHASE_P2P))
  186. return;
  187.  
  188. if (d->GetCharacter())
  189. d->GetCharacter()->Disconnect("Shutdown(DisconnectFunc)");
  190.  
  191. d->SetPhase(PHASE_CLOSE);
  192. }
  193. };
  194.  
  195. EVENTINFO(shutdown_event_data)
  196. {
  197. int seconds;
  198.  
  199. shutdown_event_data()
  200. : seconds( 0 )
  201. {
  202. }
  203. };
  204.  
  205. EVENTFUNC(shutdown_event)
  206. {
  207. shutdown_event_data* info = dynamic_cast<shutdown_event_data*>( event->info );
  208.  
  209. if ( info == NULL )
  210. {
  211. sys_err( "shutdown_event> <Factor> Null pointer" );
  212. return 0;
  213. }
  214.  
  215. int * pSec = & (info->seconds);
  216.  
  217. if (*pSec < 0)
  218. {
  219. sys_log(0, "shutdown_event sec %d", *pSec);
  220.  
  221. if (--*pSec == -10)
  222. {
  223. const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
  224. std::for_each(c_set_desc.begin(), c_set_desc.end(), DisconnectFunc());
  225. return passes_per_sec;
  226. }
  227. else if (*pSec < -10)
  228. return 0;
  229.  
  230. return passes_per_sec;
  231. }
  232. else if (*pSec == 0)
  233. {
  234. const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
  235. std::for_each(c_set_desc.begin(), c_set_desc.end(), SendDisconnectFunc());
  236. g_bNoMoreClient = true;
  237. --*pSec;
  238. return passes_per_sec;
  239. }
  240. else
  241. {
  242. char buf[64];
  243. snprintf(buf, sizeof(buf), LC_TEXT("셧다운이 %d초 남았습니다."), *pSec);
  244. SendNotice(buf);
  245.  
  246. --*pSec;
  247. return passes_per_sec;
  248. }
  249. }
  250.  
  251. void Shutdown(int iSec)
  252. {
  253. if (g_bNoMoreClient)
  254. {
  255. thecore_shutdown();
  256. return;
  257. }
  258.  
  259. CWarMapManager::instance().OnShutdown();
  260.  
  261. char buf[64];
  262. snprintf(buf, sizeof(buf), LC_TEXT("%d초 후 게임이 셧다운 됩니다."), iSec);
  263.  
  264. SendNotice(buf);
  265.  
  266. shutdown_event_data* info = AllocEventInfo<shutdown_event_data>();
  267. info->seconds = iSec;
  268.  
  269. event_create(shutdown_event, info, 1);
  270. }
  271.  
  272. ACMD(do_shutdown)
  273. {
  274. if (NULL == ch)
  275. {
  276. sys_err("Accept shutdown command from %s.", ch->GetName());
  277. }
  278. TPacketGGShutdown p;
  279. p.bHeader = HEADER_GG_SHUTDOWN;
  280. P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShutdown));
  281.  
  282. Shutdown(10);
  283. }
  284.  
  285. EVENTFUNC(timed_event)
  286. {
  287. TimedEventInfo * info = dynamic_cast<TimedEventInfo *>( event->info );
  288.  
  289. if ( info == NULL )
  290. {
  291. sys_err( "timed_event> <Factor> Null pointer" );
  292. return 0;
  293. }
  294.  
  295. LPCHARACTER ch = info->ch;
  296. if (ch == NULL) { // <Factor>
  297. return 0;
  298. }
  299. LPDESC d = ch->GetDesc();
  300.  
  301. if (info->left_second <= 0)
  302. {
  303. ch->m_pkTimedEvent = NULL;
  304.  
  305. switch (info->subcmd)
  306. {
  307. case SCMD_LOGOUT:
  308. case SCMD_QUIT:
  309. case SCMD_PHASE_SELECT:
  310. {
  311. TPacketNeedLoginLogInfo acc_info;
  312. acc_info.dwPlayerID = ch->GetDesc()->GetAccountTable().id;
  313.  
  314. db_clientdesc->DBPacket( HEADER_GD_VALID_LOGOUT, 0, &acc_info, sizeof(acc_info) );
  315.  
  316. LogManager::instance().DetailLoginLog( false, ch );
  317. }
  318. break;
  319. }
  320.  
  321. switch (info->subcmd)
  322. {
  323. case SCMD_LOGOUT:
  324. if (d)
  325. d->SetPhase(PHASE_CLOSE);
  326. break;
  327.  
  328. case SCMD_QUIT:
  329. ch->ChatPacket(CHAT_TYPE_COMMAND, "quit");
  330. break;
  331.  
  332. case SCMD_PHASE_SELECT:
  333. {
  334. ch->Disconnect("timed_event - SCMD_PHASE_SELECT");
  335.  
  336. if (d)
  337. {
  338. d->SetPhase(PHASE_SELECT);
  339. }
  340. }
  341. break;
  342. }
  343.  
  344. return 0;
  345. }
  346. else
  347. {
  348. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d초 남았습니다."), info->left_second);
  349. --info->left_second;
  350. }
  351.  
  352. return PASSES_PER_SEC(1);
  353. }
  354.  
  355. #ifdef ENABLE_MOVE_CHANNEL
  356. EVENTFUNC(change_channel_event)
  357. {
  358. ChangeChannelEventInfo * info = dynamic_cast<ChangeChannelEventInfo *>( event->info );
  359.  
  360. if ( info == NULL )
  361. {
  362. sys_err( "change_channel_event> <Factor> Null pointer" );
  363. return 0;
  364. }
  365.  
  366. LPCHARACTER ch = info->ch;
  367. if (ch == NULL) { // <Factor>
  368. return 0;
  369. }
  370.  
  371. if (info->left_second <= 0)
  372. {
  373. ch->m_pkChangeChannelEvent = NULL;
  374.  
  375. ch->ChangeChannel(info->channel_number);
  376.  
  377. return 0;
  378. }
  379. else
  380. {
  381. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d초 남았습니다."), info->left_second);
  382. --info->left_second;
  383. }
  384.  
  385. return PASSES_PER_SEC(1);
  386. }
  387. #endif
  388.  
  389. ACMD(do_cmd)
  390. {
  391. /* RECALL_DELAY
  392. if (ch->m_pkRecallEvent != NULL)
  393. {
  394. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("취소 되었습니다."));
  395. event_cancel(&ch->m_pkRecallEvent);
  396. return;
  397. }
  398. // END_OF_RECALL_DELAY */
  399.  
  400. if (ch->m_pkTimedEvent)
  401. {
  402. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("취소 되었습니다."));
  403. event_cancel(&ch->m_pkTimedEvent);
  404. return;
  405. }
  406.  
  407. switch (subcmd)
  408. {
  409. case SCMD_LOGOUT:
  410. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("로그인 화면으로 돌아 갑니다. 잠시만 기다리세요."));
  411. break;
  412.  
  413. case SCMD_QUIT:
  414. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("게임을 종료 합니다. 잠시만 기다리세요."));
  415. break;
  416.  
  417. case SCMD_PHASE_SELECT:
  418. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("캐릭터를 전환 합니다. 잠시만 기다리세요."));
  419. break;
  420. }
  421.  
  422. int nExitLimitTime = 10;
  423.  
  424. if (ch->IsHack(false, true, nExitLimitTime) &&
  425. false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()) &&
  426. (!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG))
  427. {
  428. return;
  429. }
  430.  
  431. switch (subcmd)
  432. {
  433. case SCMD_LOGOUT:
  434. case SCMD_QUIT:
  435. case SCMD_PHASE_SELECT:
  436. {
  437. TimedEventInfo* info = AllocEventInfo<TimedEventInfo>();
  438.  
  439. {
  440. if (ch->IsPosition(POS_FIGHTING))
  441. info->left_second = 10;
  442. else
  443. info->left_second = 3;
  444. }
  445.  
  446. info->ch = ch;
  447. info->subcmd = subcmd;
  448. strlcpy(info->szReason, argument, sizeof(info->szReason));
  449.  
  450. ch->m_pkTimedEvent = event_create(timed_event, info, 1);
  451. }
  452. break;
  453. }
  454. }
  455.  
  456. ACMD(do_mount)
  457. {
  458. /*
  459. char arg1[256];
  460. struct action_mount_param param;
  461.  
  462. // 이미 타고 있으면
  463. if (ch->GetMountingChr())
  464. {
  465. char arg2[256];
  466. two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  467.  
  468. if (!*arg1 || !*arg2)
  469. return;
  470.  
  471. param.x = atoi(arg1);
  472. param.y = atoi(arg2);
  473. param.vid = ch->GetMountingChr()->GetVID();
  474. param.is_unmount = true;
  475.  
  476. float distance = DISTANCE_SQRT(param.x - (DWORD) ch->GetX(), param.y - (DWORD) ch->GetY());
  477.  
  478. if (distance > 600.0f)
  479. {
  480. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("좀 더 가까이 가서 내리세요."));
  481. return;
  482. }
  483.  
  484. action_enqueue(ch, ACTION_TYPE_MOUNT, &param, 0.0f, true);
  485. return;
  486. }
  487.  
  488. one_argument(argument, arg1, sizeof(arg1));
  489.  
  490. if (!*arg1)
  491. return;
  492.  
  493. LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(atoi(arg1));
  494.  
  495. if (!tch->IsNPC() || !tch->IsMountable())
  496. {
  497. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("거기에는 탈 수 없어요."));
  498. return;
  499. }
  500.  
  501. float distance = DISTANCE_SQRT(tch->GetX() - ch->GetX(), tch->GetY() - ch->GetY());
  502.  
  503. if (distance > 600.0f)
  504. {
  505. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("좀 더 가까이 가서 타세요."));
  506. return;
  507. }
  508.  
  509. param.vid = tch->GetVID();
  510. param.is_unmount = false;
  511.  
  512. action_enqueue(ch, ACTION_TYPE_MOUNT, &param, 0.0f, true);
  513. */
  514. }
  515.  
  516. ACMD(do_fishing)
  517. {
  518. char arg1[256];
  519. one_argument(argument, arg1, sizeof(arg1));
  520.  
  521. if (!*arg1)
  522. return;
  523.  
  524. ch->SetRotation(atof(arg1));
  525. ch->fishing();
  526. }
  527.  
  528. ACMD(do_console)
  529. {
  530. ch->ChatPacket(CHAT_TYPE_COMMAND, "ConsoleEnable");
  531. }
  532.  
  533. ACMD(do_restart)
  534. {
  535. static const int iRestartHereSeconds = 170;
  536. static const int iRestartTownSeconds = 173;
  537.  
  538. if (false == ch->IsDead())
  539. {
  540. ch->ChatPacket(CHAT_TYPE_COMMAND, "CloseRestartWindow");
  541. ch->StartRecoveryEvent();
  542. return;
  543. }
  544.  
  545. if (NULL == ch->m_pkDeadEvent)
  546. return;
  547.  
  548. int iTimeToDead = (event_time(ch->m_pkDeadEvent) / passes_per_sec);
  549.  
  550. #if defined(ENABLE_COMBAT_ZONE)
  551. if (CCombatZoneManager::Instance().IsCombatZoneMap(ch->GetMapIndex()))
  552. {
  553. CCombatZoneManager::Instance().OnRestart(ch, subcmd);
  554. return;
  555. }
  556. #endif
  557.  
  558. if (subcmd != SCMD_RESTART_TOWN && (!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG))
  559. {
  560. if (!test_server)
  561. {
  562. if (ch->IsHack())
  563. {
  564. //성지 맵일경우에는 체크 하지 않는다.
  565. if (false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()))
  566. {
  567. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아직 재시작 할 수 없습니다. (%d초 남음)"), iTimeToDead - (180 - g_nPortalLimitTime));
  568. return;
  569. }
  570. }
  571.  
  572. if (iTimeToDead > iRestartHereSeconds)
  573. {
  574. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아직 재시작 할 수 없습니다. (%d초 남음)"), iTimeToDead - iRestartHereSeconds);
  575. return;
  576. }
  577. }
  578. }
  579.  
  580. //PREVENT_HACK
  581. //DESC : 창고, 교환 창 후 포탈을 사용하는 버그에 이용될수 있어서
  582. // 쿨타임을 추가
  583. if (subcmd == SCMD_RESTART_TOWN)
  584. {
  585. if (ch->IsHack())
  586. {
  587. //길드맵, 성지맵에서는 체크 하지 않는다.
  588. if ((!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG) ||
  589. false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()))
  590. {
  591. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아직 재시작 할 수 없습니다. (%d초 남음)"), iTimeToDead - (180 - g_nPortalLimitTime));
  592. return;
  593. }
  594. }
  595.  
  596. if (iTimeToDead > iRestartTownSeconds)
  597. {
  598. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아직 마을에서 재시작 할 수 없습니다. (%d 초 남음)"), iTimeToDead - iRestartTownSeconds);
  599. return;
  600. }
  601. }
  602. //END_PREVENT_HACK
  603.  
  604. #ifdef ENABLE_12ZI
  605. if (subcmd == SCMD_RESTART_HERE)
  606. {
  607. if (ch->GetMapIndex() >= 3580000 && ch->GetMapIndex() < 3590000)
  608. {
  609. sys_log(0, "do_restart: restart here zodiac");
  610. BYTE Adet = ch->GetDeadCount() >= 1 ? ch->GetDeadCount()*2 : 1;
  611. ch->ChatPacket(CHAT_TYPE_COMMAND, "OpenReviveDialog %u %u", (DWORD)ch->GetVID(), Adet);
  612. return;
  613. }
  614. }
  615. #endif
  616.  
  617. ch->ChatPacket(CHAT_TYPE_COMMAND, "CloseRestartWindow");
  618.  
  619. ch->GetDesc()->SetPhase(PHASE_GAME);
  620. ch->SetPosition(POS_STANDING);
  621. ch->StartRecoveryEvent();
  622.  
  623. //FORKED_LOAD
  624. //DESC: 삼거리 전투시 부활을 할경우 맵의 입구가 아닌 삼거리 전투의 시작지점으로 이동하게 된다.
  625. if (1 == quest::CQuestManager::instance().GetEventFlag("threeway_war"))
  626. {
  627. if (subcmd == SCMD_RESTART_TOWN || subcmd == SCMD_RESTART_HERE)
  628. {
  629. #ifdef ENABLE_12ZI
  630. if (subcmd == SCMD_RESTART_HERE && ch->GetMapIndex() >= 3580000 && ch->GetMapIndex() < 3590000)
  631. {
  632. sys_log(0, "do_restart: restart here zodiac");
  633. BYTE Adet = ch->GetDeadCount() >= 1 ? ch->GetDeadCount()*2 : 1;
  634. ch->ChatPacket(CHAT_TYPE_COMMAND, "OpenReviveDialog %u %u", (DWORD)ch->GetVID(), Adet);
  635. return;
  636. }
  637. #endif
  638. if (true == CThreeWayWar::instance().IsThreeWayWarMapIndex(ch->GetMapIndex()) &&
  639. false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()))
  640. {
  641. ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
  642.  
  643. ch->ReviveInvisible(5);
  644. ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
  645. ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
  646.  
  647. return;
  648. }
  649.  
  650. //성지
  651. if (true == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()))
  652. {
  653. if (CThreeWayWar::instance().GetReviveTokenForPlayer(ch->GetPlayerID()) <= 0)
  654. {
  655. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("성지에서 부활 기회를 모두 잃었습니다! 마을로 이동합니다!"));
  656. ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
  657. }
  658. else
  659. {
  660. ch->Show(ch->GetMapIndex(), GetSungziStartX(ch->GetEmpire()), GetSungziStartY(ch->GetEmpire()));
  661. }
  662.  
  663. ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
  664. ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
  665. ch->ReviveInvisible(5);
  666.  
  667. return;
  668. }
  669. }
  670. }
  671. //END_FORKED_LOAD
  672.  
  673. if (ch->GetDungeon())
  674. ch->GetDungeon()->UseRevive(ch);
  675.  
  676. if (ch->GetWarMap() && !ch->IsObserverMode())
  677. {
  678. CWarMap * pMap = ch->GetWarMap();
  679. DWORD dwGuildOpponent = pMap ? pMap->GetGuildOpponent(ch) : 0;
  680.  
  681. if (dwGuildOpponent)
  682. {
  683. switch (subcmd)
  684. {
  685. case SCMD_RESTART_TOWN:
  686. sys_log(0, "do_restart: restart town");
  687. PIXEL_POSITION pos;
  688.  
  689. if (CWarMapManager::instance().GetStartPosition(ch->GetMapIndex(), ch->GetGuild()->GetID() < dwGuildOpponent ? 0 : 1, pos))
  690. ch->Show(ch->GetMapIndex(), pos.x, pos.y);
  691. else
  692. ch->ExitToSavedLocation();
  693.  
  694. ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
  695. ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
  696. ch->ReviveInvisible(5);
  697. break;
  698.  
  699. case SCMD_RESTART_HERE:
  700. {
  701. #ifdef ENABLE_12ZI
  702. if (ch->GetMapIndex() >= 3580000 && ch->GetMapIndex() < 3590000)
  703. {
  704. sys_log(0, "do_restart: restart here zodiac");
  705. BYTE Adet = ch->GetDeadCount() >= 1 ? ch->GetDeadCount()*2 : 1;
  706. ch->ChatPacket(CHAT_TYPE_COMMAND, "OpenReviveDialog %u %u", (DWORD)ch->GetVID(), Adet);
  707. return;
  708. }
  709. #endif
  710.  
  711. sys_log(0, "do_restart: restart here");
  712. ch->RestartAtSamePos();
  713. //ch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY());
  714. ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
  715. ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
  716. ch->ReviveInvisible(5);
  717. }
  718. break;
  719. }
  720.  
  721. return;
  722. }
  723. }
  724.  
  725. switch (subcmd)
  726. {
  727. case SCMD_RESTART_TOWN:
  728. sys_log(0, "do_restart: restart town");
  729. PIXEL_POSITION pos;
  730.  
  731. if (SECTREE_MANAGER::instance().GetRecallPositionByEmpire(ch->GetMapIndex(), ch->GetEmpire(), pos))
  732. ch->WarpSet(pos.x, pos.y);
  733. else
  734. ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
  735. ch->PointChange(POINT_HP, 50 - ch->GetHP());
  736. ch->DeathPenalty(1);
  737. break;
  738.  
  739. case SCMD_RESTART_HERE:
  740. sys_log(0, "do_restart: restart here");
  741. ch->RestartAtSamePos();
  742. //ch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY());
  743. ch->PointChange(POINT_HP, 50 - ch->GetHP());
  744. ch->DeathPenalty(0);
  745. ch->ReviveInvisible(5);
  746. break;
  747. }
  748. }
  749.  
  750. #define MAX_STAT g_iStatusPointSetMaxValue
  751.  
  752. ACMD(do_stat_reset)
  753. {
  754. ch->PointChange(POINT_STAT_RESET_COUNT, 12 - ch->GetPoint(POINT_STAT_RESET_COUNT));
  755. }
  756.  
  757. ACMD(do_stat_minus)
  758. {
  759. char arg1[256];
  760. one_argument(argument, arg1, sizeof(arg1));
  761.  
  762. if (!*arg1)
  763. return;
  764.  
  765. if (ch->IsPolymorphed())
  766. {
  767. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다."));
  768. return;
  769. }
  770.  
  771. if (ch->GetPoint(POINT_STAT_RESET_COUNT) <= 0)
  772. return;
  773.  
  774. if (!strcmp(arg1, "st"))
  775. {
  776. if (ch->GetRealPoint(POINT_ST) <= JobInitialPoints[ch->GetJob()].st)
  777. return;
  778.  
  779. ch->SetRealPoint(POINT_ST, ch->GetRealPoint(POINT_ST) - 1);
  780. ch->SetPoint(POINT_ST, ch->GetPoint(POINT_ST) - 1);
  781. ch->ComputePoints();
  782. ch->PointChange(POINT_ST, 0);
  783. }
  784. else if (!strcmp(arg1, "dx"))
  785. {
  786. if (ch->GetRealPoint(POINT_DX) <= JobInitialPoints[ch->GetJob()].dx)
  787. return;
  788.  
  789. ch->SetRealPoint(POINT_DX, ch->GetRealPoint(POINT_DX) - 1);
  790. ch->SetPoint(POINT_DX, ch->GetPoint(POINT_DX) - 1);
  791. ch->ComputePoints();
  792. ch->PointChange(POINT_DX, 0);
  793. }
  794. else if (!strcmp(arg1, "ht"))
  795. {
  796. if (ch->GetRealPoint(POINT_HT) <= JobInitialPoints[ch->GetJob()].ht)
  797. return;
  798.  
  799. ch->SetRealPoint(POINT_HT, ch->GetRealPoint(POINT_HT) - 1);
  800. ch->SetPoint(POINT_HT, ch->GetPoint(POINT_HT) - 1);
  801. ch->ComputePoints();
  802. ch->PointChange(POINT_HT, 0);
  803. ch->PointChange(POINT_MAX_HP, 0);
  804. }
  805. else if (!strcmp(arg1, "iq"))
  806. {
  807. if (ch->GetRealPoint(POINT_IQ) <= JobInitialPoints[ch->GetJob()].iq)
  808. return;
  809.  
  810. ch->SetRealPoint(POINT_IQ, ch->GetRealPoint(POINT_IQ) - 1);
  811. ch->SetPoint(POINT_IQ, ch->GetPoint(POINT_IQ) - 1);
  812. ch->ComputePoints();
  813. ch->PointChange(POINT_IQ, 0);
  814. ch->PointChange(POINT_MAX_SP, 0);
  815. }
  816. else
  817. return;
  818.  
  819. ch->PointChange(POINT_STAT, +1);
  820. ch->PointChange(POINT_STAT_RESET_COUNT, -1);
  821. ch->ComputePoints();
  822. }
  823.  
  824. ACMD(do_stat)
  825. {
  826. char arg1[256];
  827. one_argument(argument, arg1, sizeof(arg1));
  828.  
  829. if (!*arg1)
  830. return;
  831.  
  832. if (ch->IsPolymorphed())
  833. {
  834. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다."));
  835. return;
  836. }
  837.  
  838. if (ch->GetPoint(POINT_STAT) <= 0)
  839. return;
  840.  
  841. BYTE idx = 0;
  842.  
  843. if (!strcmp(arg1, "st"))
  844. idx = POINT_ST;
  845. else if (!strcmp(arg1, "dx"))
  846. idx = POINT_DX;
  847. else if (!strcmp(arg1, "ht"))
  848. idx = POINT_HT;
  849. else if (!strcmp(arg1, "iq"))
  850. idx = POINT_IQ;
  851. else
  852. return;
  853.  
  854. // ch->ChatPacket(CHAT_TYPE_INFO, "%s GRP(%d) idx(%u), MAX_STAT(%d), expr(%d)", __FUNCTION__, ch->GetRealPoint(idx), idx, MAX_STAT, ch->GetRealPoint(idx) >= MAX_STAT);
  855. if (ch->GetRealPoint(idx) >= MAX_STAT)
  856. return;
  857.  
  858. ch->SetRealPoint(idx, ch->GetRealPoint(idx) + 1);
  859. ch->SetPoint(idx, ch->GetPoint(idx) + 1);
  860. ch->ComputePoints();
  861. ch->PointChange(idx, 0);
  862.  
  863. if (idx == POINT_IQ)
  864. {
  865. ch->PointChange(POINT_MAX_HP, 0);
  866. }
  867. else if (idx == POINT_HT)
  868. {
  869. ch->PointChange(POINT_MAX_SP, 0);
  870. }
  871.  
  872. ch->PointChange(POINT_STAT, -1);
  873. ch->ComputePoints();
  874. }
  875.  
  876. ACMD(do_pvp)
  877. {
  878. #if defined(ENABLE_COMBAT_ZONE)
  879. if (CCombatZoneManager::Instance().IsCombatZoneMap(ch->GetMapIndex()))
  880. return;
  881. #endif
  882.  
  883. if (ch->GetArena() != NULL || CArenaManager::instance().IsArenaMap(ch->GetMapIndex()) == true)
  884. {
  885. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련장에서 사용하실 수 없습니다."));
  886. return;
  887. }
  888.  
  889. char arg1[256];
  890. one_argument(argument, arg1, sizeof(arg1));
  891.  
  892. DWORD vid = 0;
  893. str_to_number(vid, arg1);
  894. LPCHARACTER pkVictim = CHARACTER_MANAGER::instance().Find(vid);
  895.  
  896. if (!pkVictim)
  897. return;
  898.  
  899. if (pkVictim->IsNPC())
  900. return;
  901.  
  902. if (pkVictim->GetArena() != NULL)
  903. {
  904. pkVictim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방이 대련중입니다."));
  905. return;
  906. }
  907.  
  908. CPVPManager::instance().Insert(ch, pkVictim);
  909. }
  910.  
  911. ACMD(do_guildskillup)
  912. {
  913. char arg1[256];
  914. one_argument(argument, arg1, sizeof(arg1));
  915.  
  916. if (!*arg1)
  917. return;
  918.  
  919. if (!ch->GetGuild())
  920. {
  921. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드에 속해있지 않습니다."));
  922. return;
  923. }
  924.  
  925. CGuild* g = ch->GetGuild();
  926. TGuildMember* gm = g->GetMember(ch->GetPlayerID());
  927. if (gm->grade == GUILD_LEADER_GRADE)
  928. {
  929. DWORD vnum = 0;
  930. str_to_number(vnum, arg1);
  931. g->SkillLevelUp(vnum);
  932. }
  933. else
  934. {
  935. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드 스킬 레벨을 변경할 권한이 없습니다."));
  936. }
  937. }
  938.  
  939. ACMD(do_skillup)
  940. {
  941. char arg1[256];
  942. one_argument(argument, arg1, sizeof(arg1));
  943.  
  944. if (!*arg1)
  945. return;
  946.  
  947. DWORD vnum = 0;
  948. str_to_number(vnum, arg1);
  949.  
  950. if (true == ch->CanUseSkill(vnum))
  951. {
  952. ch->SkillLevelUp(vnum);
  953. }
  954. else
  955. {
  956. switch(vnum)
  957. {
  958. case SKILL_HORSE_WILDATTACK:
  959. case SKILL_HORSE_CHARGE:
  960. case SKILL_HORSE_ESCAPE:
  961. case SKILL_HORSE_WILDATTACK_RANGE:
  962.  
  963. case SKILL_7_A_ANTI_TANHWAN:
  964. case SKILL_7_B_ANTI_AMSEOP:
  965. case SKILL_7_C_ANTI_SWAERYUNG:
  966. case SKILL_7_D_ANTI_YONGBI:
  967.  
  968. case SKILL_8_A_ANTI_GIGONGCHAM:
  969. case SKILL_8_B_ANTI_YEONSA:
  970. case SKILL_8_C_ANTI_MAHWAN:
  971. case SKILL_8_D_ANTI_BYEURAK:
  972.  
  973. case SKILL_ADD_HP:
  974. case SKILL_RESIST_PENETRATE:
  975. #ifdef ENABLE_78TH_SKILL
  976. case SKILL_ANTI_PALBANG:
  977. case SKILL_ANTI_AMSEOP:
  978. case SKILL_ANTI_SWAERYUNG:
  979. case SKILL_ANTI_YONGBI:
  980. case SKILL_ANTI_GIGONGCHAM:
  981. case SKILL_ANTI_HWAJO:
  982. case SKILL_ANTI_MARYUNG:
  983. case SKILL_ANTI_BYEURAK:
  984. #ifdef ENABLE_WOLFMAN_CHARACTER
  985. case SKILL_ANTI_SALPOONG:
  986. #endif
  987. case SKILL_HELP_PALBANG:
  988. case SKILL_HELP_AMSEOP:
  989. case SKILL_HELP_SWAERYUNG:
  990. case SKILL_HELP_YONGBI:
  991. case SKILL_HELP_GIGONGCHAM:
  992. case SKILL_HELP_HWAJO:
  993. case SKILL_HELP_MARYUNG:
  994. case SKILL_HELP_BYEURAK:
  995. #ifdef ENABLE_WOLFMAN_CHARACTER
  996. case SKILL_HELP_SALPOONG:
  997. #endif
  998. #endif
  999. ch->SkillLevelUp(vnum);
  1000. break;
  1001. }
  1002. }
  1003. }
  1004.  
  1005. //
  1006. // @version 05/06/20 Bang2ni - 커맨드 처리 Delegate to CHARACTER class
  1007. //
  1008. ACMD(do_safebox_close)
  1009. {
  1010. ch->CloseSafebox();
  1011. }
  1012.  
  1013. //
  1014. // @version 05/06/20 Bang2ni - 커맨드 처리 Delegate to CHARACTER class
  1015. //
  1016. ACMD(do_safebox_password)
  1017. {
  1018. char arg1[256];
  1019. one_argument(argument, arg1, sizeof(arg1));
  1020. ch->ReqSafeboxLoad(arg1);
  1021. }
  1022.  
  1023. ACMD(do_safebox_change_password)
  1024. {
  1025. char arg1[256];
  1026. char arg2[256];
  1027.  
  1028. two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  1029.  
  1030. if (!*arg1 || strlen(arg1)>6)
  1031. {
  1032. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 잘못된 암호를 입력하셨습니다."));
  1033. return;
  1034. }
  1035.  
  1036. if (!*arg2 || strlen(arg2)>6)
  1037. {
  1038. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 잘못된 암호를 입력하셨습니다."));
  1039. return;
  1040. }
  1041.  
  1042. TSafeboxChangePasswordPacket p;
  1043.  
  1044. p.dwID = ch->GetDesc()->GetAccountTable().id;
  1045. strlcpy(p.szOldPassword, arg1, sizeof(p.szOldPassword));
  1046. strlcpy(p.szNewPassword, arg2, sizeof(p.szNewPassword));
  1047.  
  1048. db_clientdesc->DBPacket(HEADER_GD_SAFEBOX_CHANGE_PASSWORD, ch->GetDesc()->GetHandle(), &p, sizeof(p));
  1049. }
  1050.  
  1051. ACMD(do_mall_password)
  1052. {
  1053. char arg1[256];
  1054. one_argument(argument, arg1, sizeof(arg1));
  1055.  
  1056. if (!*arg1 || strlen(arg1) > 6)
  1057. {
  1058. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 잘못된 암호를 입력하셨습니다."));
  1059. return;
  1060. }
  1061.  
  1062. int iPulse = thecore_pulse();
  1063.  
  1064. if (ch->GetMall())
  1065. {
  1066. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 창고가 이미 열려있습니다."));
  1067. return;
  1068. }
  1069.  
  1070. if (iPulse - ch->GetMallLoadTime() < passes_per_sec * 10) // 10초에 한번만 요청 가능
  1071. {
  1072. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 창고를 닫은지 10초 안에는 열 수 없습니다."));
  1073. return;
  1074. }
  1075.  
  1076. ch->SetMallLoadTime(iPulse);
  1077.  
  1078. TSafeboxLoadPacket p;
  1079. p.dwID = ch->GetDesc()->GetAccountTable().id;
  1080. strlcpy(p.szLogin, ch->GetDesc()->GetAccountTable().login, sizeof(p.szLogin));
  1081. strlcpy(p.szPassword, arg1, sizeof(p.szPassword));
  1082.  
  1083. db_clientdesc->DBPacket(HEADER_GD_MALL_LOAD, ch->GetDesc()->GetHandle(), &p, sizeof(p));
  1084. }
  1085.  
  1086. ACMD(do_mall_close)
  1087. {
  1088. if (ch->GetMall())
  1089. {
  1090. ch->SetMallLoadTime(thecore_pulse());
  1091. ch->CloseMall();
  1092. ch->Save();
  1093. }
  1094. }
  1095.  
  1096. ACMD(do_ungroup)
  1097. {
  1098. if (!ch->GetParty())
  1099. return;
  1100.  
  1101. if (!CPartyManager::instance().IsEnablePCParty())
  1102. {
  1103. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<파티> 서버 문제로 파티 관련 처리를 할 수 없습니다."));
  1104. return;
  1105. }
  1106.  
  1107. if (ch->GetDungeon())
  1108. {
  1109. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<파티> 던전 안에서는 파티에서 나갈 수 없습니다."));
  1110. return;
  1111. }
  1112.  
  1113. #ifdef ENABLE_12ZI
  1114. if (ch->GetZodiac())
  1115. {
  1116. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can't break the group in the zodiac temple."));
  1117. return;
  1118. }
  1119.  
  1120. if (ch->GetMapIndex() >= 3580000 && ch->GetMapIndex() < 3590000)
  1121. {
  1122. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can't break the group in the zodiac temple."));
  1123. return;
  1124. }
  1125. #endif
  1126.  
  1127. LPPARTY pParty = ch->GetParty();
  1128.  
  1129. if (pParty->GetMemberCount() == 2)
  1130. {
  1131. // party disband
  1132. CPartyManager::instance().DeleteParty(pParty);
  1133. }
  1134. else
  1135. {
  1136. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<파티> 파티에서 나가셨습니다."));
  1137. //pParty->SendPartyRemoveOneToAll(ch);
  1138. pParty->Quit(ch->GetPlayerID());
  1139. //pParty->SendPartyRemoveAllToOne(ch);
  1140. }
  1141. }
  1142.  
  1143. ACMD(do_close_shop)
  1144. {
  1145. if (ch->GetMyShop())
  1146. {
  1147. ch->CloseMyShop();
  1148. return;
  1149. }
  1150. }
  1151.  
  1152. ACMD(do_set_walk_mode)
  1153. {
  1154. ch->SetNowWalking(true);
  1155. ch->SetWalking(true);
  1156. }
  1157.  
  1158. ACMD(do_set_run_mode)
  1159. {
  1160. ch->SetNowWalking(false);
  1161. ch->SetWalking(false);
  1162. }
  1163.  
  1164. ACMD(do_war)
  1165. {
  1166. //내 길드 정보를 얻어오고
  1167. CGuild * g = ch->GetGuild();
  1168.  
  1169. if (!g)
  1170. return;
  1171.  
  1172. //전쟁중인지 체크한번!
  1173. if (g->UnderAnyWar())
  1174. {
  1175. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 이미 다른 전쟁에 참전 중 입니다."));
  1176. return;
  1177. }
  1178.  
  1179. //파라메터를 두배로 나누고
  1180. char arg1[256], arg2[256];
  1181. DWORD type = GUILD_WAR_TYPE_FIELD; //fixme102 base int modded uint
  1182. two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  1183.  
  1184. if (!*arg1)
  1185. return;
  1186.  
  1187. if (*arg2)
  1188. {
  1189. str_to_number(type, arg2);
  1190.  
  1191. if (type >= GUILD_WAR_TYPE_MAX_NUM)
  1192. type = GUILD_WAR_TYPE_FIELD;
  1193. }
  1194.  
  1195. //길드의 마스터 아이디를 얻어온뒤
  1196. DWORD gm_pid = g->GetMasterPID();
  1197.  
  1198. //마스터인지 체크(길전은 길드장만이 가능)
  1199. if (gm_pid != ch->GetPlayerID())
  1200. {
  1201. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드전에 대한 권한이 없습니다."));
  1202. return;
  1203. }
  1204.  
  1205. //상대 길드를 얻어오고
  1206. CGuild * opp_g = CGuildManager::instance().FindGuildByName(arg1);
  1207.  
  1208. if (!opp_g)
  1209. {
  1210. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 그런 길드가 없습니다."));
  1211. return;
  1212. }
  1213.  
  1214. //상대길드와의 상태 체크
  1215. switch (g->GetGuildWarState(opp_g->GetID()))
  1216. {
  1217. case GUILD_WAR_NONE:
  1218. {
  1219. if (opp_g->UnderAnyWar())
  1220. {
  1221. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 상대방 길드가 이미 전쟁 중 입니다."));
  1222. return;
  1223. }
  1224.  
  1225. int iWarPrice = KOR_aGuildWarInfo[type].iWarPrice;
  1226.  
  1227. if (g->GetGuildMoney() < iWarPrice)
  1228. {
  1229. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 전비가 부족하여 길드전을 할 수 없습니다."));
  1230. return;
  1231. }
  1232.  
  1233. if (opp_g->GetGuildMoney() < iWarPrice)
  1234. {
  1235. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 상대방 길드의 전비가 부족하여 길드전을 할 수 없습니다."));
  1236. return;
  1237. }
  1238. }
  1239. break;
  1240.  
  1241. case GUILD_WAR_SEND_DECLARE:
  1242. {
  1243. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이미 선전포고 중인 길드입니다."));
  1244. return;
  1245. }
  1246. break;
  1247.  
  1248. case GUILD_WAR_RECV_DECLARE:
  1249. {
  1250. if (opp_g->UnderAnyWar())
  1251. {
  1252. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 상대방 길드가 이미 전쟁 중 입니다."));
  1253. g->RequestRefuseWar(opp_g->GetID());
  1254. return;
  1255. }
  1256. }
  1257. break;
  1258.  
  1259. case GUILD_WAR_RESERVE:
  1260. {
  1261. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 이미 전쟁이 예약된 길드 입니다."));
  1262. return;
  1263. }
  1264. break;
  1265.  
  1266. case GUILD_WAR_END:
  1267. return;
  1268.  
  1269. default:
  1270. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 이미 전쟁 중인 길드입니다."));
  1271. g->RequestRefuseWar(opp_g->GetID());
  1272. return;
  1273. }
  1274.  
  1275. if (!g->CanStartWar(type))
  1276. {
  1277. // 길드전을 할 수 있는 조건을 만족하지않는다.
  1278. if (g->GetLadderPoint() == 0)
  1279. {
  1280. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 레더 점수가 모자라서 길드전을 할 수 없습니다."));
  1281. sys_log(0, "GuildWar.StartError.NEED_LADDER_POINT");
  1282. }
  1283. else if (g->GetMemberCount() < GUILD_WAR_MIN_MEMBER_COUNT)
  1284. {
  1285. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드전을 하기 위해선 최소한 %d명이 있어야 합니다."), GUILD_WAR_MIN_MEMBER_COUNT);
  1286. sys_log(0, "GuildWar.StartError.NEED_MINIMUM_MEMBER[%d]", GUILD_WAR_MIN_MEMBER_COUNT);
  1287. }
  1288. else
  1289. {
  1290. sys_log(0, "GuildWar.StartError.UNKNOWN_ERROR");
  1291. }
  1292. return;
  1293. }
  1294.  
  1295. // 필드전 체크만 하고 세세한 체크는 상대방이 승낙할때 한다.
  1296. if (!opp_g->CanStartWar(GUILD_WAR_TYPE_FIELD))
  1297. {
  1298. if (opp_g->GetLadderPoint() == 0)
  1299. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 상대방 길드의 레더 점수가 모자라서 길드전을 할 수 없습니다."));
  1300. else if (opp_g->GetMemberCount() < GUILD_WAR_MIN_MEMBER_COUNT)
  1301. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 상대방 길드의 길드원 수가 부족하여 길드전을 할 수 없습니다."));
  1302. return;
  1303. }
  1304.  
  1305. do
  1306. {
  1307. if (g->GetMasterCharacter() != NULL)
  1308. break;
  1309.  
  1310. CCI *pCCI = P2P_MANAGER::instance().FindByPID(g->GetMasterPID());
  1311.  
  1312. if (pCCI != NULL)
  1313. break;
  1314.  
  1315. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 상대방 길드의 길드장이 접속중이 아닙니다."));
  1316. g->RequestRefuseWar(opp_g->GetID());
  1317. return;
  1318.  
  1319. } while (false);
  1320.  
  1321. do
  1322. {
  1323. if (opp_g->GetMasterCharacter() != NULL)
  1324. break;
  1325.  
  1326. CCI *pCCI = P2P_MANAGER::instance().FindByPID(opp_g->GetMasterPID());
  1327.  
  1328. if (pCCI != NULL)
  1329. break;
  1330.  
  1331. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 상대방 길드의 길드장이 접속중이 아닙니다."));
  1332. g->RequestRefuseWar(opp_g->GetID());
  1333. return;
  1334.  
  1335. } while (false);
  1336.  
  1337. g->RequestDeclareWar(opp_g->GetID(), type);
  1338. }
  1339.  
  1340. ACMD(do_nowar)
  1341. {
  1342. CGuild* g = ch->GetGuild();
  1343. if (!g)
  1344. return;
  1345.  
  1346. char arg1[256];
  1347. one_argument(argument, arg1, sizeof(arg1));
  1348.  
  1349. if (!*arg1)
  1350. return;
  1351.  
  1352. DWORD gm_pid = g->GetMasterPID();
  1353.  
  1354. if (gm_pid != ch->GetPlayerID())
  1355. {
  1356. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드전에 대한 권한이 없습니다."));
  1357. return;
  1358. }
  1359.  
  1360. CGuild* opp_g = CGuildManager::instance().FindGuildByName(arg1);
  1361.  
  1362. if (!opp_g)
  1363. {
  1364. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 그런 길드가 없습니다."));
  1365. return;
  1366. }
  1367.  
  1368. g->RequestRefuseWar(opp_g->GetID());
  1369. }
  1370.  
  1371. ACMD(do_detaillog)
  1372. {
  1373. ch->DetailLog();
  1374. }
  1375.  
  1376. ACMD(do_monsterlog)
  1377. {
  1378. ch->ToggleMonsterLog();
  1379. }
  1380.  
  1381. ACMD(do_pkmode)
  1382. {
  1383. char arg1[256];
  1384. one_argument(argument, arg1, sizeof(arg1));
  1385.  
  1386. if (!*arg1)
  1387. return;
  1388.  
  1389. BYTE mode = 0;
  1390. str_to_number(mode, arg1);
  1391.  
  1392. if (mode == PK_MODE_PROTECT)
  1393. return;
  1394.  
  1395. if (ch->GetLevel() < PK_PROTECT_LEVEL && mode != 0)
  1396. return;
  1397.  
  1398. #if defined(ENABLE_COMBAT_ZONE)
  1399. if (CCombatZoneManager::Instance().IsCombatZoneMap(ch->GetMapIndex()))
  1400. return;
  1401. #endif
  1402.  
  1403. ch->SetPKMode(mode);
  1404. }
  1405.  
  1406. ACMD(do_messenger_auth)
  1407. {
  1408. if (ch->GetArena())
  1409. {
  1410. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련장에서 사용하실 수 없습니다."));
  1411. return;
  1412. }
  1413.  
  1414. char arg1[256], arg2[256];
  1415. two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  1416.  
  1417. if (!*arg1 || !*arg2)
  1418. return;
  1419.  
  1420. char answer = LOWER(*arg1);
  1421. // @fixme130 AuthToAdd void -> bool
  1422. bool bIsDenied = answer != 'y';
  1423. bool bIsAdded = MessengerManager::instance().AuthToAdd(ch->GetName(), arg2, bIsDenied); // DENY
  1424. if (bIsAdded && bIsDenied)
  1425. {
  1426. LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg2);
  1427.  
  1428. if (tch)
  1429. tch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님으로 부터 친구 등록을 거부 당했습니다."), ch->GetName());
  1430. }
  1431.  
  1432. }
  1433.  
  1434. ACMD(do_setblockmode)
  1435. {
  1436. char arg1[256];
  1437. one_argument(argument, arg1, sizeof(arg1));
  1438.  
  1439. if (*arg1)
  1440. {
  1441. BYTE flag = 0;
  1442. str_to_number(flag, arg1);
  1443. ch->SetBlockMode(flag);
  1444. }
  1445. }
  1446.  
  1447. ACMD(do_unmount)
  1448. {
  1449. if (true == ch->UnEquipSpecialRideUniqueItem())
  1450. {
  1451. ch->RemoveAffect(AFFECT_MOUNT);
  1452. ch->RemoveAffect(AFFECT_MOUNT_BONUS);
  1453.  
  1454. if (ch->IsHorseRiding())
  1455. {
  1456. ch->StopRiding();
  1457. }
  1458. }
  1459. else
  1460. {
  1461. ch->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("인벤토리가 꽉 차서 내릴 수 없습니다."));
  1462. }
  1463.  
  1464. }
  1465.  
  1466. ACMD(do_observer_exit)
  1467. {
  1468. if (ch->IsObserverMode())
  1469. {
  1470. if (ch->GetWarMap())
  1471. ch->SetWarMap(NULL);
  1472.  
  1473. if (ch->GetArena() != NULL || ch->GetArenaObserverMode() == true)
  1474. {
  1475. ch->SetArenaObserverMode(false);
  1476.  
  1477. if (ch->GetArena() != NULL)
  1478. ch->GetArena()->RemoveObserver(ch->GetPlayerID());
  1479.  
  1480. ch->SetArena(NULL);
  1481. ch->WarpSet(ARENA_RETURN_POINT_X(ch->GetEmpire()), ARENA_RETURN_POINT_Y(ch->GetEmpire()));
  1482. }
  1483. else
  1484. {
  1485. ch->ExitToSavedLocation();
  1486. }
  1487. ch->SetObserverMode(false);
  1488. }
  1489. }
  1490.  
  1491. ACMD(do_view_equip)
  1492. {
  1493. if (ch->GetGMLevel() <= GM_PLAYER)
  1494. return;
  1495.  
  1496. char arg1[256];
  1497. one_argument(argument, arg1, sizeof(arg1));
  1498.  
  1499. if (*arg1)
  1500. {
  1501. DWORD vid = 0;
  1502. str_to_number(vid, arg1);
  1503. LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  1504.  
  1505. if (!tch)
  1506. return;
  1507.  
  1508. if (!tch->IsPC())
  1509. return;
  1510. /*
  1511. int iSPCost = ch->GetMaxSP() / 3;
  1512.  
  1513. if (ch->GetSP() < iSPCost)
  1514. {
  1515. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("정신력이 부족하여 다른 사람의 장비를 볼 수 없습니다."));
  1516. return;
  1517. }
  1518. ch->PointChange(POINT_SP, -iSPCost);
  1519. */
  1520. tch->SendEquipment(ch);
  1521. }
  1522. }
  1523.  
  1524. ACMD(do_party_request)
  1525. {
  1526. if (ch->GetArena())
  1527. {
  1528. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("대련장에서 사용하실 수 없습니다."));
  1529. return;
  1530. }
  1531.  
  1532. if (ch->GetParty())
  1533. {
  1534. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이미 파티에 속해 있으므로 가입신청을 할 수 없습니다."));
  1535. return;
  1536. }
  1537.  
  1538. char arg1[256];
  1539. one_argument(argument, arg1, sizeof(arg1));
  1540.  
  1541. if (!*arg1)
  1542. return;
  1543.  
  1544. DWORD vid = 0;
  1545. str_to_number(vid, arg1);
  1546. LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  1547.  
  1548. if (tch)
  1549. if (!ch->RequestToParty(tch))
  1550. ch->ChatPacket(CHAT_TYPE_COMMAND, "PartyRequestDenied");
  1551. }
  1552.  
  1553. ACMD(do_party_request_accept)
  1554. {
  1555. char arg1[256];
  1556. one_argument(argument, arg1, sizeof(arg1));
  1557.  
  1558. if (!*arg1)
  1559. return;
  1560.  
  1561. DWORD vid = 0;
  1562. str_to_number(vid, arg1);
  1563. LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  1564.  
  1565. if (tch)
  1566. ch->AcceptToParty(tch);
  1567. }
  1568.  
  1569. ACMD(do_party_request_deny)
  1570. {
  1571. char arg1[256];
  1572. one_argument(argument, arg1, sizeof(arg1));
  1573.  
  1574. if (!*arg1)
  1575. return;
  1576.  
  1577. DWORD vid = 0;
  1578. str_to_number(vid, arg1);
  1579. LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  1580.  
  1581. if (tch)
  1582. ch->DenyToParty(tch);
  1583. }
  1584.  
  1585. ACMD(do_monarch_warpto)
  1586. {
  1587. if (!CMonarch::instance().IsMonarch(ch->GetPlayerID(), ch->GetEmpire()))
  1588. {
  1589. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("군주만이 사용 가능한 기능입니다"));
  1590. return;
  1591. }
  1592.  
  1593. //군주 쿨타임 검사
  1594. if (!ch->IsMCOK(CHARACTER::MI_WARP))
  1595. {
  1596. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d 초간 쿨타임이 적용중입니다."), ch->GetMCLTime(CHARACTER::MI_WARP));
  1597. return;
  1598. }
  1599.  
  1600. //군주 몹 소환 비용
  1601. const int WarpPrice = 10000;
  1602.  
  1603. //군주 국고 검사
  1604. if (!CMonarch::instance().IsMoneyOk(WarpPrice, ch->GetEmpire()))
  1605. {
  1606. int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire());
  1607. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("국고에 돈이 부족합니다. 현재 : %u 필요금액 : %u"), NationMoney, WarpPrice);
  1608. return;
  1609. }
  1610.  
  1611. int x = 0, y = 0;
  1612. char arg1[256];
  1613.  
  1614. one_argument(argument, arg1, sizeof(arg1));
  1615.  
  1616. if (!*arg1)
  1617. {
  1618. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("사용법: warpto <character name>"));
  1619. return;
  1620. }
  1621.  
  1622. LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  1623.  
  1624. if (!tch)
  1625. {
  1626. CCI * pkCCI = P2P_MANAGER::instance().Find(arg1);
  1627.  
  1628. if (pkCCI)
  1629. {
  1630. if (pkCCI->bEmpire != ch->GetEmpire())
  1631. {
  1632. ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("타제국 유저에게는 이동할수 없습니다"));
  1633. return;
  1634. }
  1635.  
  1636. if (pkCCI->bChannel != g_bChannel)
  1637. {
  1638. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("해당 유저는 %d 채널에 있습니다. (현재 채널 %d)"), pkCCI->bChannel, g_bChannel);
  1639. return;
  1640. }
  1641. if (!IsMonarchWarpZone(pkCCI->lMapIndex))
  1642. {
  1643. ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("해당 지역으로 이동할 수 없습니다."));
  1644. return;
  1645. }
  1646.  
  1647. PIXEL_POSITION pos;
  1648.  
  1649. if (!SECTREE_MANAGER::instance().GetCenterPositionOfMap(pkCCI->lMapIndex, pos))
  1650. ch->ChatPacket(CHAT_TYPE_INFO, "Cannot find map (index %d)", pkCCI->lMapIndex);
  1651. else
  1652. {
  1653. //ch->ChatPacket(CHAT_TYPE_INFO, "You warp to (%d, %d)", pos.x, pos.y);
  1654. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 에게로 이동합니다"), arg1);
  1655. ch->WarpSet(pos.x, pos.y);
  1656.  
  1657. //군주 돈 삭감
  1658. CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch);
  1659.  
  1660. //쿨타임 초기화
  1661. ch->SetMC(CHARACTER::MI_WARP);
  1662. }
  1663. }
  1664. else if (NULL == CHARACTER_MANAGER::instance().FindPC(arg1))
  1665. {
  1666. ch->ChatPacket(CHAT_TYPE_INFO, "There is no one by that name");
  1667. }
  1668.  
  1669. return;
  1670. }
  1671. else
  1672. {
  1673. if (tch->GetEmpire() != ch->GetEmpire())
  1674. {
  1675. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("타제국 유저에게는 이동할수 없습니다"));
  1676. return;
  1677. }
  1678. if (!IsMonarchWarpZone(tch->GetMapIndex()))
  1679. {
  1680. ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("해당 지역으로 이동할 수 없습니다."));
  1681. return;
  1682. }
  1683. x = tch->GetX();
  1684. y = tch->GetY();
  1685. }
  1686.  
  1687. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 에게로 이동합니다"), arg1);
  1688. ch->WarpSet(x, y);
  1689. ch->Stop();
  1690.  
  1691. //군주 돈 삭감
  1692. CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch);
  1693.  
  1694. //쿨타임 초기화
  1695. ch->SetMC(CHARACTER::MI_WARP);
  1696. }
  1697.  
  1698. ACMD(do_monarch_transfer)
  1699. {
  1700. char arg1[256];
  1701. one_argument(argument, arg1, sizeof(arg1));
  1702.  
  1703. if (!*arg1)
  1704. {
  1705. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("사용법: transfer <name>"));
  1706. return;
  1707. }
  1708.  
  1709. if (!CMonarch::instance().IsMonarch(ch->GetPlayerID(), ch->GetEmpire()))
  1710. {
  1711. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("군주만이 사용 가능한 기능입니다"));
  1712. return;
  1713. }
  1714.  
  1715. //군주 쿨타임 검사
  1716. if (!ch->IsMCOK(CHARACTER::MI_TRANSFER))
  1717. {
  1718. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d 초간 쿨타임이 적용중입니다."), ch->GetMCLTime(CHARACTER::MI_TRANSFER));
  1719. return;
  1720. }
  1721.  
  1722. //군주 워프 비용
  1723. const int WarpPrice = 10000;
  1724.  
  1725. //군주 국고 검사
  1726. if (!CMonarch::instance().IsMoneyOk(WarpPrice, ch->GetEmpire()))
  1727. {
  1728. int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire());
  1729. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("국고에 돈이 부족합니다. 현재 : %u 필요금액 : %u"), NationMoney, WarpPrice);
  1730. return;
  1731. }
  1732.  
  1733.  
  1734. LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  1735.  
  1736. if (!tch)
  1737. {
  1738. CCI * pkCCI = P2P_MANAGER::instance().Find(arg1);
  1739.  
  1740. if (pkCCI)
  1741. {
  1742. if (pkCCI->bEmpire != ch->GetEmpire())
  1743. {
  1744. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("다른 제국 유저는 소환할 수 없습니다."));
  1745. return;
  1746. }
  1747. if (pkCCI->bChannel != g_bChannel)
  1748. {
  1749. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님은 %d 채널에 접속 중 입니다. (현재 채널: %d)"), arg1, pkCCI->bChannel, g_bChannel);
  1750. return;
  1751. }
  1752. if (!IsMonarchWarpZone(pkCCI->lMapIndex))
  1753. {
  1754. ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("해당 지역으로 이동할 수 없습니다."));
  1755. return;
  1756. }
  1757. if (!IsMonarchWarpZone(ch->GetMapIndex()))
  1758. {
  1759. ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("해당 지역으로 소환할 수 없습니다."));
  1760. return;
  1761. }
  1762.  
  1763. TPacketGGTransfer pgg;
  1764.  
  1765. pgg.bHeader = HEADER_GG_TRANSFER;
  1766. strlcpy(pgg.szName, arg1, sizeof(pgg.szName));
  1767. pgg.lX = ch->GetX();
  1768. pgg.lY = ch->GetY();
  1769.  
  1770. P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGTransfer));
  1771. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님을 소환하였습니다."), arg1);
  1772.  
  1773. //군주 돈 삭감
  1774. CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch);
  1775. //쿨타임 초기화
  1776. ch->SetMC(CHARACTER::MI_TRANSFER);
  1777. }
  1778. else
  1779. {
  1780. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("입력하신 이름을 가진 사용자가 없습니다."));
  1781. }
  1782.  
  1783. return;
  1784. }
  1785.  
  1786.  
  1787. if (ch == tch)
  1788. {
  1789. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("자신을 소환할 수 없습니다."));
  1790. return;
  1791. }
  1792.  
  1793. if (tch->GetEmpire() != ch->GetEmpire())
  1794. {
  1795. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("다른 제국 유저는 소환할 수 없습니다."));
  1796. return;
  1797. }
  1798. if (!IsMonarchWarpZone(tch->GetMapIndex()))
  1799. {
  1800. ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("해당 지역으로 이동할 수 없습니다."));
  1801. return;
  1802. }
  1803. if (!IsMonarchWarpZone(ch->GetMapIndex()))
  1804. {
  1805. ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("해당 지역으로 소환할 수 없습니다."));
  1806. return;
  1807. }
  1808.  
  1809. //tch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ());
  1810. tch->WarpSet(ch->GetX(), ch->GetY(), ch->GetMapIndex());
  1811.  
  1812. //군주 돈 삭감
  1813. CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch);
  1814. //쿨타임 초기화
  1815. ch->SetMC(CHARACTER::MI_TRANSFER);
  1816. }
  1817.  
  1818. ACMD(do_monarch_info)
  1819. {
  1820. if (CMonarch::instance().IsMonarch(ch->GetPlayerID(), ch->GetEmpire()))
  1821. {
  1822. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("나의 군주 정보"));
  1823. TMonarchInfo * p = CMonarch::instance().GetMonarch();
  1824. for (int n = 1; n < 4; ++n)
  1825. {
  1826. if (n == ch->GetEmpire())
  1827. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("[%s군주] : %s 보유금액 %lld "), EMPIRE_NAME(n), p->name[n], p->money[n]);
  1828. else
  1829. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("[%s군주] : %s "), EMPIRE_NAME(n), p->name[n]);
  1830.  
  1831. }
  1832. }
  1833. else
  1834. {
  1835. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("군주 정보"));
  1836. TMonarchInfo * p = CMonarch::instance().GetMonarch();
  1837. for (int n = 1; n < 4; ++n)
  1838. {
  1839. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("[%s군주] : %s "), EMPIRE_NAME(n), p->name[n]);
  1840.  
  1841. }
  1842. }
  1843.  
  1844. }
  1845.  
  1846. ACMD(do_elect)
  1847. {
  1848. db_clientdesc->DBPacketHeader(HEADER_GD_COME_TO_VOTE, ch->GetDesc()->GetHandle(), 0);
  1849. }
  1850.  
  1851. // LUA_ADD_GOTO_INFO
  1852. struct GotoInfo
  1853. {
  1854. std::string st_name;
  1855.  
  1856. BYTE empire;
  1857. int mapIndex;
  1858. DWORD x, y;
  1859.  
  1860. GotoInfo()
  1861. {
  1862. st_name = "";
  1863. empire = 0;
  1864. mapIndex = 0;
  1865.  
  1866. x = 0;
  1867. y = 0;
  1868. }
  1869.  
  1870. GotoInfo(const GotoInfo& c_src)
  1871. {
  1872. __copy__(c_src);
  1873. }
  1874.  
  1875. void operator = (const GotoInfo& c_src)
  1876. {
  1877. __copy__(c_src);
  1878. }
  1879.  
  1880. void __copy__(const GotoInfo& c_src)
  1881. {
  1882. st_name = c_src.st_name;
  1883. empire = c_src.empire;
  1884. mapIndex = c_src.mapIndex;
  1885.  
  1886. x = c_src.x;
  1887. y = c_src.y;
  1888. }
  1889. };
  1890.  
  1891. ACMD(do_monarch_tax)
  1892. {
  1893. char arg1[256];
  1894. one_argument(argument, arg1, sizeof(arg1));
  1895.  
  1896. if (!*arg1)
  1897. {
  1898. ch->ChatPacket(CHAT_TYPE_INFO, "Usage: monarch_tax <1-50>");
  1899. return;
  1900. }
  1901.  
  1902. // 군주 검사
  1903. if (!ch->IsMonarch())
  1904. {
  1905. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("군주만이 사용할수 있는 기능입니다"));
  1906. return;
  1907. }
  1908.  
  1909. // 세금설정
  1910. int tax = 0;
  1911. str_to_number(tax, arg1);
  1912.  
  1913. if (tax < 1 || tax > 50)
  1914. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("1-50 사이의 수치를 선택해주세요"));
  1915.  
  1916. quest::CQuestManager::instance().SetEventFlag("trade_tax", tax);
  1917.  
  1918. // 군주에게 메세지 하나
  1919. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("세금이 %d %로 설정되었습니다"));
  1920.  
  1921. // 공지
  1922. char szMsg[1024];
  1923.  
  1924. snprintf(szMsg, sizeof(szMsg), "군주의 명으로 세금이 %d %% 로 변경되었습니다", tax);
  1925. BroadcastNotice(szMsg);
  1926.  
  1927. snprintf(szMsg, sizeof(szMsg), "앞으로는 거래 금액의 %d %% 가 국고로 들어가게됩니다.", tax);
  1928. BroadcastNotice(szMsg);
  1929.  
  1930. // 쿨타임 초기화
  1931. ch->SetMC(CHARACTER::MI_TAX);
  1932. }
  1933.  
  1934. static const DWORD cs_dwMonarchMobVnums[] =
  1935. {
  1936. 191, // 산견신
  1937. 192, // 저신
  1938. 193, // 웅신
  1939. 194, // 호신
  1940. 391, // 미정
  1941. 392, // 은정
  1942. 393, // 세랑
  1943. 394, // 진희
  1944. 491, // 맹환
  1945. 492, // 보우
  1946. 493, // 구패
  1947. 494, // 추흔
  1948. 591, // 비류단대장
  1949. 691, // 웅귀 족장
  1950. 791, // 밀교교주
  1951. 1304, // 누렁범귀
  1952. 1901, // 구미호
  1953. 2091, // 여왕거미
  1954. 2191, // 거대사막거북
  1955. 2206, // 화염왕i
  1956. 0,
  1957. };
  1958.  
  1959. ACMD(do_monarch_mob)
  1960. {
  1961. char arg1[256];
  1962. LPCHARACTER tch;
  1963.  
  1964. one_argument(argument, arg1, sizeof(arg1));
  1965.  
  1966. if (!ch->IsMonarch())
  1967. {
  1968. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("군주만이 사용할수 있는 기능입니다"));
  1969. return;
  1970. }
  1971.  
  1972. if (!*arg1)
  1973. {
  1974. ch->ChatPacket(CHAT_TYPE_INFO, "Usage: mmob <mob name>");
  1975. return;
  1976. }
  1977.  
  1978. #ifdef ENABLE_MONARCH_MOB_CMD_MAP_CHECK // @warme006
  1979. BYTE pcEmpire = ch->GetEmpire();
  1980. BYTE mapEmpire = SECTREE_MANAGER::instance().GetEmpireFromMapIndex(ch->GetMapIndex());
  1981. if (mapEmpire != pcEmpire && mapEmpire != 0)
  1982. {
  1983. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("자국 영토에서만 사용할 수 있는 기능입니다"));
  1984. return;
  1985. }
  1986. #endif
  1987.  
  1988. // 군주 몹 소환 비용
  1989. const int SummonPrice = 5000000;
  1990.  
  1991. // 군주 쿨타임 검사
  1992. if (!ch->IsMCOK(CHARACTER::MI_SUMMON))
  1993. {
  1994. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d 초간 쿨타임이 적용중입니다."), ch->GetMCLTime(CHARACTER::MI_SUMMON));
  1995. return;
  1996. }
  1997.  
  1998. // 군주 국고 검사
  1999. if (!CMonarch::instance().IsMoneyOk(SummonPrice, ch->GetEmpire()))
  2000. {
  2001. int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire());
  2002. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("국고에 돈이 부족합니다. 현재 : %u 필요금액 : %u"), NationMoney, SummonPrice);
  2003. return;
  2004. }
  2005.  
  2006. const CMob * pkMob;
  2007. DWORD vnum = 0;
  2008.  
  2009. if (isdigit(*arg1))
  2010. {
  2011. str_to_number(vnum, arg1);
  2012.  
  2013. if ((pkMob = CMobManager::instance().Get(vnum)) == NULL)
  2014. vnum = 0;
  2015. }
  2016. else
  2017. {
  2018. pkMob = CMobManager::Instance().Get(arg1, true);
  2019.  
  2020. if (pkMob)
  2021. vnum = pkMob->m_table.dwVnum;
  2022. }
  2023.  
  2024. DWORD count;
  2025.  
  2026. // 소환 가능 몹 검사
  2027. for (count = 0; cs_dwMonarchMobVnums[count] != 0; ++count)
  2028. if (cs_dwMonarchMobVnums[count] == vnum)
  2029. break;
  2030.  
  2031. if (0 == cs_dwMonarchMobVnums[count])
  2032. {
  2033. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소환할수 없는 몬스터 입니다. 소환가능한 몬스터는 홈페이지를 참조하세요"));
  2034. return;
  2035. }
  2036.  
  2037. tch = CHARACTER_MANAGER::instance().SpawnMobRange(vnum,
  2038. ch->GetMapIndex(),
  2039. ch->GetX() - number(200, 750),
  2040. ch->GetY() - number(200, 750),
  2041. ch->GetX() + number(200, 750),
  2042. ch->GetY() + number(200, 750),
  2043. true,
  2044. pkMob->m_table.bType == CHAR_TYPE_STONE,
  2045. true);
  2046.  
  2047. if (tch)
  2048. {
  2049. // 군주 돈 삭감
  2050. CMonarch::instance().SendtoDBDecMoney(SummonPrice, ch->GetEmpire(), ch);
  2051.  
  2052. // 쿨타임 초기화
  2053. ch->SetMC(CHARACTER::MI_SUMMON);
  2054. }
  2055. }
  2056.  
  2057. static const char* FN_point_string(int apply_number)
  2058. {
  2059. switch (apply_number)
  2060. {
  2061. case POINT_MAX_HP: return LC_TEXT("최대 생명력 +%d");
  2062. case POINT_MAX_SP: return LC_TEXT("최대 정신력 +%d");
  2063. case POINT_HT: return LC_TEXT("체력 +%d");
  2064. case POINT_IQ: return LC_TEXT("지능 +%d");
  2065. case POINT_ST: return LC_TEXT("근력 +%d");
  2066. case POINT_DX: return LC_TEXT("민첩 +%d");
  2067. case POINT_ATT_SPEED: return LC_TEXT("공격속도 +%d");
  2068. case POINT_MOV_SPEED: return LC_TEXT("이동속도 %d");
  2069. case POINT_CASTING_SPEED: return LC_TEXT("쿨타임 -%d");
  2070. case POINT_HP_REGEN: return LC_TEXT("생명력 회복 +%d");
  2071. case POINT_SP_REGEN: return LC_TEXT("정신력 회복 +%d");
  2072. case POINT_POISON_PCT: return LC_TEXT("독공격 %d");
  2073. #ifdef ENABLE_WOLFMAN_CHARACTER
  2074. case POINT_BLEEDING_PCT: return LC_TEXT("독공격 %d");
  2075. #endif
  2076. case POINT_STUN_PCT: return LC_TEXT("스턴 +%d");
  2077. case POINT_SLOW_PCT: return LC_TEXT("슬로우 +%d");
  2078. case POINT_CRITICAL_PCT: return LC_TEXT("%d%% 확률로 치명타 공격");
  2079. case POINT_RESIST_CRITICAL: return LC_TEXT("상대의 치명타 확률 %d%% 감소");
  2080. case POINT_PENETRATE_PCT: return LC_TEXT("%d%% 확률로 관통 공격");
  2081. case POINT_RESIST_PENETRATE: return LC_TEXT("상대의 관통 공격 확률 %d%% 감소");
  2082. case POINT_ATTBONUS_HUMAN: return LC_TEXT("인간류 몬스터 타격치 +%d%%");
  2083. case POINT_ATTBONUS_ANIMAL: return LC_TEXT("동물류 몬스터 타격치 +%d%%");
  2084. case POINT_ATTBONUS_ORC: return LC_TEXT("웅귀족 타격치 +%d%%");
  2085. case POINT_ATTBONUS_MILGYO: return LC_TEXT("밀교류 타격치 +%d%%");
  2086. case POINT_ATTBONUS_UNDEAD: return LC_TEXT("시체류 타격치 +%d%%");
  2087. case POINT_ATTBONUS_DEVIL: return LC_TEXT("악마류 타격치 +%d%%");
  2088. case POINT_STEAL_HP: return LC_TEXT("타격치 %d%% 를 생명력으로 흡수");
  2089. case POINT_STEAL_SP: return LC_TEXT("타력치 %d%% 를 정신력으로 흡수");
  2090. case POINT_MANA_BURN_PCT: return LC_TEXT("%d%% 확률로 타격시 상대 전신력 소모");
  2091. case POINT_DAMAGE_SP_RECOVER: return LC_TEXT("%d%% 확률로 피해시 정신력 회복");
  2092. case POINT_BLOCK: return LC_TEXT("물리타격시 블럭 확률 %d%%");
  2093. case POINT_DODGE: return LC_TEXT("활 공격 회피 확률 %d%%");
  2094. case POINT_RESIST_SWORD: return LC_TEXT("한손검 방어 %d%%");
  2095. case POINT_RESIST_TWOHAND: return LC_TEXT("양손검 방어 %d%%");
  2096. case POINT_RESIST_DAGGER: return LC_TEXT("두손검 방어 %d%%");
  2097. case POINT_RESIST_BELL: return LC_TEXT("방울 방어 %d%%");
  2098. case POINT_RESIST_FAN: return LC_TEXT("부채 방어 %d%%");
  2099. case POINT_RESIST_BOW: return LC_TEXT("활공격 저항 %d%%");
  2100. #ifdef ENABLE_WOLFMAN_CHARACTER
  2101. case POINT_RESIST_CLAW: return LC_TEXT("두손검 방어 %d%%");
  2102. #endif
  2103. case POINT_RESIST_FIRE: return LC_TEXT("화염 저항 %d%%");
  2104. case POINT_RESIST_ELEC: return LC_TEXT("전기 저항 %d%%");
  2105. case POINT_RESIST_MAGIC: return LC_TEXT("마법 저항 %d%%");
  2106. #ifdef ENABLE_MAGIC_REDUCTION_SYSTEM
  2107. case POINT_RESIST_MAGIC_REDUCTION: return LC_TEXT("마법 저항 %d%%");
  2108. #endif
  2109. case POINT_RESIST_WIND: return LC_TEXT("바람 저항 %d%%");
  2110. case POINT_RESIST_ICE: return LC_TEXT("냉기 저항 %d%%");
  2111. case POINT_RESIST_EARTH: return LC_TEXT("대지 저항 %d%%");
  2112. case POINT_RESIST_DARK: return LC_TEXT("어둠 저항 %d%%");
  2113. case POINT_REFLECT_MELEE: return LC_TEXT("직접 타격치 반사 확률 : %d%%");
  2114. case POINT_REFLECT_CURSE: return LC_TEXT("저주 되돌리기 확률 %d%%");
  2115. case POINT_POISON_REDUCE: return LC_TEXT("독 저항 %d%%");
  2116. #ifdef ENABLE_WOLFMAN_CHARACTER
  2117. case POINT_BLEEDING_REDUCE: return LC_TEXT("독 저항 %d%%");
  2118. #endif
  2119. case POINT_KILL_SP_RECOVER: return LC_TEXT("%d%% 확률로 적퇴치시 정신력 회복");
  2120. case POINT_EXP_DOUBLE_BONUS: return LC_TEXT("%d%% 확률로 적퇴치시 경험치 추가 상승");
  2121. case POINT_GOLD_DOUBLE_BONUS: return LC_TEXT("%d%% 확률로 적퇴치시 돈 2배 드롭");
  2122. case POINT_ITEM_DROP_BONUS: return LC_TEXT("%d%% 확률로 적퇴치시 아이템 2배 드롭");
  2123. case POINT_POTION_BONUS: return LC_TEXT("물약 사용시 %d%% 성능 증가");
  2124. case POINT_KILL_HP_RECOVERY: return LC_TEXT("%d%% 확률로 적퇴치시 생명력 회복");
  2125. // case POINT_IMMUNE_STUN: return LC_TEXT("기절하지 않음 %d%%");
  2126. // case POINT_IMMUNE_SLOW: return LC_TEXT("느려지지 않음 %d%%");
  2127. // case POINT_IMMUNE_FALL: return LC_TEXT("넘어지지 않음 %d%%");
  2128. // case POINT_SKILL: return LC_TEXT("");
  2129. // case POINT_BOW_DISTANCE: return LC_TEXT("");
  2130. case POINT_ATT_GRADE_BONUS: return LC_TEXT("공격력 +%d");
  2131. case POINT_DEF_GRADE_BONUS: return LC_TEXT("방어력 +%d");
  2132. case POINT_MAGIC_ATT_GRADE: return LC_TEXT("마법 공격력 +%d");
  2133. case POINT_MAGIC_DEF_GRADE: return LC_TEXT("마법 방어력 +%d");
  2134. // case POINT_CURSE_PCT: return LC_TEXT("");
  2135. case POINT_MAX_STAMINA: return LC_TEXT("최대 지구력 +%d");
  2136. case POINT_ATTBONUS_WARRIOR: return LC_TEXT("무사에게 강함 +%d%%");
  2137. case POINT_ATTBONUS_ASSASSIN: return LC_TEXT("자객에게 강함 +%d%%");
  2138. case POINT_ATTBONUS_SURA: return LC_TEXT("수라에게 강함 +%d%%");
  2139. case POINT_ATTBONUS_SHAMAN: return LC_TEXT("무당에게 강함 +%d%%");
  2140. #ifdef ENABLE_WOLFMAN_CHARACTER
  2141. case POINT_ATTBONUS_WOLFMAN: return LC_TEXT("무당에게 강함 +%d%%");
  2142. #endif
  2143. case POINT_ATTBONUS_MONSTER: return LC_TEXT("몬스터에게 강함 +%d%%");
  2144. case POINT_MALL_ATTBONUS: return LC_TEXT("공격력 +%d%%");
  2145. case POINT_MALL_DEFBONUS: return LC_TEXT("방어력 +%d%%");
  2146. case POINT_MALL_EXPBONUS: return LC_TEXT("경험치 %d%%");
  2147. case POINT_MALL_ITEMBONUS: return LC_TEXT("아이템 드롭율 %.1f배");
  2148. case POINT_MALL_GOLDBONUS: return LC_TEXT("돈 드롭율 %.1f배");
  2149. case POINT_MAX_HP_PCT: return LC_TEXT("최대 생명력 +%d%%");
  2150. case POINT_MAX_SP_PCT: return LC_TEXT("최대 정신력 +%d%%");
  2151. case POINT_SKILL_DAMAGE_BONUS: return LC_TEXT("스킬 데미지 %d%%");
  2152. case POINT_NORMAL_HIT_DAMAGE_BONUS: return LC_TEXT("평타 데미지 %d%%");
  2153. case POINT_SKILL_DEFEND_BONUS: return LC_TEXT("스킬 데미지 저항 %d%%");
  2154. case POINT_NORMAL_HIT_DEFEND_BONUS: return LC_TEXT("평타 데미지 저항 %d%%");
  2155. // case POINT_PC_BANG_EXP_BONUS: return LC_TEXT("");
  2156. // case POINT_PC_BANG_DROP_BONUS: return LC_TEXT("");
  2157. // case POINT_EXTRACT_HP_PCT: return LC_TEXT("");
  2158. case POINT_RESIST_WARRIOR: return LC_TEXT("무사공격에 %d%% 저항");
  2159. case POINT_RESIST_ASSASSIN: return LC_TEXT("자객공격에 %d%% 저항");
  2160. case POINT_RESIST_SURA: return LC_TEXT("수라공격에 %d%% 저항");
  2161. case POINT_RESIST_SHAMAN: return LC_TEXT("무당공격에 %d%% 저항");
  2162. #ifdef ENABLE_WOLFMAN_CHARACTER
  2163. case POINT_RESIST_WOLFMAN: return LC_TEXT("무당공격에 %d%% 저항");
  2164. #endif
  2165. #ifdef ENABLE_PENDANT
  2166. case POINT_ATTBONUS_SWORD: return LC_TEXT("Anti Magic1 Resistance %d%%");
  2167. case POINT_ATTBONUS_TWOHAND: return LC_TEXT("Anti Magic2 Resistance %d%%");
  2168. case POINT_ATTBONUS_DAGGER: return LC_TEXT("Anti Magic3 Resistance %d%%");
  2169. case POINT_ATTBONUS_BELL: return LC_TEXT("Anti Magic4 Resistance %d%%");
  2170. case POINT_ATTBONUS_FAN: return LC_TEXT("Anti Magic5 Resistance %d%%");
  2171. case POINT_ATTBONUS_BOW: return LC_TEXT("Anti Magic6 Resistance %d%%");
  2172. case POINT_ATTBONUS_CLAW: return LC_TEXT("Anti Magic7 Resistance %d%%");
  2173. #endif
  2174. default: return NULL;
  2175. }
  2176. }
  2177.  
  2178. static bool FN_hair_affect_string(LPCHARACTER ch, char *buf, size_t bufsiz)
  2179. {
  2180. if (NULL == ch || NULL == buf)
  2181. return false;
  2182.  
  2183. CAffect* aff = NULL;
  2184. time_t expire = 0;
  2185. struct tm ltm;
  2186. int year, mon, day;
  2187. int offset = 0;
  2188.  
  2189. aff = ch->FindAffect(AFFECT_HAIR);
  2190.  
  2191. if (NULL == aff)
  2192. return false;
  2193.  
  2194. expire = ch->GetQuestFlag("hair.limit_time");
  2195.  
  2196. if (expire < get_global_time())
  2197. return false;
  2198.  
  2199. // set apply string
  2200. offset = snprintf(buf, bufsiz, FN_point_string(aff->bApplyOn), aff->lApplyValue);
  2201.  
  2202. if (offset < 0 || offset >= (int) bufsiz)
  2203. offset = bufsiz - 1;
  2204.  
  2205. localtime_r(&expire, &ltm);
  2206.  
  2207. year = ltm.tm_year + 1900;
  2208. mon = ltm.tm_mon + 1;
  2209. day = ltm.tm_mday;
  2210.  
  2211. snprintf(buf + offset, bufsiz - offset, LC_TEXT(" (만료일 : %d년 %d월 %d일)"), year, mon, day);
  2212.  
  2213. return true;
  2214. }
  2215.  
  2216. ACMD(do_costume)
  2217. {
  2218. char buf[512];
  2219. const size_t bufferSize = sizeof(buf);
  2220.  
  2221. char arg1[256];
  2222. one_argument(argument, arg1, sizeof(arg1));
  2223.  
  2224. CItem* pBody = ch->GetWear(WEAR_COSTUME_BODY);
  2225. CItem* pHair = ch->GetWear(WEAR_COSTUME_HAIR);
  2226. #ifdef ENABLE_MOUNT_COSTUME_SYSTEM
  2227. CItem* pMount = ch->GetWear(WEAR_COSTUME_MOUNT);
  2228. #endif
  2229. #ifdef ENABLE_ACCE_COSTUME_SYSTEM
  2230. CItem* pAcce = ch->GetWear(WEAR_COSTUME_ACCE);
  2231. #endif
  2232. #ifdef ENABLE_WEAPON_COSTUME_SYSTEM
  2233. CItem* pWeapon = ch->GetWear(WEAR_COSTUME_WEAPON);
  2234. #endif
  2235.  
  2236. ch->ChatPacket(CHAT_TYPE_INFO, "COSTUME status:");
  2237.  
  2238. if (pHair)
  2239. {
  2240. const char* itemName = pHair->GetName();
  2241. ch->ChatPacket(CHAT_TYPE_INFO, " HAIR : %s", itemName);
  2242.  
  2243. for (int i = 0; i < pHair->GetAttributeCount(); ++i)
  2244. {
  2245. const TPlayerItemAttribute& attr = pHair->GetAttribute(i);
  2246. if (0 < attr.bType)
  2247. {
  2248. snprintf(buf, bufferSize, FN_point_string(attr.bType), attr.sValue);
  2249. ch->ChatPacket(CHAT_TYPE_INFO, " %s", buf);
  2250. }
  2251. }
  2252.  
  2253. if (pHair->IsEquipped() && arg1[0] == 'h')
  2254. ch->UnequipItem(pHair);
  2255. }
  2256.  
  2257. if (pBody)
  2258. {
  2259. const char* itemName = pBody->GetName();
  2260. ch->ChatPacket(CHAT_TYPE_INFO, " BODY : %s", itemName);
  2261.  
  2262. if (pBody->IsEquipped() && arg1[0] == 'b')
  2263. ch->UnequipItem(pBody);
  2264. }
  2265.  
  2266. #ifdef ENABLE_MOUNT_COSTUME_SYSTEM
  2267. if (pMount)
  2268. {
  2269. const char* itemName = pMount->GetName();
  2270. ch->ChatPacket(CHAT_TYPE_INFO, " MOUNT : %s", itemName);
  2271.  
  2272. if (pMount->IsEquipped() && arg1[0] == 'm')
  2273. ch->UnequipItem(pMount);
  2274. }
  2275. #endif
  2276.  
  2277. #ifdef ENABLE_ACCE_COSTUME_SYSTEM
  2278. if (pAcce)
  2279. {
  2280. const char * itemName = pAcce->GetName();
  2281. ch->ChatPacket(CHAT_TYPE_INFO, " ACCE: %s", itemName);
  2282. for (int i = 0; i < pAcce->GetAttributeCount(); ++i)
  2283. {
  2284. const TPlayerItemAttribute& attr = pAcce->GetAttribute(i);
  2285. if (attr.bType > 0)
  2286. {
  2287. const char * pAttrName = FN_point_string(attr.bType);
  2288. if (pAttrName == NULL)
  2289. continue;
  2290.  
  2291. snprintf(buf, sizeof(buf), FN_point_string(attr.bType), attr.sValue);
  2292. ch->ChatPacket(CHAT_TYPE_INFO, " %s", buf);
  2293. }
  2294. }
  2295.  
  2296. if (pAcce->IsEquipped() && arg1[0] == 's')
  2297. ch->UnequipItem(pAcce);
  2298. }
  2299. #endif
  2300.  
  2301. #ifdef ENABLE_WEAPON_COSTUME_SYSTEM
  2302. if (pWeapon)
  2303. {
  2304. const char* itemName = pWeapon->GetName();
  2305. ch->ChatPacket(CHAT_TYPE_INFO, " WEAPON : %s", itemName);
  2306.  
  2307. if (pWeapon->IsEquipped() && arg1[0] == 'w')
  2308. ch->UnequipItem(pWeapon);
  2309. }
  2310. #endif
  2311. }
  2312.  
  2313. ACMD(do_hair)
  2314. {
  2315. char buf[256];
  2316.  
  2317. if (false == FN_hair_affect_string(ch, buf, sizeof(buf)))
  2318. return;
  2319.  
  2320. ch->ChatPacket(CHAT_TYPE_INFO, buf);
  2321. }
  2322.  
  2323. ACMD(do_inventory)
  2324. {
  2325. int index = 0;
  2326. int count = 1;
  2327.  
  2328. char arg1[256];
  2329. char arg2[256];
  2330.  
  2331. LPITEM item;
  2332.  
  2333. two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2334.  
  2335. if (!*arg1)
  2336. {
  2337. ch->ChatPacket(CHAT_TYPE_INFO, "Usage: inventory <start_index> <count>");
  2338. return;
  2339. }
  2340.  
  2341. if (!*arg2)
  2342. {
  2343. index = 0;
  2344. str_to_number(count, arg1);
  2345. }
  2346. else
  2347. {
  2348. str_to_number(index, arg1); index = MIN(index, INVENTORY_MAX_NUM);
  2349. str_to_number(count, arg2); count = MIN(count, INVENTORY_MAX_NUM);
  2350. }
  2351.  
  2352. for (int i = 0; i < count; ++i)
  2353. {
  2354. if (index >= INVENTORY_MAX_NUM)
  2355. break;
  2356.  
  2357. item = ch->GetInventoryItem(index);
  2358.  
  2359. ch->ChatPacket(CHAT_TYPE_INFO, "inventory [%d] = %s",
  2360. index, item ? item->GetName() : "<NONE>");
  2361. ++index;
  2362. }
  2363. }
  2364.  
  2365. #ifdef ENABLE_ATTR_TRANSFER_SYSTEM
  2366. ACMD(do_attr_transfer)
  2367. {
  2368. if (!ch->CanDoAttrTransfer())
  2369. return;
  2370.  
  2371. sys_log(1, "%s has used an Attr Transfer command: %s.", ch->GetName(), argument);
  2372.  
  2373. int w_index = 0, i_index = 0;
  2374. const char *line;
  2375. char arg1[256], arg2[256], arg3[256];
  2376. line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2377. one_argument(line, arg3, sizeof(arg3));
  2378. if (0 == arg1[0])
  2379. {
  2380. ch->ChatPacket(CHAT_TYPE_INFO, "Usage:");
  2381. ch->ChatPacket(CHAT_TYPE_INFO, "- attrtransfer open");
  2382. ch->ChatPacket(CHAT_TYPE_INFO, "- attrtransfer close");
  2383. ch->ChatPacket(CHAT_TYPE_INFO, "- attrtransfer add <attr_transfer_slot> <inventory_slot>");
  2384. ch->ChatPacket(CHAT_TYPE_INFO, "- attrtransfer delete <attr_transfer_slot>");
  2385. return;
  2386. }
  2387.  
  2388. const std::string& strArg1 = std::string(arg1);
  2389. if (strArg1 == "open")
  2390. {
  2391. AttrTransfer_open(ch);
  2392. return;
  2393. }
  2394. else if (strArg1 == "close")
  2395. {
  2396. AttrTransfer_close(ch);
  2397. return;
  2398. }
  2399. else if (strArg1 == "make")
  2400. {
  2401. AttrTransfer_make(ch);
  2402. return;
  2403. }
  2404. else if (strArg1 == "add")
  2405. {
  2406. if (0 == arg2[0] || !isdigit(*arg2) || 0 == arg3[0] || !isdigit(*arg3))
  2407. return;
  2408.  
  2409. str_to_number(w_index, arg2);
  2410. str_to_number(i_index, arg3);
  2411. AttrTransfer_add_item(ch, w_index, i_index);
  2412. return;
  2413. }
  2414. else if (strArg1 == "delete")
  2415. {
  2416. if (0 == arg2[0] || !isdigit(*arg2))
  2417. return;
  2418.  
  2419. str_to_number(w_index, arg2);
  2420. AttrTransfer_delete_item(ch, w_index);
  2421. return;
  2422. }
  2423.  
  2424. switch (LOWER(arg1[0]))
  2425. {
  2426. case 'o':
  2427. AttrTransfer_open(ch);
  2428. break;
  2429. case 'c':
  2430. AttrTransfer_close(ch);
  2431. break;
  2432. case 'm':
  2433. AttrTransfer_make(ch);
  2434. break;
  2435. case 'a':
  2436. {
  2437. if (0 == arg2[0] || !isdigit(*arg2) || 0 == arg3[0] || !isdigit(*arg3))
  2438. return;
  2439.  
  2440. str_to_number(w_index, arg2);
  2441. str_to_number(i_index, arg3);
  2442. AttrTransfer_add_item(ch, w_index, i_index);
  2443. }
  2444. break;
  2445. case 'd':
  2446. {
  2447. if (0 == arg2[0] || !isdigit(*arg2))
  2448. return;
  2449.  
  2450. str_to_number(w_index, arg2);
  2451. AttrTransfer_delete_item(ch, w_index);
  2452. }
  2453. break;
  2454. default:
  2455. return;
  2456. }
  2457. }
  2458. #endif
  2459.  
  2460. //gift notify quest command
  2461. ACMD(do_gift)
  2462. {
  2463. ch->ChatPacket(CHAT_TYPE_COMMAND, "gift");
  2464. }
  2465.  
  2466. #ifdef ENABLE_NEWPET_SYSTEM
  2467. ACMD(do_CubePetAdd)
  2468. {
  2469. int pos = 0;
  2470. int invpos = 0;
  2471.  
  2472. const char *line;
  2473. char arg1[256], arg2[256], arg3[256];
  2474.  
  2475. line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2476. one_argument(line, arg3, sizeof(arg3));
  2477.  
  2478. if (0 == arg1[0])
  2479. return;
  2480.  
  2481. const std::string& strArg1 = std::string(arg1);
  2482. (void)strArg1;
  2483. switch (LOWER(arg1[0]))
  2484. {
  2485. case 'a': // add cue_index inven_index
  2486. {
  2487. if (0 == arg2[0] || !isdigit(*arg2) ||
  2488. 0 == arg3[0] || !isdigit(*arg3))
  2489. return;
  2490.  
  2491. str_to_number(pos, arg2);
  2492. str_to_number(invpos, arg3);
  2493.  
  2494. }
  2495. break;
  2496.  
  2497. default:
  2498. return;
  2499. }
  2500.  
  2501. if (ch->GetNewPetSystem()->IsActivePet())
  2502. ch->GetNewPetSystem()->SetItemCube(pos, invpos);
  2503. else
  2504. return;
  2505.  
  2506. }
  2507.  
  2508. ACMD(do_PetSkill)
  2509. {
  2510. char arg1[256];
  2511. one_argument(argument, arg1, sizeof(arg1));
  2512.  
  2513. if (!*arg1)
  2514. return;
  2515.  
  2516. DWORD skillslot = 0;
  2517. str_to_number(skillslot, arg1);
  2518.  
  2519. if (skillslot > 2 || skillslot < 0)
  2520. return;
  2521.  
  2522. if (ch->GetNewPetSystem()->IsActivePet())
  2523. ch->GetNewPetSystem()->DoPetSkill(skillslot);
  2524. else
  2525. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You must have summoned the pet to proceed."));
  2526. }
  2527.  
  2528. ACMD(do_FeedCubePet)
  2529. {
  2530. char arg1[256];
  2531. one_argument(argument, arg1, sizeof(arg1));
  2532.  
  2533. if (!*arg1)
  2534. return;
  2535.  
  2536. DWORD feedtype = 0;
  2537. str_to_number(feedtype, arg1);
  2538.  
  2539. if (ch->GetNewPetSystem()->IsActivePet())
  2540. ch->GetNewPetSystem()->ItemCubeFeed(feedtype);
  2541. else
  2542. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You don't have a called attendant."));
  2543. }
  2544.  
  2545. ACMD(do_PetEvo)
  2546. {
  2547. if (ch->GetExchange() || ch->GetMyShop() || ch->GetShopOwner() || ch->IsOpenSafebox() || ch->IsCubeOpen())
  2548. {
  2549. //ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("[PetEvolution] You cannot evolve your pet now!"));
  2550. return;
  2551. }
  2552.  
  2553. if (ch->GetNewPetSystem()->IsActivePet())
  2554. {
  2555. int it[3][7] =
  2556. {
  2557. { 55003, 30058, 30073, 30041, 30017, 30074, 30088 }, //Here Modify Items to request for 1 evo
  2558. { 55004, 27994, 30035, 30089, 30031, 30011, 30080 }, //Here Modify Items to request for 2 evo
  2559. { 55005, 30083, 27992, 27993, 30086, 30077, 30550 } //Here Modify Items to request for 3 evo
  2560. };
  2561.  
  2562. int ic[3][7] =
  2563. {
  2564. { 10, 10, 10, 10, 10, 5, 5 },
  2565. { 10, 2, 10, 10, 10, 10, 5 },
  2566. { 10, 10, 2, 2, 10, 10, 5 }
  2567. };
  2568.  
  2569. int tmpevo = ch->GetNewPetSystem()->GetEvolution();
  2570.  
  2571. if (tmpevo == 2 && ch->GetNewPetSystem()->GetLevel() == 81 && ch->GetNewPetSystem()->GetYas() < 30)
  2572. {
  2573. ch->ChatPacket(CHAT_TYPE_INFO, "Your pet's age must be at least 30 days!");
  2574. return;
  2575.  
  2576. }
  2577.  
  2578. if (ch->GetNewPetSystem()->GetLevel() == 40 && tmpevo == 0 ||
  2579. ch->GetNewPetSystem()->GetLevel() >= 81 && tmpevo == 1 ||
  2580. ch->GetNewPetSystem()->GetLevel() >= 81 && tmpevo == 2)
  2581. {
  2582. for (int b = 0; b < 7; b++)
  2583. {
  2584. if (ch->CountSpecifyItem(it[tmpevo][b]) < ic[tmpevo][b])
  2585. {
  2586. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("[PetEvolution] Items Required:"));
  2587. for (int c = 0; c < 7; c++)
  2588. {
  2589. DWORD vnum = it[tmpevo][c];
  2590. //ch->ChatPacket(CHAT_TYPE_INFO, "%s x%d , %s x%d , %s x%d , %s x%d , %s x%d , %s x%d , %s x%d", ITEM_MANAGER::instance().GetTable(vnum)->szLocaleName , ic[tmpevo][c] , ITEM_MANAGER::instance().GetTable(vnum)->szLocaleName , ic[tmpevo][c] , ITEM_MANAGER::instance().GetTable(vnum)->szLocaleName , ic[tmpevo][c] , ITEM_MANAGER::instance().GetTable(vnum)->szLocaleName , ic[tmpevo][c] , ITEM_MANAGER::instance().GetTable(vnum)->szLocaleName , ic[tmpevo][c] , ITEM_MANAGER::instance().GetTable(vnum)->szLocaleName , ic[tmpevo][c] , ITEM_MANAGER::instance().GetTable(vnum)->szLocaleName , ic[tmpevo][c]);
  2591. ch->ChatPacket(CHAT_TYPE_INFO, "%s x%d", ITEM_MANAGER::instance().GetTable(vnum)->szLocaleName , ic[tmpevo][c]);
  2592. }
  2593. return;
  2594. }
  2595. }
  2596. for (int c = 0; c < 7; c++)
  2597. {
  2598. ch->RemoveSpecifyItem(it[tmpevo][c], ic[tmpevo][c]);
  2599. }
  2600. ch->GetNewPetSystem()->IncreasePetEvolution();
  2601.  
  2602. }
  2603. else
  2604. {
  2605. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can't evolve your pet!"));
  2606. return;
  2607. }
  2608. }
  2609. else
  2610. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Your pet should be summoned!"));
  2611. }
  2612.  
  2613. ACMD(do_PetChangeName)
  2614. {
  2615. char arg1[256], arg2[256];
  2616. two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2617.  
  2618. if (!*arg1 || !*arg2)
  2619. return;
  2620.  
  2621. int bCell = 0;
  2622. str_to_number(bCell, arg1);
  2623. LPITEM item = ch->GetInventoryItem(bCell);
  2624. if (!item)
  2625. return;
  2626. if (ch->CountSpecifyItem(55008) < 1)
  2627. return;
  2628.  
  2629. if (ch->GetGold() < 100000)
  2630. {
  2631. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량을 하기 위한 돈이 부족합니다."));
  2632. return;
  2633. }
  2634.  
  2635. if (ch->GetNewPetSystem()->IsActivePet())
  2636. {
  2637. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("The activated pet cannot be selected."));
  2638. return;
  2639. }
  2640.  
  2641. DBManager::instance().DirectQuery("UPDATE new_petsystem SET name = '%s' WHERE id = '%d'", arg2, item->GetID());
  2642. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Success."));
  2643. ch->RemoveSpecifyItem(55008, 1);
  2644. ch->PointChange(POINT_GOLD, -100000);
  2645. }
  2646. #endif
  2647.  
  2648. #ifdef ENABLE_AUTO_HUNT_SYSTEM
  2649. ACMD(do_autohunt_activate)
  2650. {
  2651. if (ch->GetAutoHuntStatus() == false)
  2652. ch->SetAutoHuntStatus(true);
  2653. else
  2654. ch->SetAutoHuntStatus(false);
  2655. }
  2656. #endif
  2657.  
  2658. #ifdef ENABLE_GEM_SYSTEM
  2659. ACMD(do_gaya_system)
  2660. {
  2661. char arg1[255];
  2662. char arg2[255];
  2663. two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2664.  
  2665. if (0 == arg1[0])
  2666. return;
  2667.  
  2668. const std::string& strArg1 = std::string(arg1);
  2669.  
  2670. if (strArg1 == "craft"){
  2671.  
  2672. if (0 == arg2[0])
  2673. return;
  2674.  
  2675. int slot = atoi(arg2);
  2676. ch->CraftGayaItems(slot);
  2677.  
  2678. }
  2679. else if(strArg1 == "market"){
  2680.  
  2681. if (0 == arg2[0])
  2682. return;
  2683.  
  2684. int slot = atoi(arg2);
  2685. ch->MarketGayaItems(slot);
  2686.  
  2687. }
  2688. else if(strArg1 == "refresh")
  2689. {
  2690. ch->RefreshGayaItems();
  2691. }
  2692. }
  2693. #endif
  2694.  
  2695. #ifdef ENABLE_12ZI
  2696. ACMD(do_open_cz)
  2697. {
  2698. int iPulse = thecore_pulse();
  2699.  
  2700. if (iPulse - ch->GetLastZodiacCzLastTime() < passes_per_sec * 1)
  2701. {
  2702. //ch->ChatPacket(CHAT_TYPE_INFO, "You have to wait a bit.");
  2703. return;
  2704. }
  2705.  
  2706. ch->SetLastZodiacCzLastTime(iPulse);
  2707.  
  2708. ch->ChatPacket(CHAT_TYPE_COMMAND, "OpenUI12zi %d %d %d %d %d", ch->GetYellowmark(), ch->GetGreenmark(), ch->GetYellowreward(), ch->GetGreenreward(), ch->GetGoldreward());
  2709. }
  2710.  
  2711. ACMD(do_cz_reward)
  2712. {
  2713. int iPulse = thecore_pulse();
  2714.  
  2715. if (iPulse - ch->GetLastZodiacCzLastTime() < passes_per_sec * 1)
  2716. {
  2717. //ch->ChatPacket(CHAT_TYPE_INFO, "You have to wait a bit.");
  2718. return;
  2719. }
  2720.  
  2721. ch->SetLastZodiacCzLastTime(iPulse);
  2722.  
  2723. char arg1[256];
  2724. one_argument(argument, arg1, sizeof(arg1));
  2725.  
  2726. if (!*arg1)
  2727. {
  2728. //ch->ChatPacket(CHAT_TYPE_INFO, "Missing action applied!");
  2729. return;
  2730. }
  2731.  
  2732. BYTE type = 0;
  2733. str_to_number(type, arg1);
  2734.  
  2735. if (type == 1)
  2736. {
  2737. if (ch->GetYellowmark() == 1073741823)
  2738. {
  2739. ch->AutoGiveItem(33026, 1);
  2740. ch->SetYellowreward(1);
  2741. ch->ClearYellowMark();
  2742. }
  2743. else
  2744. {
  2745. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough coffins!");
  2746. return;
  2747. }
  2748. }
  2749. else if (type == 2)
  2750. {
  2751. if (ch->GetGreenmark() == 1073741823)
  2752. {
  2753. ch->AutoGiveItem(33027, 1);
  2754. ch->SetGreenreward(1);
  2755. ch->ClearGreenMark();
  2756. }
  2757. else
  2758. {
  2759. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough Green Box points!");
  2760. return;
  2761. }
  2762. }
  2763. else if (type == 3)
  2764. {
  2765. int sari = ch->GetYellowreward();
  2766. int yesil = ch->GetGreenreward();
  2767. int altin = ch->GetGoldreward();
  2768.  
  2769. if ((sari-altin) == 0 || (yesil-altin) == 0)
  2770. {
  2771. //ch->ChatPacket(CHAT_TYPE_INFO, "You do not have enough Yildiz coffins!");
  2772. return;
  2773. }
  2774.  
  2775. ch->AutoGiveItem(33028, 1);
  2776. ch->SetGoldreward(1);
  2777. }
  2778.  
  2779. ch->ChatPacket(CHAT_TYPE_COMMAND, "OpenUI12zi %d %d %d %d %d", ch->GetYellowmark(), ch->GetGreenmark(), ch->GetYellowreward(), ch->GetGreenreward(), ch->GetGoldreward());
  2780. }
  2781.  
  2782. ACMD(do_cz_check_box)
  2783. {
  2784. if (!ch)
  2785. return;
  2786.  
  2787. int iPulse = thecore_pulse();
  2788.  
  2789. if (iPulse - ch->GetLastZodiacCzLastTime() < passes_per_sec / 2)
  2790. {
  2791. //ch->ChatPacket(CHAT_TYPE_INFO, "You have to wait a bit.");
  2792. return;
  2793. }
  2794.  
  2795. ch->SetLastZodiacCzLastTime(iPulse);
  2796.  
  2797. char arg1[256];
  2798. char arg2[256];
  2799. two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2800.  
  2801. if (!*arg1 || !*arg2)
  2802. {
  2803. //ch->ChatPacket(CHAT_TYPE_INFO, "Missing action applied!");
  2804. return;
  2805. }
  2806.  
  2807. BYTE type = 0, value = 0, zero = 0;
  2808. str_to_number(type, arg1);
  2809. str_to_number(value, arg2);
  2810.  
  2811. DWORD column_item_list_yellow[] = { 33001, 33003, 33005, 33007, 33009, 33011 };
  2812. DWORD column_item_list_green[] = { 33002, 33004, 33006, 33008, 33010, 33012 };
  2813.  
  2814. DWORD row_item_list_yellow[] = { 33013, 33015, 33017, 33019, 33021 };
  2815. DWORD row_item_list_green[] = { 33014, 33016, 33018, 33020, 33022 };
  2816. {
  2817. if (type == 0)
  2818. {
  2819. if (value == 0 || value == 6 || value == 12 || value == 18 || value == 24)
  2820. {
  2821. if (ch->CountSpecifyItem(column_item_list_yellow[0]) >= 50)
  2822. ch->RemoveSpecifyItem(column_item_list_yellow[0], 50);
  2823. else
  2824. {
  2825. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2826. return;
  2827. }
  2828. }
  2829. else if (value == 1 || value == 7 || value == 13 || value == 19 || value == 25)
  2830. {
  2831. if (ch->CountSpecifyItem(column_item_list_yellow[1]) >= 50)
  2832. ch->RemoveSpecifyItem(column_item_list_yellow[1], 50);
  2833. else
  2834. {
  2835. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2836. return;
  2837. }
  2838. }
  2839. else if (value == 2 || value == 8 || value == 14 || value == 20 || value == 26)
  2840. {
  2841. if (ch->CountSpecifyItem(column_item_list_yellow[2]) >= 50)
  2842. ch->RemoveSpecifyItem(column_item_list_yellow[2], 50);
  2843. else
  2844. {
  2845. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2846. return;
  2847. }
  2848. }
  2849. else if (value == 3 || value == 9 || value == 15 || value == 21 || value == 27)
  2850. {
  2851. if (ch->CountSpecifyItem(column_item_list_yellow[3]) >= 50)
  2852. ch->RemoveSpecifyItem(column_item_list_yellow[3], 50);
  2853. else
  2854. {
  2855. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2856. return;
  2857. }
  2858. }
  2859. else if (value == 4 || value == 10 || value == 16 || value == 22 || value == 28)
  2860. {
  2861. if (ch->CountSpecifyItem(column_item_list_yellow[4]) >= 50)
  2862. ch->RemoveSpecifyItem(column_item_list_yellow[4], 50);
  2863. else
  2864. {
  2865. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2866. return;
  2867. }
  2868. }
  2869. else if (value == 5 || value == 11 || value == 17 || value == 23 || value == 29)
  2870. {
  2871. if (ch->CountSpecifyItem(column_item_list_yellow[5]) >= 50)
  2872. ch->RemoveSpecifyItem(column_item_list_yellow[5], 50);
  2873. else
  2874. {
  2875. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2876. return;
  2877. }
  2878. }
  2879.  
  2880. if (value >= zero && value <= 5)
  2881. {
  2882. if (ch->CountSpecifyItem(row_item_list_yellow[0]) >= 50)
  2883. ch->RemoveSpecifyItem(row_item_list_yellow[0], 50);
  2884. else
  2885. {
  2886. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2887. return;
  2888. }
  2889. }
  2890. else if (value >= 6 && value <= 11)
  2891. {
  2892. if (ch->CountSpecifyItem(row_item_list_yellow[1]) >= 50)
  2893. ch->RemoveSpecifyItem(row_item_list_yellow[1], 50);
  2894. else
  2895. {
  2896. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2897. return;
  2898. }
  2899. }
  2900. else if (value >= 12 && value <= 17)
  2901. {
  2902. if (ch->CountSpecifyItem(row_item_list_yellow[2]) >= 50)
  2903. ch->RemoveSpecifyItem(row_item_list_yellow[2], 50);
  2904. else
  2905. {
  2906. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2907. return;
  2908. }
  2909. }
  2910. else if (value >= 18 && value <= 23)
  2911. {
  2912. if (ch->CountSpecifyItem(row_item_list_yellow[3]) >= 50)
  2913. ch->RemoveSpecifyItem(row_item_list_yellow[3], 50);
  2914. else
  2915. {
  2916. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2917. return;
  2918. }
  2919. }
  2920. else if (value >= 24 && value <= 29)
  2921. {
  2922. if (ch->CountSpecifyItem(row_item_list_yellow[4]) >= 50)
  2923. ch->RemoveSpecifyItem(row_item_list_yellow[4], 50);
  2924. else
  2925. {
  2926. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2927. return;
  2928. }
  2929. }
  2930. }
  2931. else
  2932. {
  2933. if (value == 0 || value == 6 || value == 12 || value == 18 || value == 24)
  2934. {
  2935. if (ch->CountSpecifyItem(column_item_list_green[0]) >= 50)
  2936. ch->RemoveSpecifyItem(column_item_list_green[0], 50);
  2937. else
  2938. {
  2939. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2940. return;
  2941. }
  2942. }
  2943. else if (value == 1 || value == 7 || value == 13 || value == 19 || value == 25)
  2944. {
  2945. if (ch->CountSpecifyItem(column_item_list_green[1]) >= 50)
  2946. ch->RemoveSpecifyItem(column_item_list_green[1], 50);
  2947. else
  2948. {
  2949. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2950. return;
  2951. }
  2952. }
  2953. else if (value == 2 || value == 8 || value == 14 || value == 20 || value == 26)
  2954. {
  2955. if (ch->CountSpecifyItem(column_item_list_green[2]) >= 50)
  2956. ch->RemoveSpecifyItem(column_item_list_green[2], 50);
  2957. else
  2958. {
  2959. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2960. return;
  2961. }
  2962. }
  2963. else if (value == 3 || value == 9 || value == 15 || value == 21 || value == 27)
  2964. {
  2965. if (ch->CountSpecifyItem(column_item_list_green[3]) >= 50)
  2966. ch->RemoveSpecifyItem(column_item_list_green[3], 50);
  2967. else
  2968. {
  2969. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2970. return;
  2971. }
  2972. }
  2973. else if (value == 4 || value == 10 || value == 16 || value == 22 || value == 28)
  2974. {
  2975. if (ch->CountSpecifyItem(column_item_list_green[4]) >= 50)
  2976. ch->RemoveSpecifyItem(column_item_list_green[4], 50);
  2977. else
  2978. {
  2979. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2980. return;
  2981. }
  2982. }
  2983. else if (value == 5 || value == 11 || value == 17 || value == 23 || value == 29)
  2984. {
  2985. if (ch->CountSpecifyItem(column_item_list_green[5]) >= 50)
  2986. ch->RemoveSpecifyItem(column_item_list_green[5], 50);
  2987. else
  2988. {
  2989. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  2990. return;
  2991. }
  2992. }
  2993.  
  2994. if (value >= zero && value <= 5)
  2995. {
  2996. if (ch->CountSpecifyItem(row_item_list_green[0]) >= 50)
  2997. ch->RemoveSpecifyItem(row_item_list_green[0], 50);
  2998. else
  2999. {
  3000. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  3001. return;
  3002. }
  3003. }
  3004. else if (value >= 6 && value <= 11)
  3005. {
  3006. if (ch->CountSpecifyItem(row_item_list_green[1]) >= 50)
  3007. ch->RemoveSpecifyItem(row_item_list_green[1], 50);
  3008. else
  3009. {
  3010. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  3011. return;
  3012. }
  3013. }
  3014. else if (value >= 12 && value <= 17)
  3015. {
  3016. if (ch->CountSpecifyItem(row_item_list_green[2]) >= 50)
  3017. ch->RemoveSpecifyItem(row_item_list_green[2], 50);
  3018. else
  3019. {
  3020. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  3021. return;
  3022. }
  3023. }
  3024. else if (value >= 18 && value <= 23)
  3025. {
  3026. if (ch->CountSpecifyItem(row_item_list_green[3]) >= 50)
  3027. ch->RemoveSpecifyItem(row_item_list_green[3], 50);
  3028. else
  3029. {
  3030. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  3031. return;
  3032. }
  3033. }
  3034. else if (value >= 24 && value <= 29)
  3035. {
  3036. if (ch->CountSpecifyItem(row_item_list_green[4]) >= 50)
  3037. ch->RemoveSpecifyItem(row_item_list_green[4], 50);
  3038. else
  3039. {
  3040. //ch->ChatPacket(CHAT_TYPE_INFO, "You don't have enough zodiac charm!");
  3041. return;
  3042. }
  3043. }
  3044. }
  3045. }
  3046.  
  3047. int size = 1;
  3048. for (BYTE b = 0; b < value; ++b)
  3049. size *= 2;
  3050.  
  3051. if (type == 0)
  3052. ch->SetYellowmark(size);
  3053. else
  3054. ch->SetGreenmark(size);
  3055.  
  3056. ch->ChatPacket(CHAT_TYPE_COMMAND, "OpenUI12zi %d %d %d %d %d", ch->GetYellowmark(), ch->GetGreenmark(), ch->GetYellowreward(), ch->GetGreenreward(), ch->GetGoldreward());
  3057. }
  3058.  
  3059. ACMD(do_revivedialog)
  3060. {
  3061. if (!ch)
  3062. return;
  3063.  
  3064. char arg1[256];
  3065. one_argument(argument, arg1, sizeof(arg1));
  3066.  
  3067. if (!*arg1)
  3068. {
  3069. ch->ChatPacket(CHAT_TYPE_INFO, "Veri eksik!");
  3070. return;
  3071. }
  3072.  
  3073. DWORD vid = 0;
  3074. str_to_number(vid, arg1);
  3075. LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  3076.  
  3077. if (!tch)
  3078. {
  3079. ch->ChatPacket(CHAT_TYPE_INFO, "Diriltecek kisi yok!");
  3080. return;
  3081. }
  3082.  
  3083. if (!tch->IsPC())
  3084. {
  3085. ch->ChatPacket(CHAT_TYPE_INFO, "Diriltmeye calistiginiz kisi insan degil!");
  3086. return;
  3087. }
  3088.  
  3089. if (!tch->IsDead())
  3090. {
  3091. ch->ChatPacket(CHAT_TYPE_INFO, "Diriltmeye calistiginiz kisi olu degil!");
  3092. return;
  3093. }
  3094.  
  3095. BYTE Adet = tch->GetDeadCount() >= 1 ? tch->GetDeadCount()*2 : 1;
  3096. ch->ChatPacket(CHAT_TYPE_COMMAND, "OpenReviveDialog %u %u", (DWORD)tch->GetVID(), Adet);
  3097. }
  3098.  
  3099. ACMD(do_revive)
  3100. {
  3101. if (!ch)
  3102. return;
  3103.  
  3104. char arg1[256];
  3105. one_argument(argument, arg1, sizeof(arg1));
  3106.  
  3107. if (!*arg1)
  3108. {
  3109. ch->ChatPacket(CHAT_TYPE_INFO, "Veri eksik!");
  3110. return;
  3111. }
  3112.  
  3113. DWORD vid = 0;
  3114. str_to_number(vid, arg1);
  3115. LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  3116.  
  3117. if (!tch)
  3118. {
  3119. ch->ChatPacket(CHAT_TYPE_INFO, "Diriltecek kisi yok!");
  3120. return;
  3121. }
  3122.  
  3123. if (!tch->IsPC())
  3124. {
  3125. ch->ChatPacket(CHAT_TYPE_INFO, "Diriltmeye calistiginiz kisi insan degil!");
  3126. return;
  3127. }
  3128.  
  3129. if (!tch->IsDead())
  3130. {
  3131. ch->ChatPacket(CHAT_TYPE_INFO, "Diriltmeye calistiginiz kisi olu degil!");
  3132. return;
  3133. }
  3134.  
  3135. if (!(ch->GetMapIndex() >= 3580000 && ch->GetMapIndex() < 3590000) || !(tch->GetMapIndex() >= 3580000 && tch->GetMapIndex() < 3590000))
  3136. {
  3137. ch->ChatPacket(CHAT_TYPE_INFO, "Zodyak tapinaginda degilsiniz!");
  3138. return;
  3139. }
  3140.  
  3141. BYTE Adet = tch->GetDeadCount() >= 1 ? tch->GetDeadCount()*2 : 1;
  3142. if (ch->CountSpecifyItem(33025) < (int)Adet)
  3143. {
  3144. ch->ChatPacket(CHAT_TYPE_COMMAND, "NotEnoughPrism %u", Adet);
  3145. return;
  3146. }
  3147.  
  3148. ch->RemoveSpecifyItem(33025, Adet);
  3149. tch->ChatPacket(CHAT_TYPE_COMMAND, "CloseRestartWindow");
  3150. tch->GetDesc()->SetPhase(PHASE_GAME);
  3151. tch->SetPosition(POS_STANDING);
  3152. tch->StartRecoveryEvent();
  3153. tch->RestartAtSamePos();
  3154. tch->PointChange(POINT_HP, tch->GetMaxHP() - tch->GetHP());
  3155. tch->PointChange(POINT_SP, tch->GetMaxSP() - tch->GetSP());
  3156. tch->ReviveInvisible(5);
  3157. sys_log(0, "do_restart: restart here zodiac");
  3158. }
  3159.  
  3160. ACMD(do_jump_floor)
  3161. {
  3162. if (ch)
  3163. {
  3164. if ((ch->GetParty() && ch->GetParty()->GetLeaderPID() == ch->GetPlayerID()) || !ch->GetParty())
  3165. {
  3166. LPZODIAC pkZodiac = CZodiacManager::instance().FindByMapIndex(ch->GetMapIndex());
  3167. if (pkZodiac && pkZodiac->IsNextFloor() == true)
  3168. {
  3169. pkZodiac->NewFloor(pkZodiac->GetNextFloor());
  3170. }
  3171. }
  3172. }
  3173. }
  3174.  
  3175. ACMD(do_next_floor)
  3176. {
  3177. if (ch)
  3178. {
  3179. if ((ch->GetParty() && ch->GetParty()->GetLeaderPID() == ch->GetPlayerID()) || !ch->GetParty())
  3180. {
  3181. LPZODIAC pkZodiac = CZodiacManager::instance().FindByMapIndex(ch->GetMapIndex());
  3182. if (pkZodiac && pkZodiac->IsNextFloor() == true)
  3183. {
  3184. pkZodiac->NewFloor(pkZodiac->GetFloor()+1);
  3185. }
  3186. }
  3187. }
  3188. }
  3189. #endif
  3190.  
  3191. ACMD(do_cube)
  3192. {
  3193. if (!ch->CanDoCube())
  3194. return;
  3195.  
  3196. dev_log(LOG_DEB0, "CUBE COMMAND <%s>: %s", ch->GetName(), argument);
  3197. int cube_index = 0, inven_index = 0;
  3198. const char *line;
  3199.  
  3200. char arg1[256], arg2[256], arg3[256];
  3201.  
  3202. line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3203. one_argument(line, arg3, sizeof(arg3));
  3204.  
  3205. if (0 == arg1[0])
  3206. {
  3207. // print usage
  3208. ch->ChatPacket(CHAT_TYPE_INFO, "Usage: cube open");
  3209. ch->ChatPacket(CHAT_TYPE_INFO, " cube close");
  3210. ch->ChatPacket(CHAT_TYPE_INFO, " cube add <inveltory_index>");
  3211. ch->ChatPacket(CHAT_TYPE_INFO, " cube delete <cube_index>");
  3212. ch->ChatPacket(CHAT_TYPE_INFO, " cube list");
  3213. ch->ChatPacket(CHAT_TYPE_INFO, " cube cancel");
  3214. ch->ChatPacket(CHAT_TYPE_INFO, " cube make [all]");
  3215. return;
  3216. }
  3217.  
  3218. const std::string& strArg1 = std::string(arg1);
  3219.  
  3220. // r_info (request information)
  3221. // /cube r_info ==> (Client -> Server) 현재 NPC가 만들 수 있는 레시피 요청
  3222. // (Server -> Client) /cube r_list npcVNUM resultCOUNT 123,1/125,1/128,1/130,5
  3223. //
  3224. // /cube r_info 3 ==> (Client -> Server) 현재 NPC가 만들수 있는 레시피 중 3번째 아이템을 만드는 데 필요한 정보를 요청
  3225. // /cube r_info 3 5 ==> (Client -> Server) 현재 NPC가 만들수 있는 레시피 중 3번째 아이템부터 이후 5개의 아이템을 만드는 데 필요한 재료 정보를 요청
  3226. // (Server -> Client) /cube m_info startIndex count 125,1|126,2|127,2|123,5&555,5&555,4/120000@125,1|126,2|127,2|123,5&555,5&555,4/120000
  3227. //
  3228. if (strArg1 == "r_info")
  3229. {
  3230. if (0 == arg2[0])
  3231. Cube_request_result_list(ch);
  3232. else
  3233. {
  3234. if (isdigit(*arg2))
  3235. {
  3236. int listIndex = 0, requestCount = 1;
  3237. str_to_number(listIndex, arg2);
  3238.  
  3239. if (0 != arg3[0] && isdigit(*arg3))
  3240. str_to_number(requestCount, arg3);
  3241.  
  3242. Cube_request_material_info(ch, listIndex, requestCount);
  3243. }
  3244. }
  3245.  
  3246. return;
  3247. }
  3248.  
  3249. switch (LOWER(arg1[0]))
  3250. {
  3251. case 'o': // open
  3252. Cube_open(ch);
  3253. break;
  3254.  
  3255. case 'c': // close
  3256. Cube_close(ch);
  3257. break;
  3258.  
  3259. case 'l': // list
  3260. Cube_show_list(ch);
  3261. break;
  3262.  
  3263. case 'a': // add cue_index inven_index
  3264. {
  3265. if (0 == arg2[0] || !isdigit(*arg2) ||
  3266. 0 == arg3[0] || !isdigit(*arg3))
  3267. return;
  3268.  
  3269. str_to_number(cube_index, arg2);
  3270. str_to_number(inven_index, arg3);
  3271. Cube_add_item (ch, cube_index, inven_index);
  3272. }
  3273. break;
  3274.  
  3275. case 'd': // delete
  3276. {
  3277. if (0 == arg2[0] || !isdigit(*arg2))
  3278. return;
  3279.  
  3280. str_to_number(cube_index, arg2);
  3281. Cube_delete_item (ch, cube_index);
  3282. }
  3283. break;
  3284.  
  3285. case 'm': // make
  3286. if (0 != arg2[0])
  3287. {
  3288. while (true == Cube_make(ch))
  3289. dev_log (LOG_DEB0, "cube make success");
  3290. }
  3291. else
  3292. Cube_make(ch);
  3293. break;
  3294.  
  3295. default:
  3296. return;
  3297. }
  3298. }
  3299.  
  3300. ACMD(do_in_game_mall)
  3301. {
  3302. if (LC_IsEurope() == true)
  3303. {
  3304. char country_code[3];
  3305.  
  3306. switch (LC_GetLocalType())
  3307. {
  3308. case LC_GERMANY: country_code[0] = 'd'; country_code[1] = 'e'; country_code[2] = '\0'; break;
  3309. case LC_FRANCE: country_code[0] = 'f'; country_code[1] = 'r'; country_code[2] = '\0'; break;
  3310. case LC_ITALY: country_code[0] = 'i'; country_code[1] = 't'; country_code[2] = '\0'; break;
  3311. case LC_SPAIN: country_code[0] = 'e'; country_code[1] = 's'; country_code[2] = '\0'; break;
  3312. case LC_UK: country_code[0] = 'e'; country_code[1] = 'n'; country_code[2] = '\0'; break;
  3313. case LC_TURKEY: country_code[0] = 't'; country_code[1] = 'r'; country_code[2] = '\0'; break;
  3314. case LC_POLAND: country_code[0] = 'p'; country_code[1] = 'l'; country_code[2] = '\0'; break;
  3315. case LC_PORTUGAL: country_code[0] = 'p'; country_code[1] = 't'; country_code[2] = '\0'; break;
  3316. case LC_GREEK: country_code[0] = 'g'; country_code[1] = 'r'; country_code[2] = '\0'; break;
  3317. case LC_RUSSIA: country_code[0] = 'r'; country_code[1] = 'u'; country_code[2] = '\0'; break;
  3318. case LC_DENMARK: country_code[0] = 'd'; country_code[1] = 'k'; country_code[2] = '\0'; break;
  3319. case LC_BULGARIA: country_code[0] = 'b'; country_code[1] = 'g'; country_code[2] = '\0'; break;
  3320. case LC_CROATIA: country_code[0] = 'h'; country_code[1] = 'r'; country_code[2] = '\0'; break;
  3321. case LC_MEXICO: country_code[0] = 'm'; country_code[1] = 'x'; country_code[2] = '\0'; break;
  3322. case LC_ARABIA: country_code[0] = 'a'; country_code[1] = 'e'; country_code[2] = '\0'; break;
  3323. case LC_CZECH: country_code[0] = 'c'; country_code[1] = 'z'; country_code[2] = '\0'; break;
  3324. case LC_ROMANIA: country_code[0] = 'r'; country_code[1] = 'o'; country_code[2] = '\0'; break;
  3325. case LC_HUNGARY: country_code[0] = 'h'; country_code[1] = 'u'; country_code[2] = '\0'; break;
  3326. case LC_NETHERLANDS: country_code[0] = 'n'; country_code[1] = 'l'; country_code[2] = '\0'; break;
  3327. case LC_USA: country_code[0] = 'u'; country_code[1] = 's'; country_code[2] = '\0'; break;
  3328. case LC_CANADA: country_code[0] = 'c'; country_code[1] = 'a'; country_code[2] = '\0'; break;
  3329. default:
  3330. if (test_server == true)
  3331. {
  3332. country_code[0] = 'd'; country_code[1] = 'e'; country_code[2] = '\0';
  3333. }
  3334. break;
  3335. }
  3336.  
  3337. char buf[512+1];
  3338. char sas[33];
  3339. MD5_CTX ctx;
  3340. const char sas_key[] = "GF9001";
  3341.  
  3342. snprintf(buf, sizeof(buf), "%u%u%s", ch->GetPlayerID(), ch->GetAID(), sas_key);
  3343.  
  3344. MD5Init(&ctx);
  3345. MD5Update(&ctx, (const unsigned char *) buf, strlen(buf));
  3346. #ifdef __FreeBSD__
  3347. MD5End(&ctx, sas);
  3348. #else
  3349. static const char hex[] = "0123456789abcdef";
  3350. unsigned char digest[16];
  3351. MD5Final(digest, &ctx);
  3352. int i;
  3353. for (i = 0; i < 16; ++i) {
  3354. sas[i+i] = hex[digest[i] >> 4];
  3355. sas[i+i+1] = hex[digest[i] & 0x0f];
  3356. }
  3357. sas[i+i] = '\0';
  3358. #endif
  3359.  
  3360. snprintf(buf, sizeof(buf), "mall http://%s/ishop?pid=%u&c=%s&sid=%d&sas=%s",
  3361. g_strWebMallURL.c_str(), ch->GetPlayerID(), country_code, g_server_id, sas);
  3362.  
  3363. ch->ChatPacket(CHAT_TYPE_COMMAND, buf);
  3364. }
  3365. }
  3366.  
  3367. // 주사위
  3368. ACMD(do_dice)
  3369. {
  3370. char arg1[256], arg2[256];
  3371. int start = 1, end = 100;
  3372.  
  3373. two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3374.  
  3375. if (*arg1 && *arg2)
  3376. {
  3377. start = atoi(arg1);
  3378. end = atoi(arg2);
  3379. }
  3380. else if (*arg1 && !*arg2)
  3381. {
  3382. start = 1;
  3383. end = atoi(arg1);
  3384. }
  3385.  
  3386. end = MAX(start, end);
  3387. start = MIN(start, end);
  3388.  
  3389. int n = number(start, end);
  3390.  
  3391. #ifdef ENABLE_DICE_SYSTEM
  3392. if (ch->GetParty())
  3393. ch->GetParty()->ChatPacketToAllMember(CHAT_TYPE_DICE_INFO, LC_TEXT("%s님이 주사위를 굴려 %d가 나왔습니다. (%d-%d)"), ch->GetName(), n, start, end);
  3394. else
  3395. ch->ChatPacket(CHAT_TYPE_DICE_INFO, LC_TEXT("당신이 주사위를 굴려 %d가 나왔습니다. (%d-%d)"), n, start, end);
  3396. #else
  3397. if (ch->GetParty())
  3398. ch->GetParty()->ChatPacketToAllMember(CHAT_TYPE_INFO, LC_TEXT("%s님이 주사위를 굴려 %d가 나왔습니다. (%d-%d)"), ch->GetName(), n, start, end);
  3399. else
  3400. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("당신이 주사위를 굴려 %d가 나왔습니다. (%d-%d)"), n, start, end);
  3401. #endif
  3402. }
  3403.  
  3404. #ifdef ENABLE_NEWSTUFF
  3405. ACMD(do_click_safebox)
  3406. {
  3407. if ((ch->GetGMLevel() <= GM_PLAYER) && (ch->GetDungeon() || ch->GetWarMap()))
  3408. {
  3409. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot open the safebox in dungeon or at war."));
  3410. return;
  3411. }
  3412.  
  3413. ch->SetSafeboxOpenPosition();
  3414. ch->ChatPacket(CHAT_TYPE_COMMAND, "ShowMeSafeboxPassword");
  3415. }
  3416. ACMD(do_force_logout)
  3417. {
  3418. LPDESC pDesc=DESC_MANAGER::instance().FindByCharacterName(ch->GetName());
  3419. if (!pDesc)
  3420. return;
  3421. pDesc->DelayedDisconnect(0);
  3422. }
  3423. #endif
  3424.  
  3425. ACMD(do_click_mall)
  3426. {
  3427. ch->ChatPacket(CHAT_TYPE_COMMAND, "ShowMeMallPassword");
  3428. }
  3429.  
  3430. ACMD(do_ride)
  3431. {
  3432. dev_log(LOG_DEB0, "[DO_RIDE] start");
  3433. if (ch->IsDead() || ch->IsStun())
  3434. return;
  3435.  
  3436. // 내리기
  3437. {
  3438. if (ch->IsHorseRiding())
  3439. {
  3440. dev_log(LOG_DEB0, "[DO_RIDE] stop riding");
  3441. ch->StopRiding();
  3442. return;
  3443. }
  3444.  
  3445. if (ch->GetMountVnum())
  3446. {
  3447. dev_log(LOG_DEB0, "[DO_RIDE] unmount");
  3448. do_unmount(ch, NULL, 0, 0);
  3449. return;
  3450. }
  3451. }
  3452.  
  3453. // 타기
  3454. {
  3455. if (ch->GetHorse() != NULL)
  3456. {
  3457. dev_log(LOG_DEB0, "[DO_RIDE] start riding");
  3458. ch->StartRiding();
  3459. return;
  3460. }
  3461.  
  3462. for (BYTE i=0; i<INVENTORY_MAX_NUM; ++i)
  3463. {
  3464. LPITEM item = ch->GetInventoryItem(i);
  3465. if (NULL == item)
  3466. continue;
  3467.  
  3468. // 유니크 탈것 아이템
  3469. if (item->IsRideItem())
  3470. {
  3471. if (
  3472. NULL==ch->GetWear(WEAR_UNIQUE1)
  3473. || NULL==ch->GetWear(WEAR_UNIQUE2)
  3474. #ifdef ENABLE_MOUNT_COSTUME_SYSTEM
  3475. || NULL==ch->GetWear(WEAR_COSTUME_MOUNT)
  3476. #endif
  3477. )
  3478. {
  3479. dev_log(LOG_DEB0, "[DO_RIDE] USE UNIQUE ITEM");
  3480. //ch->EquipItem(item);
  3481. ch->UseItem(TItemPos (INVENTORY, i));
  3482. return;
  3483. }
  3484. }
  3485.  
  3486. // 일반 탈것 아이템
  3487. // TODO : 탈것용 SubType 추가
  3488. switch (item->GetVnum())
  3489. {
  3490. case 71114: // 저신이용권
  3491. case 71116: // 산견신이용권
  3492. case 71118: // 투지범이용권
  3493. case 71120: // 사자왕이용권
  3494. dev_log(LOG_DEB0, "[DO_RIDE] USE QUEST ITEM");
  3495. ch->UseItem(TItemPos (INVENTORY, i));
  3496. return;
  3497. }
  3498.  
  3499. // GF mantis #113524, 52001~52090 번 탈것
  3500. if( (item->GetVnum() > 52000) && (item->GetVnum() < 52091) ) {
  3501. dev_log(LOG_DEB0, "[DO_RIDE] USE QUEST ITEM");
  3502. ch->UseItem(TItemPos (INVENTORY, i));
  3503. return;
  3504. }
  3505. }
  3506. }
  3507.  
  3508.  
  3509. // 타거나 내릴 수 없을때
  3510. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말을 먼저 소환해주세요."));
  3511. }
  3512.  
  3513. #ifdef ENABLE_MINIGAME_RUMI_EVENT
  3514. ACMD(do_cards)
  3515. {
  3516. const char *line;
  3517.  
  3518. char arg1[256], arg2[256];
  3519.  
  3520. line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3521. switch (LOWER(arg1[0]))
  3522. {
  3523. case 'o': // open
  3524. if (isdigit(*arg2))
  3525. {
  3526. DWORD safemode;
  3527. str_to_number(safemode, arg2);
  3528. ch->Cards_open(safemode);
  3529. }
  3530. break;
  3531. case 'p': // open
  3532. ch->Cards_pullout();
  3533. break;
  3534. case 'e': // open
  3535. ch->CardsEnd();
  3536. break;
  3537. case 'd': // open
  3538. if (isdigit(*arg2))
  3539. {
  3540. DWORD destroy_index;
  3541. str_to_number(destroy_index, arg2);
  3542. ch->CardsDestroy(destroy_index);
  3543. }
  3544. break;
  3545. case 'a': // open
  3546. if (isdigit(*arg2))
  3547. {
  3548. DWORD accpet_index;
  3549. str_to_number(accpet_index, arg2);
  3550. ch->CardsAccept(accpet_index);
  3551. }
  3552. break;
  3553. case 'r': // open
  3554. if (isdigit(*arg2))
  3555. {
  3556. DWORD restore_index;
  3557. str_to_number(restore_index, arg2);
  3558. ch->CardsRestore(restore_index);
  3559. }
  3560. break;
  3561. default:
  3562. return;
  3563. }
  3564. }
  3565. #endif
  3566.  
  3567. #ifdef ENABLE_MOVE_CHANNEL
  3568. ACMD(do_change_channel)
  3569. {
  3570. char arg1[256];
  3571. one_argument(argument, arg1, sizeof(arg1));
  3572.  
  3573. DWORD channel_number = 0;
  3574. str_to_number(channel_number, arg1);
  3575.  
  3576. //if (ch->m_pkChangeChannelEvent)
  3577. //{
  3578. // ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Change channel canceled."));
  3579. // event_cancel(&ch->m_pkChangeChannelEvent);
  3580. // return;
  3581. //}
  3582.  
  3583. if(!ch)
  3584. {
  3585. return;
  3586. }
  3587.  
  3588. if(channel_number == 99 || g_bChannel == 99){
  3589. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot change channel."));
  3590. return;
  3591. }
  3592.  
  3593. if (ch->GetMapIndex() == 64 || ch->GetMapIndex() == 210)
  3594. {
  3595. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot change channel."));
  3596. return;
  3597. }
  3598.  
  3599. if(channel_number == g_bChannel)
  3600. {
  3601. //ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You are already on this channel."));
  3602. return;
  3603. }
  3604.  
  3605. if (ch->IsDead() || ch->GetExchange())
  3606. {
  3607. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot change channel."));
  3608. return;
  3609. }
  3610.  
  3611. if(channel_number <= 0 || channel_number > 6)
  3612. {
  3613. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Cannot connect to the channel at this time. Please try again later."));
  3614. return;
  3615. }
  3616.  
  3617. if (channel_number != 0)
  3618. {
  3619. if (ch->m_pkChangeChannelEvent)
  3620. {
  3621. //ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("CH_CANCELED"));
  3622. event_cancel(&ch->m_pkChangeChannelEvent);
  3623. return;
  3624. }
  3625.  
  3626. ChangeChannelEventInfo* info = AllocEventInfo<ChangeChannelEventInfo>();
  3627.  
  3628. {
  3629. if (ch->IsPosition(POS_FIGHTING))
  3630. info->left_second = 10;
  3631. else
  3632. info->left_second = 3;
  3633. }
  3634.  
  3635. info->ch = ch;
  3636. info->channel_number = channel_number;
  3637.  
  3638. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Please wait a moment. Changing channel..."));
  3639. ch->m_pkChangeChannelEvent = event_create(change_channel_event, info, 1);
  3640. }
  3641. }
  3642. #endif
  3643.  
  3644. #ifdef __AUCTION__
  3645. // temp_auction
  3646. ACMD(do_get_item_id_list)
  3647. {
  3648. for (int i = 0; i < INVENTORY_MAX_NUM; i++)
  3649. {
  3650. LPITEM item = ch->GetInventoryItem(i);
  3651. if (item != NULL)
  3652. ch->ChatPacket(CHAT_TYPE_INFO, "name : %s id : %d", item->GetProto()->szName, item->GetID());
  3653. }
  3654. }
  3655.  
  3656. // temp_auction
  3657.  
  3658. ACMD(do_enroll_auction)
  3659. {
  3660. char arg1[256];
  3661. char arg2[256];
  3662. char arg3[256];
  3663. char arg4[256];
  3664. two_arguments (two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3), arg4, sizeof(arg4));
  3665.  
  3666. DWORD item_id = strtoul(arg1, NULL, 10);
  3667. BYTE empire = strtoul(arg2, NULL, 10);
  3668. int bidPrice = strtol(arg3, NULL, 10);
  3669. int immidiatePurchasePrice = strtol(arg4, NULL, 10);
  3670.  
  3671. LPITEM item = ITEM_MANAGER::instance().Find(item_id);
  3672. if (item == NULL)
  3673. return;
  3674.  
  3675. AuctionManager::instance().enroll_auction(ch, item, empire, bidPrice, immidiatePurchasePrice);
  3676. }
  3677.  
  3678. ACMD(do_enroll_wish)
  3679. {
  3680. char arg1[256];
  3681. char arg2[256];
  3682. char arg3[256];
  3683. one_argument (two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3));
  3684.  
  3685. DWORD item_num = strtoul(arg1, NULL, 10);
  3686. BYTE empire = strtoul(arg2, NULL, 10);
  3687. int wishPrice = strtol(arg3, NULL, 10);
  3688.  
  3689. AuctionManager::instance().enroll_wish(ch, item_num, empire, wishPrice);
  3690. }
  3691.  
  3692. ACMD(do_enroll_sale)
  3693. {
  3694. char arg1[256];
  3695. char arg2[256];
  3696. char arg3[256];
  3697. one_argument (two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3));
  3698.  
  3699. DWORD item_id = strtoul(arg1, NULL, 10);
  3700. DWORD wisher_id = strtoul(arg2, NULL, 10);
  3701. int salePrice = strtol(arg3, NULL, 10);
  3702.  
  3703. LPITEM item = ITEM_MANAGER::instance().Find(item_id);
  3704. if (item == NULL)
  3705. return;
  3706.  
  3707. AuctionManager::instance().enroll_sale(ch, item, wisher_id, salePrice);
  3708. }
  3709.  
  3710. // temp_auction
  3711. // packet으로 통신하게 하고, 이건 삭제해야한다.
  3712. ACMD(do_get_auction_list)
  3713. {
  3714. char arg1[256];
  3715. char arg2[256];
  3716. char arg3[256];
  3717. two_arguments (one_argument (argument, arg1, sizeof(arg1)), arg2, sizeof(arg2), arg3, sizeof(arg3));
  3718.  
  3719. AuctionManager::instance().get_auction_list (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10), strtoul(arg3, NULL, 10));
  3720. }
  3721. //
  3722. //ACMD(do_get_wish_list)
  3723. //{
  3724. // char arg1[256];
  3725. // char arg2[256];
  3726. // char arg3[256];
  3727. // two_arguments (one_argument (argument, arg1, sizeof(arg1)), arg2, sizeof(arg2), arg3, sizeof(arg3));
  3728. //
  3729. // AuctionManager::instance().get_wish_list (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10), strtoul(arg3, NULL, 10));
  3730. //}
  3731. ACMD (do_get_my_auction_list)
  3732. {
  3733. char arg1[256];
  3734. char arg2[256];
  3735. two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3736.  
  3737. AuctionManager::instance().get_my_auction_list (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
  3738. }
  3739.  
  3740. ACMD (do_get_my_purchase_list)
  3741. {
  3742. char arg1[256];
  3743. char arg2[256];
  3744. two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3745.  
  3746. AuctionManager::instance().get_my_purchase_list (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
  3747. }
  3748.  
  3749. ACMD (do_auction_bid)
  3750. {
  3751. char arg1[256];
  3752. char arg2[256];
  3753. two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3754.  
  3755. AuctionManager::instance().bid (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
  3756. }
  3757.  
  3758. ACMD (do_auction_impur)
  3759. {
  3760. char arg1[256];
  3761. one_argument (argument, arg1, sizeof(arg1));
  3762.  
  3763. AuctionManager::instance().immediate_purchase (ch, strtoul(arg1, NULL, 10));
  3764. }
  3765.  
  3766. ACMD (do_get_auctioned_item)
  3767. {
  3768. char arg1[256];
  3769. char arg2[256];
  3770. two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3771.  
  3772. AuctionManager::instance().get_auctioned_item (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
  3773. }
  3774.  
  3775. ACMD (do_buy_sold_item)
  3776. {
  3777. char arg1[256];
  3778. char arg2[256];
  3779. one_argument (argument, arg1, sizeof(arg1));
  3780.  
  3781. AuctionManager::instance().get_auctioned_item (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
  3782. }
  3783.  
  3784. ACMD (do_cancel_auction)
  3785. {
  3786. char arg1[256];
  3787. one_argument (argument, arg1, sizeof(arg1));
  3788.  
  3789. AuctionManager::instance().cancel_auction (ch, strtoul(arg1, NULL, 10));
  3790. }
  3791.  
  3792. ACMD (do_cancel_wish)
  3793. {
  3794. char arg1[256];
  3795. one_argument (argument, arg1, sizeof(arg1));
  3796.  
  3797. AuctionManager::instance().cancel_wish (ch, strtoul(arg1, NULL, 10));
  3798. }
  3799.  
  3800. ACMD (do_cancel_sale)
  3801. {
  3802. char arg1[256];
  3803. one_argument (argument, arg1, sizeof(arg1));
  3804.  
  3805. AuctionManager::instance().cancel_sale (ch, strtoul(arg1, NULL, 10));
  3806. }
  3807.  
  3808. ACMD (do_rebid)
  3809. {
  3810. char arg1[256];
  3811. char arg2[256];
  3812. two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3813.  
  3814. AuctionManager::instance().rebid (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
  3815. }
  3816.  
  3817. ACMD (do_bid_cancel)
  3818. {
  3819. char arg1[256];
  3820. char arg2[256];
  3821. two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3822.  
  3823. AuctionManager::instance().bid_cancel (ch, strtoul(arg1, NULL, 10));
  3824. }
  3825. #endif
  3826.  
  3827. #ifdef ENABLE_DS_CHANGE_ATTR
  3828. ACMD(do_ds_change_attr)
  3829. {
  3830. char arg1[256];
  3831. one_argument(argument, arg1, sizeof(arg1));
  3832.  
  3833. if (!*arg1)
  3834. return;
  3835.  
  3836. if (ch->GetExchange() || ch->GetMyShop() || ch->GetShopOwner() || ch->IsOpenSafebox() || ch->IsCubeOpen()) {
  3837. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´U¸¥ °A·¡A¢AI ¿¸°≫oAA¿¡¼´A ≫oA¡°A·¡¸| CO¼o °¡ ¾ø½A´I´U."));
  3838. return;
  3839. }
  3840.  
  3841. DWORD dwPos = 0;
  3842. str_to_number(dwPos, arg1);
  3843. // M K L B E
  3844. const BYTE needFireCountList[] = { 1, 3, 9, 27, 81 };
  3845. BYTE bNeedFire = -1;
  3846.  
  3847. if (dwPos < 0 || dwPos >= DRAGON_SOUL_INVENTORY_MAX_NUM)
  3848. return;
  3849.  
  3850. LPITEM item = ch->GetItem(TItemPos(DRAGON_SOUL_INVENTORY, dwPos));
  3851.  
  3852. if (!item || item->IsExchanging() || item->IsEquipped())
  3853. return;
  3854.  
  3855. if (item->IsDragonSoul()) {
  3856. bNeedFire = needFireCountList[(item->GetVnum() / 100) % 10];
  3857. if (bNeedFire != -1) {
  3858. if (DSManager::instance().IsActiveDragonSoul(item) == true)
  3859. {
  3860. //ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("CANNOT_CHANGE_BONUS_OF_EQUIPPED_DRAGON_SOUL_ITEM"));
  3861. return;
  3862. }
  3863.  
  3864. if (!ch->CountSpecifyItem(100700) >= bNeedFire)
  3865. {
  3866. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("CANNOT_CHANGE_BONUS_YOU_HAVE_NOT_ENOUGH_FLAMES"));
  3867. return;
  3868. }
  3869.  
  3870. bool ret2 = DSManager::instance().PutAttributes2(item);
  3871.  
  3872. if (!ret2 == true)
  3873. {
  3874. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("This Dragon Stone Bonus cannot be changed."));
  3875. return;
  3876. }
  3877. if (ch->CountSpecifyItem(100700) >= bNeedFire)
  3878. {
  3879. for (BYTE i=0;i < 6;i++)
  3880. {
  3881. item->SetForceAttribute(i, 0, 0);
  3882. }
  3883. }
  3884.  
  3885. if (ch->CountSpecifyItem(100700) >= bNeedFire)
  3886. {
  3887. bool ret = DSManager::instance().PutAttributes2(item);
  3888. if (ch->GetGold() < 500000)
  3889. {
  3890. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("YOU_DONT_HAVE_ENOUGH_MONEY"));
  3891. return;
  3892. }
  3893. else
  3894. {
  3895. ch->PointChange(POINT_GOLD, -500000);
  3896. }
  3897.  
  3898. if (ret == true)
  3899. {
  3900. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("SUCCESSFULLY_CHANGED_BONUS_OF_DRAGON_SOUL_ITEM"));
  3901. ch->RemoveSpecifyItem(100700, bNeedFire);
  3902. // DSManager::instance().PutAttributes2(item);
  3903. ch->ChatPacket(CHAT_TYPE_COMMAND, "DS_ChangeAttr_Success");
  3904. }
  3905. else
  3906. {
  3907. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("FAILED_CHANGING_BONUS_OF_DRAGON_SOUL_ITEM"));
  3908. ch->ChatPacket(CHAT_TYPE_COMMAND, "DS_ChangeAttr_Failed");
  3909. }
  3910. }
  3911. else
  3912. {
  3913. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("CANNOT_CHANGE_BONUS_YOU_HAVE_NOT_ENOUGH_FLAMES"));
  3914. return;
  3915. }
  3916. // for (BYTE i=0;i < 6;i++) { item->SetForceAttribute(i, 0, 0); }
  3917. }
  3918. }
  3919. }
  3920. #endif
  3921.  
  3922. #ifdef WJ_ELDER_ATTRIBUTE_SYSTEM
  3923. ACMD(do_add_new_attribute)
  3924. {
  3925. std::vector<std::string> vecArgs;
  3926. split_argument(argument,vecArgs);
  3927.  
  3928. if (vecArgs.size() < 6)
  3929. {
  3930. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NEW_ATTRIBUTE_UNKNOWN_ARGUMENT"));
  3931. return;
  3932. }
  3933.  
  3934. int sourceItemPos, targetItemPos, attrtype0, attrtype1, attrtype2, attrtype3;
  3935. // int targetItemPos;
  3936. // int attrtype0;
  3937. // int attrtype1;
  3938. // int attrtype2;
  3939. // int attrtype3;
  3940.  
  3941. str_to_number(sourceItemPos, vecArgs[1].c_str());
  3942. str_to_number(targetItemPos, vecArgs[2].c_str());
  3943. str_to_number(attrtype0, vecArgs[3].c_str());
  3944. str_to_number(attrtype1, vecArgs[4].c_str());
  3945. str_to_number(attrtype2, vecArgs[5].c_str());
  3946. str_to_number(attrtype3, vecArgs[6].c_str());
  3947.  
  3948. LPITEM item = ch->GetInventoryItem(targetItemPos);
  3949.  
  3950. if (!item)
  3951. {
  3952. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NEW_ATTRIBUTE_CANNOT_FIND_ITEM"));
  3953. return;
  3954. }
  3955.  
  3956. if (item->GetType() != ITEM_WEAPON && item->GetType() != ITEM_ARMOR)
  3957. {
  3958. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NEW_ATTRIBUTE_COSTUME"));
  3959. return;
  3960. }
  3961.  
  3962. if (item->IsEquipped())
  3963. {
  3964. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NEW_ATTRIBUTE_EQUIPPED"));
  3965. return;
  3966. }
  3967.  
  3968. if (item->IsExchanging())
  3969. {
  3970. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NEW_ATTRIBUTE_EXCHANGING"));
  3971. return;
  3972. }
  3973.  
  3974. if (ch->CountSpecifyItem(71051) < 1)
  3975. {
  3976. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NEW_ATTRIBUTE_ENOUGH_NEW_ATTRIBUTE"));
  3977. return;
  3978. }
  3979.  
  3980. TItemTable const * pProto = item->GetProto();
  3981.  
  3982. bool addontype = false;
  3983. if (pProto && pProto->sAddonType)
  3984. addontype = true;
  3985.  
  3986. int attrtype0prob = number(1,5), attrtype1prob = number(1,5), attrtype2prob = number(1,5), attrtype3prob = number(1,5);
  3987. // int attrtype1prob = number(1,5);
  3988. // int attrtype2prob = number(1,5);
  3989. // int attrtype3prob = number(1,5);
  3990.  
  3991. bool error = false;
  3992. if (addontype == false)
  3993. {
  3994. if (attrtype0 == attrtype1 || attrtype0 == attrtype2 || attrtype0 == attrtype3 || attrtype0 == item->GetAttributeType(4))
  3995. error = true;
  3996. if (attrtype1 == attrtype0 || attrtype1 == attrtype2 || attrtype1 == attrtype3 || attrtype1 == item->GetAttributeType(4))
  3997. error = true;
  3998. if (attrtype2 == attrtype0 || attrtype2 == attrtype0 || attrtype2 == attrtype3 || attrtype2 == item->GetAttributeType(4))
  3999. error = true;
  4000. if (attrtype3 == attrtype0 || attrtype3 == attrtype1 || attrtype3 == attrtype2 || attrtype3 == item->GetAttributeType(4))
  4001. error = true;
  4002. if (item->GetAttributeType(4) == attrtype0 || item->GetAttributeType(4) == attrtype1 || item->GetAttributeType(4) == attrtype2 || item->GetAttributeType(4) == attrtype3)
  4003. error = true;
  4004. }
  4005. else
  4006. {
  4007. if (attrtype0 == attrtype1 || attrtype0 == item->GetAttributeType(4))
  4008. error = true;
  4009. if (attrtype1 == attrtype0 || attrtype1 == item->GetAttributeType(4))
  4010. error = true;
  4011. }
  4012.  
  4013. for (int i=0; i < 4; ++i)
  4014. {
  4015. if (addontype == false)
  4016. {
  4017. if (item->GetAttributeType(i) == attrtype0 && i != 0)
  4018. error = true;
  4019. if (item->GetAttributeType(i) == attrtype1 && i != 1)
  4020. error = true;
  4021. if (item->GetAttributeType(i) == attrtype2 && i != 2)
  4022. error = true;
  4023. if (item->GetAttributeType(i) == attrtype3 && i != 3)
  4024. error = true;
  4025. }
  4026. else
  4027. {
  4028. if (item->GetAttributeType(i+2) == attrtype0 && i != 0)
  4029. error = true;
  4030. if (item->GetAttributeType(i+2) == attrtype1 && i != 1)
  4031. error = true;
  4032. }
  4033. }
  4034. if (error)
  4035. {
  4036. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NEW_ATTRIBUTE_ERROR"));
  4037. return;
  4038. }
  4039.  
  4040. if (addontype == false)
  4041. {
  4042. item->AddNewAttr(0, attrtype0, attrtype0prob);
  4043. item->AddNewAttr(1, attrtype1, attrtype1prob);
  4044. item->AddNewAttr(2, attrtype2, attrtype2prob);
  4045. item->AddNewAttr(3, attrtype3, attrtype3prob);
  4046. }
  4047. else
  4048. {
  4049. int oldattr5type = item->GetAttributeType(4), oldattr5value = item->GetAttributeValue(4);
  4050. // int oldattr5value = item->GetAttributeValue(4);
  4051.  
  4052. item->RemoveAttributeAt(0);
  4053. item->RemoveAttributeAt(1);
  4054. item->ApplyAddon(100);
  4055. item->ChangeAttribute();
  4056. item->AddNewAttr(2, attrtype0, attrtype0prob);
  4057. item->AddNewAttr(3, attrtype1, attrtype1prob);
  4058. item->AddNewAttr(4, oldattr5type, oldattr5value);
  4059.  
  4060. if (item->GetAttributeType(1) != 71)
  4061. {
  4062. if (item->GetAttributeType(0) != 72)
  4063. {
  4064. item->SetForceAttribute(0, 72, 13);
  4065. item->SetForceAttribute(1, 71, 1);
  4066. }
  4067. else
  4068. item->SetForceAttribute(1, 71, -1);
  4069. }
  4070. }
  4071.  
  4072. ch->RemoveSpecifyItem(71051, 1);
  4073. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NEW_ATTRIBUTE_SUCCESS_ATTR"));
  4074. }
  4075. #endif
  4076.  
Advertisement
Add Comment
Please, Sign In to add comment