Exemplo n.º 1
0
void CAIPetDummy::ActionMagicCasting()
{
	m_PPathFind->LookAt(m_PMagicState->GetTarget()->loc.p);

	STATESTATUS status = m_PMagicState->Update(m_Tick);

	if(status == STATESTATUS_INTERRUPT)
	{
		m_ActionType = ACTION_MAGIC_INTERRUPT;
		ActionMagicInterrupt();
	}
	else if(status == STATESTATUS_ERROR)
	{
		TransitionBack(true);
	}
	else if(status == STATESTATUS_FINISH)
	{
		m_ActionType = ACTION_MAGIC_FINISH;
		ActionMagicFinish();
	}
	else
	{
		m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE));
	}

}
Exemplo n.º 2
0
void CAIPetDummy::ActionSleep()
{
    if (!m_PPet->StatusEffectContainer->HasPreventActionEffect())
    {
        TransitionBack();
    }
}
Exemplo n.º 3
0
void CAIPetDummy::ActionEngage()
{
    DSP_DEBUG_BREAK_IF(m_PBattleTarget == nullptr);

    if (m_PPet->PMaster == nullptr || m_PPet->PMaster->isDead())
    {
        m_ActionType = ACTION_FALL;
        ActionFall();
        return;
    }

    if (battleutils::HasClaim(m_PPet, m_PBattleTarget))
    {
        m_PPet->animation = ANIMATION_ATTACK;
        m_PPet->updatemask |= UPDATE_HP;
        m_LastActionTime = m_Tick - 1000;
        TransitionBack(true);
    }
    else
    {
        m_PPet->animation = ANIMATION_NONE;
        m_PPet->updatemask |= UPDATE_HP;
        if (m_PPet->PMaster->objtype == TYPE_PC)
        {
            ((CCharEntity*)m_PPet->PMaster)->pushPacket(new CMessageBasicPacket(((CCharEntity*)m_PPet->PMaster),
                ((CCharEntity*)m_PPet->PMaster), 0, 0, 12));
            m_ActionType = ACTION_DISENGAGE;
            return;
        }
    }
}
Exemplo n.º 4
0
void CAICharCharm::CheckCurrentAction(uint32 tick)
{
    m_Tick = tick;

    CBattleEntity* PSelf = m_PChar;

    switch (m_ActionType)
    {
        case ACTION_NONE:			  		ActionRoaming();			break;
        case ACTION_ROAMING:                ActionRoaming();            break;
        case ACTION_ATTACK:					ActionAttack();				break;
        case ACTION_ENGAGE:					ActionEngage();				break;
        case ACTION_DISENGAGE:				ActionDisengage();	 		break;
        case ACTION_FALL:					ActionFall();				break;
        case ACTION_SLEEP:                  ActionSleep();              break;

        case ACTION_MAGIC_START:			TransitionBack(true);		break;
        case ACTION_RANGED_START:			TransitionBack(true);		break;
        case ACTION_ITEM_START:				TransitionBack(true);		break;
        case ACTION_CHANGE_TARGET:	        TransitionBack(true);       break;
        case ACTION_WEAPONSKILL_START:		TransitionBack(true);	    break;
        case ACTION_JOBABILITY_START:		TransitionBack(true);	    break;
        case ACTION_RAISE_MENU_SELECTION:	TransitionBack(true);       break;

        default: DSP_DEBUG_BREAK_IF(true);
    }

    if (m_PChar && PSelf->PBattleAI == this)
    {
        m_PChar->UpdateEntity();
    }
}
Exemplo n.º 5
0
void CAIPetDummy::ActionSleep()
{
    if (!m_PPet->StatusEffectContainer->HasPreventActionEffect())
    {
    	TransitionBack();
    }

	m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE));

}
Exemplo n.º 6
0
void CAIPetDummy::ActionMagicInterrupt()
{
    m_LastActionTime = m_Tick;
    m_LastMagicTime = m_Tick;

    m_PMagicState->InterruptSpell();

    m_PSpell = nullptr;
    m_PBattleSubTarget = nullptr;

    TransitionBack();
}
Exemplo n.º 7
0
void CAIPetDummy::preparePetAbility(CBattleEntity* PTarg){
    if (m_PMobSkill != nullptr){

        apAction_t Action;
        m_PPet->m_ActionList.clear();

        // find correct targe
        if (m_PMobSkill->getValidTargets() & TARGET_SELF)
        { //self
            m_PBattleSubTarget = m_PPet;
        }
        else if (m_PMobSkill->getValidTargets() & TARGET_PLAYER_PARTY)
        {
			// Only overwrite the sub target if it it not specified or
			// the input target doesn't match the sub target.
			if (m_PBattleSubTarget == nullptr || PTarg != m_PBattleSubTarget) {
				m_PBattleSubTarget = m_PPet->PMaster;
			}
        }
        else
        {
            if (m_PBattleTarget != nullptr)
            {
                m_PBattleSubTarget = m_PBattleTarget;
            }
            DSP_DEBUG_BREAK_IF(m_PBattleSubTarget == nullptr);
        }

        Action.ActionTarget = m_PBattleSubTarget;
        Action.reaction = REACTION_HIT;
        Action.speceffect = SPECEFFECT_HIT;
        Action.animation = 0;
        Action.param = m_PMobSkill->getMsgForAction();
        Action.messageID = 43; //readies message
        Action.knockback = 0;
 
        m_skillTP = m_PPet->health.tp;
        m_PPet->health.tp = 0;

        m_PPet->m_ActionList.push_back(Action);
        m_PPet->loc.zone->PushPacket(m_PPet, CHAR_INRANGE, new CActionPacket(m_PPet));

        m_LastActionTime = m_Tick;
        m_ActionType = ACTION_MOBABILITY_USING;
    }
    else{
        ShowWarning("ai_pet_dummy::ActionAbilityFinish Pet skill is NULL \n");
        TransitionBack(true);
    }
}
Exemplo n.º 8
0
void CAIPetDummy::ActionDisengage()
{
	if( m_PPet->PMaster==NULL || m_PPet->PMaster->isDead()){
		m_ActionType = ACTION_FALL;
		ActionFall();
		return;
	}

	m_PPet->animation = ANIMATION_NONE;
	m_LastActionTime = m_Tick;
	m_PBattleTarget  = NULL;
	TransitionBack();
	m_PPet->loc.zone->PushPacket(m_PPet, CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE));
}
Exemplo n.º 9
0
void CAIPetDummy::ActionMagicInterrupt()
{
	m_LastActionTime = m_Tick;
	m_LastMagicTime = m_Tick;

	m_PMagicState->InterruptSpell();

	m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE));

	m_PSpell = NULL;
	m_PBattleSubTarget = NULL;

	TransitionBack();
}
Exemplo n.º 10
0
void CAIPetDummy::ActionDisengage()
{
    if (m_PPet->PMaster == nullptr || m_PPet->PMaster->isDead()){
        m_ActionType = ACTION_FALL;
        ActionFall();
        return;
    }

    m_queueSic = false;
    m_PPet->animation = ANIMATION_NONE;
    m_PPet->updatemask |= UPDATE_HP;
    m_LastActionTime = m_Tick;
    m_PBattleTarget = nullptr;
    TransitionBack();
}
Exemplo n.º 11
0
void CAIPetDummy::ActionMagicCasting()
{
    m_PPathFind->LookAt(m_PMagicState->GetTarget()->loc.p);

    STATESTATUS status = m_PMagicState->Update(m_Tick);

    if (status == STATESTATUS_INTERRUPT)
    {
        m_ActionType = ACTION_MAGIC_INTERRUPT;
        ActionMagicInterrupt();
    }
    else if (status == STATESTATUS_ERROR)
    {
        TransitionBack(true);
    }
    else if (status == STATESTATUS_FINISH)
    {
        m_ActionType = ACTION_MAGIC_FINISH;
        ActionMagicFinish();
    }
}
Exemplo n.º 12
0
void CAIPetDummy::ActionMagicStart()
{
    // disabled
    DSP_DEBUG_BREAK_IF(m_PSpell == nullptr);
    DSP_DEBUG_BREAK_IF(m_PBattleSubTarget == nullptr);

    m_LastActionTime = m_Tick;
    m_LastMagicTime = m_Tick;

    STATESTATUS status = m_PMagicState->CastSpell(GetCurrentSpell(), m_PBattleSubTarget);

    if (status == STATESTATUS_START)
    {
        m_ActionType = ACTION_MAGIC_CASTING;
    }
    else
    {
        TransitionBack(true);
    }

}
Exemplo n.º 13
0
void CAIPetDummy::ActionMagicStart()
{
	// disabled
	DSP_DEBUG_BREAK_IF(m_PSpell == NULL);
	DSP_DEBUG_BREAK_IF(m_PBattleSubTarget == NULL);

	m_LastActionTime = m_Tick;
	m_LastMagicTime = m_Tick;

	STATESTATUS status = m_PMagicState->CastSpell(m_PSpell, m_PBattleSubTarget);

	if(status == STATESTATUS_START)
	{
		m_ActionType = ACTION_MAGIC_CASTING;

		m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE));
	}
	else
	{
		TransitionBack(true);
	}

}
Exemplo n.º 14
0
void CAIUltimateSummon::ActionEngage()
{
	DSP_DEBUG_BREAK_IF(m_PBattleTarget == NULL);

	if( m_PPet->PMaster==NULL || m_PPet->PMaster->isDead())
	{
		m_ActionType = ACTION_FALL;
		ActionFall();
		return;
	}

	bool hasClaim = false;

	if(m_PBattleTarget->m_OwnerID.id == m_PPet->PMaster->id)
		hasClaim = true;

	if(m_PBattleTarget->m_OwnerID.id == 0)
		hasClaim = true;


	if(m_PPet->PMaster->PParty != NULL)
	{
		// alliance
		if (m_PPet->PMaster->PParty->m_PAlliance != NULL)
		{
			for (uint8 a = 0; a < m_PPet->PMaster->PParty->m_PAlliance->partyList.size(); ++a)
			{
				for (uint8 i = 0; i < m_PPet->PMaster->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i)
				{
					if (m_PPet->PMaster->PParty->m_PAlliance->partyList.at(a)->members[i]->id == m_PBattleTarget->m_OwnerID.id)
						hasClaim = true;
				}
			}
		}
		else  // party
			for (uint8 i = 0; i < m_PPet->PMaster->PParty->members.size(); ++i)
			{
				if (m_PPet->PMaster->PParty->members[i]->id == m_PBattleTarget->m_OwnerID.id)
					hasClaim = true;
			}
	}


	if(hasClaim)
	{
		m_PPet->animation = ANIMATION_ATTACK;
		m_LastActionTime = m_Tick - 1000;
		TransitionBack(true);
		m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE));
	}
	else
	{
		m_PPet->animation = ANIMATION_NONE;
		if(m_PPet->PMaster->objtype == TYPE_PC)
		{
			((CCharEntity*)m_PPet->PMaster)->pushPacket(new CMessageBasicPacket(((CCharEntity*)m_PPet->PMaster),
				((CCharEntity*)m_PPet->PMaster),0,0,12));
			m_ActionType = ACTION_ROAMING;
			return;
		}
	}

}
Exemplo n.º 15
0
void CAIPetDummy::ActionEngage()
{
    DSP_DEBUG_BREAK_IF(m_PBattleTarget == nullptr);

    if (m_PPet->PMaster == nullptr || m_PPet->PMaster->isDead())
    {
        m_ActionType = ACTION_FALL;
        ActionFall();
        return;
    }

    bool hasClaim = false;

    if (m_PBattleTarget->m_OwnerID.id == m_PPet->PMaster->id)
        hasClaim = true;

    if (m_PBattleTarget->m_OwnerID.id == 0)
        hasClaim = true;


    if (m_PPet->PMaster->PParty != nullptr)
    {
        // alliance
        if (m_PPet->PMaster->PParty->m_PAlliance != nullptr)
        {
            for (uint8 a = 0; a < m_PPet->PMaster->PParty->m_PAlliance->partyList.size(); ++a)
            {
                for (uint8 i = 0; i < m_PPet->PMaster->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i)
                {
                    if (m_PPet->PMaster->PParty->m_PAlliance->partyList.at(a)->members[i]->id == m_PBattleTarget->m_OwnerID.id)
                        hasClaim = true;
                }
            }
        }
        else  // party
            for (uint8 i = 0; i < m_PPet->PMaster->PParty->members.size(); ++i)
            {
                if (m_PPet->PMaster->PParty->members[i]->id == m_PBattleTarget->m_OwnerID.id)
                    hasClaim = true;
            }
    }


    if (hasClaim)
    {
        m_PPet->animation = ANIMATION_ATTACK;
        m_PPet->updatemask |= UPDATE_HP;
        m_LastActionTime = m_Tick - 1000;
        TransitionBack(true);
    }
    else
    {
        m_PPet->animation = ANIMATION_NONE;
        m_PPet->updatemask |= UPDATE_HP;
        if (m_PPet->PMaster->objtype == TYPE_PC)
        {
            ((CCharEntity*)m_PPet->PMaster)->pushPacket(new CMessageBasicPacket(((CCharEntity*)m_PPet->PMaster),
                ((CCharEntity*)m_PPet->PMaster), 0, 0, 12));
            m_ActionType = ACTION_DISENGAGE;
            return;
        }
    }
}
Exemplo n.º 16
0
void CAIPetDummy::ActionAbilityStart()
{
    if (m_PPet->StatusEffectContainer->HasPreventActionEffect())
    {
        return;
    }

    if (m_PPet->objtype == TYPE_MOB && m_PPet->PMaster->objtype == TYPE_PC)
    {
        if (m_MasterCommand == MASTERCOMMAND_SIC && m_PPet->health.tp >= 1000 && m_PBattleTarget != nullptr)
        {
            m_MasterCommand = MASTERCOMMAND_NONE;
            CMobEntity* PMob = (CMobEntity*)m_PPet->PMaster->PPet;
            std::vector<CMobSkill*> MobSkills = battleutils::GetMobSkillsByFamily(PMob->m_Family);

            if (MobSkills.size() > 0)
            {
                int maxSearch = 10;
                // keep looking for an ability until one is valid
                do {
                    SetCurrentMobSkill(MobSkills.at(dsprand::GetRandomNumber(MobSkills.size())));
                } while (luautils::OnMobSkillCheck(m_PBattleTarget, m_PPet, GetCurrentMobSkill()) != 0 && maxSearch--);

                // could not find skill
                if (maxSearch == 0)
                {
                    TransitionBack(true);
                    return;
                }

                preparePetAbility(m_PBattleTarget);
                return;
            }
            return;
        }
    }


    if (m_PPet->getPetType() == PETTYPE_JUG_PET){
        if (m_MasterCommand == MASTERCOMMAND_SIC && m_PPet->health.tp >= 1000 && m_PBattleTarget != nullptr){ //choose random tp move
            m_MasterCommand = MASTERCOMMAND_NONE;
            if (m_PPet->PetSkills.size() > 0){
                SetCurrentMobSkill(m_PPet->PetSkills.at(dsprand::GetRandomNumber(m_PPet->PetSkills.size())));
                preparePetAbility(m_PBattleTarget);
                return;
            }
        }
    }
    else if (m_PPet->getPetType() == PETTYPE_AVATAR){
        for (int i = 0; i < m_PPet->PetSkills.size(); i++){
            if (m_PPet->PetSkills[i]->getAnimationTime() == m_MasterCommand){
                SetCurrentMobSkill(m_PPet->PetSkills[i]);
                m_MasterCommand = MASTERCOMMAND_NONE;
                preparePetAbility(m_PPet);
                return;
            }
        }
        m_MasterCommand = MASTERCOMMAND_NONE;
    }
    else if (m_PPet->getPetType() == PETTYPE_WYVERN){

        WYVERNTYPE wyverntype = m_PPet->getWyvernType();

        if (m_MasterCommand == MASTERCOMMAND_ELEMENTAL_BREATH && (wyverntype == WYVERNTYPE_MULTIPURPOSE || wyverntype == WYVERNTYPE_OFFENSIVE)){
            m_MasterCommand = MASTERCOMMAND_NONE;

            //offensive or multipurpose wyvern
            if (m_PBattleTarget != nullptr){ //prepare elemental breaths
                int skip = dsprand::GetRandomNumber(6);
                int hasSkipped = 0;

                for (int i = 0; i < m_PPet->PetSkills.size(); i++){
                    if (m_PPet->PetSkills[i]->getValidTargets() == TARGET_ENEMY){
                        if (hasSkipped == skip){
                            SetCurrentMobSkill(m_PPet->PetSkills[i]);
                            break;
                        }
                        else{
                            hasSkipped++;
                        }
                    }
                }

                preparePetAbility(m_PBattleTarget);
                return;
            }

        }
        else if (m_MasterCommand == MASTERCOMMAND_HEALING_BREATH && (wyverntype == WYVERNTYPE_DEFENSIVE || wyverntype == WYVERNTYPE_MULTIPURPOSE))
        {

            m_MasterCommand = MASTERCOMMAND_NONE;
            m_PBattleSubTarget = nullptr;
            //TODO: CHECK FOR STATUS EFFECTS FOR REMOVE- BREATH (higher priority than healing breaths)

            //	if(m_PPet->PMaster->PParty==nullptr){//solo with master-kun
            CItemArmor* masterHeadItem = ((CCharEntity*)(m_PPet->PMaster))->getEquip(SLOT_HEAD);

            uint16 masterHead = masterHeadItem ? masterHeadItem->getID() : 0;

			// Determine what the required HP percentage will need to be 
			// at or under in order for healing breath to activate.
			uint8 requiredHPP = 0;
			if (((CCharEntity*)(m_PPet->PMaster))->objtype == TYPE_PC && (masterHead == 12519 || masterHead == 15238)) { //Check for player & AF head, or +1
				if (wyverntype == WYVERNTYPE_DEFENSIVE) { //healer wyvern
					requiredHPP = 50;
				}
				else if (wyverntype == WYVERNTYPE_MULTIPURPOSE) { //hybrid wyvern
					requiredHPP = 33;
				}
			}
			else {
				if (wyverntype == WYVERNTYPE_DEFENSIVE) { //healer wyvern
					requiredHPP = 33;
				}
				else if (wyverntype == WYVERNTYPE_MULTIPURPOSE) { //hybrid wyvern
					requiredHPP = 25;
				}
			}

			// Only attempt to find a target if there is an HP percentage to calculate.
			if (requiredHPP) {
				CBattleEntity* master = m_PPet->PMaster;
				// Check the master first.
				if (master->GetHPP() <= requiredHPP) {
					m_PBattleSubTarget = master;
				}

				// Otherwise if this is a healer wyvern, and the member is in a party 
				// check all of the party members who qualify.
				else if (wyverntype == WYVERNTYPE_DEFENSIVE && master->PParty != nullptr) {
					master->ForParty([this, requiredHPP](CBattleEntity* PTarget){
						if (PTarget->GetHPP() <= requiredHPP) {
							m_PBattleSubTarget = PTarget;
						}
					});
				}
			}

            if (m_PBattleSubTarget != nullptr){ //target to heal
                //get highest breath for wyverns level
                m_PMobSkill = nullptr;
                for (int i = 0; i < m_PPet->PetSkills.size(); i++){
                    if (m_PPet->PetSkills[i]->getValidTargets() == TARGET_PLAYER_PARTY){
                        if (m_PPet->PetSkills[i]->getID() == 638 &&
                            m_PPet->PMaster->GetMLevel() < 20){ //can only using hb1
                            SetCurrentMobSkill(m_PPet->PetSkills[i]);
                            break;
                        }
                        else if (m_PPet->PetSkills[i]->getID() == 639 &&
                            m_PPet->PMaster->GetMLevel() < 40){ //can only using hb2
                            SetCurrentMobSkill(m_PPet->PetSkills[i]);
                            break;
                        }
                        else if (m_PPet->PetSkills[i]->getID() == 640 &&
                            m_PPet->PMaster->GetMLevel() >= 40){ //can only using hb3
                            SetCurrentMobSkill(m_PPet->PetSkills[i]);
                            break;
                        }
                    }
                }
                preparePetAbility(m_PBattleSubTarget);
                return;
            }
        }
    }

    TransitionBack(true);
}
Exemplo n.º 17
0
void CAIPetDummy::ActionAbilityStart()
{
	if(m_PPet->StatusEffectContainer->HasPreventActionEffect())
	{
		return;
	}

	if(m_PPet->objtype == TYPE_MOB && m_PPet->PMaster->objtype == TYPE_PC)
	{
		if(m_MasterCommand == MASTERCOMMAND_SIC && m_PPet->health.tp >= 100 && m_PBattleTarget != NULL)
		{
			m_MasterCommand = MASTERCOMMAND_NONE;
			CMobEntity* PMob = (CMobEntity*)m_PPet->PMaster->PPet;
			std::vector<CMobSkill*> MobSkills = battleutils::GetMobSkillsByFamily(PMob->m_Family);

			if(MobSkills.size() > 0)
			{
				int maxSearch = 10;
				// keep looking for an ability until one is valid
				do {
					m_PMobSkill = MobSkills.at(rand() % MobSkills.size());
				} while(luautils::OnMobSkillCheck(m_PBattleTarget, m_PPet, m_PMobSkill) != 0 && maxSearch--);

				// could not find skill
				if(maxSearch == 0)
				{
					TransitionBack(true);
					return;
				}

				preparePetAbility(m_PBattleTarget);
				return;
			}
			return;
		}
	}


	if(m_PPet->getPetType()==PETTYPE_JUG_PET){
		if(m_MasterCommand==MASTERCOMMAND_SIC && m_PPet->health.tp>=100 && m_PBattleTarget!=NULL){ //choose random tp move
			m_MasterCommand = MASTERCOMMAND_NONE;
			if(m_PPet->PetSkills.size()>0){
				m_PMobSkill = m_PPet->PetSkills.at(rand() % m_PPet->PetSkills.size());
				preparePetAbility(m_PBattleTarget);
				return;
			}
		}
	}
	else if(m_PPet->getPetType()==PETTYPE_AVATAR){
		for(int i=0; i<m_PPet->PetSkills.size(); i++){
			if(m_PPet->PetSkills[i]->getAnimationTime() == m_MasterCommand){
				m_PMobSkill = m_PPet->PetSkills[i];
				m_MasterCommand = MASTERCOMMAND_NONE;
				preparePetAbility(m_PPet);
				return;
			}
		}
		m_MasterCommand = MASTERCOMMAND_NONE;
	}
	else if(m_PPet->getPetType()==PETTYPE_WYVERN){

		WYVERNTYPE wyverntype = m_PPet->getWyvernType();

		if(m_MasterCommand==MASTERCOMMAND_ELEMENTAL_BREATH && (wyverntype == WYVERNTYPE_MULTIPURPOSE || wyverntype == WYVERNTYPE_OFFENSIVE)){
			m_MasterCommand = MASTERCOMMAND_NONE;

			//offensive or multipurpose wyvern
			if(m_PBattleTarget != NULL){ //prepare elemental breaths
				int skip = rand()%6;
				int hasSkipped = 0;

				for(int i=0; i<m_PPet->PetSkills.size(); i++){
					if(m_PPet->PetSkills[i]->getValidTargets() == TARGET_ENEMY){
						if(hasSkipped == skip){
							m_PMobSkill = m_PPet->PetSkills[i];
							break;
						}
						else{
							hasSkipped++;
						}
					}
				}

				preparePetAbility(m_PBattleTarget);
				return;
			}

		}
		else if(m_MasterCommand==MASTERCOMMAND_HEALING_BREATH && (wyverntype == WYVERNTYPE_DEFENSIVE || wyverntype == WYVERNTYPE_MULTIPURPOSE))
		{

			m_MasterCommand = MASTERCOMMAND_NONE;
			m_PBattleSubTarget = NULL;
			//TODO: CHECK FOR STATUS EFFECTS FOR REMOVE- BREATH (higher priority than healing breaths)

		//	if(m_PPet->PMaster->PParty==NULL){//solo with master-kun
			uint16 masterHead = ((CCharEntity*)(m_PPet->PMaster))->getStorage(LOC_INVENTORY)->GetItem(((CCharEntity*)(m_PPet->PMaster))->equip[SLOT_HEAD])->getID();

			if(((CCharEntity*)(m_PPet->PMaster))->objtype == TYPE_PC && (masterHead == 12519 || masterHead == 15238)) { //Check for player & AF head, or +1
				if(m_PPet->PMaster->GetHPP() <= 50 && wyverntype == WYVERNTYPE_DEFENSIVE){//healer wyvern
					m_PBattleSubTarget = m_PPet->PMaster;
				}
				else if(m_PPet->PMaster->GetHPP() <= 33 && wyverntype == WYVERNTYPE_MULTIPURPOSE){//hybrid wyvern
					m_PBattleSubTarget = m_PPet->PMaster;
				}
			} else {
				if(m_PPet->PMaster->GetHPP() <= 33 && wyverntype == WYVERNTYPE_DEFENSIVE)
				{//healer wyvern
					m_PBattleSubTarget = m_PPet->PMaster;
				}
				else if(m_PPet->PMaster->GetHPP() <= 25 && wyverntype == WYVERNTYPE_MULTIPURPOSE)
				{//hybrid wyvern
					m_PBattleSubTarget = m_PPet->PMaster;
				}
			}
		//	}
		//	else{ //group play
		//		//for( int i=0; i<
		//	}
			if(m_PBattleSubTarget != NULL){ //target to heal
				//get highest breath for wyverns level
				m_PMobSkill = NULL;
				for(int i=0; i<m_PPet->PetSkills.size(); i++){
					if(m_PPet->PetSkills[i]->getValidTargets() == TARGET_PLAYER_PARTY){
						if(m_PPet->PetSkills[i]->getID()==638 &&
							m_PPet->PMaster->GetMLevel() < 20){ //can only using hb1
								m_PMobSkill = m_PPet->PetSkills[i];
								break;
						}
						else if(m_PPet->PetSkills[i]->getID()==639 &&
							m_PPet->PMaster->GetMLevel() < 40){ //can only using hb2
								m_PMobSkill = m_PPet->PetSkills[i];
								break;
						}
						else if(m_PPet->PetSkills[i]->getID()==640 &&
							m_PPet->PMaster->GetMLevel() >= 40){ //can only using hb3
								m_PMobSkill = m_PPet->PetSkills[i];
								break;
						}
					}
				}
				preparePetAbility(m_PBattleSubTarget);
				return;
			}
		}
	}

	TransitionBack(true);
}