Jump to content

Recommended Posts

(Sorry for my bad english)

 

Hello,

my problem, i summon my horse then i mount my horse. I teleport or relog after that the horse is unmount and unsummon but the horse icon left top in corner is active. When i hit mobs i doesnt damage because i mount the horse but i can't see... i hope you understand this xD


My char_horse.cpp:

Spoiler



#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 "mob_manager.h"

#include "../../common/VnumHelper.h"

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;
}
/* 	DWORD dwMountVnum;
	if (m_chMount)
	{
		dwMountVnum = m_chMount->GetRaceNum(); 
		CHorseRider::StartRiding(true);
	}
	else
	{
		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(bool isMount)
{
	if (CHorseRider::StopRiding())
	{
		quest::CQuestManager::instance().Unmount(GetPlayerID());

		if (!IsDead() && !IsStun())
		{
			DWORD dwOldVnum = GetMountVnum();
			MountVnum(0);

			// [NOTE] ¸»¿¡¼­ ³»¸± ¶© ÀڱⰡ ÅÀ´ø°É ¼ÒȯÇϵµ·Ï ¼öÁ¤
			if (isMount)
				HorseSummon(true, false, dwOldVnum,"",true);
			else
				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);
		RemoveAffect(AFFECT_MOUNT_BONUS);

		return true;
	}

	return false;
}

EVENTFUNC(horse_dead_event)
{
	char_event_info* info = dynamic_cast<char_event_info*>( event->info );

	if ( info == NULL )
	{
		sys_err( "horse_dead_event> <Factor> Null pointer" );
		return 0;
	}

	// <Factor>
	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, bool isMount)
{
	if ( bSummon )
	{
		if( m_chMount != NULL || m_chHorse != NULL)
			return;
			
		if (GetHorseLevel() <= 0)
			return;
		
		if (IsRiding())
			return;
		
		sys_log(0, "HorseSummonSummon : %s lv:%d bSummon:%d fromFar:%d isMount:%d", GetName(), GetLevel(), bSummon, bFromFar, isMount);
		
		long x = GetX();
		long 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);
		}
		
		if ( isMount )
		{
			
			if (dwVnum<1)
				return;


			m_chMount = CHARACTER_MANAGER::instance().SpawnMob(
					dwVnum, 
					GetMapIndex(), 
					x, y,
					GetZ(), false, (int)(GetRotation()+180), false);

			if (!m_chMount)
			{
				ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¢¬¡í ¨ùOE?¢¯¢® ¨öC¨¡¨¢CI¢¯¢¥¨öA¢¥I¢¥U."));
				return;
			}
			
			const CMob * pkMob = CMobManager::instance().Get(dwVnum);
			m_chMount->m_stName = GetName();
			m_chMount->m_stName += "'s ";
			m_chMount->m_stName += pkMob->m_table.szLocaleName;

			if (!m_chMount->Show(GetMapIndex(), x, y, GetZ()))
			{
				M2_DESTROY_CHARACTER(m_chMount);
				sys_err("cannot show monster");
				m_chMount = NULL;
				return;
			}

			m_chMount->SetRider(this);
		}
		else
		{
			
			if (GetHorseLevel() <= 0)
				return;

			if (GetHorseHealth() <= 0)
				bFromFar = false;

			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<char_event_info>();
				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 && !m_chMount)
			return;
		
		LPCHARACTER chHorse;
		
		if (m_chHorse)
			chHorse = m_chHorse;
		else
			chHorse = m_chMount;

		chHorse->SetRider(NULL); // m_chHorse assign to NULL
		
		if (m_chHorse && (GetHorseHealth() <= 0))
			bFromFar = false;

		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((long)(chHorse->GetX()+fx), (long) (chHorse->GetY()+fy));
			chHorse->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);			
		}
		if (m_chHorse)
			m_chHorse=NULL;
		else
			m_chMount=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());
}


 


and my horse_rider.cpp:

Spoiler



#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 },
	{ 1,	40513,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40516,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40519,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40522,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40525,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40528,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40531,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40534,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40537,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40540,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40543,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40546,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40549,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40552,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40555,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40558,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40561,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40564,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40567,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 },
	{ 1,	40570,	50,	200,	5,	5,	5,	5,	99,	79,	118,	10 }
};

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(bool isMount)
{
	if (isMount)
	{
		if (m_Mount.bRiding)
			return false;
		
		m_Mount.bRiding = true;
	}
	else
	{
		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_Mount.bRiding)
	{
		m_Mount.bRiding = false;
		return true;
	}
	else if (m_Horse.bRiding)
	{
		if (!m_Horse.bRiding)
		return false;
	
		m_Horse.bRiding = false;
		StartStaminaRegenEvent();
		return true;
	}
	else
		return false;
}

EVENTINFO(horserider_info) 
{
	CHorseRider* hr;

	horserider_info() 
	: hr( 0 )
	{
	}
};

EVENTFUNC(horse_stamina_consume_event)
{
	horserider_info* info = dynamic_cast<horserider_info*>( event->info );

	if ( info == NULL )
	{
		sys_err( "horse_stamina_consume_event> <Factor> 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<horserider_info*>( event->info );

	if ( info == NULL )
	{
		sys_err( "horse_stamina_regen_event> <Factor> 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<horserider_info>();

	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<horserider_info>();

	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;
}


 

 

Link to comment
https://metin2.dev/topic/21655-chorse-teleport-bug/
Share on other sites

  • Replies 0
  • Created
  • Last Reply

Top Posters In This Topic

Popular Days

Top Posters In This Topic

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.