#include "stdafx.h" #include "constants.h" #include "utils.h" #include "horse_rider.h" #include "config.h" #include "char_manager.h" const int HORSE_HEALTH_DROP_INTERVAL = 3 * 24 * 60 * 60; const int HORSE_STAMINA_CONSUME_INTERVAL = 6 * 60; const int HORSE_STAMINA_REGEN_INTERVAL = 12 * 60; //const int HORSE_HP_DROP_INTERVAL = 60; //const int HORSE_STAMINA_CONSUME_INTERVAL = 3; //const int HORSE_STAMINA_REGEN_INTERVAL = 6; THorseStat c_aHorseStat[HORSE_MAX_LEVEL+1] = /* int iMinLevel; // ž½ÂÇÒ ¼ö ÀÖ´Â ÃÖ¼Ò ·¹º§ int iNPCRace; int iMaxHealth; // ¸»ÀÇ ÃÖ´ë ü·Â int iMaxStamina; // ¸»ÀÇ ÃÖ´ë ½ºÅ×¹Ì³Ê int iST; int iDX; int iHT; int iIQ; int iDamMean; int iDamMin; int iDamMax; int iDef; */ { { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, { 25, 20101, 3, 4, 26, 35, 18, 9, 54, 43, 64, 32 }, // 1 (ÃʱÞ) { 25, 20101, 4, 4, 27, 36, 18, 9, 55, 44, 66, 33 }, { 25, 20101, 5, 5, 28, 38, 19, 9, 56, 44, 67, 33 }, { 25, 20101, 7, 5, 29, 39, 19, 10, 57, 45, 68, 34 }, { 25, 20101, 8, 6, 30, 40, 20, 10, 58, 46, 69, 34 }, { 25, 20101, 9, 6, 31, 41, 21, 10, 59, 47, 70, 35 }, { 25, 20101, 11, 7, 32, 42, 21, 11, 60, 48, 72, 36 }, { 25, 20101, 12, 7, 33, 44, 22, 11, 61, 48, 73, 36 }, { 25, 20101, 13, 8, 34, 45, 22, 11, 62, 49, 74, 37 }, { 25, 20101, 15, 10, 35, 46, 23, 12, 63, 50, 75, 37 }, { 35, 20104, 18, 30, 40, 53, 27, 13, 69, 55, 82, 41 }, // 11 (Áß±Þ) { 35, 20104, 19, 35, 41, 54, 27, 14, 70, 56, 84, 42 }, { 35, 20104, 21, 40, 42, 56, 28, 14, 71, 56, 85, 42 }, { 35, 20104, 22, 50, 43, 57, 28, 14, 72, 57, 86, 43 }, { 35, 20104, 24, 55, 44, 58, 29, 15, 73, 58, 87, 43 }, { 35, 20104, 25, 60, 44, 59, 30, 15, 74, 59, 88, 44 }, { 35, 20104, 27, 65, 45, 60, 30, 15, 75, 60, 90, 45 }, { 35, 20104, 28, 70, 46, 62, 31, 15, 76, 60, 91, 45 }, { 35, 20104, 30, 80, 47, 63, 31, 16, 77, 61, 92, 46 }, { 35, 20104, 32, 100, 48, 64, 32, 16, 78, 62, 93, 46 }, { 50, 20107, 35, 120, 53, 71, 36, 18, 84, 67, 100, 50 }, // 21 (°í±Þ) { 50, 20107, 36, 125, 55, 74, 37, 18, 86, 68, 103, 51 }, { 50, 20107, 37, 130, 57, 76, 38, 19, 88, 70, 105, 52 }, { 50, 20107, 38, 135, 59, 78, 39, 20, 90, 72, 108, 54 }, { 50, 20107, 40, 140, 60, 80, 40, 20, 91, 72, 109, 54 }, { 50, 20107, 42, 145, 61, 81, 40, 20, 92, 73, 110, 55 }, { 50, 20107, 44, 150, 62, 83, 42, 21, 94, 75, 112, 56 }, { 50, 20107, 46, 160, 63, 84, 42, 21, 95, 76, 114, 57 }, { 50, 20107, 48, 170, 65, 87, 43, 22, 97, 77, 116, 58 }, { 50, 20107, 50, 200, 67, 89, 45, 22, 99, 79, 118, 59 } }; CHorseRider::CHorseRider() { Initialize(); } CHorseRider::~CHorseRider() { Destroy(); } void CHorseRider::Initialize() { m_eventStaminaRegen = NULL; m_eventStaminaConsume = NULL; memset(&m_Horse, 0, sizeof(m_Horse)); } void CHorseRider::Destroy() { event_cancel(&m_eventStaminaRegen); event_cancel(&m_eventStaminaConsume); } void CHorseRider::EnterHorse() { if (GetHorseLevel() <= 0) return; if (GetHorseHealth() <= 0) return; if (IsHorseRiding()) { m_Horse.bRiding = !m_Horse.bRiding; StartRiding(); } else { StartStaminaRegenEvent(); } CheckHorseHealthDropTime(false); } bool CHorseRider::ReviveHorse() { if (GetHorseLevel() <= 0) return false; if (GetHorseHealth()>0) return false; int level = GetHorseLevel(); m_Horse.sHealth = c_aHorseStat[level].iMaxHealth; m_Horse.sStamina = c_aHorseStat[level].iMaxStamina; // 2005.03.24.ipkn.¸» »ì¸°ÈÄ ´Ù½Ã Á×´Â Çö»ó ¼öÁ¤ ResetHorseHealthDropTime(); StartStaminaRegenEvent(); return true; } short CHorseRider::GetHorseMaxHealth() { int level = GetHorseLevel(); return c_aHorseStat[level].iMaxHealth; } short CHorseRider::GetHorseMaxStamina() { int level = GetHorseLevel(); return c_aHorseStat[level].iMaxStamina; } void CHorseRider::FeedHorse() { // ¸»À» °¡Áö°í »ì¾ÆÀÖÀ»¶§¸¸ if (GetHorseLevel() > 0 && GetHorseHealth() > 0) { UpdateHorseHealth(+1); // 20050324. ipkn ¸» ¸Ô¿´À»¶§µµ ü·Â °¨¼Ò µô·¹À̸¦ ´Ã¸°´Ù. ResetHorseHealthDropTime(); } } void CHorseRider::SetHorseData(const THorseInfo& crInfo) { m_Horse = crInfo; } // Stamina void CHorseRider::UpdateHorseDataByLogoff(DWORD dwLogoffTime) { if (GetHorseLevel() <= 0) return; if (dwLogoffTime >= 12 * 60) UpdateHorseStamina(dwLogoffTime / 12 / 60, false); // ·Î±×¿ÀÇÁ 12ºÐ´ç 1¾¿ ȸº¹ } void CHorseRider::UpdateHorseStamina(int iStamina, bool bSend) { int level = GetHorseLevel(); m_Horse.sStamina = MINMAX(0, m_Horse.sStamina + iStamina, c_aHorseStat[level].iMaxStamina); if (GetHorseStamina() == 0 && IsHorseRiding()) { StopRiding(); } if (bSend) SendHorseInfo(); } bool CHorseRider::StartRiding() { if (m_Horse.bRiding) return false; if (GetHorseLevel() <= 0) return false; if (GetHorseHealth() <= 0) return false; if (GetHorseStamina() <= 0) return false; m_Horse.bRiding = true; StartStaminaConsumeEvent(); SendHorseInfo(); return true; } bool CHorseRider::StopRiding() { if (!m_Horse.bRiding) return false; m_Horse.bRiding = false; StartStaminaRegenEvent(); return true; } EVENTINFO(horserider_info) { CHorseRider* hr; horserider_info() : hr( 0 ) { } }; EVENTFUNC(horse_stamina_consume_event) { horserider_info* info = dynamic_cast( event->info ); if ( info == NULL ) { sys_err( "horse_stamina_consume_event> Null pointer" ); return 0; } CHorseRider* hr = info->hr; if (hr->GetHorseHealth() <= 0) { hr->m_eventStaminaConsume = NULL; return 0; } hr->UpdateHorseStamina(-1); hr->UpdateRideTime(HORSE_STAMINA_CONSUME_INTERVAL); int delta = PASSES_PER_SEC(HORSE_STAMINA_CONSUME_INTERVAL); if (hr->GetHorseStamina() == 0) { hr->m_eventStaminaConsume = NULL; delta = 0; } hr->CheckHorseHealthDropTime(); sys_log(0, "HORSE STAMINA - %p", get_pointer(event)); return delta; } EVENTFUNC(horse_stamina_regen_event) { horserider_info* info = dynamic_cast( event->info ); if ( info == NULL ) { sys_err( "horse_stamina_regen_event> Null pointer" ); return 0; } CHorseRider* hr = info->hr; if (hr->GetHorseHealth()<=0) { hr->m_eventStaminaRegen = NULL; return 0; } hr->UpdateHorseStamina(+1); int delta = PASSES_PER_SEC(HORSE_STAMINA_REGEN_INTERVAL); if (hr->GetHorseStamina() == hr->GetHorseMaxStamina()) { delta = 0; hr->m_eventStaminaRegen = NULL; } hr->CheckHorseHealthDropTime(); sys_log(0, "HORSE STAMINA + %p", get_pointer(event)); return delta; } void CHorseRider::StartStaminaConsumeEvent() { if (GetHorseLevel() <= 0) return; if (GetHorseHealth() <= 0) return; sys_log(0,"HORSE STAMINA REGEN EVENT CANCEL %p", get_pointer(m_eventStaminaRegen)); event_cancel(&m_eventStaminaRegen); if (m_eventStaminaConsume) return; horserider_info* info = AllocEventInfo(); info->hr = this; m_eventStaminaConsume = event_create(horse_stamina_consume_event, info, PASSES_PER_SEC(HORSE_STAMINA_CONSUME_INTERVAL)); sys_log(0,"HORSE STAMINA CONSUME EVENT CREATE %p", get_pointer(m_eventStaminaConsume)); } void CHorseRider::StartStaminaRegenEvent() { if (GetHorseLevel() <= 0) return; if (GetHorseHealth() <= 0) return; sys_log(0,"HORSE STAMINA CONSUME EVENT CANCEL %p", get_pointer(m_eventStaminaConsume)); event_cancel(&m_eventStaminaConsume); if (m_eventStaminaRegen) return; horserider_info* info = AllocEventInfo(); info->hr = this; m_eventStaminaRegen = event_create(horse_stamina_regen_event, info, PASSES_PER_SEC(HORSE_STAMINA_REGEN_INTERVAL)); sys_log(0,"HORSE STAMINA REGEN EVENT CREATE %p", get_pointer(m_eventStaminaRegen)); } // Health void CHorseRider::ResetHorseHealthDropTime() { m_Horse.dwHorseHealthDropTime = get_global_time() + HORSE_HEALTH_DROP_INTERVAL; } void CHorseRider::CheckHorseHealthDropTime(bool bSend) { DWORD now = get_global_time(); while (m_Horse.dwHorseHealthDropTime < now) { m_Horse.dwHorseHealthDropTime += HORSE_HEALTH_DROP_INTERVAL; UpdateHorseHealth(-1, bSend); } } void CHorseRider::UpdateHorseHealth(int iHealth, bool bSend) { int level = GetHorseLevel(); m_Horse.sHealth = MINMAX(0, m_Horse.sHealth + iHealth, c_aHorseStat[level].iMaxHealth); if (level && m_Horse.sHealth == 0) HorseDie(); if (bSend) SendHorseInfo(); } void CHorseRider::HorseDie() { sys_log(0, "HORSE DIE %p %p", get_pointer(m_eventStaminaRegen), get_pointer(m_eventStaminaConsume)); UpdateHorseStamina(-m_Horse.sStamina); event_cancel(&m_eventStaminaRegen); event_cancel(&m_eventStaminaConsume); } void CHorseRider::SetHorseLevel(int iLevel) { m_Horse.bLevel = iLevel = MINMAX(0, iLevel, HORSE_MAX_LEVEL); m_Horse.sStamina = c_aHorseStat[iLevel].iMaxStamina; m_Horse.sHealth = c_aHorseStat[iLevel].iMaxHealth; m_Horse.dwHorseHealthDropTime = 0; ResetHorseHealthDropTime(); SendHorseInfo(); } BYTE CHorseRider::GetHorseGrade() { BYTE grade = 0; if (GetHorseLevel()) grade = (GetHorseLevel() - 1) / 10 + 1; return grade; }