Advertisement
Guest User

Untitled

a guest
Nov 27th, 2020
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.20 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "config.h"
  3. #include "char.h"
  4. #include "char_manager.h"
  5. #include "packet.h"
  6. #include "guild.h"
  7. #include "vector.h"
  8. #include "questmanager.h"
  9. #include "item.h"
  10. #include "horsename_manager.h"
  11. #include "locale_service.h"
  12. #include "arena.h"
  13.  
  14. #include "../../common/VnumHelper.h"
  15.  
  16. bool CHARACTER::StartRiding()
  17. {
  18.     if (IsDead() == true)
  19.     {
  20.         ChatPacket(CHAT_TYPE_INFO, LC_TEXT("쓰러진 상태에서는 말에 탈 수 없습니다."));
  21.         return false;
  22.     }
  23.    
  24.     if (IsPolymorphed())
  25.     {
  26.         ChatPacket(CHAT_TYPE_INFO, LC_TEXT("변신 상태에서는 말에 탈 수 없습니다."));
  27.         return false;
  28.     }
  29.  
  30.     // 턱시도 입은 상태의 말 타기 금지
  31.     LPITEM armor = GetWear(WEAR_BODY);
  32.  
  33.     if (armor && (armor->GetVnum() >= 11901 && armor->GetVnum() <= 11904))
  34.     {
  35.         ChatPacket(CHAT_TYPE_INFO, LC_TEXT("예복을 입은 상태에서 말을 탈 수 없습니다."));
  36.         return false;
  37.     }
  38.  
  39.     DWORD dwMountVnum = m_chHorse ? m_chHorse->GetRaceNum() : GetMyHorseVnum();
  40.  
  41.     if (false == CHorseRider::StartRiding())
  42.     {
  43.         if (GetHorseLevel() <= 0)
  44.             ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말을 소유하고 있지 않습니다."));
  45.         else if (GetHorseHealth() <= 0)
  46.             ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말이 죽어있는 상태 입니다."));
  47.         else if (GetHorseStamina() <= 0)
  48.             ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말의 스테미너가 부족하여 말을 탈 수 없습니다."));
  49.  
  50.         return false;
  51.     }
  52.  
  53.     // 소환한 말 없애고
  54.     HorseSummon(false);
  55.  
  56.     MountVnum(dwMountVnum);
  57.  
  58.     if(test_server)
  59.         sys_log(0, "Ride Horse : %s ", GetName());
  60.  
  61.     return true;
  62. }
  63.  
  64. bool CHARACTER::StopRiding()
  65. {
  66.     if (CHorseRider::StopRiding())
  67.     {
  68.         quest::CQuestManager::instance().Unmount(GetPlayerID());
  69.  
  70.         if (!IsDead() && !IsStun())
  71.         {
  72.             DWORD dwOldVnum = GetMountVnum();
  73.             MountVnum(0);
  74.  
  75.             // [NOTE] 말에서 내릴 땐 자기가 탔던걸 소환하도록 수정
  76.             HorseSummon(true, false, dwOldVnum);
  77.         }
  78.         else
  79.         {
  80.             m_dwMountVnum = 0;
  81.             ComputePoints();
  82.             UpdatePacket();
  83.         }
  84.  
  85.         PointChange(POINT_ST, 0);
  86.         PointChange(POINT_DX, 0);
  87.         PointChange(POINT_HT, 0);
  88.         PointChange(POINT_IQ, 0);
  89.  
  90.         return true;
  91.     }
  92.  
  93.     return false;
  94. }
  95.  
  96. EVENTFUNC(horse_dead_event)
  97. {
  98.     char_event_info* info = dynamic_cast<char_event_info*>( event->info );
  99.  
  100.     if ( info == NULL )
  101.     {
  102.         sys_err( "horse_dead_event> <Factor> Null pointer" );
  103.         return 0;
  104.     }
  105.  
  106.     // <Factor>
  107.     LPCHARACTER ch = info->ch;
  108.     if (ch == NULL) {
  109.         return 0;
  110.     }
  111.     ch->HorseSummon(false);
  112.     return 0;
  113. }
  114.  
  115. void CHARACTER::SetRider(LPCHARACTER ch)
  116. {
  117.     if (m_chRider)
  118.         m_chRider->ClearHorseInfo();
  119.  
  120.     m_chRider = ch;
  121.  
  122.     if (m_chRider)
  123.         m_chRider->SendHorseInfo();
  124. }
  125.  
  126. LPCHARACTER CHARACTER::GetRider() const
  127. {
  128.     return m_chRider;
  129. }
  130.  
  131.  
  132. void CHARACTER::HorseSummon(bool bSummon, bool bFromFar, DWORD dwVnum, const char* pPetName)
  133. {
  134.     if ( bSummon )
  135.     {
  136.         //NOTE : summon했는데 이미 horse가 있으면 아무것도 안한다.
  137.         if( m_chHorse != NULL )
  138.             return;
  139.  
  140.         if (GetHorseLevel() <= 0)
  141.             return;
  142.  
  143.         // 무언가를 타고 있다면 실패
  144.         if (IsRiding())
  145.             return;
  146.  
  147.         sys_log(0, "HorseSummon : %s lv:%d bSummon:%d fromFar:%d", GetName(), GetLevel(), bSummon, bFromFar);
  148.  
  149.         long x = GetX();
  150.         long y = GetY();
  151.  
  152.         if (GetHorseHealth() <= 0)
  153.             bFromFar = false;
  154.  
  155.         if (bFromFar)
  156.         {
  157.             x += (number(0, 1) * 2 - 1) * number(2000, 2500);
  158.             y += (number(0, 1) * 2 - 1) * number(2000, 2500);
  159.         }
  160.         else
  161.         {
  162.             x += number(-100, 100);
  163.             y += number(-100, 100);
  164.         }
  165.  
  166.         m_chHorse = CHARACTER_MANAGER::instance().SpawnMob(
  167.                 (0 == dwVnum) ? GetMyHorseVnum() : dwVnum,
  168.                 GetMapIndex(),
  169.                 x, y,
  170.                 GetZ(), false, (int)(GetRotation()+180), false);
  171.  
  172.         if (!m_chHorse)
  173.         {
  174.             ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말 소환에 실패하였습니다."));
  175.             return;
  176.         }
  177.  
  178.         if (GetHorseHealth() <= 0)
  179.         {
  180.             // 죽은거처럼 있게 하는 처리
  181.             m_chHorse->SetPosition(POS_DEAD);
  182.  
  183.             // 일정시간있다 사라지게 하자.
  184.             char_event_info* info = AllocEventInfo<char_event_info>();
  185.             info->ch = this;
  186.             m_chHorse->m_pkDeadEvent = event_create(horse_dead_event, info, PASSES_PER_SEC(60));
  187.         }
  188.  
  189.         m_chHorse->SetLevel(GetHorseLevel());
  190.  
  191.         const char* pHorseName = CHorseNameManager::instance().GetHorseName(GetPlayerID());
  192.  
  193.         if ( pHorseName != NULL && strlen(pHorseName) != 0 )
  194.         {
  195.             m_chHorse->m_stName = pHorseName;
  196.         }
  197.         else
  198.         {
  199.             m_chHorse->m_stName = GetName();
  200.             m_chHorse->m_stName += LC_TEXT("님의 말");
  201.         }
  202.  
  203.         if (!m_chHorse->Show(GetMapIndex(), x, y, GetZ()))
  204.         {
  205.             M2_DESTROY_CHARACTER(m_chHorse);
  206.             sys_err("cannot show monster");
  207.             m_chHorse = NULL;
  208.             return;
  209.         }
  210.  
  211.         if ((GetHorseHealth() <= 0))
  212.         {
  213.             TPacketGCDead pack;
  214.             pack.header = HEADER_GC_DEAD;
  215.             pack.vid    = m_chHorse->GetVID();
  216.             PacketAround(&pack, sizeof(pack));
  217.         }
  218.  
  219.         m_chHorse->SetRider(this);
  220.     }
  221.     else
  222.     {
  223.         if (!m_chHorse)
  224.             return;
  225.  
  226.         LPCHARACTER chHorse = m_chHorse;
  227.  
  228.         chHorse->SetRider(NULL); // m_chHorse assign to NULL
  229.  
  230.         if (!bFromFar)
  231.         {
  232.             M2_DESTROY_CHARACTER(chHorse);
  233.         }
  234.         else
  235.         {
  236.             // 멀어지면서 사라지는 처리 하기
  237.             chHorse->SetNowWalking(false);
  238.             float fx, fy;
  239.             chHorse->SetRotation(GetDegreeFromPositionXY(chHorse->GetX(), chHorse->GetY(), GetX(), GetY())+180);
  240.             GetDeltaByDegree(chHorse->GetRotation(), 3500, &fx, &fy);
  241.             chHorse->Goto((long)(chHorse->GetX()+fx), (long) (chHorse->GetY()+fy));
  242.             chHorse->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
  243.         }
  244.  
  245.         m_chHorse = NULL;
  246.     }
  247. }
  248.  
  249. DWORD CHARACTER::GetMyHorseVnum() const
  250. {
  251.     int delta = 0;
  252.  
  253.     if (GetGuild())
  254.     {
  255.         ++delta;
  256.  
  257.         if (GetGuild()->GetMasterPID() == GetPlayerID())
  258.             ++delta;
  259.     }
  260.  
  261.     return c_aHorseStat[GetHorseLevel()].iNPCRace + delta;
  262. }
  263.  
  264. void CHARACTER::HorseDie()
  265. {
  266.     CHorseRider::HorseDie();
  267.     HorseSummon(false);
  268. }
  269.  
  270. bool CHARACTER::ReviveHorse()
  271. {
  272.     if (CHorseRider::ReviveHorse())
  273.     {
  274.         HorseSummon(false);
  275.         HorseSummon(true);
  276.         return true;
  277.     }
  278.     return false;
  279. }
  280.  
  281. void CHARACTER::ClearHorseInfo()
  282. {
  283.     if (!IsHorseRiding())
  284.     {
  285.         ChatPacket(CHAT_TYPE_COMMAND, "hide_horse_state");
  286.  
  287.         m_bSendHorseLevel = 0;
  288.         m_bSendHorseHealthGrade = 0;
  289.         m_bSendHorseStaminaGrade = 0;
  290.     }
  291.  
  292.     m_chHorse = NULL;
  293.  
  294. }
  295.  
  296. void CHARACTER::SendHorseInfo()
  297. {
  298.     if (m_chHorse || IsHorseRiding())
  299.     {
  300.         int iHealthGrade;
  301.         int iStaminaGrade;
  302.         /*
  303.            HP  
  304. 3: 70% < ~ <= 100%
  305. 2: 30% < ~ <= 70%
  306. 1:  0% < ~ <= 30%
  307. 0: 사망
  308.  
  309. STM
  310.  
  311. 3: 71% < ~ <= 100%
  312. 2: 31% < ~ <= 70%
  313. 1: 10% < ~ <= 30%
  314. 0:   ~ <= 10%
  315.          */
  316.         if (GetHorseHealth() == 0)
  317.             iHealthGrade = 0;
  318.         else if (GetHorseHealth() * 10 <= GetHorseMaxHealth() * 3)
  319.             iHealthGrade = 1;
  320.         else if (GetHorseHealth() * 10 <= GetHorseMaxHealth() * 7)
  321.             iHealthGrade = 2;
  322.         else
  323.             iHealthGrade = 3;
  324.  
  325.         if (GetHorseStamina() * 10 <= GetHorseMaxStamina())
  326.             iStaminaGrade = 0;
  327.         else if (GetHorseStamina() * 10 <= GetHorseMaxStamina() * 3)
  328.             iStaminaGrade = 1;
  329.         else if (GetHorseStamina() * 10 <= GetHorseMaxStamina() * 7)
  330.             iStaminaGrade = 2;
  331.         else
  332.             iStaminaGrade = 3;
  333.  
  334.         if (m_bSendHorseLevel != GetHorseLevel() ||
  335.                 m_bSendHorseHealthGrade != iHealthGrade ||
  336.                 m_bSendHorseStaminaGrade != iStaminaGrade)
  337.         {
  338.             ChatPacket(CHAT_TYPE_COMMAND, "horse_state %d %d %d", GetHorseLevel(), iHealthGrade, iStaminaGrade);
  339.  
  340.             // FIX : 클라이언트에 "말 상태 버프" 아이콘을 표시하지 않을 목적으로 함수 초입에 return함으로써 아래 코드를 무시한다면
  341.             // 말을 무한대로 소환하는 무시무시한 버그가 생김.. 정확한 원인은 파악 안해봐서 모름.
  342.             m_bSendHorseLevel = GetHorseLevel();
  343.             m_bSendHorseHealthGrade = iHealthGrade;
  344.             m_bSendHorseStaminaGrade = iStaminaGrade;
  345.         }
  346.     }
  347. }
  348.        
  349. bool CHARACTER::CanUseHorseSkill()
  350. {
  351.     if(IsRiding())
  352.     {
  353.         if (GetHorseGrade() == 3)
  354.             return true;
  355.         else
  356.             return false;
  357.  
  358.         if(GetMountVnum())
  359.         {
  360.             if (GetMountVnum() >= 20209 && GetMountVnum() <= 20212)
  361.                 return true;
  362.  
  363.             //라마단 흑마
  364.             if (CMobVnumHelper::IsRamadanBlackHorse(GetMountVnum()))
  365.                 return true;
  366.         }
  367.         else
  368.             return false;
  369.  
  370.     }
  371.  
  372.     return false;
  373. }
  374.  
  375. void CHARACTER::SetHorseLevel(int iLevel)
  376. {
  377.     CHorseRider::SetHorseLevel(iLevel);
  378.     SetSkillLevel(SKILL_HORSE, GetHorseLevel());
  379. }
  380.  
  381.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement