Example #1
0
CBattleEntity* CTargetFind::getValidTarget(uint16 actionTargetID, uint8 validTargetFlags)
{

    DSP_DEBUG_BREAK_IF(actionTargetID == 0);

    CBattleEntity* PTarget = (CBattleEntity*)m_PBattleEntity->loc.zone->GetEntity(actionTargetID, TYPE_MOB | TYPE_PC | TYPE_PET);

    if (PTarget == NULL)
    {
        return NULL;
    }

    if (validTargetFlags & TARGET_ENEMY)
    {
        if (!PTarget->isDead())
        {
            if (PTarget->objtype == TYPE_MOB ||
                (PTarget->objtype == TYPE_PC && ((CCharEntity*)PTarget)->m_PVPFlag))
            {
                return PTarget;
            }
        }
    }

    if (PTarget->objtype == TYPE_PC)
    {
        if ((validTargetFlags & TARGET_SELF) && PTarget->targid == m_PBattleEntity->targid)
        {
            return PTarget;
        }
        if (validTargetFlags & TARGET_PLAYER)
        {
            return PTarget;
        }
        if ((validTargetFlags & TARGET_PLAYER_PARTY) && (m_PBattleEntity->PParty != NULL && m_PBattleEntity->PParty == PTarget->PParty))
        {
            return PTarget;
        }
        if ((validTargetFlags & TARGET_PLAYER_PARTY_PIANISSIMO) && (m_PBattleEntity->StatusEffectContainer->HasStatusEffect(EFFECT_PIANISSIMO)) &&
            (m_PBattleEntity->PParty != NULL && m_PBattleEntity->PParty == PTarget->PParty))
        {
            return PTarget;
        }
        if ((validTargetFlags & TARGET_PLAYER_DEAD) && PTarget->isDead())
        {
            return PTarget;
        }
        return NULL;
    }
    return NULL;
}
Example #2
0
uint8 CEnmityContainer::GetHighestTH()
{
    CBattleEntity* PEntity = nullptr;
    uint8 THLvl = 0;

    for (auto it = m_EnmityList.cbegin(); it != m_EnmityList.cend(); ++it)
    {
        const EnmityObject_t& PEnmityObject = it->second;
        PEntity = PEnmityObject.PEnmityOwner;

        if (PEntity != nullptr && !PEntity->isDead() && IsWithinEnmityRange(PEntity) && PEnmityObject.maxTH > THLvl)
            THLvl = PEnmityObject.maxTH;
    }

    return THLvl;
}
Example #3
0
uint8 CEnmityContainer::GetHighestTH()
{
    CBattleEntity* PEntity = nullptr;
    uint8 THLvl = 0;

    for (EnmityList_t::iterator it = m_EnmityList.begin(); it != m_EnmityList.end(); ++it)
    {
        EnmityObject_t* PEnmityObject = it->second;
        PEntity = PEnmityObject->PEnmityOwner;

        if (PEntity != nullptr && !PEntity->isDead() && IsWithinEnmityRange(PEntity) && PEnmityObject->maxTH > THLvl)
            THLvl = PEnmityObject->maxTH;
    }

    return THLvl;
}
Example #4
0
CBattleEntity* CTargetFind::getValidTarget(uint16 actionTargetID, uint8 validTargetFlags)
{
    CBattleEntity* PTarget = (CBattleEntity*)m_PBattleEntity->GetEntity(actionTargetID, TYPE_MOB | TYPE_PC | TYPE_PET);

    if (PTarget == nullptr)
    {
        return nullptr;
    }

    if (PTarget->ValidTarget(m_PBattleEntity, validTargetFlags))
    {
        return PTarget;
    }

    return nullptr;
}
Example #5
0
CBattleEntity* CEnmityContainer::GetHighestEnmity()
{
    if (m_EnmityList.empty())
    {
        return nullptr;
    }
    uint32 HighestEnmity = 0;
    auto highest = m_EnmityList.end();
    bool active = false;

    for (auto it = m_EnmityList.begin(); it != m_EnmityList.end(); ++it)
    {
        const EnmityObject_t& PEnmityObject = it->second;
        uint32 Enmity = PEnmityObject.CE + PEnmityObject.VE;

        if (Enmity >= HighestEnmity && ((PEnmityObject.active == active) || (PEnmityObject.active && !active)))
        {
            auto POwner = PEnmityObject.PEnmityOwner;
            if (!POwner || (POwner->allegiance != m_EnmityHolder->allegiance))
            {
                active = PEnmityObject.active;
                HighestEnmity = Enmity;
                highest = it;
            }
        }
    }
    CBattleEntity* PEntity = nullptr;
    if (highest != m_EnmityList.end())
    {
        PEntity = highest->second.PEnmityOwner;
        if (!PEntity)
        {
            PEntity = zoneutils::GetChar(highest->first);
        }
        if (!PEntity || PEntity->getZone() != m_EnmityHolder->getZone() ||
            PEntity->PInstance != m_EnmityHolder->PInstance)
        {
            m_EnmityList.erase(highest);
            PEntity = GetHighestEnmity();
        }

    }
    return PEntity;
}
Example #6
0
CPartyDefinePacket::CPartyDefinePacket(CParty* PParty) 
{
	this->type = 0xC8;
	this->size = 0x7C;

	//party is an alliance do the double loop
	if (PParty != NULL)
	{
		if (PParty->m_PAlliance!= NULL)
		{
            uint8 offset = 0;
            
			for (uint8 a = 0; a < PParty->m_PAlliance->partyList.size(); ++a)
			{
				for (uint8 i = 0; i < PParty->m_PAlliance->partyList.at(a)->members.size(); ++i) 
				{
					CBattleEntity* PChar = PParty->m_PAlliance->partyList.at(a)->members.at(i);
                    
					WBUFL(data,12*offset+(0x08)-4) = PChar->id;
					WBUFW(data,12*offset+(0x0C)-4) = PChar->targid;
                    WBUFW(data,12*offset+(0x0E)-4) = PChar->PParty->GetMemberFlags(PChar);
					WBUFW(data,12*offset+(0x10)-4) = PChar->getZone();
                    
					offset++;
				}
			}
		}
        else //regular party
        {
			DSP_DEBUG_BREAK_IF(PParty->members.size() > 6);

			for (uint8 i = 0; i < PParty->members.size(); ++i) 
			{
				CBattleEntity* PChar = PParty->members.at(i);

				WBUFL(data,12*i+(0x08)-4) = PChar->id;
				WBUFW(data,12*i+(0x0C)-4) = PChar->targid;
				WBUFW(data,12*i+(0x0E)-4) = PChar->PParty->GetMemberFlags(PChar);
				WBUFW(data,12*i+(0x10)-4) = PChar->getZone();
			}
        }
	}
}
Example #7
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);
}
Example #8
0
void CMagicState::CharOnTarget(apAction_t* action, int16 ce, int16 ve)
{
    if(m_PEntity->objtype != TYPE_PC)
    {
        return;
    }

    CBattleEntity* PTarget = action->ActionTarget;
    bool enmityApplied = false;

    if (m_PEntity->StatusEffectContainer->HasStatusEffect(EFFECT_TRANQUILITY) && m_PSpell->getSpellGroup() == SPELLGROUP_WHITE)
    {
        m_PEntity->addModifier(MOD_ENMITY, -m_PEntity->StatusEffectContainer->GetStatusEffect(EFFECT_TRANQUILITY)->GetPower());
    }
    if (m_PEntity->StatusEffectContainer->HasStatusEffect(EFFECT_EQUANIMITY) && m_PSpell->getSpellGroup() == SPELLGROUP_BLACK)
    {
        m_PEntity->addModifier(MOD_ENMITY, -m_PEntity->StatusEffectContainer->GetStatusEffect(EFFECT_EQUANIMITY)->GetPower());
    }

    if (PTarget->objtype == TYPE_MOB && PTarget->allegiance != m_PEntity->allegiance)
    {
        if (PTarget->isDead())
        {
            ((CMobEntity*)PTarget)->m_DropItemTime = m_PSpell->getAnimationTime();
        }

        ((CMobEntity*)PTarget)->m_OwnerID.id = m_PEntity->id;
        ((CMobEntity*)PTarget)->m_OwnerID.targid = m_PEntity->targid;
        ((CMobEntity*)PTarget)->PEnmityContainer->UpdateEnmity(m_PEntity, ce, ve);
        enmityApplied = true;
    }
    else if (PTarget->allegiance == m_PEntity->allegiance)
    {
        battleutils::GenerateInRangeEnmity(m_PEntity, ce, ve);
        enmityApplied = true;
    }

    if (m_PEntity->StatusEffectContainer->HasStatusEffect(EFFECT_TRANQUILITY) && m_PSpell->getSpellGroup() == SPELLGROUP_WHITE)
    {
        m_PEntity->delModifier(MOD_ENMITY, -m_PEntity->StatusEffectContainer->GetStatusEffect(EFFECT_TRANQUILITY)->GetPower());
        if (enmityApplied)
            m_PEntity->StatusEffectContainer->DelStatusEffect(EFFECT_TRANQUILITY);
    }
    if (m_PEntity->StatusEffectContainer->HasStatusEffect(EFFECT_EQUANIMITY) && m_PSpell->getSpellGroup() == SPELLGROUP_BLACK)
    {
        m_PEntity->delModifier(MOD_ENMITY, -m_PEntity->StatusEffectContainer->GetStatusEffect(EFFECT_EQUANIMITY)->GetPower());
        if (enmityApplied)
            m_PEntity->StatusEffectContainer->DelStatusEffect(EFFECT_EQUANIMITY);
    }

    if(action->param > 0 && m_PSpell->dealsDamage() && m_PSpell->getSpellGroup() == SPELLGROUP_BLUE &&
        m_PEntity->StatusEffectContainer->HasStatusEffect(EFFECT_CHAIN_AFFINITY) && ((CBlueSpell*)m_PSpell)->getPrimarySkillchain() != 0)
    {

        SUBEFFECT effect = battleutils::GetSkillChainEffect(PTarget, (CBlueSpell*)m_PSpell);
        if (effect != SUBEFFECT_NONE)
        {
            uint16 skillChainDamage = battleutils::TakeSkillchainDamage(m_PEntity, PTarget, action->param);


            action->addEffectParam = skillChainDamage;
            action->addEffectMessage = 287 + effect;
            action->additionalEffect = effect;

        }
        if (m_PEntity->StatusEffectContainer->HasStatusEffect(EFFECT_SEKKANOKI) || m_PEntity->StatusEffectContainer->HasStatusEffect(EFFECT_MEIKYO_SHISUI))
        {
            m_PEntity->health.tp = (m_PEntity->health.tp > 1000 ? m_PEntity->health.tp - 1000 : 0);
        }
        else
        {
            m_PEntity->health.tp = 0;
        }

        m_PEntity->StatusEffectContainer->DelStatusEffectSilent(EFFECT_CHAIN_AFFINITY);
    }
}
Example #9
0
CBattleEntity* CTargetFind::getValidTarget(uint16 actionTargetID, uint8 validTargetFlags)
{

    DSP_DEBUG_BREAK_IF(actionTargetID == 0);

    CBattleEntity* PTarget = (CBattleEntity*)m_PBattleEntity->GetEntity(actionTargetID, TYPE_MOB | TYPE_PC | TYPE_PET);

    if (PTarget == nullptr)
    {
        return nullptr;
    }

    if (PTarget->objtype == TYPE_PC)
    {
        if ((validTargetFlags & TARGET_SELF) && PTarget->targid == m_PBattleEntity->targid)
        {
            return PTarget;
        }
        if (validTargetFlags & TARGET_PLAYER)
        {
            return PTarget;
        }
        if ((validTargetFlags & TARGET_PLAYER_PARTY) && (m_PBattleEntity->PParty != nullptr && m_PBattleEntity->PParty == PTarget->PParty))
        {
            return PTarget;
        }
        if ((validTargetFlags & TARGET_PLAYER_PARTY_PIANISSIMO) && (m_PBattleEntity->StatusEffectContainer->HasStatusEffect(EFFECT_PIANISSIMO)) &&
            (m_PBattleEntity->PParty != nullptr && m_PBattleEntity->PParty == PTarget->PParty))
        {
            return PTarget;
        }
        if ((validTargetFlags & TARGET_PLAYER_DEAD) && PTarget->isDead())
        {
            return PTarget;
        }
        return nullptr;
    }

	if (PTarget->objtype == TYPE_MOB)
	{
		if (validTargetFlags & TARGET_PLAYER_DEAD && ((CMobEntity*)PTarget)->m_Behaviour & BEHAVIOUR_RAISABLE
			&& PTarget->isDead())
		{
			return PTarget;
		}

        if (validTargetFlags & TARGET_NPC)
        {
            if (PTarget->allegiance == m_PBattleEntity->allegiance && (PTarget == m_PBattleEntity ||
                !(((CMobEntity*)PTarget)->m_Behaviour & BEHAVIOUR_NOHELP)))
            {
                return PTarget;
            }
        }
	}

    if (validTargetFlags & TARGET_ENEMY)
    {
        if (!PTarget->isDead())
        {
            if (PTarget->allegiance == (m_PBattleEntity->allegiance % 2 == 0 ? m_PBattleEntity->allegiance + 1 : m_PBattleEntity->allegiance - 1))
            {
                return PTarget;
            }
        }
    }

    return nullptr;
}
bool CAutomatonController::TryHeal(const CurrentManeuvers& maneuvers)
{
    if (!PAutomaton->PMaster || m_healCooldown == 0s || m_Tick <= m_LastHealTime + (m_healCooldown - std::chrono::seconds(PAutomaton->getMod(Mod::AUTO_HEALING_DELAY))))
        return false;

    float threshold = 0;
    switch (maneuvers.light) // Light -> Higher healing threshold
    {
    case 1:
        threshold = 40;
        break;
    case 2:
        threshold = 50;
        break;
    case 3:
        threshold = 75;
        break;
    default:
        threshold = 30;
        break;
    }

    threshold = dsp_cap(threshold + PAutomaton->getMod(Mod::AUTO_HEALING_THRESHOLD), 30, 90);
    CBattleEntity* PCastTarget = nullptr;

    bool haveHate = false;
    EnmityList_t* enmityList;

    auto PMob = dynamic_cast<CMobEntity*>(PTarget);
    if (PMob)
    {
        enmityList = PMob->PEnmityContainer->GetEnmityList();
        auto masterEnmity_obj = enmityList->find(PAutomaton->PMaster->id);
        auto selfEnmity_obj = enmityList->find(PAutomaton->id);

        if (masterEnmity_obj == enmityList->end())
            haveHate = true;
        else if (selfEnmity_obj == enmityList->end())
            haveHate = false;
        else
        {
            uint16 selfEnmity = selfEnmity_obj->second.CE + selfEnmity_obj->second.VE;
            uint16 masterEnmity = masterEnmity_obj->second.CE + masterEnmity_obj->second.VE;
            haveHate = selfEnmity > masterEnmity ? true : false;
        }
    }
    
    // Prioritize hate
    if (haveHate)
    {
        if (PAutomaton->GetHPP() <= 50) // Automaton only heals itself when <= 50%
            PCastTarget = PAutomaton;
        else if (PAutomaton->PMaster->GetHPP() <= threshold && distance(PAutomaton->loc.p, PAutomaton->PMaster->loc.p) < 20)
            PCastTarget = PAutomaton->PMaster;
    }
    else
    {
        if (PAutomaton->PMaster->GetHPP() <= threshold)
            PCastTarget = PAutomaton->PMaster;
        else if (PAutomaton->GetHPP() <= 50) // Automaton only heals itself when <= 50%
            PCastTarget = PAutomaton;
    }

    if (maneuvers.light && !PCastTarget && PAutomaton->getHead() == HEAD_SOULSOOTHER && PAutomaton->PMaster->PParty) // Light + Soulsoother head -> Heal party
    {
        if (PMob)
        {
            uint16 highestEnmity = 0;
            for (uint8 i = 0; i < PAutomaton->PMaster->PParty->members.size(); ++i)
            {
                CBattleEntity* member = PAutomaton->PMaster->PParty->members.at(i);
                if (member->id != PAutomaton->PMaster->id)
                {
                    auto enmity_obj = enmityList->find(member->id);
                    if (enmity_obj != enmityList->end() && highestEnmity < enmity_obj->second.CE + enmity_obj->second.VE &&
                        member->GetHPP() <= threshold && distance(PAutomaton->loc.p, PAutomaton->PMaster->loc.p) < 20)
                    {
                        highestEnmity = enmity_obj->second.CE + enmity_obj->second.VE;
                        PCastTarget = member;
                    }
                }
            }
        }
        else
        {
            for (uint8 i = 0; i < PAutomaton->PMaster->PParty->members.size(); ++i)
            {
                CBattleEntity* member = PAutomaton->PMaster->PParty->members.at(i);
                if (member->id != PAutomaton->PMaster->id && distance(PAutomaton->loc.p, PAutomaton->PMaster->loc.p) < 20)
                {
                    if (member->GetHPP() <= threshold)
                    {
                        PCastTarget = member;
                        break;
                    }
                }
            }
        }
    }

    // This might be wrong
    if (PCastTarget)
    {
        float missinghp = PCastTarget->GetMaxHP() - PCastTarget->health.hp;
        if (missinghp > 850 && Cast(PCastTarget->targid, SpellID::Cure_VI ))
            return true;
        else if (missinghp > 600 && Cast(PCastTarget->targid, SpellID::Cure_V))
            return true;
        else if (missinghp > 350 && Cast(PCastTarget->targid, SpellID::Cure_IV))
            return true;
        else if (missinghp > 190 && Cast(PCastTarget->targid, SpellID::Cure_III))
            return true;
        else if (missinghp > 120 && Cast(PCastTarget->targid, SpellID::Cure_II))
            return true;
        else if (Cast(PCastTarget->targid, SpellID::Cure))
            return true;
    }

    return false;
}