#include "stdafx.h" #include "config.h" #include "char.h" #include "char_manager.h" #include "packet.h" #include "guild.h" #include "vector.h" #include "questmanager.h" #include "item.h" #include "horsename_manager.h" #include "locale_service.h" #include "arena.h" #include bool CHARACTER::StartRiding() { if (IsDead() == true) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¾²·¯Áø »óÅ¿¡¼­´Â ¸»¿¡ Å» ¼ö ¾ø½À´Ï´Ù.")); return false; } if (IsPolymorphed()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("º¯½Å »óÅ¿¡¼­´Â ¸»¿¡ Å» ¼ö ¾ø½À´Ï´Ù.")); return false; } // Åνõµ ÀÔÀº »óÅÂÀÇ ¸» Ÿ±â ±ÝÁö LPITEM armor = GetWear(WEAR_BODY); if (armor && (armor->GetVnum() >= 11901 && armor->GetVnum() <= 11904)) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿¹º¹À» ÀÔÀº »óÅ¿¡¼­ ¸»À» Å» ¼ö ¾ø½À´Ï´Ù.")); return false; } if (LC_IsCanada() == true) { if (CArenaManager::instance().IsArenaMap(GetMapIndex()) == true) return false; } DWORD dwMountVnum = m_chHorse ? m_chHorse->GetRaceNum() : GetMyHorseVnum(); if (false == CHorseRider::StartRiding()) { if (GetHorseLevel() <= 0) ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¸»À» ¼ÒÀ¯ÇÏ°í ÀÖÁö ¾Ê½À´Ï´Ù.")); else if (GetHorseHealth() <= 0) ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¸»ÀÌ Á×¾îÀÖ´Â »óÅ ÀÔ´Ï´Ù.")); else if (GetHorseStamina() <= 0) ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¸»ÀÇ ½ºÅ׹̳ʰ¡ ºÎÁ·ÇÏ¿© ¸»À» Å» ¼ö ¾ø½À´Ï´Ù.")); return false; } // ¼ÒȯÇÑ ¸» ¾ø¾Ö°í HorseSummon(false); MountVnum(dwMountVnum); if(test_server) sys_log(0, "Ride Horse : %s ", GetName()); return true; } bool CHARACTER::StopRiding() { if (CHorseRider::StopRiding()) { quest::CQuestManager::instance().Unmount(GetPlayerID()); if (!IsDead() && !IsStun()) { DWORD dwOldVnum = GetMountVnum(); MountVnum(0); // [NOTE] ¸»¿¡¼­ ³»¸± ¶© ÀڱⰡ ÅÀ´ø°É ¼ÒȯÇϵµ·Ï ¼öÁ¤ HorseSummon(true, false, dwOldVnum); } else { m_dwMountVnum = 0; ComputePoints(); UpdatePacket(); } PointChange(POINT_ST, 0); PointChange(POINT_DX, 0); PointChange(POINT_HT, 0); PointChange(POINT_IQ, 0); return true; } return false; } EVENTFUNC(horse_dead_event) { char_event_info* info = dynamic_cast( event->info ); if ( info == NULL ) { sys_err( "horse_dead_event> Null pointer" ); return 0; } // LPCHARACTER ch = info->ch; if (ch == NULL) { return 0; } ch->HorseSummon(false); return 0; } void CHARACTER::SetRider(LPCHARACTER ch) { if (m_chRider) m_chRider->ClearHorseInfo(); m_chRider = ch; if (m_chRider) m_chRider->SendHorseInfo(); } LPCHARACTER CHARACTER::GetRider() const { return m_chRider; } void CHARACTER::HorseSummon(bool bSummon, bool bFromFar, DWORD dwVnum, const char* pPetName) { if ( bSummon ) { //NOTE : summonÇߴµ¥ ÀÌ¹Ì horse°¡ ÀÖÀ¸¸é ¾Æ¹«°Íµµ ¾ÈÇÑ´Ù. if( m_chHorse != NULL ) return; if (GetHorseLevel() <= 0) return; // ¹«¾ð°¡¸¦ Ÿ°í ÀÖ´Ù¸é ½ÇÆÐ if (IsRiding()) return; sys_log(0, "HorseSummon : %s lv:%d bSummon:%d fromFar:%d", GetName(), GetLevel(), bSummon, bFromFar); int x = GetX(); int y = GetY(); if (GetHorseHealth() <= 0) bFromFar = false; if (bFromFar) { x += (number(0, 1) * 2 - 1) * number(2000, 2500); y += (number(0, 1) * 2 - 1) * number(2000, 2500); } else { x += number(-100, 100); y += number(-100, 100); } m_chHorse = CHARACTER_MANAGER::instance().SpawnMob( (0 == dwVnum) ? GetMyHorseVnum() : dwVnum, GetMapIndex(), x, y, GetZ(), false, (int)(GetRotation()+180), false); if (!m_chHorse) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¸» ¼Òȯ¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.")); return; } if (GetHorseHealth() <= 0) { // Á×Àº°Åó·³ ÀÖ°Ô Çϴ ó¸® m_chHorse->SetPosition(POS_DEAD); // ÀÏÁ¤½Ã°£ÀÖ´Ù »ç¶óÁö°Ô ÇÏÀÚ. char_event_info* info = AllocEventInfo(); info->ch = this; m_chHorse->m_pkDeadEvent = event_create(horse_dead_event, info, PASSES_PER_SEC(60)); } m_chHorse->SetLevel(GetHorseLevel()); const char* pHorseName = CHorseNameManager::instance().GetHorseName(GetPlayerID()); if ( pHorseName != NULL && strlen(pHorseName) != 0 ) { m_chHorse->m_stName = pHorseName; } else { m_chHorse->m_stName = GetName(); m_chHorse->m_stName += LC_TEXT("´ÔÀÇ ¸»"); } if (!m_chHorse->Show(GetMapIndex(), x, y, GetZ())) { M2_DESTROY_CHARACTER(m_chHorse); sys_err("cannot show monster"); m_chHorse = NULL; return; } if ((GetHorseHealth() <= 0)) { TPacketGCDead pack; pack.header = HEADER_GC_DEAD; pack.vid = m_chHorse->GetVID(); PacketAround(&pack, sizeof(pack)); } m_chHorse->SetRider(this); } else { if (!m_chHorse) return; LPCHARACTER chHorse = m_chHorse; chHorse->SetRider(NULL); // m_chHorse assign to NULL if (!bFromFar) { M2_DESTROY_CHARACTER(chHorse); } else { // ¸Ö¾îÁö¸é¼­ »ç¶óÁö´Â ó¸® Çϱâ chHorse->SetNowWalking(false); float fx, fy; chHorse->SetRotation(GetDegreeFromPositionXY(chHorse->GetX(), chHorse->GetY(), GetX(), GetY())+180); GetDeltaByDegree(chHorse->GetRotation(), 3500, &fx, &fy); chHorse->Goto((int)(chHorse->GetX()+fx), (int) (chHorse->GetY()+fy)); chHorse->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0); } m_chHorse = NULL; } } DWORD CHARACTER::GetMyHorseVnum() const { int delta = 0; if (GetGuild()) { ++delta; if (GetGuild()->GetMasterPID() == GetPlayerID()) ++delta; } return c_aHorseStat[GetHorseLevel()].iNPCRace + delta; } void CHARACTER::HorseDie() { CHorseRider::HorseDie(); HorseSummon(false); } bool CHARACTER::ReviveHorse() { if (CHorseRider::ReviveHorse()) { HorseSummon(false); HorseSummon(true); return true; } return false; } void CHARACTER::ClearHorseInfo() { if (!IsHorseRiding()) { ChatPacket(CHAT_TYPE_COMMAND, "hide_horse_state"); m_bSendHorseLevel = 0; m_bSendHorseHealthGrade = 0; m_bSendHorseStaminaGrade = 0; } m_chHorse = NULL; } void CHARACTER::SendHorseInfo() { if (m_chHorse || IsHorseRiding()) { int iHealthGrade; int iStaminaGrade; /* HP 3: 70% < ~ <= 100% 2: 30% < ~ <= 70% 1: 0% < ~ <= 30% 0: »ç¸Á STM 3: 71% < ~ <= 100% 2: 31% < ~ <= 70% 1: 10% < ~ <= 30% 0: ~ <= 10% */ if (GetHorseHealth() == 0) iHealthGrade = 0; else if (GetHorseHealth() * 10 <= GetHorseMaxHealth() * 3) iHealthGrade = 1; else if (GetHorseHealth() * 10 <= GetHorseMaxHealth() * 7) iHealthGrade = 2; else iHealthGrade = 3; if (GetHorseStamina() * 10 <= GetHorseMaxStamina()) iStaminaGrade = 0; else if (GetHorseStamina() * 10 <= GetHorseMaxStamina() * 3) iStaminaGrade = 1; else if (GetHorseStamina() * 10 <= GetHorseMaxStamina() * 7) iStaminaGrade = 2; else iStaminaGrade = 3; if (m_bSendHorseLevel != GetHorseLevel() || m_bSendHorseHealthGrade != iHealthGrade || m_bSendHorseStaminaGrade != iStaminaGrade) { ChatPacket(CHAT_TYPE_COMMAND, "horse_state %d %d %d", GetHorseLevel(), iHealthGrade, iStaminaGrade); // FIX : Ŭ¶óÀ̾ðÆ®¿¡ "¸» »óÅ ¹öÇÁ" ¾ÆÀÌÄÜÀ» Ç¥½ÃÇÏÁö ¾ÊÀ» ¸ñÀûÀ¸·Î ÇÔ¼ö ÃÊÀÔ¿¡ returnÇÔÀ¸·Î½á ¾Æ·¡ Äڵ带 ¹«½ÃÇÑ´Ù¸é // ¸»À» ¹«ÇÑ´ë·Î ¼ÒȯÇÏ´Â ¹«½Ã¹«½ÃÇÑ ¹ö±×°¡ »ý±è.. Á¤È®ÇÑ ¿øÀÎÀº ÆÄ¾Ç ¾ÈÇغÁ¼­ ¸ð¸§. m_bSendHorseLevel = GetHorseLevel(); m_bSendHorseHealthGrade = iHealthGrade; m_bSendHorseStaminaGrade = iStaminaGrade; } } } bool CHARACTER::CanUseHorseSkill() { if(IsRiding()) { if (GetHorseGrade() == 3) return true; else return false; if(GetMountVnum()) { if (GetMountVnum() >= 20209 && GetMountVnum() <= 20212) return true; //¶ó¸¶´Ü È渶 if (CMobVnumHelper::IsRamadanBlackHorse(GetMountVnum())) return true; } else return false; } return false; } void CHARACTER::SetHorseLevel(int iLevel) { CHorseRider::SetHorseLevel(iLevel); SetSkillLevel(SKILL_HORSE, GetHorseLevel()); }