Example #1
0
void CalculateStats(CMobEntity * PMob)
{
    // remove all to keep mods in sync
    PMob->StatusEffectContainer->KillAllStatusEffect();
    PMob->restoreModifiers();
    PMob->restoreMobModifiers();

    bool isNM = PMob->m_Type & MOBTYPE_NOTORIOUS;
    JOBTYPE mJob = PMob->GetMJob();
    JOBTYPE sJob = PMob->GetSJob();
    uint8 mLvl = PMob->GetMLevel();
    ZONETYPE zoneType = PMob->loc.zone->GetType();

    if(PMob->HPmodifier == 0)
    {
        float hpScale = PMob->HPscale;

        if (PMob->getMobMod(MOBMOD_HP_SCALE) != 0)
        {
            hpScale = (float)PMob->getMobMod(MOBMOD_HP_SCALE) / 100.0f;
        }

        float growth = 1.06f;
        float petGrowth = 0.75f;
        float base = 18.0f;

        //give hp boost every 10 levels after 25
        //special boosts at 25 and 50
        if(mLvl > 75)
        {
            growth = 1.28f;
            petGrowth = 1.03f;
        }
        else if(mLvl > 65)
        {
            growth = 1.27f;
            petGrowth = 1.02f;
        }
        else if(mLvl > 55)
        {
            growth = 1.25f;
            petGrowth = 0.99f;
        }
        else if(mLvl > 50)
        {
            growth = 1.21f;
            petGrowth = 0.96f;
        }
        else if(mLvl > 45)
        {
            growth = 1.17f;
            petGrowth = 0.95f;
        }
        else if(mLvl > 35)
        {
            growth = 1.14f;
            petGrowth = 0.92f;
        }
        else if(mLvl > 25)
        {
            growth = 1.1f;
            petGrowth = 0.82f;
        }

        // pets have lower health
        if(PMob->PMaster != nullptr)
        {
            growth = petGrowth;
        }


        PMob->health.maxhp = (int16)(base * pow(mLvl, growth) * hpScale);

        if(isNM)
        {
            PMob->health.maxhp = (int32)(PMob->health.maxhp * 2.0f);
            if(mLvl > 75){
                PMob->health.maxhp = (int32)(PMob->health.maxhp * 2.5f);
            }
        }

    }
    else
    {
        PMob->health.maxhp = PMob->HPmodifier;
    }

    if(isNM)
    {
        PMob->health.maxhp = (int32)(PMob->health.maxhp * map_config.nm_hp_multiplier);
    }
    else
    {
        PMob->health.maxhp = (int32)(PMob->health.maxhp * map_config.mob_hp_multiplier);
    }

    bool hasMp = false;

    switch(mJob){
    case JOB_PLD:
    case JOB_WHM:
    case JOB_BLM:
    case JOB_RDM:
    case JOB_DRK:
    case JOB_BLU:
    case JOB_SCH:
    case JOB_SMN:
        hasMp = true;
        break;
    default:
        break;
    }

    switch(sJob){
    case JOB_PLD:
    case JOB_WHM:
    case JOB_BLM:
    case JOB_RDM:
    case JOB_DRK:
    case JOB_BLU:
    case JOB_SCH:
    case JOB_SMN:
        hasMp = true;
        break;
    default:
        break;
    }

    if(PMob->getMobMod(MOBMOD_MP_BASE))
    {
        hasMp = true;
    }

    if(hasMp)
    {
        float scale = PMob->MPscale;

        if(PMob->getMobMod(MOBMOD_MP_BASE))
        {
            scale = (float)PMob->getMobMod(MOBMOD_MP_BASE) / 100.0f;
        }

        if(PMob->MPmodifier == 0)
        {
            PMob->health.maxmp = (int16)(18.2 * pow(mLvl,1.1075) * scale) + 10;
            if(isNM)
            {
                PMob->health.maxmp = (int32)(PMob->health.maxmp * 1.5f);
                if(mLvl>75)
                {
                    PMob->health.maxmp = (int32)(PMob->health.maxmp * 1.5f);
                }
            }
        }
        else
        {
            PMob->health.maxmp = PMob->MPmodifier;
        }

        if(isNM)
        {
            PMob->health.maxmp = (int32)(PMob->health.maxmp * map_config.nm_mp_multiplier);
        }
        else
        {
            PMob->health.maxmp = (int32)(PMob->health.maxmp * map_config.mob_mp_multiplier);
        }
    }

    PMob->UpdateHealth();

    PMob->health.tp = 0;
    PMob->health.hp = PMob->GetMaxHP();
    PMob->health.mp = PMob->GetMaxMP();

    PMob->m_Weapons[SLOT_MAIN]->setDamage(GetWeaponDamage(PMob));

    //reduce weapon delay of MNK
    if(PMob->GetMJob()==JOB_MNK){
        PMob->m_Weapons[SLOT_MAIN]->resetDelay();
    }

    uint16 fSTR = GetBaseToRank(PMob->strRank, mLvl);
    uint16 fDEX = GetBaseToRank(PMob->dexRank, mLvl);
    uint16 fVIT = GetBaseToRank(PMob->vitRank, mLvl);
    uint16 fAGI = GetBaseToRank(PMob->agiRank, mLvl);
    uint16 fINT = GetBaseToRank(PMob->intRank, mLvl);
    uint16 fMND = GetBaseToRank(PMob->mndRank, mLvl);
    uint16 fCHR = GetBaseToRank(PMob->chrRank, mLvl);

    uint16 mSTR = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),2), mLvl);
    uint16 mDEX = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),3), mLvl);
    uint16 mVIT = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),4), mLvl);
    uint16 mAGI = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),5), mLvl);
    uint16 mINT = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),6), mLvl);
    uint16 mMND = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),7), mLvl);
    uint16 mCHR = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),8), mLvl);

    uint16 sSTR = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),2), PMob->GetSLevel());
    uint16 sDEX = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),3), PMob->GetSLevel());
    uint16 sVIT = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),4), PMob->GetSLevel());
    uint16 sAGI = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),5), PMob->GetSLevel());
    uint16 sINT = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),6), PMob->GetSLevel());
    uint16 sMND = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),7), PMob->GetSLevel());
    uint16 sCHR = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),8), PMob->GetSLevel());

    if(PMob->GetSLevel() > 15)
    {
        sSTR /= 2;
        sDEX /= 2;
        sAGI /= 2;
        sINT /= 2;
        sMND /= 2;
        sCHR /= 2;
        sVIT /= 2;
    }
    else
    {
        sSTR = 0;
        sDEX = 0;
        sAGI = 0;
        sINT = 0;
        sMND = 0;
        sCHR = 0;
        sVIT = 0;
    }

    PMob->stats.STR = fSTR + mSTR + sSTR;
    PMob->stats.DEX = fDEX + mDEX + sDEX;
    PMob->stats.VIT = fVIT + mVIT + sVIT;
    PMob->stats.AGI = fAGI + mAGI + sAGI;
    PMob->stats.INT = fINT + mINT + sINT;
    PMob->stats.MND = fMND + mMND + sMND;
    PMob->stats.CHR = fCHR + mCHR + sCHR;

    if(isNM)
    {
        PMob->stats.STR = (uint16)(PMob->stats.STR * 1.5f * map_config.nm_stat_multiplier);
        PMob->stats.DEX = (uint16)(PMob->stats.DEX * 1.5f * map_config.nm_stat_multiplier);
        PMob->stats.VIT = (uint16)(PMob->stats.VIT * 1.5f * map_config.nm_stat_multiplier);
        PMob->stats.AGI = (uint16)(PMob->stats.AGI * 1.5f * map_config.nm_stat_multiplier);
        PMob->stats.INT = (uint16)(PMob->stats.INT * 1.5f * map_config.nm_stat_multiplier);
        PMob->stats.MND = (uint16)(PMob->stats.MND * 1.5f * map_config.nm_stat_multiplier);
        PMob->stats.CHR = (uint16)(PMob->stats.CHR * 1.5f * map_config.nm_stat_multiplier);
    }
    else
    {
        PMob->stats.STR = (uint16)(PMob->stats.STR * map_config.mob_stat_multiplier);
        PMob->stats.DEX = (uint16)(PMob->stats.DEX * map_config.mob_stat_multiplier);
        PMob->stats.VIT = (uint16)(PMob->stats.VIT * map_config.mob_stat_multiplier);
        PMob->stats.AGI = (uint16)(PMob->stats.AGI * map_config.mob_stat_multiplier);
        PMob->stats.INT = (uint16)(PMob->stats.INT * map_config.mob_stat_multiplier);
        PMob->stats.MND = (uint16)(PMob->stats.MND * map_config.mob_stat_multiplier);
        PMob->stats.CHR = (uint16)(PMob->stats.CHR * map_config.mob_stat_multiplier);
    }

    // special case, give spell list to my pet
    if(PMob->getMobMod(MOBMOD_PET_SPELL_LIST) && PMob->PPet != nullptr)
    {
        // Stubborn_Dredvodd
        CMobEntity* PPet = (CMobEntity*)PMob->PPet;

        // give pet spell list
        PPet->m_SpellListContainer = mobSpellList::GetMobSpellList(PMob->getMobMod(MOBMOD_PET_SPELL_LIST));
    }

    if(PMob->getMobMod(MOBMOD_SPELL_LIST))
    {
        PMob->m_SpellListContainer = mobSpellList::GetMobSpellList(PMob->getMobMod(MOBMOD_SPELL_LIST));
    }

    // cap all stats for mLvl / job
    for (int i=SKILL_DIV; i <=SKILL_BLU; i++)
    {
        uint16 maxSkill = battleutils::GetMaxSkill((SKILLTYPE)i,PMob->GetMJob(),mLvl > 99 ? 99 : mLvl);
        if (maxSkill != 0)
        {
            PMob->WorkingSkills.skill[i] = maxSkill;
        }
        else //if the mob is WAR/BLM and can cast spell
        {
            // set skill as high as main level, so their spells won't get resisted
            uint16 maxSubSkill = battleutils::GetMaxSkill((SKILLTYPE)i,PMob->GetSJob(),mLvl > 99 ? 99 : mLvl);

            if (maxSubSkill != 0)
            {
                PMob->WorkingSkills.skill[i] = maxSubSkill;
            }
        }
    }
    for (int i=SKILL_H2H; i <=SKILL_STF; i++)
    {
        uint16 maxSkill = battleutils::GetMaxSkill(3, mLvl > 99 ? 99 : mLvl);
        if (maxSkill != 0)
        {
            PMob->WorkingSkills.skill[i] = maxSkill;
        }
    }

    PMob->addModifier(Mod::DEF, GetBase(PMob,PMob->defRank));
    PMob->addModifier(Mod::EVA, GetEvasion(PMob));
    PMob->addModifier(Mod::ATT, GetBase(PMob,PMob->attRank));
    PMob->addModifier(Mod::ACC, GetBase(PMob,PMob->accRank));

    //natural magic evasion
    PMob->addModifier(Mod::MEVA, GetMagicEvasion(PMob));

    // add traits for sub and main
    battleutils::AddTraits(PMob, traits::GetTraits(mJob), mLvl);
    battleutils::AddTraits(PMob, traits::GetTraits(PMob->GetSJob()), PMob->GetSLevel());

    SetupJob(PMob);
    SetupRoaming(PMob);

    // All beastmen drop gil
    if (PMob->m_EcoSystem == SYSTEM_BEASTMEN)
    {
        PMob->defaultMobMod(MOBMOD_GIL_BONUS, 100);
    }

    if (PMob->PMaster != nullptr)
    {
        SetupPetSkills(PMob);
    }

    PMob->m_Behaviour |= PMob->getMobMod(MOBMOD_BEHAVIOR);

    if(zoneType == ZONETYPE_DUNGEON)
    {
        SetupDungeonMob(PMob);
    }
    else if(zoneType == ZONETYPE_BATTLEFIELD)
    {
        SetupBattlefieldMob(PMob);
    }
    else if(zoneType == ZONETYPE_DYNAMIS)
    {
        SetupDynamisMob(PMob);
    }

    if(PMob->m_Type & MOBTYPE_NOTORIOUS)
    {
        SetupNMMob(PMob);
    }

    if(PMob->m_Type & MOBTYPE_EVENT)
    {
        SetupEventMob(PMob);
    }

    if(PMob->m_Family == 335)
    {
        SetupMaat(PMob);
    }

    if (PMob->CanStealGil())
    {
        PMob->ResetGilPurse();
    }

    if(PMob->m_Type & MOBTYPE_EVENT || PMob->m_Type & MOBTYPE_FISHED || PMob->m_Type & MOBTYPE_BATTLEFIELD ||
        zoneType == ZONETYPE_BATTLEFIELD || zoneType == ZONETYPE_DYNAMIS)
    {
        PMob->setMobMod(MOBMOD_CHARMABLE, 0);
    }

    // Check for possible miss-setups
    if (PMob->getMobMod(MOBMOD_SPECIAL_SKILL) != 0 && PMob->getMobMod(MOBMOD_SPECIAL_COOL) == 0)
    {
        ShowError("Mobutils::CalculateStats Mob (%s, %d) with special skill but no cool down set!\n", PMob->GetName(), PMob->id);
    }

    if (PMob->SpellContainer->HasSpells() && PMob->getMobMod(MOBMOD_MAGIC_COOL) == 0)
    {
        ShowError("Mobutils::CalculateStats Mob (%s, %d) with magic but no cool down set!\n", PMob->GetName(), PMob->id);
    }

    if (PMob->m_Detects == 0)
    {
        ShowError("Mobutils::CalculateStats Mob (%s, %d, %d) has no detection methods!\n", PMob->GetName(), PMob->id, PMob->m_Family);
    }
}
Example #2
0
void CalculateStats(CMobEntity * PMob)
{
    // remove all to keep mods in sync
    PMob->StatusEffectContainer->KillAllStatusEffect();
    PMob->restoreModifiers();
    PMob->restoreMobModifiers();

    bool isNM = PMob->m_Type & MOBTYPE_NOTORIOUS;
    JOBTYPE mJob = PMob->GetMJob();
    JOBTYPE sJob = PMob->GetSJob();
    uint8 mLvl = PMob->GetMLevel();
    ZONETYPE zoneType = PMob->loc.zone->GetType();

    if(PMob->HPmodifier == 0)
    {
        float hpScale = PMob->HPscale;

        if (PMob->getMobMod(MOBMOD_HP_SCALE) != 0)
        {
            hpScale = (float)PMob->getMobMod(MOBMOD_HP_SCALE) / 100.0f;
        }

        float growth = 1.06;
        float petGrowth = 0.75;
        float base = 18.0;

        //give hp boost every 10 levels after 25
        //special boosts at 25 and 50
        if(mLvl > 75)
        {
            growth = 1.28;
            petGrowth = 1.03;
        }
        else if(mLvl > 65)
        {
            growth = 1.27;
            petGrowth = 1.02;
        }
        else if(mLvl > 55)
        {
            growth = 1.25;
            petGrowth = 0.99;
        }
        else if(mLvl > 50)
        {
            growth = 1.21;
            petGrowth = 0.96;
        }
        else if(mLvl > 45)
        {
            growth = 1.17;
            petGrowth = 0.95;
        }
        else if(mLvl > 35)
        {
            growth = 1.14;
            petGrowth = 0.92;
        }
        else if(mLvl > 25)
        {
            growth = 1.1;
            petGrowth = 0.82;
        }

        // pets have lower health
        if(PMob->PMaster != nullptr)
        {
            growth = petGrowth;
        }


        PMob->health.maxhp = (int16)(base * pow(mLvl, growth) * hpScale);

        if(isNM)
        {
            PMob->health.maxhp *= 2.0;
            if(mLvl > 75){
                PMob->health.maxhp *= 2.5;
            }
        }

    }
    else
    {
        PMob->health.maxhp = PMob->HPmodifier;
    }

    if(isNM)
    {
        PMob->health.maxhp *= map_config.nm_hp_multiplier;
    }
    else
    {
        PMob->health.maxhp *= map_config.mob_hp_multiplier;
    }

    bool hasMp = false;

    switch(mJob){
    case JOB_PLD:
    case JOB_WHM:
    case JOB_BLM:
    case JOB_RDM:
    case JOB_DRK:
    case JOB_BLU:
    case JOB_SCH:
    case JOB_SMN:
        hasMp = true;
        break;
    }

    switch(sJob){
    case JOB_PLD:
    case JOB_WHM:
    case JOB_BLM:
    case JOB_RDM:
    case JOB_DRK:
    case JOB_BLU:
    case JOB_SCH:
    case JOB_SMN:
        hasMp = true;
        break;
    }

    if(PMob->getMobMod(MOBMOD_MP_BASE))
    {
        hasMp = true;
    }

    if(hasMp)
    {
        float scale = PMob->MPscale;

        if(PMob->getMobMod(MOBMOD_MP_BASE))
        {
            scale = (float)PMob->getMobMod(MOBMOD_MP_BASE) / 100.0f;
        }

        if(PMob->MPmodifier == 0)
        {
            PMob->health.maxmp = (int16)(18.2 * pow(mLvl,1.1075) * scale) + 10;
            if(isNM)
            {
                PMob->health.maxmp *= 1.5;
                if(mLvl>75)
                {
                    PMob->health.maxmp *= 1.5;
                }
            }
        }
        else
        {
            PMob->health.maxmp = PMob->MPmodifier;
        }

        if(isNM)
        {
            PMob->health.maxhp *= map_config.nm_mp_multiplier;
        }
        else
        {
            PMob->health.maxhp *= map_config.mob_mp_multiplier;
        }
    }

    PMob->UpdateHealth();

    PMob->health.tp = 0;
    PMob->health.hp = PMob->GetMaxHP();
    PMob->health.mp = PMob->GetMaxMP();

    PMob->m_Weapons[SLOT_MAIN]->setDamage(GetWeaponDamage(PMob));

    //reduce weapon delay of MNK
    if(PMob->GetMJob()==JOB_MNK){
        PMob->m_Weapons[SLOT_MAIN]->resetDelay();
    }

    uint16 fSTR = GetBaseToRank(PMob->strRank, mLvl);
    uint16 fDEX = GetBaseToRank(PMob->dexRank, mLvl);
    uint16 fVIT = GetBaseToRank(PMob->vitRank, mLvl);
    uint16 fAGI = GetBaseToRank(PMob->agiRank, mLvl);
    uint16 fINT = GetBaseToRank(PMob->intRank, mLvl);
    uint16 fMND = GetBaseToRank(PMob->mndRank, mLvl);
    uint16 fCHR = GetBaseToRank(PMob->chrRank, mLvl);

    uint16 mSTR = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),2), mLvl);
    uint16 mDEX = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),3), mLvl);
    uint16 mVIT = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),4), mLvl);
    uint16 mAGI = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),5), mLvl);
    uint16 mINT = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),6), mLvl);
    uint16 mMND = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),7), mLvl);
    uint16 mCHR = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),8), mLvl);

    uint16 sSTR = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),2), PMob->GetSLevel());
    uint16 sDEX = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),3), PMob->GetSLevel());
    uint16 sVIT = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),4), PMob->GetSLevel());
    uint16 sAGI = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),5), PMob->GetSLevel());
    uint16 sINT = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),6), PMob->GetSLevel());
    uint16 sMND = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),7), PMob->GetSLevel());
    uint16 sCHR = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),8), PMob->GetSLevel());

    if(PMob->GetSLevel() > 15)
    {
        sSTR /= 2;
        sDEX /= 2;
        sAGI /= 2;
        sINT /= 2;
        sMND /= 2;
        sCHR /= 2;
        sVIT /= 2;
    }
    else
    {
        sSTR = 0;
        sDEX = 0;
        sAGI = 0;
        sINT = 0;
        sMND = 0;
        sCHR = 0;
        sVIT = 0;
    }

    PMob->stats.STR = fSTR + mSTR + sSTR;
    PMob->stats.DEX = fDEX + mDEX + sDEX;
    PMob->stats.VIT = fVIT + mVIT + sVIT;
    PMob->stats.AGI = fAGI + mAGI + sAGI;
    PMob->stats.INT = fINT + mINT + sINT;
    PMob->stats.MND = fMND + mMND + sMND;
    PMob->stats.CHR = fCHR + mCHR + sCHR;

    if(isNM)
    {
        PMob->stats.STR *= (1.5 * map_config.nm_stat_multiplier);
        PMob->stats.DEX *= (1.5 * map_config.nm_stat_multiplier);
        PMob->stats.VIT *= (1.5 * map_config.nm_stat_multiplier);
        PMob->stats.AGI *= (1.5 * map_config.nm_stat_multiplier);
        PMob->stats.INT *= (1.5 * map_config.nm_stat_multiplier);
        PMob->stats.MND *= (1.5 * map_config.nm_stat_multiplier);
        PMob->stats.CHR *= (1.5 * map_config.nm_stat_multiplier);
    }
    else
    {
        PMob->stats.STR *= map_config.mob_stat_multiplier;
        PMob->stats.DEX *= map_config.mob_stat_multiplier;
        PMob->stats.VIT *= map_config.mob_stat_multiplier;
        PMob->stats.AGI *= map_config.mob_stat_multiplier;
        PMob->stats.INT *= map_config.mob_stat_multiplier;
        PMob->stats.MND *= map_config.mob_stat_multiplier;
        PMob->stats.CHR *= map_config.mob_stat_multiplier;
    }

    // special case, give spell list to my pet
    if(PMob->getMobMod(MOBMOD_PET_SPELL_LIST) && PMob->PPet != nullptr)
    {
        // Stubborn_Dredvodd
        CMobEntity* PPet = (CMobEntity*)PMob->PPet;

        // give pet spell list
        PPet->m_SpellListContainer = mobSpellList::GetMobSpellList(PMob->getMobMod(MOBMOD_PET_SPELL_LIST));
    }

    if(PMob->getMobMod(MOBMOD_SPELL_LIST))
    {
        PMob->m_SpellListContainer = mobSpellList::GetMobSpellList(PMob->getMobMod(MOBMOD_SPELL_LIST));
    }

    // cap all stats for mLvl / job
    for (int i=SKILL_DIV; i <=SKILL_BLU; i++)
    {
        uint16 maxSkill = battleutils::GetMaxSkill((SKILLTYPE)i,PMob->GetMJob(),mLvl > 99 ? 99 : mLvl);
        if (maxSkill != 0)
            {
            PMob->WorkingSkills.skill[i] = maxSkill;
        }
        else //if the mob is WAR/BLM and can cast spell
        {
            // set skill as high as main level, so their spells won't get resisted
            uint16 maxSubSkill = battleutils::GetMaxSkill((SKILLTYPE)i,PMob->GetSJob(),mLvl > 99 ? 99 : mLvl);

            if (maxSubSkill != 0)
            {
                PMob->WorkingSkills.skill[i] = maxSubSkill;
            }
        }
    }

    PMob->addModifier(MOD_DEF, GetBase(PMob,PMob->defRank));
    PMob->addModifier(MOD_EVA, GetEvasion(PMob));
    PMob->addModifier(MOD_ATT, GetBase(PMob,PMob->attRank));
    PMob->addModifier(MOD_ACC, GetBase(PMob,PMob->accRank));

    //natural magic evasion
    PMob->addModifier(MOD_MEVA, GetMagicEvasion(PMob));

    // add traits for sub and main
    battleutils::AddTraits(PMob, traits::GetTraits(mJob), mLvl);
    battleutils::AddTraits(PMob, traits::GetTraits(PMob->GetSJob()), PMob->GetSLevel());

    SetupJob(PMob);
    SetupRoaming(PMob);

    if (PMob->PMaster != nullptr)
    {
        SetupPetSkills(PMob);
    }

    PMob->m_Behaviour |= PMob->getMobMod(MOBMOD_BEHAVIOR);

    if(zoneType == ZONETYPE_DUNGEON)
    {
        SetupDungeonMob(PMob);
    }
    else if(zoneType == ZONETYPE_BATTLEFIELD)
    {
        SetupBattlefieldMob(PMob);
    }
    else if(zoneType == ZONETYPE_DYNAMIS)
    {
        SetupDynamisMob(PMob);
    }

    if(PMob->m_Type & MOBTYPE_NOTORIOUS)
    {
        SetupNMMob(PMob);
    }

    if(PMob->m_Type & MOBTYPE_EVENT)
    {
        SetupEventMob(PMob);
    }

    if(PMob->m_Family == 335)
    {
        SetupMaat(PMob);
    }
}