[CODE] Taming

#1
Este skill permite amaestrar animales y algunos monstruos. Es de uso directo, es decir, hay que llamar al skill, o ejecutarlo, para poder usarlo. Una vez hecho esto, el cursor cambiará al de forma de selección, donde esperará que seleccionemos la criatura a amaestrar. Ésta ha de encontrarse cerca de nuestro. Una vez seleccionada se realizará un chequeo para comprobar que el nivel de habilidad es suficiente para amaestrarlo, y de no ser así se nos notificará con un mensaje y el amaestreamiento quedará cancelado. En caso contrario comenzaremos a intentar amaestrar la criatura. Este proceso dura 10 segundos (el tiempo mínimo requerido antes de poder volver a usar el skill), y durante este tiempo el animal no ha de ser atacado, y no deberemos alejarnos demasiado de él, ya que de lo contrario el uso de la habilidad se detendrá y habrá que comenzar de nuevo.Independientemente de que el nivel de conocimiento fuese suficiente o no, al finalizar el intento se realiza otro cálculo, que es el que indicará si el proceso ha concluido de forma satisfactoria o no. De ser así, la criatura pasará a ser etiquetada azul (inocente), y en el caso de que sea un monstruo habrá que esperar un rato incluso evitar sus ataques antes de que se vuelva pacífico. A partir de aqui, la criatura entrará en nuestro poder, y podremos dárle ordenes. Por otro lado, sobra decir que cuanto más alta tengamos la habilidad, el cálculo final tendrá más posibilidades de salir bien ante criaturas que requieran bajo nivel, siendo cada vez menor la posibilidad de salir bien cuanto más cercano sea el nivel requerido comparado con el que tenemos nosotros.

Condiciones para un amaestramiento satisfactorio:
La mascota deberá poder tener contacto visual con el amaestrador, ya que de lo contrario el proceso será cancelado.
La mascota deberá poder acceder a pie al lugar donde se encuentra el amaestrador.
El amaestrador no puede hacerse invisible.
El amaestrador deberá tener los slots de Follower suficientes libres, ya que de lo contrario no podrá disponer de la mascota.
Nota: Cada personaje tiene 5 slots como máximo.

Fuente de información: LocalStrike | UO

Ahora... el Skill requiere:
-. 50 CHARISMA
Para amaestrar se necesita como mínimo:
-. 100 STR (si es WAR)
-. 100 INT (si es MAG)
Mientras más mejor.

Todos en común: Orc, Troll, Ogre, MG, Ettin, MasterMage-Orc, Minos, etc. (Todos los NPCs menos los especificados para las distintas Clases)
WARs: + Zombie, Skel, hh, Liche, dd, Uni.
MAGs: + Stone, Clay, IceGolem, Tentocle, BB, DD.
GM: TODOS

Les dejo los codes, recomendados sources 3.0

Función: void CGame::NpcProcess()
Buscar:

Code: Select all

		if (m_pNpcList[i] != NULL) {
			if (m_pNpcList[i]->m_cBehavior == DEF_BEHAVIOR_ATTACK) {
				switch (iDice(1,7)) {
					case 1: dwActionTime = m_pNpcList[i]->m_dwActionTime; break;
					case 2: dwActionTime = m_pNpcList[i]->m_dwActionTime - 100; break;
					case 3: dwActionTime = m_pNpcList[i]->m_dwActionTime - 200; break;
					case 4: dwActionTime = m_pNpcList[i]->m_dwActionTime - 300; break;
					case 5: dwActionTime = m_pNpcList[i]->m_dwActionTime - 400; break;
					case 6: dwActionTime = m_pNpcList[i]->m_dwActionTime - 600; break;
					case 7: dwActionTime = m_pNpcList[i]->m_dwActionTime - 700; break;
				}
				if (dwActionTime < 600) dwActionTime = 600;
			}
			else dwActionTime = m_pNpcList[i]->m_dwActionTime; 		
			if (m_pNpcList[i]->m_cMagicEffectStatus[DEF_MAGICTYPE_ICE] != 0) 
				dwActionTime += (dwActionTime/2);
		}
Abajo de eso agragar:

