Guest User

Untitled

a guest
Nov 27th, 2020
73
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×