Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1.  
  2. #include "stdafx.h"
  3.  
  4. #include "config.h"
  5. #include "char.h"
  6. #include "char_manager.h"
  7. #include "affect.h"
  8. #include "packet.h"
  9. #include "buffer_manager.h"
  10. #include "desc_client.h"
  11. #include "battle.h"
  12. #include "guild.h"
  13. #include "utils.h"
  14. #include "locale_service.h"
  15. #include "lua_incl.h"
  16. #include "arena.h"
  17. #include "horsename_manager.h"
  18. #include "item.h"
  19. #include "DragonSoul.h"
  20.  
  21. #define IS_NO_SAVE_AFFECT(type) ((type) == AFFECT_WAR_FLAG || (type) == AFFECT_REVIVE_INVISIBLE || ((type) >= AFFECT_PREMIUM_START && (type) <= AFFECT_PREMIUM_END))
  22. #define IS_NO_CLEAR_ON_DEATH_AFFECT(type) ((type) == AFFECT_BLOCK_CHAT || ((type) >= 500 && (type) < 600))
  23.  
  24. void SendAffectRemovePacket(LPDESC d, DWORD pid, DWORD type, BYTE point)
  25. {
  26. TPacketGCAffectRemove ptoc;
  27. ptoc.bHeader = HEADER_GC_AFFECT_REMOVE;
  28. ptoc.dwType = type;
  29. ptoc.bApplyOn = point;
  30. d->Packet(&ptoc, sizeof(TPacketGCAffectRemove));
  31.  
  32. TPacketGDRemoveAffect ptod;
  33. ptod.dwPID = pid;
  34. ptod.dwType = type;
  35. ptod.bApplyOn = point;
  36. db_clientdesc->DBPacket(HEADER_GD_REMOVE_AFFECT, 0, &ptod, sizeof(ptod));
  37. }
  38.  
  39. void SendAffectAddPacket(LPDESC d, CAffect * pkAff)
  40. {
  41. TPacketGCAffectAdd ptoc;
  42. ptoc.bHeader = HEADER_GC_AFFECT_ADD;
  43. ptoc.elem.dwType = pkAff->dwType;
  44. ptoc.elem.bApplyOn = pkAff->bApplyOn;
  45. ptoc.elem.lApplyValue = pkAff->lApplyValue;
  46. ptoc.elem.dwFlag = pkAff->dwFlag;
  47. ptoc.elem.lDuration = pkAff->lDuration;
  48. ptoc.elem.lSPCost = pkAff->lSPCost;
  49. d->Packet(&ptoc, sizeof(TPacketGCAffectAdd));
  50. }
  51. ////////////////////////////////////////////////////////////////////
  52. // Affect
  53. CAffect * CHARACTER::FindAffect(DWORD dwType, BYTE bApply) const
  54. {
  55. auto it = m_list_pkAffect.begin();
  56.  
  57. while (it != m_list_pkAffect.end())
  58. {
  59. CAffect * pkAffect = *it++;
  60.  
  61. if (pkAffect->dwType == dwType && (bApply == APPLY_NONE || bApply == pkAffect->bApplyOn))
  62. return pkAffect;
  63. }
  64.  
  65. return NULL;
  66. }
  67.  
  68. EVENTFUNC(affect_event)
  69. {
  70. char_event_info* info = dynamic_cast<char_event_info*>( event->info );
  71.  
  72. if ( info == NULL )
  73. {
  74. sys_err( "affect_event> <Factor> Null pointer" );
  75. return 0;
  76. }
  77.  
  78. LPCHARACTER ch = info->ch;
  79.  
  80. if (ch == NULL) { // <Factor>
  81. return 0;
  82. }
  83.  
  84. if (!ch->UpdateAffect())
  85. return 0;
  86. else
  87. return passes_per_sec; // 1ÃÊ
  88. }
  89.  
  90. bool CHARACTER::UpdateAffect()
  91. {
  92.  
  93. if (IsAffectFlag(AFF_GWIGUM) && !GetWear(WEAR_WEAPON))
  94. RemoveAffect(SKILL_GWIGEOM);
  95.  
  96. if (IsAffectFlag(AFF_GEOMGYEONG) && !GetWear(WEAR_WEAPON))
  97. RemoveAffect(SKILL_GEOMKYUNG);
  98.  
  99. // affect_event ¿¡¼­ ó¸®ÇÒ ÀÏÀº ¾Æ´ÏÁö¸¸, 1ÃÊÂ¥¸® À̺¥Æ®¿¡¼­ ó¸®ÇÏ´Â °ÍÀÌ
  100. // ÀÌ°Í »ÓÀÌ¶ó ¿©±â¼­ ¹°¾à 󸮸¦ ÇÑ´Ù.
  101. if (GetPoint(POINT_HP_RECOVERY) > 0)
  102. {
  103. if (GetMaxHP() <= GetHP())
  104. {
  105. PointChange(POINT_HP_RECOVERY, -GetPoint(POINT_HP_RECOVERY));
  106. }
  107. else
  108. {
  109. int iVal = 0;
  110.  
  111. if (LC_IsYMIR())
  112. {
  113. iVal = MIN(GetPoint(POINT_HP_RECOVERY), GetMaxHP() * 9 / 100);
  114. }
  115. else
  116. {
  117. iVal = MIN(GetPoint(POINT_HP_RECOVERY), GetMaxHP() * 7 / 100);
  118. }
  119.  
  120. PointChange(POINT_HP, iVal);
  121. PointChange(POINT_HP_RECOVERY, -iVal);
  122. }
  123. }
  124.  
  125. if (GetPoint(POINT_SP_RECOVERY) > 0)
  126. {
  127. if (GetMaxSP() <= GetSP())
  128. PointChange(POINT_SP_RECOVERY, -GetPoint(POINT_SP_RECOVERY));
  129. else
  130. {
  131. int iVal;
  132.  
  133. if (!g_iUseLocale)
  134. iVal = MIN(GetPoint(POINT_SP_RECOVERY), GetMaxSP() * 7 / 100);
  135. else
  136. iVal = MIN(GetPoint(POINT_SP_RECOVERY), GetMaxSP() * 7 / 100);
  137.  
  138. PointChange(POINT_SP, iVal);
  139. PointChange(POINT_SP_RECOVERY, -iVal);
  140. }
  141. }
  142.  
  143. if (GetPoint(POINT_HP_RECOVER_CONTINUE) > 0)
  144. {
  145. PointChange(POINT_HP, GetPoint(POINT_HP_RECOVER_CONTINUE));
  146. }
  147.  
  148. if (GetPoint(POINT_SP_RECOVER_CONTINUE) > 0)
  149. {
  150. PointChange(POINT_SP, GetPoint(POINT_SP_RECOVER_CONTINUE));
  151. }
  152.  
  153. AutoRecoveryItemProcess( AFFECT_AUTO_HP_RECOVERY );
  154. AutoRecoveryItemProcess( AFFECT_AUTO_SP_RECOVERY );
  155.  
  156. // ½ºÅ׹̳ª ȸº¹
  157. if (GetMaxStamina() > GetStamina())
  158. {
  159. int iSec = (get_dword_time() - GetStopTime()) / 3000;
  160. if (iSec)
  161. PointChange(POINT_STAMINA, GetMaxStamina()/1);
  162. }
  163.  
  164.  
  165. // ProcessAffect´Â affect°¡ ¾øÀ¸¸é true¸¦ ¸®ÅÏÇÑ´Ù.
  166. if (ProcessAffect())
  167. if (GetPoint(POINT_HP_RECOVERY) == 0 && GetPoint(POINT_SP_RECOVERY) == 0 && GetStamina() == GetMaxStamina())
  168. {
  169. m_pkAffectEvent = NULL;
  170. return false;
  171. }
  172.  
  173. return true;
  174. }
  175.  
  176. void CHARACTER::StartAffectEvent()
  177. {
  178. if (m_pkAffectEvent)
  179. return;
  180.  
  181. char_event_info* info = AllocEventInfo<char_event_info>();
  182. info->ch = this;
  183. m_pkAffectEvent = event_create(affect_event, info, passes_per_sec);
  184. sys_log(1, "StartAffectEvent %s %p %p", GetName(), this, get_pointer(m_pkAffectEvent));
  185. }
  186.  
  187. void CHARACTER::ClearAffect(bool bSave)
  188. {
  189. TAffectFlag afOld = m_afAffectFlag;
  190. WORD wMovSpd = GetPoint(POINT_MOV_SPEED);
  191. WORD wAttSpd = GetPoint(POINT_ATT_SPEED);
  192.  
  193. auto it = m_list_pkAffect.begin();
  194.  
  195. while (it != m_list_pkAffect.end())
  196. {
  197. CAffect * pkAff = *it;
  198.  
  199. if (bSave)
  200. {
  201. if ( IS_NO_CLEAR_ON_DEATH_AFFECT(pkAff->dwType) || IS_NO_SAVE_AFFECT(pkAff->dwType) )
  202. {
  203. ++it;
  204. continue;
  205. }
  206.  
  207. #ifdef ENABLE_NEW_AFFECT_POTION
  208. int pkAff_blend[] = {AFFECT_POTION_1, AFFECT_POTION_2, AFFECT_POTION_3, AFFECT_POTION_4, AFFECT_POTION_5, AFFECT_POTION_6};
  209.  
  210. if ((pkAff->dwType == pkAff_blend[0]) || (pkAff->dwType == pkAff_blend[1]) || (pkAff->dwType == pkAff_blend[2]) ||
  211. (pkAff->dwType == pkAff_blend[3]) || (pkAff->dwType == pkAff_blend[4]) || (pkAff->dwType == pkAff_blend[5]))
  212. {
  213. ++it;
  214. continue;
  215. }
  216. #endif
  217.  
  218. if (IsPC())
  219. {
  220. SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
  221. }
  222. }
  223.  
  224. ComputeAffect(pkAff, false);
  225.  
  226. it = m_list_pkAffect.erase(it);
  227. CAffect::Release(pkAff);
  228. }
  229.  
  230. if (afOld != m_afAffectFlag ||
  231. wMovSpd != GetPoint(POINT_MOV_SPEED) ||
  232. wAttSpd != GetPoint(POINT_ATT_SPEED))
  233. UpdatePacket();
  234.  
  235. CheckMaximumPoints();
  236.  
  237. if (m_list_pkAffect.empty())
  238. event_cancel(&m_pkAffectEvent);
  239. }
  240.  
  241. int CHARACTER::ProcessAffect()
  242. {
  243. bool bDiff = false;
  244. CAffect *pkAff = NULL;
  245.  
  246. //
  247. // ÇÁ¸®¹Ì¾ö ó¸®
  248. //
  249. for (int i = 0; i <= PREMIUM_MAX_NUM; ++i)
  250. {
  251. int aff_idx = i + AFFECT_PREMIUM_START;
  252.  
  253. pkAff = FindAffect(aff_idx);
  254.  
  255. if (!pkAff)
  256. continue;
  257.  
  258. int remain = GetPremiumRemainSeconds(i);
  259.  
  260. if (remain < 0)
  261. {
  262. RemoveAffect(aff_idx);
  263. bDiff = true;
  264. }
  265. else
  266. pkAff->lDuration = remain + 1;
  267. }
  268.  
  269. ////////// HAIR_AFFECT
  270. pkAff = FindAffect(AFFECT_HAIR);
  271. if (pkAff)
  272. {
  273. // IF HAIR_LIMIT_TIME() < CURRENT_TIME()
  274. if ( this->GetQuestFlag("hair.limit_time") < get_global_time())
  275. {
  276. // SET HAIR NORMAL
  277. this->SetPart(PART_HAIR, 0);
  278. // REMOVE HAIR AFFECT
  279. RemoveAffect(AFFECT_HAIR);
  280. }
  281. else
  282. {
  283. // INCREASE AFFECT DURATION
  284. ++(pkAff->lDuration);
  285. }
  286. }
  287. ////////// HAIR_AFFECT
  288. //
  289.  
  290. CHorseNameManager::instance().Validate(this);
  291.  
  292. TAffectFlag afOld = m_afAffectFlag;
  293. long lMovSpd = GetPoint(POINT_MOV_SPEED);
  294. long lAttSpd = GetPoint(POINT_ATT_SPEED);
  295.  
  296. auto it = m_list_pkAffect.begin();
  297.  
  298. while (it != m_list_pkAffect.end())
  299. {
  300. pkAff = *it;
  301.  
  302. bool bEnd = false;
  303.  
  304. if (pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)
  305. {
  306. if (!GetGuild() || !GetGuild()->UnderAnyWar())
  307. bEnd = true;
  308. }
  309.  
  310. if (pkAff->lSPCost > 0)
  311. {
  312. if (GetSP() < pkAff->lSPCost)
  313. bEnd = true;
  314. else
  315. PointChange(POINT_SP, -pkAff->lSPCost);
  316. }
  317.  
  318. // AFFECT_DURATION_BUG_FIX
  319. // ¹«ÇÑ È¿°ú ¾ÆÀÌÅÛµµ ½Ã°£À» ÁÙÀδÙ.
  320. // ½Ã°£À» ¸Å¿ì Å©°Ô Àâ±â ¶§¹®¿¡ »ó°ü ¾øÀ» °ÍÀ̶ó »ý°¢µÊ.
  321. if ( --pkAff->lDuration <= 0 )
  322. {
  323. bEnd = true;
  324. }
  325. // END_AFFECT_DURATION_BUG_FIX
  326.  
  327. if (bEnd)
  328. {
  329. it = m_list_pkAffect.erase(it);
  330. ComputeAffect(pkAff, false);
  331. bDiff = true;
  332. if (IsPC())
  333. {
  334. SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
  335. }
  336.  
  337. CAffect::Release(pkAff);
  338.  
  339. continue;
  340. }
  341.  
  342. ++it;
  343. }
  344.  
  345. if (bDiff)
  346. {
  347. if (afOld != m_afAffectFlag ||
  348. lMovSpd != GetPoint(POINT_MOV_SPEED) ||
  349. lAttSpd != GetPoint(POINT_ATT_SPEED))
  350. {
  351. UpdatePacket();
  352. }
  353.  
  354. CheckMaximumPoints();
  355. }
  356.  
  357. if (m_list_pkAffect.empty())
  358. return true;
  359.  
  360. return false;
  361. }
  362.  
  363. void CHARACTER::SaveAffect()
  364. {
  365. TPacketGDAddAffect p;
  366.  
  367. auto it = m_list_pkAffect.begin();
  368.  
  369. while (it != m_list_pkAffect.end())
  370. {
  371. CAffect * pkAff = *it++;
  372.  
  373. if (IS_NO_SAVE_AFFECT(pkAff->dwType))
  374. continue;
  375.  
  376. sys_log(1, "AFFECT_SAVE: %u %u %d %d", pkAff->dwType, pkAff->bApplyOn, pkAff->lApplyValue, pkAff->lDuration);
  377.  
  378. p.dwPID = GetPlayerID();
  379. p.elem.dwType = pkAff->dwType;
  380. p.elem.bApplyOn = pkAff->bApplyOn;
  381. p.elem.lApplyValue = pkAff->lApplyValue;
  382. p.elem.dwFlag = pkAff->dwFlag;
  383. p.elem.lDuration = pkAff->lDuration;
  384. p.elem.lSPCost = pkAff->lSPCost;
  385. db_clientdesc->DBPacket(HEADER_GD_ADD_AFFECT, 0, &p, sizeof(p));
  386. }
  387. }
  388.  
  389. EVENTINFO(load_affect_login_event_info)
  390. {
  391. DWORD pid;
  392. DWORD count;
  393. char* data;
  394.  
  395. load_affect_login_event_info()
  396. : pid( 0 )
  397. , count( 0 )
  398. , data( 0 )
  399. {
  400. }
  401. };
  402.  
  403. EVENTFUNC(load_affect_login_event)
  404. {
  405. load_affect_login_event_info* info = dynamic_cast<load_affect_login_event_info*>( event->info );
  406.  
  407. if ( info == NULL )
  408. {
  409. sys_err( "load_affect_login_event_info> <Factor> Null pointer" );
  410. return 0;
  411. }
  412.  
  413. DWORD dwPID = info->pid;
  414. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID);
  415.  
  416. if (!ch)
  417. {
  418. M2_DELETE_ARRAY(info->data);
  419. return 0;
  420. }
  421.  
  422. LPDESC d = ch->GetDesc();
  423.  
  424. if (!d)
  425. {
  426. M2_DELETE_ARRAY(info->data);
  427. return 0;
  428. }
  429.  
  430. if (d->IsPhase(PHASE_HANDSHAKE) ||
  431. d->IsPhase(PHASE_LOGIN) ||
  432. d->IsPhase(PHASE_SELECT) ||
  433. d->IsPhase(PHASE_DEAD) ||
  434. d->IsPhase(PHASE_LOADING))
  435. {
  436. return PASSES_PER_SEC(1);
  437. }
  438. else if (d->IsPhase(PHASE_CLOSE))
  439. {
  440. M2_DELETE_ARRAY(info->data);
  441. return 0;
  442. }
  443. else if (d->IsPhase(PHASE_GAME))
  444. {
  445. sys_log(1, "Affect Load by Event");
  446. ch->LoadAffect(info->count, (TPacketAffectElement*)info->data);
  447. M2_DELETE_ARRAY(info->data);
  448. return 0;
  449. }
  450. else
  451. {
  452. sys_err("input_db.cpp:quest_login_event INVALID PHASE pid %d", ch->GetPlayerID());
  453. M2_DELETE_ARRAY(info->data);
  454. return 0;
  455. }
  456. }
  457.  
  458. void CHARACTER::LoadAffect(DWORD dwCount, TPacketAffectElement * pElements)
  459. {
  460. m_bIsLoadedAffect = false;
  461.  
  462. if (!GetDesc()->IsPhase(PHASE_GAME))
  463. {
  464. if (test_server)
  465. sys_log(0, "LOAD_AFFECT: Creating Event", GetName(), dwCount);
  466.  
  467. load_affect_login_event_info* info = AllocEventInfo<load_affect_login_event_info>();
  468.  
  469. info->pid = GetPlayerID();
  470. info->count = dwCount;
  471. info->data = M2_NEW char[sizeof(TPacketAffectElement) * dwCount];
  472. thecore_memcpy(info->data, pElements, sizeof(TPacketAffectElement) * dwCount);
  473.  
  474. event_create(load_affect_login_event, info, PASSES_PER_SEC(1));
  475.  
  476. return;
  477. }
  478.  
  479. ClearAffect(true);
  480.  
  481. if (test_server)
  482. sys_log(0, "LOAD_AFFECT: %s count %d", GetName(), dwCount);
  483.  
  484. TAffectFlag afOld = m_afAffectFlag;
  485.  
  486. long lMovSpd = GetPoint(POINT_MOV_SPEED);
  487. long lAttSpd = GetPoint(POINT_ATT_SPEED);
  488.  
  489. for (DWORD i = 0; i < dwCount; ++i, ++pElements)
  490. {
  491. // ¹«¿µÁøÀº ·ÎµåÇÏÁö¾Ê´Â´Ù.
  492. if (pElements->dwType == SKILL_MUYEONG)
  493. continue;
  494.  
  495. if (AFFECT_AUTO_HP_RECOVERY == pElements->dwType || AFFECT_AUTO_SP_RECOVERY == pElements->dwType)
  496. {
  497. LPITEM item = FindItemByID( pElements->dwFlag );
  498.  
  499. if (NULL == item)
  500. continue;
  501.  
  502. item->Lock(true);
  503. }
  504.  
  505. if (pElements->bApplyOn >= POINT_MAX_NUM)
  506. {
  507. sys_err("invalid affect data %s ApplyOn %u ApplyValue %d",
  508. GetName(), pElements->bApplyOn, pElements->lApplyValue);
  509. continue;
  510. }
  511.  
  512. if (test_server)
  513. {
  514. sys_log(0, "Load Affect : Affect %s %d %d", GetName(), pElements->dwType, pElements->bApplyOn );
  515. }
  516.  
  517. CAffect* pkAff = CAffect::Acquire();
  518. m_list_pkAffect.push_back(pkAff);
  519.  
  520. pkAff->dwType = pElements->dwType;
  521. pkAff->bApplyOn = pElements->bApplyOn;
  522. pkAff->lApplyValue = pElements->lApplyValue;
  523. pkAff->dwFlag = pElements->dwFlag;
  524. pkAff->lDuration = pElements->lDuration;
  525. pkAff->lSPCost = pElements->lSPCost;
  526.  
  527. SendAffectAddPacket(GetDesc(), pkAff);
  528.  
  529. ComputeAffect(pkAff, true);
  530.  
  531.  
  532. }
  533.  
  534. if ( CArenaManager::instance().IsArenaMap(GetMapIndex()) == true )
  535. {
  536. RemoveGoodAffect();
  537. }
  538.  
  539. if (afOld != m_afAffectFlag || lMovSpd != GetPoint(POINT_MOV_SPEED) || lAttSpd != GetPoint(POINT_ATT_SPEED))
  540. {
  541. UpdatePacket();
  542. }
  543.  
  544. StartAffectEvent();
  545.  
  546. m_bIsLoadedAffect = true;
  547.  
  548. // ¿ëÈ¥¼® ¼ÂÆà ·Îµå ¹× ÃʱâÈ­
  549. DragonSoul_Initialize();
  550. }
  551.  
  552. bool CHARACTER::AddAffect(DWORD dwType, BYTE bApplyOn, long lApplyValue, DWORD dwFlag, long lDuration, long lSPCost, bool bOverride, bool IsCube )
  553. {
  554. // CHAT_BLOCK
  555. if (dwType == AFFECT_BLOCK_CHAT && lDuration > 1)
  556. {
  557. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿î¿µÀÚ Á¦Á¦·Î äÆÃÀÌ ±ÝÁö µÇ¾ú½À´Ï´Ù."));
  558. }
  559. // END_OF_CHAT_BLOCK
  560.  
  561. if (lDuration == 0)
  562. {
  563. sys_err("Character::AddAffect lDuration == 0 type %d", lDuration, dwType);
  564. lDuration = 1;
  565. }
  566.  
  567. CAffect * pkAff = NULL;
  568.  
  569. if (IsCube)
  570. pkAff = FindAffect(dwType,bApplyOn);
  571. else
  572. pkAff = FindAffect(dwType);
  573.  
  574. if (dwFlag == AFF_STUN)
  575. {
  576. if (m_posDest.x != GetX() || m_posDest.y != GetY())
  577. {
  578. m_posDest.x = m_posStart.x = GetX();
  579. m_posDest.y = m_posStart.y = GetY();
  580. battle_end(this);
  581.  
  582. SyncPacket();
  583. }
  584. }
  585.  
  586. // ÀÌ¹Ì ÀÖ´Â È¿°ú¸¦ µ¤¾î ¾²´Â ó¸®
  587. if (pkAff && bOverride)
  588. {
  589. ComputeAffect(pkAff, false); // ÀÏ´Ü È¿°ú¸¦ »èÁ¦ÇÏ°í
  590.  
  591. if (GetDesc())
  592. SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
  593. }
  594. else
  595. {
  596. //
  597. // »õ ¿¡Æ带 Ãß°¡
  598. //
  599. // NOTE: µû¶ó¼­ °°Àº type À¸·Îµµ ¿©·¯ ¿¡ÆåÆ®¸¦ ºÙÀ» ¼ö ÀÖ´Ù.
  600. //
  601. pkAff = CAffect::Acquire();
  602. m_list_pkAffect.push_back(pkAff);
  603.  
  604. }
  605.  
  606. sys_log(1, "AddAffect %s type %d apply %d %d flag %u duration %d", GetName(), dwType, bApplyOn, lApplyValue, dwFlag, lDuration);
  607. sys_log(0, "AddAffect %s type %d apply %d %d flag %u duration %d", GetName(), dwType, bApplyOn, lApplyValue, dwFlag, lDuration);
  608.  
  609. pkAff->dwType = dwType;
  610. pkAff->bApplyOn = bApplyOn;
  611. pkAff->lApplyValue = lApplyValue;
  612. pkAff->dwFlag = dwFlag;
  613. pkAff->lDuration = lDuration;
  614. pkAff->lSPCost = lSPCost;
  615.  
  616. WORD wMovSpd = GetPoint(POINT_MOV_SPEED);
  617. WORD wAttSpd = GetPoint(POINT_ATT_SPEED);
  618.  
  619. ComputeAffect(pkAff, true);
  620.  
  621. if (pkAff->dwFlag || wMovSpd != GetPoint(POINT_MOV_SPEED) || wAttSpd != GetPoint(POINT_ATT_SPEED))
  622. UpdatePacket();
  623.  
  624. StartAffectEvent();
  625.  
  626. if (IsPC())
  627. {
  628. SendAffectAddPacket(GetDesc(), pkAff);
  629.  
  630. if (IS_NO_SAVE_AFFECT(pkAff->dwType))
  631. return true;
  632.  
  633. TPacketGDAddAffect p;
  634. p.dwPID = GetPlayerID();
  635. p.elem.dwType = pkAff->dwType;
  636. p.elem.bApplyOn = pkAff->bApplyOn;
  637. p.elem.lApplyValue = pkAff->lApplyValue;
  638. p.elem.dwFlag = pkAff->dwFlag;
  639. p.elem.lDuration = pkAff->lDuration;
  640. p.elem.lSPCost = pkAff->lSPCost;
  641. db_clientdesc->DBPacket(HEADER_GD_ADD_AFFECT, 0, &p, sizeof(p));
  642. }
  643.  
  644. return true;
  645. }
  646.  
  647. void CHARACTER::RefreshAffect()
  648. {
  649. auto it = m_list_pkAffect.begin();
  650.  
  651. while (it != m_list_pkAffect.end())
  652. {
  653. CAffect * pkAff = *it++;
  654. ComputeAffect(pkAff, true);
  655. }
  656. }
  657.  
  658. void CHARACTER::ComputeAffect(CAffect * pkAff, bool bAdd)
  659. {
  660. if (bAdd && pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)
  661. {
  662. if (!GetGuild())
  663. return;
  664.  
  665. if (!GetGuild()->UnderAnyWar())
  666. return;
  667. }
  668.  
  669. if (pkAff->dwFlag)
  670. {
  671. if (!bAdd)
  672. m_afAffectFlag.Reset(pkAff->dwFlag);
  673. else
  674. m_afAffectFlag.Set(pkAff->dwFlag);
  675. }
  676.  
  677. if (bAdd)
  678. PointChange(pkAff->bApplyOn, pkAff->lApplyValue);
  679. else
  680. PointChange(pkAff->bApplyOn, -pkAff->lApplyValue);
  681.  
  682. if (pkAff->dwType == SKILL_MUYEONG)
  683. {
  684. if (bAdd)
  685. StartMuyeongEvent();
  686. else
  687. StopMuyeongEvent();
  688. }
  689. }
  690.  
  691. bool CHARACTER::RemoveAffect(CAffect * pkAff)
  692. {
  693. if (!pkAff)
  694. return false;
  695.  
  696. // AFFECT_BUF_FIX
  697. m_list_pkAffect.remove(pkAff);
  698. // END_OF_AFFECT_BUF_FIX
  699.  
  700. ComputeAffect(pkAff, false);
  701.  
  702. // ¹é±â ¹ö±× ¼öÁ¤.
  703. // ¹é±â ¹ö±×´Â ¹öÇÁ ½ºÅ³ ½ÃÀü->µÐ°©->¹é±â »ç¿ë(AFFECT_REVIVE_INVISIBLE) ÈÄ ¹Ù·Î °ø°Ý ÇÒ °æ¿ì¿¡ ¹ß»ýÇÑ´Ù.
  704. // ¿øÀÎÀº µÐ°©À» ½ÃÀüÇÏ´Â ½ÃÁ¡¿¡, ¹öÇÁ ½ºÅ³ È¿°ú¸¦ ¹«½ÃÇÏ°í µÐ°© È¿°ú¸¸ Àû¿ëµÇ°Ô µÇ¾îÀִµ¥,
  705. // ¹é±â »ç¿ë ÈÄ ¹Ù·Î °ø°ÝÇϸé RemoveAffect°¡ ºÒ¸®°Ô µÇ°í, ComputePointsÇϸ鼭 µÐ°© È¿°ú + ¹öÇÁ ½ºÅ³ È¿°ú°¡ µÈ´Ù.
  706. // ComputePoints¿¡¼­ µÐ°© »óÅÂ¸é ¹öÇÁ ½ºÅ³ È¿°ú ¾È ¸ÔÈ÷µµ·Ï ÇÏ¸é µÇ±ä Çϴµ¥,
  707. // ComputePoints´Â ±¤¹üÀ§ÇÏ°Ô »ç¿ëµÇ°í À־ Å« º¯È­¸¦ ÁÖ´Â °ÍÀÌ ²¨·ÁÁø´Ù.(¾î¶² side effect°¡ ¹ß»ýÇÒÁö ¾Ë±â Èûµé´Ù.)
  708. // µû¶ó¼­ AFFECT_REVIVE_INVISIBLE°¡ RemoveAffect·Î »èÁ¦µÇ´Â °æ¿ì¸¸ ¼öÁ¤ÇÑ´Ù.
  709. // ½Ã°£ÀÌ ´Ù µÇ¾î ¹é±â È¿°ú°¡ Ç®¸®´Â °æ¿ì´Â ¹ö±×°¡ ¹ß»ýÇÏÁö ¾ÊÀ¸¹Ç·Î ±×¿Í ¶È°°ÀÌ ÇÔ.
  710. // (ProcessAffect¸¦ º¸¸é ½Ã°£ÀÌ ´Ù µÇ¾î¼­ Affect°¡ »èÁ¦µÇ´Â °æ¿ì, ComputePoints¸¦ ºÎ¸£Áö ¾Ê´Â´Ù.)
  711. if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType)
  712. ComputePoints();
  713. else
  714. UpdatePacket();
  715. CheckMaximumPoints();
  716.  
  717. if (test_server)
  718. sys_log(0, "AFFECT_REMOVE: %s (flag %u apply: %u)", GetName(), pkAff->dwFlag, pkAff->bApplyOn);
  719.  
  720. if (IsPC())
  721. {
  722. SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
  723. }
  724.  
  725. CAffect::Release(pkAff);
  726. return true;
  727. }
  728.  
  729. bool CHARACTER::RemoveAffect(DWORD dwType)
  730. {
  731. // CHAT_BLOCK
  732. if (dwType == AFFECT_BLOCK_CHAT)
  733. {
  734. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("äÆà ±ÝÁö°¡ Ç®·È½À´Ï´Ù."));
  735. }
  736. // END_OF_CHAT_BLOCK
  737.  
  738. bool flag = false;
  739.  
  740. CAffect * pkAff;
  741.  
  742. while ((pkAff = FindAffect(dwType)))
  743. {
  744. RemoveAffect(pkAff);
  745. flag = true;
  746. }
  747.  
  748. return flag;
  749. }
  750.  
  751. bool CHARACTER::IsAffectFlag(DWORD dwAff) const
  752. {
  753. return m_afAffectFlag.IsSet(dwAff);
  754. }
  755.  
  756. void CHARACTER::RemoveGoodAffect()
  757. {
  758. RemoveAffect(AFFECT_MOV_SPEED);
  759. RemoveAffect(AFFECT_ATT_SPEED);
  760. RemoveAffect(AFFECT_STR);
  761. RemoveAffect(AFFECT_DEX);
  762. RemoveAffect(AFFECT_INT);
  763. RemoveAffect(AFFECT_CON);
  764. RemoveAffect(AFFECT_CHINA_FIREWORK);
  765.  
  766. RemoveAffect(SKILL_JEONGWI);
  767. RemoveAffect(SKILL_GEOMKYUNG);
  768. RemoveAffect(SKILL_CHUNKEON);
  769. RemoveAffect(SKILL_EUNHYUNG);
  770. RemoveAffect(SKILL_GYEONGGONG);
  771. RemoveAffect(SKILL_GWIGEOM);
  772. RemoveAffect(SKILL_TERROR);
  773. RemoveAffect(SKILL_JUMAGAP);
  774. RemoveAffect(SKILL_MANASHILED);
  775. RemoveAffect(SKILL_HOSIN);
  776. RemoveAffect(SKILL_REFLECT);
  777. RemoveAffect(SKILL_KWAESOK);
  778. RemoveAffect(SKILL_JEUNGRYEOK);
  779. RemoveAffect(SKILL_GICHEON);
  780. }
  781.  
  782. bool CHARACTER::IsGoodAffect(BYTE bAffectType) const
  783. {
  784. switch (bAffectType)
  785. {
  786. case (AFFECT_MOV_SPEED):
  787. case (AFFECT_ATT_SPEED):
  788. case (AFFECT_STR):
  789. case (AFFECT_DEX):
  790. case (AFFECT_INT):
  791. case (AFFECT_CON):
  792. case (AFFECT_CHINA_FIREWORK):
  793.  
  794. case (SKILL_JEONGWI):
  795. case (SKILL_GEOMKYUNG):
  796. case (SKILL_CHUNKEON):
  797. case (SKILL_EUNHYUNG):
  798. case (SKILL_GYEONGGONG):
  799. case (SKILL_GWIGEOM):
  800. case (SKILL_TERROR):
  801. case (SKILL_JUMAGAP):
  802. case (SKILL_MANASHILED):
  803. case (SKILL_HOSIN):
  804. case (SKILL_REFLECT):
  805. case (SKILL_KWAESOK):
  806. case (SKILL_JEUNGRYEOK):
  807. case (SKILL_GICHEON):
  808. return true;
  809. }
  810. return false;
  811. }
  812.  
  813. void CHARACTER::RemoveBadAffect()
  814. {
  815. sys_log(0, "RemoveBadAffect %s", GetName());
  816. // µ¶
  817. RemovePoison();
  818. RemoveFire();
  819.  
  820. // ½ºÅÏ : Value%·Î »ó´ë¹æÀ» 5ÃÊ°£ ¸Ó¸® À§¿¡ º°ÀÌ µ¹¾Æ°£´Ù. (¶§¸®¸é 1/2 È®·ü·Î Ç®¸²) AFF_STUN
  821. RemoveAffect(AFFECT_STUN);
  822.  
  823. // ½½·Î¿ì : Value%·Î »ó´ë¹æÀÇ °ø¼Ó/ÀÌ¼Ó ¸ðµÎ ´À·ÁÁø´Ù. ¼ö·Ãµµ¿¡ µû¶ó ´Þ¶óÁü ±â¼ú·Î »ç¿ë ÇÑ °æ¿ì¿¡ AFF_SLOW
  824. RemoveAffect(AFFECT_SLOW);
  825.  
  826. // Åõ¼Ó¸¶·É
  827. RemoveAffect(SKILL_TUSOK);
  828.  
  829. // ÀúÁÖ
  830. //RemoveAffect(SKILL_CURSE);
  831.  
  832. // ÆĹý¼ú
  833. //RemoveAffect(SKILL_PABUP);
  834.  
  835. // ±âÀý : Value%·Î »ó´ë¹æÀ» ±âÀý½ÃŲ´Ù. 2ÃÊ AFF_FAINT
  836. //RemoveAffect(AFFECT_FAINT);
  837.  
  838. // ´Ù¸®¹­ÀÓ : Value%·Î »ó´ë¹æÀÇ À̵¿¼Óµµ¸¦ ¶³¾îÆ®¸°´Ù. 5ÃÊ°£ -40 AFF_WEB
  839. //RemoveAffect(AFFECT_WEB);
  840.  
  841. // Àáµé±â : Value%·Î »ó´ë¹æÀ» 10ÃÊ°£ ÀáÀç¿î´Ù. (¶§¸®¸é Ç®¸²) AFF_SLEEP
  842. //RemoveAffect(AFFECT_SLEEP);
  843.  
  844. // ÀúÁÖ : Value%·Î »ó´ë¹æÀÇ °øµî/¹æµî ¸ðµÎ ¶³¾îÆ®¸°´Ù. ¼ö·Ãµµ¿¡ µû¶ó ´Þ¶óÁü ±â¼ú·Î »ç¿ë ÇÑ °æ¿ì¿¡ AFF_CURSE
  845. //RemoveAffect(AFFECT_CURSE);
  846.  
  847. // ¸¶ºñ : Value%·Î »ó´ë¹æÀ» 4ÃÊ°£ ¸¶ºñ½ÃŲ´Ù. AFF_PARA
  848. //RemoveAffect(AFFECT_PARALYZE);
  849.  
  850. // ºÎµ¿¹ÚºÎ : ¹«´ç ±â¼ú
  851. //RemoveAffect(SKILL_BUDONG);
  852. }