Code: Select all

		// Taming
		if (   (m_pNpcList[i] != NULL) 
			&& (m_pNpcList[i]->m_dwTamingTime != 0)
			&& (m_pNpcList[i]->m_cOriginalSide != m_pNpcList[i]->m_cSide)
			&& (dwTime > m_pNpcList[i]->m_dwTamingTime)) 
		{	m_pNpcList[i]->m_cSide = m_pNpcList[i]->m_cOriginalSide;
			m_pNpcList[i]->m_dwTamingTime = 0;
			m_pNpcList[i]->m_cMoveType = DEF_MOVETYPE_RANDOMWAYPOINT;
			SendEventToNearClient_TypeA(i, DEF_OWNERTYPE_NPC, MSGID_EVENT_MOTION, DEF_OBJECTNULLACTION, NULL, NULL, NULL);		
		}
Ahora buscar:

Code: Select all

			switch (m_pNpcList[i]->m_cBehavior) {
			case DEF_BEHAVIOR_DEAD:
				NpcBehavior_Dead(i);
				break;
			case DEF_BEHAVIOR_STOP:
				NpcBehavior_Stop(i);
				break;
			case DEF_BEHAVIOR_MOVE:
				NpcBehavior_Move(i);
				break;
			case DEF_BEHAVIOR_ATTACK:
				NpcBehavior_Attack(i);
				break;
			case DEF_BEHAVIOR_FLEE:
				NpcBehavior_Flee(i);
				break;
			}
Y abajo agregar:

Code: Select all

			// Taming
			if (   (m_pNpcList[i] != NULL) && (m_pNpcList[i]->m_iHP > 0) 
				&& (m_pNpcList[i]->m_dwTamingTime != 0)
				&& (m_pNpcList[i]->m_cFollowOwnerType == DEF_OWNERTYPE_PLAYER) 
				&& ((dwTime - m_pNpcList[i]->m_dwSummonWaitTime) > 1000*60)) // Wait 60sec for the character to connect again
			{	m_pNpcList[i]->m_cFollowOwnerType   = 0;	
				m_pNpcList[i]->m_iSummonControlMode = 0;
			}
			if ((m_pNpcList[i] != NULL) && (m_pNpcList[i]->m_iHP != 0) && (m_pNpcList[i]->m_bIsSummoned == TRUE)) {
				switch (m_pNpcList[i]->m_sType) {
				case 64: // new - kills crop after specific amount of time
					if ((dwTime - m_pNpcList[i]->m_dwSummonedTime) > 300000) DeleteNpc(i);
					break;
				case 29: // Ogre summon popo:10 min
				case 33: // WW summon popo		
				case 31: // Demon summon popo
					if ((dwTime - m_pNpcList[i]->m_dwSummonedTime) > 1000*60*10) 
						NpcKilledHandler(NULL, NULL, i, 0);
					else if ((m_pNpcList[i]->m_cFollowOwnerType == DEF_OWNERTYPE_PLAYER)
						&& ((dwTime - m_pNpcList[i]->m_dwSummonWaitTime) > 1000*60)) // Wait 60sec for the character to connect again
					{	m_pNpcList[i]->m_cFollowOwnerType   = 0;	
						m_pNpcList[i]->m_iSummonControlMode = 0;
					}
					break;	
				case 43: // LWB
				case 44: // GHK
				case 45: // GHKABS
				case 46: // TK
				case 47: // BG Crusade summons 10 min
					if ((dwTime - m_pNpcList[i]->m_dwSummonedTime) > 1000*60*10) 
						NpcKilledHandler(NULL, NULL, i, 0);
					else if ((m_pNpcList[i]->m_cFollowOwnerType == DEF_OWNERTYPE_PLAYER)
						&& ((dwTime - m_pNpcList[i]->m_dwSummonWaitTime) > 1000*60)) // Wait 60sec for the character to connect again
					{	m_pNpcList[i]->m_cFollowOwnerType   = 0;		
						m_pNpcList[i]->m_iSummonControlMode = 0;
					}
					break;		
				case 82: // Sorceress	
				case 83: // ATK	
				case 84: // MasterElf	
				case 85: // DSK	
				case 86: // HBT		
				case 88: // Barbarian
					if (   (m_bIsHeldenianMode == TRUE)
						&& (m_pMapList[m_pNpcList[i]->m_cMapIndex] != NULL)
						&& (m_pMapList[m_pNpcList[i]->m_cMapIndex]->m_bIsHeldenianMap == 1))
					{	if (   (m_pNpcList[i]->m_cFollowOwnerType == DEF_OWNERTYPE_PLAYER)
							&& ((dwTime - m_pNpcList[i]->m_dwSummonWaitTime) > 1000*60)) // Wait 60sec for the character to connect again
						{	// Master has not connected again, remove summon
							NpcKilledHandler(NULL, NULL, i, 0);
						}else break; // Keep them alive					
					}else if ((dwTime - m_pNpcList[i]->m_dwSummonedTime) > 1000*60*15) 
						NpcKilledHandler(NULL, NULL, i, 0);	// Heldenian soldiers limited to 15min if not Heldenian
					break;	
				case 36: // AGT         Those will last forever when summonned
				case 37: // AGC
				case 38: // MS
				case 39: // DT
				case 40: // ESG
				case 41: // ManaStone
				case 87: // CT
				case 89: // AGC
				case 91: // gates
					if (   (m_pNpcList[i]->m_cFollowOwnerType == DEF_OWNERTYPE_PLAYER)
						&& ((dwTime - m_pNpcList[i]->m_dwSummonWaitTime) > 1000*60)) // Wait 60sec for the character to connect again
					{	m_pNpcList[i]->m_cFollowOwnerType   = 0;		
						m_pNpcList[i]->m_iSummonControlMode = 0;
					}
					break;
				default: //other summons: 5 minutes
					if ((dwTime - m_pNpcList[i]->m_dwSummonedTime) > DEF_SUMMONTIME) 
						NpcKilledHandler(NULL, NULL, i, 0);
					else if ((m_pNpcList[i]->m_cFollowOwnerType == DEF_OWNERTYPE_PLAYER)
						&& ((dwTime - m_pNpcList[i]->m_dwSummonWaitTime) > 1000*60)) // Wait 60sec for the character to connect again
					{	m_pNpcList[i]->m_cFollowOwnerType   = 0;		
						m_pNpcList[i]->m_iSummonControlMode = 0;
					}
					break;
				}
			}
