Guest User

Untitled

a guest
Jan 18th, 2025
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.74 KB | None | 0 0
  1. #include "stdafx.h"
  2.  
  3. #include "config.h"
  4. #include "char.h"
  5. #include "char_manager.h"
  6. #include "affect.h"
  7. #include "packet.h"
  8. #include "buffer_manager.h"
  9. #include "desc_client.h"
  10. #include "battle.h"
  11. #include "guild.h"
  12. #include "utils.h"
  13. #include "locale_service.h"
  14. #include "lua_incl.h"
  15. #include "arena.h"
  16. #include "horsename_manager.h"
  17. #include "item.h"
  18. #include "DragonSoul.h"
  19. #include "../../common/CommonDefines.h"
  20.  
  21. #ifdef ENABLE_PREMIUM_SYSTEM
  22. #include "premium_system.h"
  23. #endif
  24.  
  25. #if defined(ENABLE_NEW_AUTOPOTION)
  26. constexpr DWORD AUTO_POTION_START_INDEX = AFFECT_AUTO_ATTACK_SPEED_RECOVERY + 20;
  27. constexpr DWORD AUTO_POTION_END_INDEX = AFFECT_AUTO_WHITE_POTION_RECOVERY + 20;
  28. #define IS_NO_SAVE_AFFECT(type) ((type) == AFFECT_WAR_FLAG || (type) == AFFECT_REVIVE_INVISIBLE || ((type) >= AFFECT_PREMIUM_START && (type) <= AFFECT_PREMIUM_END) || (type) == AFFECT_MOUNT_BONUS || (type >= AUTO_POTION_START_INDEX && type <= AUTO_POTION_END_INDEX)) // @fixme156 added MOUNT_BONUS (if the game core crashes, the bonus would double if present in player.affect)
  29. #define IS_NO_CLEAR_ON_DEATH_AFFECT(type) ((type) == AFFECT_BLOCK_CHAT || ((type) >= 500 && (type) < 600) || (type) == AFFECT_AUTO_ATTACK_SPEED_RECOVERY || (type) == AFFECT_AUTO_MOV_SPEED_RECOVERY || (type) == AFFECT_AUTO_CRITICAL_RECOVERY || (type) == AFFECT_AUTO_PENETRATE_RECOVERY || (type) == AFFECT_AUTO_VIT_RECOVERY || (type) == AFFECT_AUTO_STR_RECOVERY || (type) == AFFECT_AUTO_INT_RECOVERY || (type) == AFFECT_AUTO_DEX_RECOVERY || (type) == AFFECT_AUTO_RED_POTION_RECOVERY|| (type) == AFFECT_AUTO_ORANGE_POTION_RECOVERY|| (type) == AFFECT_AUTO_YELLOW_POTION_RECOVERY|| (type) == AFFECT_AUTO_GREEN_POTION_RECOVERY|| (type) == AFFECT_AUTO_BLUE_POTION_RECOVERY|| (type) == AFFECT_AUTO_WHITE_POTION_RECOVERY || (type >= AUTO_POTION_START_INDEX && type <= AUTO_POTION_END_INDEX))
  30. #else
  31. #define IS_NO_SAVE_AFFECT(type) ((type) == AFFECT_WAR_FLAG || (type) == AFFECT_REVIVE_INVISIBLE || ((type) >= AFFECT_PREMIUM_START && (type) <= AFFECT_PREMIUM_END) || (type) == AFFECT_MOUNT_BONUS) // @fixme156 added MOUNT_BONUS (if the game core crashes, the bonus would double if present in player.affect)
  32. #define IS_NO_CLEAR_ON_DEATH_AFFECT(type) ((type) == AFFECT_BLOCK_CHAT || ((type) >= 500 && (type) < 600))
  33. #endif
  34.  
  35. #if defined(__CONQUEROR_LEVEL__)
  36. # define IS_SUNGMA_AFFECT(type) (((type) >= AFFECT_SUNGMA_STR && (type) < AFFECT_SUNGMA_IMMUNE))
  37. #endif
  38.  
  39. #ifdef RENEWAL_PICKUP_AFFECT
  40. bool IsRealTimeAffect(DWORD affectType)
  41. {
  42. switch(affectType)
  43. {
  44. case AFFECT_PICKUP_ENABLE:
  45. case AFFECT_PICKUP_DEACTIVE:
  46. return true;
  47. }
  48. return false;
  49. }
  50. #endif
  51.  
  52. void SendAffectRemovePacket(LPDESC d, DWORD pid, DWORD type, BYTE point)
  53. {
  54. TPacketGCAffectRemove ptoc;
  55. ptoc.bHeader = HEADER_GC_AFFECT_REMOVE;
  56. ptoc.dwType = type;
  57. ptoc.bApplyOn = point;
  58. d->Packet(&ptoc, sizeof(TPacketGCAffectRemove));
  59.  
  60. TPacketGDRemoveAffect ptod;
  61. ptod.dwPID = pid;
  62. ptod.dwType = type;
  63. ptod.bApplyOn = point;
  64. db_clientdesc->DBPacket(HEADER_GD_REMOVE_AFFECT, 0, &ptod, sizeof(ptod));
  65. }
  66.  
  67. void SendAffectAddPacket(LPDESC d, CAffect * pkAff)
  68. {
  69. TPacketGCAffectAdd ptoc;
  70. ptoc.bHeader = HEADER_GC_AFFECT_ADD;
  71. ptoc.elem.dwType = pkAff->dwType;
  72. ptoc.elem.bApplyOn = pkAff->bApplyOn;
  73. ptoc.elem.lApplyValue = pkAff->lApplyValue;
  74. ptoc.elem.dwFlag = pkAff->dwFlag;
  75. #ifdef RENEWAL_PICKUP_AFFECT
  76. ptoc.elem.lDuration = IsRealTimeAffect(pkAff->dwType) ? pkAff->lDuration - time(0) : pkAff->lDuration;
  77. #else
  78. ptoc.elem.lDuration = pkAff->lDuration;
  79. #endif
  80. ptoc.elem.lSPCost = pkAff->lSPCost;
  81. d->Packet(&ptoc, sizeof(TPacketGCAffectAdd));
  82. }
  83. ////////////////////////////////////////////////////////////////////
  84. // Affect
  85. CAffect * CHARACTER::FindAffect(DWORD dwType, BYTE bApply) const
  86. {
  87. itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
  88.  
  89. while (it != m_list_pkAffect.end())
  90. {
  91. CAffect * pkAffect = *it++;
  92.  
  93. if (pkAffect->dwType == dwType && (bApply == APPLY_NONE || bApply == pkAffect->bApplyOn))
  94. return pkAffect;
  95. }
  96.  
  97. return NULL;
  98. }
  99.  
  100. EVENTFUNC(affect_event)
  101. {
  102. char_event_info* info = dynamic_cast<char_event_info*>( event->info );
  103.  
  104. if ( info == NULL )
  105. {
  106. sys_err( "affect_event> <Factor> Null pointer" );
  107. return 0;
  108. }
  109.  
  110. LPCHARACTER ch = info->ch;
  111.  
  112. if (ch == NULL) { // <Factor>
  113. return 0;
  114. }
  115.  
  116. if (!ch->UpdateAffect())
  117. return 0;
  118. else
  119. return passes_per_sec;
  120. }
  121.  
  122. bool CHARACTER::UpdateAffect()
  123. {
  124. if (GetPoint(POINT_HP_RECOVERY) > 0)
  125. {
  126. if (GetMaxHP() <= GetHP())
  127. {
  128. PointChange(POINT_HP_RECOVERY, -GetPoint(POINT_HP_RECOVERY));
  129. }
  130. else
  131. {
  132. int64_t iVal = MIN(GetPoint(POINT_HP_RECOVERY), GetMaxHP() * 7 / 100);
  133.  
  134. PointChange(POINT_HP, iVal);
  135. PointChange(POINT_HP_RECOVERY, -iVal);
  136. }
  137. }
  138.  
  139. if (GetPoint(POINT_SP_RECOVERY) > 0)
  140. {
  141. if (GetMaxSP() <= GetSP())
  142. PointChange(POINT_SP_RECOVERY, -GetPoint(POINT_SP_RECOVERY));
  143. else
  144. {
  145. int64_t iVal = MIN(GetPoint(POINT_SP_RECOVERY), GetMaxSP() * 7 / 100);
  146.  
  147. PointChange(POINT_SP, iVal);
  148. PointChange(POINT_SP_RECOVERY, -iVal);
  149. }
  150. }
  151.  
  152. if (GetPoint(POINT_HP_RECOVER_CONTINUE) > 0)
  153. {
  154. PointChange(POINT_HP, GetPoint(POINT_HP_RECOVER_CONTINUE));
  155. }
  156.  
  157. if (GetPoint(POINT_SP_RECOVER_CONTINUE) > 0)
  158. {
  159. PointChange(POINT_SP, GetPoint(POINT_SP_RECOVER_CONTINUE));
  160. }
  161.  
  162. AutoRecoveryItemProcess( AFFECT_AUTO_HP_RECOVERY );
  163. AutoRecoveryItemProcess( AFFECT_AUTO_SP_RECOVERY );
  164.  
  165. #if defined(ENABLE_NEW_AUTOPOTION)
  166. AutoRecoveryItemProcess(AFFECT_AUTO_ATTACK_SPEED_RECOVERY);
  167. AutoRecoveryItemProcess(AFFECT_AUTO_MOV_SPEED_RECOVERY);
  168. AutoRecoveryItemProcess(AFFECT_AUTO_CRITICAL_RECOVERY);
  169. AutoRecoveryItemProcess(AFFECT_AUTO_PENETRATE_RECOVERY);
  170. AutoRecoveryItemProcess(AFFECT_AUTO_VIT_RECOVERY);
  171. AutoRecoveryItemProcess(AFFECT_AUTO_STR_RECOVERY);
  172. AutoRecoveryItemProcess(AFFECT_AUTO_INT_RECOVERY);
  173. AutoRecoveryItemProcess(AFFECT_AUTO_DEX_RECOVERY);
  174. AutoRecoveryItemProcess(AFFECT_AUTO_RED_POTION_RECOVERY);
  175. AutoRecoveryItemProcess(AFFECT_AUTO_ORANGE_POTION_RECOVERY);
  176. AutoRecoveryItemProcess(AFFECT_AUTO_YELLOW_POTION_RECOVERY);
  177. AutoRecoveryItemProcess(AFFECT_AUTO_GREEN_POTION_RECOVERY);
  178. AutoRecoveryItemProcess(AFFECT_AUTO_BLUE_POTION_RECOVERY);
  179. AutoRecoveryItemProcess(AFFECT_AUTO_WHITE_POTION_RECOVERY);
  180. #endif
  181.  
  182. if (GetMaxStamina() > GetStamina())
  183. {
  184. int iSec = (get_dword_time() - GetStopTime()) / 3000;
  185. if (iSec)
  186. PointChange(POINT_STAMINA, GetMaxStamina()/1);
  187. }
  188.  
  189. if (ProcessAffect())
  190. if (GetPoint(POINT_HP_RECOVERY) == 0 && GetPoint(POINT_SP_RECOVERY) == 0 && GetStamina() == GetMaxStamina())
  191. {
  192. m_pkAffectEvent = NULL;
  193. return false;
  194. }
  195.  
  196. return true;
  197. }
  198.  
  199. void CHARACTER::StartAffectEvent()
  200. {
  201. if (m_pkAffectEvent)
  202. return;
  203.  
  204. char_event_info* info = AllocEventInfo<char_event_info>();
  205. info->ch = this;
  206. m_pkAffectEvent = event_create(affect_event, info, passes_per_sec);
  207. sys_log(1, "StartAffectEvent %s %p %p", GetName(), this, get_pointer(m_pkAffectEvent));
  208. }
  209.  
  210. void CHARACTER::ClearAffect(bool bSave)
  211. {
  212. TAffectFlag afOld = m_afAffectFlag;
  213. WORD wMovSpd = GetPoint(POINT_MOV_SPEED);
  214. WORD wAttSpd = GetPoint(POINT_ATT_SPEED);
  215.  
  216. itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
  217.  
  218. while (it != m_list_pkAffect.end())
  219. {
  220. CAffect * pkAff = *it;
  221.  
  222. if (bSave)
  223. {
  224. if ( IS_NO_CLEAR_ON_DEATH_AFFECT(pkAff->dwType) || IS_NO_SAVE_AFFECT(pkAff->dwType) )
  225. {
  226. ++it;
  227. continue;
  228. }
  229.  
  230. #ifdef ENABLE_MULTI_FARM_BLOCK
  231. if(pkAff->dwType == AFFECT_MULTI_FARM_PREMIUM)
  232. {
  233. ++it;
  234. continue;
  235. }
  236. #endif
  237.  
  238. #if defined(__CONQUEROR_LEVEL__)
  239. if (IS_SUNGMA_AFFECT(pkAff->dwType))
  240. {
  241. ++it;
  242. continue;
  243. }
  244. #endif
  245.  
  246. #ifdef ENABLE_OFFLINESHOP_SYSTEM
  247. if(AFFECT_DECORATION == pkAff->dwType)
  248. {
  249. ++it;
  250. continue;
  251. }
  252. #endif
  253.  
  254. #ifdef METINSTONES_QUEUE
  255. if (pkAff->dwType == AFFECT_AUTO_METIN_FARM)
  256. {
  257. ++it;
  258. continue;
  259. }
  260. #endif
  261.  
  262.  
  263. #ifdef METINSTONES_QUEUE
  264. if (pkAff->dwType == AFFECT_THIEF_GLOVES_STONES)
  265. {
  266. ++it;
  267. continue;
  268. }
  269. #endif
  270.  
  271. #ifdef METINSTONES_QUEUE
  272. if (pkAff->dwType == AFFECT_THIEF_GLOVES_BOSSES)
  273. {
  274. ++it;
  275. continue;
  276. }
  277. #endif
  278.  
  279.  
  280.  
  281. if (pkAff->dwType == AFFECT_SINGLE_BONUS_URIEL)
  282. {
  283. ++it;
  284. continue;
  285. }
  286.  
  287. if (pkAff->dwType == AFFECT_SINGLE_BONUS_URIEL_DELAY)
  288. {
  289. ++it;
  290. continue;
  291. }
  292.  
  293.  
  294. if (IsPC())
  295. {
  296. SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
  297. }
  298. }
  299.  
  300. ComputeAffect(pkAff, false);
  301.  
  302. it = m_list_pkAffect.erase(it);
  303. CAffect::Release(pkAff);
  304. }
  305.  
  306. if (afOld != m_afAffectFlag ||
  307. wMovSpd != GetPoint(POINT_MOV_SPEED) ||
  308. wAttSpd != GetPoint(POINT_ATT_SPEED))
  309. UpdatePacket();
  310.  
  311. CheckMaximumPoints();
  312.  
  313. if (m_list_pkAffect.empty())
  314. event_cancel(&m_pkAffectEvent);
  315. }
  316.  
  317. int CHARACTER::ProcessAffect()
  318. {
  319. bool bDiff = false;
  320. CAffect *pkAff = NULL;
  321.  
  322. for (int i = 0; i <= PREMIUM_MAX_NUM; ++i)
  323. {
  324. int aff_idx = i + AFFECT_PREMIUM_START;
  325.  
  326. pkAff = FindAffect(aff_idx);
  327.  
  328. if (!pkAff)
  329. continue;
  330.  
  331. int remain = GetPremiumRemainSeconds(i);
  332.  
  333. if (remain < 0)
  334. {
  335. RemoveAffect(aff_idx);
  336. bDiff = true;
  337. }
  338. else
  339. pkAff->lDuration = remain + 1;
  340. }
  341.  
  342. ////////// HAIR_AFFECT
  343. pkAff = FindAffect(AFFECT_HAIR);
  344. if (pkAff)
  345. {
  346. // IF HAIR_LIMIT_TIME() < CURRENT_TIME()
  347. if ( this->GetQuestFlag("hair.limit_time") < get_global_time())
  348. {
  349. // SET HAIR NORMAL
  350. this->SetPart(PART_HAIR, 0);
  351. // REMOVE HAIR AFFECT
  352. RemoveAffect(AFFECT_HAIR);
  353. }
  354. else
  355. {
  356. // INCREASE AFFECT DURATION
  357. ++(pkAff->lDuration);
  358. }
  359. }
  360. ////////// HAIR_AFFECT
  361.  
  362. CHorseNameManager::instance().Validate(this);
  363.  
  364. TAffectFlag afOld = m_afAffectFlag;
  365. long lMovSpd = GetPoint(POINT_MOV_SPEED);
  366. long lAttSpd = GetPoint(POINT_ATT_SPEED);
  367.  
  368. itertype(m_list_pkAffect) it;
  369.  
  370. it = m_list_pkAffect.begin();
  371.  
  372. while (it != m_list_pkAffect.end())
  373. {
  374. pkAff = *it;
  375.  
  376. bool bEnd = false;
  377.  
  378. if (pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)
  379. {
  380. if (!GetGuild() || !GetGuild()->UnderAnyWar())
  381. bEnd = true;
  382. }
  383.  
  384. if (pkAff->lSPCost > 0)
  385. {
  386. if (GetSP() < pkAff->lSPCost)
  387. bEnd = true;
  388. else
  389. PointChange(POINT_SP, -pkAff->lSPCost);
  390. }
  391.  
  392. // AFFECT_DURATION_BUG_FIX
  393.  
  394. #ifdef RENEWAL_PICKUP_AFFECT
  395. const int leftTime = IsRealTimeAffect(pkAff->dwType) ? pkAff->lDuration-time(0) : --pkAff->lDuration;
  396. if (leftTime <= 0)
  397. #else
  398. if (--pkAff->lDuration <= 0)
  399. #endif
  400. {
  401. bEnd = true;
  402. }
  403. // END_AFFECT_DURATION_BUG_FIX
  404.  
  405. if (bEnd)
  406. {
  407. it = m_list_pkAffect.erase(it);
  408. ComputeAffect(pkAff, false);
  409. bDiff = true;
  410. if (IsPC())
  411. {
  412. SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
  413. }
  414.  
  415. CAffect::Release(pkAff);
  416.  
  417. continue;
  418. }
  419.  
  420. ++it;
  421. }
  422.  
  423. if (bDiff)
  424. {
  425. if (afOld != m_afAffectFlag ||
  426. lMovSpd != GetPoint(POINT_MOV_SPEED) ||
  427. lAttSpd != GetPoint(POINT_ATT_SPEED))
  428. {
  429. UpdatePacket();
  430. }
  431.  
  432. CheckMaximumPoints();
  433. }
  434.  
  435. if (m_list_pkAffect.empty())
  436. return true;
  437.  
  438. return false;
  439. }
  440.  
  441. void CHARACTER::SaveAffect()
  442. {
  443. TPacketGDAddAffect p;
  444.  
  445. itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
  446.  
  447. while (it != m_list_pkAffect.end())
  448. {
  449. CAffect * pkAff = *it++;
  450.  
  451. if (IS_NO_SAVE_AFFECT(pkAff->dwType))
  452. continue;
  453.  
  454. sys_log(1, "AFFECT_SAVE: %u %u %d %d", pkAff->dwType, pkAff->bApplyOn, pkAff->lApplyValue, pkAff->lDuration);
  455.  
  456. p.dwPID = GetPlayerID();
  457. p.elem.dwType = pkAff->dwType;
  458. p.elem.bApplyOn = pkAff->bApplyOn;
  459. p.elem.lApplyValue = pkAff->lApplyValue;
  460. p.elem.dwFlag = pkAff->dwFlag;
  461. p.elem.lDuration = pkAff->lDuration;
  462. p.elem.lSPCost = pkAff->lSPCost;
  463. db_clientdesc->DBPacket(HEADER_GD_ADD_AFFECT, 0, &p, sizeof(p));
  464. }
  465. }
  466.  
  467. EVENTINFO(load_affect_login_event_info)
  468. {
  469. DWORD pid;
  470. DWORD count;
  471. char* data;
  472.  
  473. load_affect_login_event_info()
  474. : pid( 0 )
  475. , count( 0 )
  476. , data( 0 )
  477. {
  478. }
  479. };
  480.  
  481. EVENTFUNC(load_affect_login_event)
  482. {
  483. load_affect_login_event_info* info = dynamic_cast<load_affect_login_event_info*>( event->info );
  484.  
  485. if ( info == NULL )
  486. {
  487. sys_err( "load_affect_login_event_info> <Factor> Null pointer" );
  488. return 0;
  489. }
  490.  
  491. DWORD dwPID = info->pid;
  492. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID);
  493.  
  494. if (!ch)
  495. {
  496. M2_DELETE_ARRAY(info->data);
  497. return 0;
  498. }
  499.  
  500. LPDESC d = ch->GetDesc();
  501.  
  502. if (!d)
  503. {
  504. M2_DELETE_ARRAY(info->data);
  505. return 0;
  506. }
  507.  
  508. if (d->IsPhase(PHASE_HANDSHAKE) ||
  509. d->IsPhase(PHASE_LOGIN) ||
  510. d->IsPhase(PHASE_SELECT) ||
  511. d->IsPhase(PHASE_DEAD) ||
  512. d->IsPhase(PHASE_LOADING))
  513. {
  514. return PASSES_PER_SEC(1);
  515. }
  516. else if (d->IsPhase(PHASE_CLOSE))
  517. {
  518. M2_DELETE_ARRAY(info->data);
  519. return 0;
  520. }
  521. else if (d->IsPhase(PHASE_GAME))
  522. {
  523. sys_log(1, "Affect Load by Event");
  524. ch->LoadAffect(info->count, (TPacketAffectElement*)info->data);
  525. M2_DELETE_ARRAY(info->data);
  526. return 0;
  527. }
  528. else
  529. {
  530. sys_err("input_db.cpp:quest_login_event INVALID PHASE pid %d", ch->GetPlayerID());
  531. M2_DELETE_ARRAY(info->data);
  532. return 0;
  533. }
  534. }
  535.  
  536. void CHARACTER::LoadAffect(DWORD dwCount, TPacketAffectElement * pElements)
  537. {
  538. m_bIsLoadedAffect = false;
  539.  
  540. if (!GetDesc()->IsPhase(PHASE_GAME))
  541. {
  542. if (test_server)
  543. sys_log(0, "LOAD_AFFECT: Creating Event", GetName(), dwCount);
  544.  
  545. load_affect_login_event_info* info = AllocEventInfo<load_affect_login_event_info>();
  546.  
  547. info->pid = GetPlayerID();
  548. info->count = dwCount;
  549. info->data = M2_NEW char[sizeof(TPacketAffectElement) * dwCount];
  550. thecore_memcpy(info->data, pElements, sizeof(TPacketAffectElement) * dwCount);
  551.  
  552. event_create(load_affect_login_event, info, PASSES_PER_SEC(1));
  553.  
  554. return;
  555. }
  556.  
  557. ClearAffect(true);
  558.  
  559. if (test_server)
  560. sys_log(0, "LOAD_AFFECT: %s count %d", GetName(), dwCount);
  561.  
  562. TAffectFlag afOld = m_afAffectFlag;
  563.  
  564. long lMovSpd = GetPoint(POINT_MOV_SPEED);
  565. long lAttSpd = GetPoint(POINT_ATT_SPEED);
  566.  
  567. for (DWORD i = 0; i < dwCount; ++i, ++pElements)
  568. {
  569. if (pElements->dwType == SKILL_MUYEONG)
  570. continue;
  571.  
  572. #if defined(__CONQUEROR_LEVEL__) && defined(__9THSKILL__)
  573. if (pElements->dwType == SKILL_CHEONUN)
  574. continue;
  575. #endif
  576.  
  577. if (AFFECT_AUTO_HP_RECOVERY == pElements->dwType || AFFECT_AUTO_SP_RECOVERY == pElements->dwType)
  578. {
  579. LPITEM item = FindItemByID( pElements->dwFlag );
  580.  
  581. if (NULL == item)
  582. continue;
  583.  
  584. item->Lock(true);
  585. }
  586.  
  587. if (pElements->bApplyOn >= POINT_MAX_NUM)
  588. {
  589. sys_err("invalid affect data %s ApplyOn %u ApplyValue %d",
  590. GetName(), pElements->bApplyOn, pElements->lApplyValue);
  591. continue;
  592. }
  593.  
  594. if (test_server)
  595. {
  596. sys_log(0, "Load Affect : Affect %s %d %d", GetName(), pElements->dwType, pElements->bApplyOn );
  597. }
  598.  
  599. CAffect* pkAff = CAffect::Acquire();
  600. m_list_pkAffect.emplace_back(pkAff);
  601.  
  602. pkAff->dwType = pElements->dwType;
  603. pkAff->bApplyOn = pElements->bApplyOn;
  604. pkAff->lApplyValue = pElements->lApplyValue;
  605. pkAff->dwFlag = pElements->dwFlag;
  606. pkAff->lDuration = pElements->lDuration;
  607. pkAff->lSPCost = pElements->lSPCost;
  608.  
  609. SendAffectAddPacket(GetDesc(), pkAff);
  610.  
  611. ComputeAffect(pkAff, true);
  612.  
  613. }
  614.  
  615. if ( CArenaManager::instance().IsArenaMap(GetMapIndex()) == true )
  616. {
  617. RemoveGoodAffect();
  618. }
  619.  
  620. if (afOld != m_afAffectFlag || lMovSpd != GetPoint(POINT_MOV_SPEED) || lAttSpd != GetPoint(POINT_ATT_SPEED))
  621. {
  622. UpdatePacket();
  623. }
  624.  
  625. StartAffectEvent();
  626.  
  627. m_bIsLoadedAffect = true;
  628.  
  629. ComputePoints(); // @fixme156
  630. DragonSoul_Initialize();
  631.  
  632. // @fixme118 BEGIN (regain affect hp/mp)
  633. if (!IsDead())
  634. {
  635. PointChange(POINT_HP, GetMaxHP() - GetHP());
  636. PointChange(POINT_SP, GetMaxSP() - GetSP());
  637. }
  638. // @fixme118 END
  639. }
  640.  
  641. bool CHARACTER::AddAffect(DWORD dwType, BYTE bApplyOn, long lApplyValue, DWORD dwFlag, long lDuration, long lSPCost, bool bOverride, bool IsCube )
  642. {
  643. // CHAT_BLOCK
  644. if (dwType == AFFECT_BLOCK_CHAT && lDuration > 1)
  645. {
  646. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿î¿µÀÚ Á¦Á¦·Î äÆÃÀÌ ±ÝÁö µÇ¾ú½À´Ï´Ù."));
  647. }
  648. // END_OF_CHAT_BLOCK
  649.  
  650. if (lDuration == 0)
  651. {
  652. sys_err("Character::AddAffect lDuration == 0 type %d", lDuration, dwType);
  653. lDuration = 1;
  654. }
  655.  
  656. CAffect * pkAff = NULL;
  657.  
  658. if (IsCube)
  659. pkAff = FindAffect(dwType,bApplyOn);
  660. else
  661. pkAff = FindAffect(dwType);
  662.  
  663. if (dwFlag == AFF_STUN)
  664. {
  665. if (m_posDest.x != GetX() || m_posDest.y != GetY())
  666. {
  667. m_posDest.x = m_posStart.x = GetX();
  668. m_posDest.y = m_posStart.y = GetY();
  669. battle_end(this);
  670.  
  671. SyncPacket();
  672. }
  673. }
  674.  
  675. if (pkAff && bOverride)
  676. {
  677. ComputeAffect(pkAff, false);
  678.  
  679. if (GetDesc())
  680. SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
  681. }
  682. else
  683. {
  684. pkAff = CAffect::Acquire();
  685. m_list_pkAffect.emplace_back(pkAff);
  686.  
  687. }
  688.  
  689. sys_log(1, "AddAffect %s type %d apply %d %d flag %u duration %d", GetName(), dwType, bApplyOn, lApplyValue, dwFlag, lDuration);
  690. sys_log(0, "AddAffect %s type %d apply %d %d flag %u duration %d", GetName(), dwType, bApplyOn, lApplyValue, dwFlag, lDuration);
  691.  
  692. pkAff->dwType = dwType;
  693. pkAff->bApplyOn = bApplyOn;
  694. pkAff->lApplyValue = lApplyValue;
  695. pkAff->dwFlag = dwFlag;
  696.  
  697. #ifdef RENEWAL_PICKUP_AFFECT
  698. pkAff->lDuration = IsRealTimeAffect(dwType) ? time(0)+ lDuration : lDuration;
  699. #else
  700. pkAff->lDuration = lDuration;
  701. #endif
  702.  
  703. pkAff->lSPCost = lSPCost;
  704.  
  705. WORD wMovSpd = GetPoint(POINT_MOV_SPEED);
  706. WORD wAttSpd = GetPoint(POINT_ATT_SPEED);
  707.  
  708. ComputeAffect(pkAff, true);
  709.  
  710. if (pkAff->dwFlag || wMovSpd != GetPoint(POINT_MOV_SPEED) || wAttSpd != GetPoint(POINT_ATT_SPEED))
  711. UpdatePacket();
  712.  
  713. StartAffectEvent();
  714.  
  715. if (IsPC())
  716. {
  717. SendAffectAddPacket(GetDesc(), pkAff);
  718.  
  719. if (IS_NO_SAVE_AFFECT(pkAff->dwType))
  720. return true;
  721.  
  722. TPacketGDAddAffect p;
  723. p.dwPID = GetPlayerID();
  724. p.elem.dwType = pkAff->dwType;
  725. p.elem.bApplyOn = pkAff->bApplyOn;
  726. p.elem.lApplyValue = pkAff->lApplyValue;
  727. p.elem.dwFlag = pkAff->dwFlag;
  728. p.elem.lDuration = pkAff->lDuration;
  729. p.elem.lSPCost = pkAff->lSPCost;
  730. db_clientdesc->DBPacket(HEADER_GD_ADD_AFFECT, 0, &p, sizeof(p));
  731. }
  732.  
  733. return true;
  734. }
  735.  
  736. void CHARACTER::RefreshAffect()
  737. {
  738. itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
  739.  
  740. while (it != m_list_pkAffect.end())
  741. {
  742. CAffect * pkAff = *it++;
  743. ComputeAffect(pkAff, true);
  744. }
  745. }
  746.  
  747. void CHARACTER::ComputeAffect(CAffect * pkAff, bool bAdd)
  748. {
  749. if (bAdd && pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)
  750. {
  751. if (!GetGuild())
  752. return;
  753.  
  754. if (!GetGuild()->UnderAnyWar())
  755. return;
  756. }
  757.  
  758. if (pkAff->dwFlag)
  759. {
  760. if (!bAdd)
  761. m_afAffectFlag.Reset(pkAff->dwFlag);
  762. else
  763. m_afAffectFlag.Set(pkAff->dwFlag);
  764. }
  765.  
  766. if (bAdd)
  767. PointChange(pkAff->bApplyOn, pkAff->lApplyValue);
  768. else
  769. PointChange(pkAff->bApplyOn, -pkAff->lApplyValue);
  770.  
  771. if (pkAff->dwType == SKILL_MUYEONG)
  772. {
  773. if (bAdd)
  774. StartMuyeongEvent();
  775. else
  776. StopMuyeongEvent();
  777. }
  778.  
  779. #if defined(__CONQUEROR_LEVEL__) && defined(__9THSKILL__)
  780. if (pkAff->dwType == SKILL_CHEONUN)
  781. {
  782. if (bAdd)
  783. StartCheonunEvent(pkAff->lApplyValue);
  784. else
  785. StopCheonunEvent();
  786. }
  787. #endif
  788.  
  789. }
  790.  
  791. bool CHARACTER::RemoveAffect(CAffect * pkAff, bool single)
  792. {
  793. if (!pkAff)
  794. return false;
  795.  
  796. #if defined(ENABLE_NEW_AUTOPOTION)
  797. switch (pkAff->dwType)
  798. {
  799. case AFFECT_AUTO_ATTACK_SPEED_RECOVERY:
  800. case AFFECT_AUTO_MOV_SPEED_RECOVERY:
  801. case AFFECT_AUTO_CRITICAL_RECOVERY:
  802. case AFFECT_AUTO_PENETRATE_RECOVERY:
  803. case AFFECT_AUTO_VIT_RECOVERY:
  804. case AFFECT_AUTO_STR_RECOVERY:
  805. case AFFECT_AUTO_INT_RECOVERY:
  806. case AFFECT_AUTO_DEX_RECOVERY:
  807. case AFFECT_AUTO_RED_POTION_RECOVERY:
  808. case AFFECT_AUTO_ORANGE_POTION_RECOVERY:
  809. case AFFECT_AUTO_YELLOW_POTION_RECOVERY:
  810. case AFFECT_AUTO_GREEN_POTION_RECOVERY:
  811. case AFFECT_AUTO_BLUE_POTION_RECOVERY:
  812. case AFFECT_AUTO_WHITE_POTION_RECOVERY:
  813. RemoveAffect(pkAff->dwType + 20);
  814. break;
  815.  
  816. default:
  817. break;
  818. }
  819. #endif
  820.  
  821. // AFFECT_BUF_FIX
  822. m_list_pkAffect.remove(pkAff);
  823. // END_OF_AFFECT_BUF_FIX
  824.  
  825. ComputeAffect(pkAff, false);
  826.  
  827. if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType)
  828. #if defined(ENABLE_NEW_AUTOPOTION)
  829. {
  830. if (pkAff->dwType < AFFECT_AUTO_ATTACK_SPEED_RECOVERY || pkAff->dwType > AFFECT_AUTO_WHITE_POTION_RECOVERY)
  831. ComputePoints();
  832. }
  833. #else
  834. ComputePoints();
  835. #endif
  836.  
  837. if (single) //@fixme1024
  838. {
  839. if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType && AFFECT_MOUNT != pkAff->dwType) //@fixme1011
  840. ComputePoints();
  841. else // @fixme110
  842. UpdatePacket();
  843. }
  844. else
  845. UpdatePacket();
  846.  
  847. CheckMaximumPoints();
  848.  
  849. if (test_server)
  850. sys_log(0, "AFFECT_REMOVE: %s (flag %u apply: %u)", GetName(), pkAff->dwFlag, pkAff->bApplyOn);
  851.  
  852. if (IsPC())
  853. {
  854. SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
  855. }
  856.  
  857. #ifdef RENEWAL_PICKUP_AFFECT
  858. for (auto it = affects.begin(); it != affects.end(); ++it)
  859. if(IsRealTimeAffect(pkAff->dwType))
  860. {
  861. ++it;
  862. continue;
  863. }
  864. #endif
  865.  
  866. CAffect::Release(pkAff);
  867. return true;
  868. }
  869.  
  870. bool CHARACTER::RemoveAffect(DWORD dwType)
  871. {
  872. // CHAT_BLOCK
  873. if (dwType == AFFECT_BLOCK_CHAT)
  874. {
  875. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("äÆÃ ±ÝÁö°¡ Ç®·È½À´Ï´Ù."));
  876. }
  877. // END_OF_CHAT_BLOCK
  878.  
  879. bool flag = false;
  880.  
  881. CAffect * pkAff;
  882.  
  883. while ((pkAff = FindAffect(dwType)))
  884. {
  885. RemoveAffect(pkAff, false); //@fixme1024
  886. flag = true;
  887. }
  888.  
  889. return flag;
  890. }
  891.  
  892. bool CHARACTER::IsAffectFlag(DWORD dwAff) const
  893. {
  894. return m_afAffectFlag.IsSet(dwAff);
  895. }
  896.  
  897. #ifdef ENABLE_PREMIUM_SYSTEM
  898. void CHARACTER::SetAffectFlag(DWORD dwAff)
  899. {
  900. return m_afAffectFlag.Set(dwAff);
  901. }
  902.  
  903. void CHARACTER::ResetAffectFlag(DWORD dwAff)
  904. {
  905. return m_afAffectFlag.Reset(dwAff);
  906. }
  907. #endif
  908.  
  909. void CHARACTER::RemoveGoodAffect()
  910. {
  911. RemoveAffect(AFFECT_MOV_SPEED);
  912. RemoveAffect(AFFECT_ATT_SPEED);
  913. RemoveAffect(AFFECT_STR);
  914. RemoveAffect(AFFECT_DEX);
  915. RemoveAffect(AFFECT_INT);
  916. RemoveAffect(AFFECT_CON);
  917. RemoveAffect(AFFECT_CHINA_FIREWORK);
  918.  
  919. RemoveAffect(SKILL_JEONGWI);
  920. RemoveAffect(SKILL_GEOMKYUNG);
  921. RemoveAffect(SKILL_CHUNKEON);
  922. RemoveAffect(SKILL_EUNHYUNG);
  923. RemoveAffect(SKILL_GYEONGGONG);
  924. RemoveAffect(SKILL_GWIGEOM);
  925. RemoveAffect(SKILL_TERROR);
  926. RemoveAffect(SKILL_JUMAGAP);
  927. RemoveAffect(SKILL_MANASHILED);
  928. RemoveAffect(SKILL_HOSIN);
  929. RemoveAffect(SKILL_REFLECT);
  930. RemoveAffect(SKILL_KWAESOK);
  931. RemoveAffect(SKILL_JEUNGRYEOK);
  932. RemoveAffect(SKILL_GICHEON);
  933. #ifdef ENABLE_WOLFMAN_CHARACTER
  934.  
  935. RemoveAffect(SKILL_JEOKRANG);
  936. RemoveAffect(SKILL_CHEONGRANG);
  937. #endif
  938.  
  939. #if defined(__CONQUEROR_LEVEL__) && defined(__9THSKILL__)
  940. RemoveAffect(SKILL_CHEONUN);
  941. #endif
  942.  
  943. }
  944.  
  945. bool CHARACTER::IsGoodAffect(BYTE bAffectType) const
  946. {
  947. switch (bAffectType)
  948. {
  949. case (AFFECT_MOV_SPEED):
  950. case (AFFECT_ATT_SPEED):
  951. case (AFFECT_STR):
  952. case (AFFECT_DEX):
  953. case (AFFECT_INT):
  954. case (AFFECT_CON):
  955. case (AFFECT_CHINA_FIREWORK):
  956.  
  957. case (SKILL_JEONGWI):
  958. case (SKILL_GEOMKYUNG):
  959. case (SKILL_CHUNKEON):
  960. case (SKILL_EUNHYUNG):
  961. case (SKILL_GYEONGGONG):
  962. case (SKILL_GWIGEOM):
  963. case (SKILL_TERROR):
  964. case (SKILL_JUMAGAP):
  965. case (SKILL_MANASHILED):
  966. case (SKILL_HOSIN):
  967. case (SKILL_REFLECT):
  968. case (SKILL_KWAESOK):
  969. case (SKILL_JEUNGRYEOK):
  970. case (SKILL_GICHEON):
  971. #ifdef ENABLE_WOLFMAN_CHARACTER
  972.  
  973. case (SKILL_JEOKRANG):
  974. case (SKILL_CHEONGRANG):
  975. #endif
  976.  
  977. #if defined(__CONQUEROR_LEVEL__) && defined(__9THSKILL__)
  978. case (SKILL_CHEONUN):
  979. #endif
  980.  
  981. return true;
  982. }
  983. return false;
  984. }
  985.  
  986. void CHARACTER::RemoveBadAffect()
  987. {
  988. sys_log(0, "RemoveBadAffect %s", GetName());
  989. RemovePoison();
  990. #ifdef ENABLE_WOLFMAN_CHARACTER
  991. RemoveBleeding();
  992. #endif
  993. RemoveFire();
  994.  
  995. RemoveAffect(AFFECT_STUN);
  996.  
  997. RemoveAffect(AFFECT_SLOW);
  998.  
  999. RemoveAffect(SKILL_TUSOK);
  1000.  
  1001. //RemoveAffect(SKILL_CURSE);
  1002.  
  1003. //RemoveAffect(SKILL_PABUP);
  1004.  
  1005. //RemoveAffect(AFFECT_FAINT);
  1006.  
  1007. //RemoveAffect(AFFECT_WEB);
  1008.  
  1009. //RemoveAffect(AFFECT_SLEEP);
  1010.  
  1011. //RemoveAffect(AFFECT_CURSE);
  1012.  
  1013. //RemoveAffect(AFFECT_PARALYZE);
  1014.  
  1015. //RemoveAffect(SKILL_BUDONG);
  1016. }
  1017. //martysama0134's 747bda46b83d0f642ccb846d9a8c1cbe
  1018.  
Advertisement
Add Comment
Please, Sign In to add comment