Función: void CGame::NpcBehavior_Move(int iNpcH)
Agregar:

Code: Select all

	// Taming
	if ((m_pNpcList[iNpcH]->m_dwTamingTime != 0) && (m_pNpcList[iNpcH]->m_iSummonControlMode == 1)) return;
Buscar:

Code: Select all

		switch (m_pNpcList[iNpcH]->m_cFollowOwnerType) {
Y reemplazarlo por:

Code: Select all

		switch (m_pNpcList[iNpcH]->m_cFollowOwnerType) {
		case DEF_OWNERTYPE_PLAYER:
			if (m_pClientList[m_pNpcList[iNpcH]->m_iFollowOwnerIndex] == NULL) {
				m_pNpcList[iNpcH]->m_cMoveType = DEF_MOVETYPE_RANDOM;
				m_pNpcList[iNpcH]->m_dwSummonWaitTime  = timeGetTime();
				return;
			}
			dX = m_pClientList[m_pNpcList[iNpcH]->m_iFollowOwnerIndex]->m_sX;
			dY = m_pClientList[m_pNpcList[iNpcH]->m_iFollowOwnerIndex]->m_sY;
			break;

		case DEF_OWNERTYPE_NPC:
			if (m_pNpcList[m_pNpcList[iNpcH]->m_iFollowOwnerIndex] == NULL) {
				m_pNpcList[iNpcH]->m_cMoveType = DEF_MOVETYPE_RANDOM;
				m_pNpcList[iNpcH]->m_iFollowOwnerIndex = NULL;
				return;
			}
			dX = m_pNpcList[m_pNpcList[iNpcH]->m_iFollowOwnerIndex]->m_sX;
			dY = m_pNpcList[m_pNpcList[iNpcH]->m_iFollowOwnerIndex]->m_sY;
			break;
		}
Función: BOOL CGame::bCreateNewNpc(char * pNpcName, char * pName, char * pMapName, short sClass, char cSA, char cMoveType, int * poX, int * poY, char * pWaypointList, RECT * pArea, int iSpotMobIndex, char cChangeSide, BOOL bHideGenMode, BOOL bIsSummoned, BOOL bFirmBerserk, BOOL bIsMaster, int iGuildGUID)
Buscar:

Code: Select all

		if (bIsSummoned == TRUE)
Y reemplazarlo por:

Code: Select all

		if (bIsSummoned == TRUE) 
		{	m_pNpcList[i]->m_dwSummonedTime = timeGetTime();	
			m_pNpcList[i]->m_dwSummonWaitTime = 0;	
		}
Función: void CGame::NpcKilledHandler(short sAttackerH, char cAttackerType, int iNpcH, short sDamage)
Abajo de:

Code: Select all

	ReleaseFollowMode(iNpcH);
Agregar:

Code: Select all

	m_pNpcList[iNpcH]->m_cFollowOwnerType  = NULL; // Snoopy's add
	m_pNpcList[iNpcH]->m_iFollowOwnerIndex = NULL; // Snoopy's add
Ahora buscar:

Code: Select all

		if (iQuestIndex != NULL) {
Y reemplazar todo el IF por:

Code: Select all

		if (iQuestIndex != NULL) {
			if (m_pQuestConfigList[iQuestIndex] != NULL) {
				switch (m_pQuestConfigList[iQuestIndex]->m_iType) {
				case DEF_QUESTTYPE_MONSTERHUNT:
					if ((m_pClientList[sAttackerH]->m_bQuestMatchFlag_Loc == TRUE) &&
						(m_pQuestConfigList[iQuestIndex]->m_iTargetType == m_pNpcList[iNpcH]->m_sType) && 
						// Taming
						(m_pNpcList[iNpcH]->m_bIsSummoned == FALSE)	&& 
						// Only master quest can be done on own tamed mobs
						((m_pNpcList[iNpcH]->m_dwTamingTime == 0) || (m_pNpcList[iNpcH]->m_iFollowOwnerIndex == sAttackerH))) {
						// Prevents making quests on summons
						// Á¶°Ç¿¡ ÇÕ´çÇÏ´Ù. Ä«¿îÆ® Áõ°¡ÈÄ ÆÇ´Ü.
						m_pClientList[sAttackerH]->m_iCurQuestCount++;
						cQuestRemain = (m_pQuestConfigList[m_pClientList[sAttackerH]->m_iQuest]->m_iMaxCount - m_pClientList[sAttackerH]->m_iCurQuestCount);
						SendNotifyMsg(NULL, sAttackerH, DEF_NOTIFY_QUESTCOUNTER, cQuestRemain, NULL, NULL, NULL);
						_bCheckIsQuestCompleted(sAttackerH);
					}
					break;
				}
			}
		}
Función: BOOL CGame::_bInitNpcAttr(class CNpc * pNpc, char * pNpcName, short sClass, char cSA)
Buscar:

Code: Select all

			if (pNpc->m_iHP == 0) pNpc->m_iHP = 1;
Abajo agregar:

Code: Select all

			pNpc->m_cOriginalSide      = m_pNpcConfigList[i]->m_cSide;
			pNpc->m_dwTamingTime	   = 0; // Taming
---------------------------------------------------------------------------------
NPC.H

Code: Select all

	// Taming
	DWORD m_dwTamingTime;
	char  m_cFollowOwnerCharName[11];
	DWORD m_dwSummonWaitTime;
	char m_cOriginalSide;
---------------------------------------------------------------------------------
Función: void CGame::CalculateSSN_ItemIndex(int iClientH, short sWeaponIndex, int iValue) & void CGame::CalculateSSN_SkillIndex(int iClientH, short sSkillIndex, int iValue)
Buscar:

Code: Select all

		switch (sSkillIndex) {
Abajo agregar:

Code: Select all

		case 22: // Taming
			if (m_pClientList[iClientH]->m_cSkillMastery[sSkillIndex] > (m_pClientList[iClientH]->m_iCharisma * 2)) {
				m_pClientList[iClientH]->m_cSkillMastery[sSkillIndex]--;
				m_pClientList[iClientH]->m_iSkillSSN[sSkillIndex] = iOldSSN;
			}
			else m_pClientList[iClientH]->m_iSkillSSN[sSkillIndex] = 0;
			break;
Función: void CGame::DelayEventProcessor()
Buscar:

Code: Select all

		switch (m_pDelayEventList[i]->m_iDelayType) {
Y abajo agregar:

Code: Select all

		case DEF_DELAYEVENTTYPE_TAMING_SKILL: // Taming
			switch (m_pDelayEventList[i]->m_cTargetType) {
			case DEF_OWNERTYPE_PLAYER:				
				if (m_pClientList[m_pDelayEventList[i]->m_iTargetH] == NULL) break;
				// If not the right Taming usage exit
				if (m_pClientList[m_pDelayEventList[i]->m_iTargetH]->m_bSkillUsingStatus[22] == FALSE) break;
				if (m_pClientList[m_pDelayEventList[i]->m_iTargetH]->m_iSkillUsingTimeID[22] != m_pDelayEventList[i]->m_iV2) break;
				_TamingHandler(m_pDelayEventList[i]->m_iTargetH
								, 22
								, m_pDelayEventList[i]->m_cMapIndex
								, m_pDelayEventList[i]->m_dX
								, m_pDelayEventList[i]->m_dY);
				m_pClientList[m_pDelayEventList[i]->m_iTargetH]->m_bSkillUsingStatus[22] = FALSE;
				m_pClientList[m_pDelayEventList[i]->m_iTargetH]->m_iSkillUsingTimeID[22] = NULL;
				break;
			}
			break;
-----------------------------------------------------------
DELAYEVENT.H

Code: Select all

#define DEF_DELAYEVENTTYPE_TAMING_SKILL				10
-----------------------------------------------------------
Función: void CGame::ClearSkillUsingStatus(int iClientH)
Buscar:

Code: Select all

	if (m_pClientList[iClientH]->m_bSkillUsingStatus[19] == TRUE) {
		tX = m_pClientList[iClientH]->m_sX;
		tY = m_pClientList[iClientH]->m_sY;
		if (m_pMapList[m_pClientList[iClientH]->m_cMapIndex]->bGetMoveable(tX, tY, NULL) == FALSE) {
			fX = m_pClientList[iClientH]->m_sX + _tmp_cCorpseX[m_pClientList[iClientH]->m_cDir];
			fY = m_pClientList[iClientH]->m_sY + _tmp_cCorpseY[m_pClientList[iClientH]->m_cDir];
			if (m_pMapList[m_pClientList[iClientH]->m_cMapIndex]->bGetMoveable(fX, fY, NULL) == FALSE) {
				m_pClientList[iClientH]->m_cDir = iDice(1,8);
				fX = m_pClientList[iClientH]->m_sX + _tmp_cCorpseX[m_pClientList[iClientH]->m_cDir];
				fY = m_pClientList[iClientH]->m_sY + _tmp_cCorpseY[m_pClientList[iClientH]->m_cDir];
				if (m_pMapList[m_pClientList[iClientH]->m_cMapIndex]->bGetMoveable(fX , fY, NULL) == FALSE) return;
			}
			SendNotifyMsg(NULL, iClientH, DEF_NOTIFY_DAMAGEMOVE, m_pClientList[iClientH]->m_cDir, NULL, NULL, NULL);
		}
	}
Abajo agregar:

Code: Select all

	// Taming
	else if (m_pClientList[iClientH]->m_bSkillUsingStatus[22] == TRUE) 
	{	SendNotifyMsg(NULL, iClientH, DEF_NOTIFY_SKILLUSINGEND, NULL, NULL, NULL, NULL);
		bRemoveFromDelayEventList(iClientH, DEF_OWNERTYPE_PLAYER, DEF_DELAYEVENTTYPE_TAMING_SKILL);
	}
Función: void CGame::UseSkillHandler(int iClientH, int iV1, int iV2, int iV3)
Buscar:

Code: Select all

	switch (m_pSkillConfigList[iV1]->m_sType) {
Abajo agregar:

Code: Select all

	case DEF_SKILLEFFECTTYPE_TAMING: // Taming
		if (   ((m_pClientList[iClientH]->m_iStatus & 0x00000010) == 0)      // Invi character can not tame !
			&& (m_pClientList[iClientH]->m_bSkillUsingStatus[19] == FALSE)) // PretendCorpse character canot Tame
		{	m_pClientList[iClientH]->m_bSkillUsingStatus[iV1] = TRUE;
			m_pClientList[iClientH]->m_iSkillUsingTimeID[iV1] = (int)timeGetTime();
			// Register delay to perform Taming
			bRegisterDelayEvent(DEF_DELAYEVENTTYPE_TAMING_SKILL // int iDelayType
								, 22 // int iEffectType
								, timeGetTime() + m_pSkillConfigList[22]->m_sValue2*100 // nbe of 1/10th seconds in Skill.cfg
								, iClientH // int iTargetH
								, DEF_OWNERTYPE_PLAYER // char cTargetType
								, m_pClientList[iClientH]->m_cMapIndex // char cMapIndex
								, m_pClientList[iClientH]->m_sX // int X
								, m_pClientList[iClientH]->m_sY // int Y
								, (int)m_pClientList[iClientH]->m_bSkillUsingStatus[iV1] // int iV1
								, m_pClientList[iClientH]->m_iSkillUsingTimeID[iV1] // int iV2
								, NULL); // int iV3		
		}else SendNotifyMsg(NULL, iClientH, DEF_NOTIFY_SKILLUSINGEND, NULL, NULL, NULL, NULL);
		break;
---------------------------------------------------
SKILL.H

Code: Select all

#define DEF_SKILLEFFECTTYPE_TAMING			3
---------------------------------------------------

Función en general:

Code: Select all

void CGame::_TamingHandler(int iClientH, int iSkillNum, char cMapIndex, int dX, int dY)
{int iSkillLevel, iRange, iTamingLevel, iResult, iX, iY, iTamingType, iNbeTamed = 0;//, iFollowersNum, iNamingValue;
 short sOwnerH;
 char cOwnerType, cTamedString[500];//, cName_Master[11], cName[11];
	if (m_pClientList[iClientH] == NULL) return;
	if (m_pMapList[cMapIndex] == NULL) return;
	if (m_pClientList[iClientH]->m_iAdminUserLevel == 0) 
	{	if (   (m_pClientList[iClientH]->m_iStr > 100)
			&& (m_pClientList[iClientH]->m_iCharisma > 49))
		{	iTamingType = 2; // War-GuildMaster
		}else if (	(m_pClientList[iClientH]->m_iInt > 100)
			&&		(m_pClientList[iClientH]->m_iCharisma > 49))
		{	iTamingType = 1; // Mage-GuildMaster
		}	
	}else iTamingType = 3; // GameMaster
	iSkillLevel = (int)m_pClientList[iClientH]->m_cSkillMastery[iSkillNum];
	iRange = 2 + iSkillLevel / 20; // ÃÖ´ë ¹üÀ§´Â 8
	for (iX = dX - iRange; iX <= dX + iRange; iX++)
	for (iY = dY - iRange; iY <= dY + iRange; iY++) 
	{	sOwnerH = NULL;
		if ((iX > 0) && (iY > 0) && (iX < m_pMapList[cMapIndex]->m_sSizeX) && (iY < m_pMapList[cMapIndex]->m_sSizeY))
		{	m_pMapList[cMapIndex]->GetOwner(&sOwnerH, &cOwnerType, iX, iY);
		}
		if (sOwnerH != NULL) {
			switch (cOwnerType) {
			case DEF_OWNERTYPE_PLAYER:
				if (m_pClientList[sOwnerH] == NULL) break;
				break;
			case DEF_OWNERTYPE_NPC:
				if (m_pNpcList[sOwnerH] == NULL) break;
				// ¸ó½ºÅÍÀÇ Á¾·ù¿¡ µû¶ó ±æµé¿©Áú °ÍÀÎÁö¸¦ °áÁ¤ÇÑ´Ù.
				// 1st list for everybody			
				iTamingLevel = 201; // 201 means impossible
				switch (m_pNpcList[sOwnerH]->m_sType) {
					case 14: iTamingLevel = 35; break;	// Orc
					case 28: iTamingLevel = 65; break;	// Troll
					case 29: iTamingLevel = 100; break;	// Ogre
					case 58: iTamingLevel = 100; break;	// MG
					case 59: iTamingLevel = 120; break;	// Ettin
					case 77: iTamingLevel = 160; break;	// MasterMage-Orc 
					case 78: iTamingLevel = 170; break;	// Minos 
				}
				switch (iTamingType) {
				case 1: // Mage-GuildMaster				
					if (iTamingLevel > 199) iTamingLevel = 199;
					switch (m_pNpcList[sOwnerH]->m_sType) {
						case 12:							// Stone
						case 23: iTamingLevel =  40; break;	// Clay
						case 65: iTamingLevel =  70; break;	// IceGolem
						case 80: iTamingLevel =  80; break;	// Tentocle
						case 53: iTamingLevel = 100; break;	// BB
						case 31: iTamingLevel = 170; break;	// DD
					}
					break;
				case 2: // War-GuildMaster	
					if (iTamingLevel > 197) iTamingLevel = 197;
					switch (m_pNpcList[sOwnerH]->m_sType) { 
					case 18:							// Zombie 
					case 11: iTamingLevel =  35; break;	// Skel
					case 27: iTamingLevel =  65; break;	// hh
					case 30: iTamingLevel = 120; break;	// Liche
					case 31: iTamingLevel = 170; break;	// DD
					case 32: // Uni possible for some purest Wars
						if (   (m_pClientList[iClientH]->m_iPKCount == 0) // Uni
							&& (m_pClientList[iClientH]->m_iEnemyKillCount == 0)
							&& (m_pClientList[iClientH]->m_iRating > 0) )
						{	iTamingLevel = 100;
						}					
						break;
					}
					break;
				case 3: // GameMaster
					iTamingLevel = 30;
					if (m_pNpcList[sOwnerH]->m_cSide == 0) iTamingLevel = 201;
					break;
				}
				iResult = iDice(2,iSkillLevel);
				// ½ºÅ³ÀÇ µî±Þ¿¡ µû¶ó ±æµéÀÏ ¼ö ÀÖ´Â °¹¼ö°¡ ´Þ¶óÁø´Ù.
				if (   (iResult >= iTamingLevel)
					&& (m_pNpcList[sOwnerH]->m_dwTamingTime == 0)
					&& (m_pNpcList[sOwnerH]->m_cSide != m_pClientList[iClientH]->m_cSide))
				{	iNbeTamed++;
					// Now change npc side...
					m_pNpcList[sOwnerH]->m_cOriginalSide = m_pNpcList[sOwnerH]->m_cSide;
					switch (iTamingType) {
					default:
					case 0: // Default -> npc becomes neutral 	
					case 3: // GameMaster
						m_pNpcList[sOwnerH]->m_cSide = 0;
						break;
					case 1: // Mage-GuildMaster -> npc becomes friendly 					
						switch (m_pNpcList[sOwnerH]->m_sType) {	
						case 12: // Stone
						case 23: // Clay
						case 65: // IceGolem
						case 80: // Tentocle
						case 53: // BB
						case 31: // DD						
							m_pNpcList[sOwnerH]->m_cSide = m_pClientList[iClientH]->m_cSide;
							break;
						default:
							m_pNpcList[sOwnerH]->m_cSide = 0;
							break;	
						}
						break;
					case 2: // War-GuildMaster	-> npc becomes friendly
						switch (m_pNpcList[sOwnerH]->m_sType) { 
						case 18: // Zombie 
						case 11: // Skel
						case 27: // hh
						case 30: // Liche
						case 31: // DD
							if (iDice(1,95) <= iSkillLevel) 
								 m_pNpcList[sOwnerH]->m_cSide = m_pClientList[iClientH]->m_cSide;
							else m_pNpcList[sOwnerH]->m_cSide = 0;
							break;
						case 32: // Uni
							m_pNpcList[sOwnerH]->m_cSide = m_pClientList[iClientH]->m_cSide;				
							break;
						default:  
							m_pNpcList[sOwnerH]->m_cSide = 0;
							break;	
						}
						break;
					}
					if (iGetFollowerNumber(sOwnerH, cOwnerType) > 5) return;
					m_pNpcList[sOwnerH]->m_dwTamingTime			 = timeGetTime() + 3000*iSkillLevel + 120000;
					m_pNpcList[sOwnerH]->m_cBehavior			 = DEF_BEHAVIOR_MOVE;
					m_pNpcList[sOwnerH]->m_sBehaviorTurnCount	 = 0;
					m_pNpcList[sOwnerH]->m_iTargetIndex			 = NULL;
					if (m_pNpcList[sOwnerH]->m_cSide == m_pClientList[iClientH]->m_cSide)
					{	m_pNpcList[sOwnerH]->m_cMoveType		 = DEF_MOVETYPE_FOLLOW;
						m_pNpcList[sOwnerH]->m_cFollowOwnerType  = DEF_OWNERTYPE_PLAYER;
						m_pNpcList[sOwnerH]->m_iFollowOwnerIndex = iClientH;								
					}
					SendEventToNearClient_TypeA(sOwnerH, DEF_OWNERTYPE_NPC, MSGID_EVENT_MOTION, DEF_OBJECTNULLACTION, NULL, NULL, NULL);
					// Increase skill if not easy Taming
					if (iTamingLevel >= iSkillLevel)
					{	CalculateSSN_SkillIndex(iClientH, 22, 1);
				}	} // End of succes in taming 1 creature
				break;
	}	}	}
	if (iNbeTamed == 0)  // No creature tamed
	{	SendNotifyMsg(NULL, iClientH, DEF_NOTIFY_SKILLUSINGEND, 0, NULL, NULL, NULL);
	}else 
	{	SendNotifyMsg(NULL, iClientH, DEF_NOTIFY_SKILLUSINGEND, 1, NULL, NULL, NULL);
		ZeroMemory(cTamedString, sizeof(cTamedString));
		switch (iTamingType) {	
		case 2:	// War-GuildMaster
			wsprintf(cTamedString, " Undead turned: %d", iNbeTamed);
			break;
		case 1:	// Mage-GuildMaster
			wsprintf(cTamedString, " Magic things controled: %d", iNbeTamed);
			break;
		default:
		case 0:
		case 3:	 // GameMaster
			wsprintf(cTamedString, " Creatures neutralised: %d", iNbeTamed);
			break;
		}
		ShowClientMsg(iClientH, cTamedString);
		// Debug	
		wsprintf(cTamedString, "(!) Taming skill: %s is using Taming skill (%d%%) (Type %d), he tamed %d creatures."
				 , m_pClientList[iClientH]->m_cCharName
				 , iSkillLevel
				 , iTamingType
				 , iNbeTamed);
		PutLogList(cTamedString);
	}
}
Función: int CGame::iCalculateAttackEffect(short sTargetH, char cTargetType, short sAttackerH, char cAttackerType, int tdX, int tdY, int iAttackMode, BOOL bNearAttack, BOOL bIsDash, BOOL bArrowUse)
Buscar:

Code: Select all

			else {
				if ((m_pNpcList[sTargetH]->m_sType != 21) && (m_pNpcList[sTargetH]->m_sType != 55) && (m_pNpcList[sTargetH]->m_sType != 56)
					&& (m_pNpcList[sTargetH]->m_cSide == cAttackerSide)) goto CAE_SKIPCOUNTERATTACK;
Abajo agregar:

Code: Select all

				// Tammed mobs
				if ((m_pNpcList[sTargetH]->m_dwTamingTime != 0) && (m_pNpcList[sTargetH]->m_iSummonControlMode == 1)) goto CAE_SKIPCOUNTERATTACK;
-----------------------------------------------------------
GAME.H

Code: Select all

	void _TamingHandler(int iClientH, int iSkillNum, char cMapIndex, int dX, int dY);
Obviamente tendremos en nuestros contents, en SKILLCFG.txt:

Code: Select all

skill = 22 Taming             	1 2
Y en nuestros files, en Skill.cfg

Code: Select all

skill = 22 Taming               3    1 15  0 0 0 0
by snoopy81
Centuu.-

Sol Lucet Omnibus.-

Who is online

Users browsing this forum: No registered users and 1 guest

cron