Exemplo n.º 1
0
uint32 CMobEntity::GetRandomGil()
{

    int16 min = getMobMod(MOBMOD_GIL_MIN);
    int16 max = getMobMod(MOBMOD_GIL_MAX);

    if(min && max)
    {
        // make sure divide won't crash server
        if(max <= min)
        {
            max = min+2;
        }

        if(max-min < 2)
        {
            max = min+2;
            ShowWarning("CMobEntity::GetRandomGil Max value is set too low, defauting\n");
        }

        return rand()%(max-min)+min;
    }

    float gil = pow(GetMLevel(), 1.05f);

    if(gil < 1){
        gil = 1;
    }

    uint16 highGil = (float)(gil) / 3 + 4;

    if(max)
    {
        highGil = max;
    }

    if(highGil < 2){
        highGil = 2;
    }

    // randomize it
	gil += rand()%highGil;

    // NMs get more gil
    if((m_Type & MOBTYPE_NOTORIOUS) == MOBTYPE_NOTORIOUS){
        gil *= 10;
    }

    // thfs drop more gil
    if(GetMJob() == JOB_THF){
        gil = (float)gil * 1.5;
    }

    if(min && gil < min)
    {
        gil = min;
    }

    return gil;
}
Exemplo n.º 2
0
bool CMobEntity::CanLink(position_t* pos, int16 superLink)
{
    // handle super linking
    if (superLink && getMobMod(MOBMOD_SUPERLINK) == superLink)
    {
        return true;
    }

    // can't link right now
    if (m_neutral)
    {
        return false;
    }

    // link only if I see him
    if (m_Detects & DETECT_SIGHT) {

        if (!isFaceing(loc.p, *pos, 40))
        {
            return false;
        }
    }

    if (distance(loc.p, *pos) > getMobMod(MOBMOD_LINK_RADIUS))
    {
        return false;
    }

    if (!PAI->PathFind->CanSeePoint(*pos))
    {
        return false;
    }
    return true;
}
Exemplo n.º 3
0
uint32 CMobEntity::GetRandomGil()
{

    int16 min = getMobMod(MOBMOD_GIL_MIN);
    int16 max = getMobMod(MOBMOD_GIL_MAX);

    if (min && max)
    {
        // make sure divide won't crash server
        if (max <= min)
        {
            max = min + 2;
        }

        if (max - min < 2)
        {
            max = min + 2;
            ShowWarning("CMobEntity::GetRandomGil Max value is set too low, defauting\n");
        }

        return dsprand::GetRandomNumber(min, max);
    }

    float gil = pow(GetMLevel(), 1.05f);

    if (gil < 1) {
        gil = 1;
    }

    uint16 highGil = (float)(gil) / 3 + 4;

    if (max)
    {
        highGil = max;
    }

    if (highGil < 2) {
        highGil = 2;
    }

    // randomize it
    gil += dsprand::GetRandomNumber(highGil);

    if (min && gil < min)
    {
        gil = min;
    }

    if (getMobMod(MOBMOD_GIL_BONUS) != 0)
    {
        gil = (float)gil * (getMobMod(MOBMOD_GIL_BONUS) / 100.0f);
    }

    return gil;
}
Exemplo n.º 4
0
void CMobEntity::Spawn()
{
    CBattleEntity::Spawn();
    m_giveExp = true;
    m_HiPCLvl = 0;
    m_THLvl = 0;
    m_ItemStolen = false;
    m_DropItemTime = 1000;
    animationsub = getMobMod(MOBMOD_SPAWN_ANIMATIONSUB);
    CallForHelp(false);

    PEnmityContainer->Clear();

    uint8 level = m_minLevel;

    // Generate a random level between min and max level
    if (m_maxLevel != m_minLevel)
    {
        level += dsprand::GetRandomNumber(0, m_maxLevel - m_minLevel);
    }

    SetMLevel(level);
    SetSLevel(level);//calculated in function
    delRageMode();

    mobutils::CalculateStats(this);
    mobutils::GetAvailableSpells(this);

    // spawn somewhere around my point
    loc.p = m_SpawnPoint;

    if (m_roamFlags & ROAMFLAG_STEALTH)
    {
        HideName(true);
        Untargetable(true);
    }

    // add people to my posse
    if (getMobMod(MOBMOD_ASSIST))
    {
        for (int8 i = 1; i < getMobMod(MOBMOD_ASSIST) + 1; i++)
        {
            CMobEntity* PMob = (CMobEntity*)GetEntity(targid + i, TYPE_MOB);

            if (PMob != nullptr)
            {
                PMob->setMobMod(MOBMOD_SUPERLINK, targid);
            }
        }
    }
    
    m_DespawnTimer = time_point::min();
    luautils::OnMobSpawn(this);
}
Exemplo n.º 5
0
bool CMobEntity::CanDropGil()
{
    // smaller than 0 means drop no gil
    if (getMobMod(MOBMOD_GIL_MAX) < 0) return false;

    if (getMobMod(MOBMOD_GIL_MIN) > 0 || getMobMod(MOBMOD_GIL_MAX))
    {
        return true;
    }

    return getMobMod(MOBMOD_GIL_BONUS) > 0;
}
Exemplo n.º 6
0
bool CMobEntity::CanDropGil()
{
    // smaller than 0 means drop no gil
    if(getMobMod(MOBMOD_GIL_MAX) < 0) return false;

    if(getMobMod(MOBMOD_GIL_MIN) > 0 || getMobMod(MOBMOD_GIL_MAX))
    {
        return true;
    }

    return m_EcoSystem == SYSTEM_BEASTMEN;
}
Exemplo n.º 7
0
bool CMobEntity::CanRoamHome()
{
    if ((speed == 0 && !(m_roamFlags & ROAMFLAG_WORM)) || getMobMod(MOBMOD_NO_MOVE) > 0) return false;

    if (getMobMod(MOBMOD_NO_DESPAWN) != 0 ||
        map_config.mob_no_despawn)
    {
        return true;
    }

    return distance(m_SpawnPoint, loc.p) < roam_home_distance;
}
Exemplo n.º 8
0
bool CMobEntity::OnAttack(CAttackState& state, action_t& action)
{
    static_cast<CMobController*>(PAI->GetController())->TapDeaggroTime();

    if (getMobMod(MOBMOD_ATTACK_SKILL_LIST))
    {
        return static_cast<CMobController*>(PAI->GetController())->MobSkill(getMobMod(MOBMOD_ATTACK_SKILL_LIST));
    }
    else
    {
        return CBattleEntity::OnAttack(state, action);
    }
}
Exemplo n.º 9
0
uint8 CMobEntity::TPUseChance()
{
    auto& MobSkillList = battleutils::GetMobSkillList(getMobMod(MOBMOD_SKILL_LIST));

    if (health.tp < 1000 || MobSkillList.empty() == true || !PBattleAI->GetMobAbilityEnabled())
    {
        return 0;
    }

    if (health.tp == 3000 || (GetHPP() <= 25 && health.tp >= 1000))
    {
        return 100;
    }

    return getMobMod(MOBMOD_TP_USE_CHANCE);
}
Exemplo n.º 10
0
uint8 CMobEntity::TPUseChance()
{
    auto& MobSkillList = battleutils::GetMobSkillList(getMobMod(MOBMOD_SKILL_LIST));

    if (health.tp < 1000 || MobSkillList.empty() == true || !static_cast<CMobController*>(PAI->GetController())->IsWeaponSkillEnabled())
    {
        return 0;
    }

    if (health.tp == 3000 || (GetHPP() <= 25 && health.tp >= 1000))
    {
        return 100;
    }

    return getMobMod(MOBMOD_TP_USE_CHANCE);
}
Exemplo n.º 11
0
bool CMobEntity::CanAttack(CBattleEntity* PTarget, std::unique_ptr<CMessageBasicPacket>& errMsg)
{
    auto skill_list_id {getMobMod(MOBMOD_ATTACK_SKILL_LIST)};
    if (skill_list_id)
    {
        auto attack_range {m_ModelSize};
        auto skillList {battleutils::GetMobSkillList(skill_list_id)};
        if (!skillList.empty())
        {
            auto skill {battleutils::GetMobSkill(skillList.front())};
            if (skill)
            {
                attack_range = skill->getDistance();
            }
        }
        if (distance(loc.p, PTarget->loc.p) > attack_range || !PAI->GetController()->IsAutoAttackEnabled())
        {
            return false;
        }
        return true;
    }
    else
    {
        return CBattleEntity::CanAttack(PTarget, errMsg);
    }
}
Exemplo n.º 12
0
void CMobEntity::OnDisengage(CAttackState& state)
{
    PAI->PathFind->Clear();
    PEnmityContainer->Clear();

    if (getMobMod(MOBMOD_IDLE_DESPAWN))
    {
        SetDespawnTime(std::chrono::milliseconds(getMobMod(MOBMOD_IDLE_DESPAWN)));
    }
    // this will let me decide to walk home or despawn
    m_neutral = true;

    delRageMode();
    m_OwnerID.clean();

    CBattleEntity::OnDisengage(state);

    luautils::OnMobDisengage(this);
}
Exemplo n.º 13
0
uint8 CMobEntity::TPUseChance()
{
    if(health.tp < 1000) return 0;

    if(health.tp == 3000 || (GetHPP() <= 25 && health.tp >= 1000))
    {
        return 100;
    }

    return getMobMod(MOBMOD_TP_USE_CHANCE);
}
Exemplo n.º 14
0
bool CMobEntity::CanRoamHome()
{
    if(speed == 0 && !(m_roamFlags & ROAMFLAG_WORM)) return false;

    if (getMobMod(MOBMOD_NO_DESPAWN) != 0 ||
        map_config.mob_no_despawn)
    {
        return true;
    }

    return distance(m_SpawnPoint, loc.p) < MOB_ROAM_HOME_DISTANCE;
}
Exemplo n.º 15
0
bool CMobEntity::CanLink(position_t* pos, int16 superLink)
{
    // handle super linking
    if(superLink && getMobMod(MOBMOD_SUPERLINK) == superLink)
    {
        return true;
    }

    // can't link right now
    if(m_neutral)
    {
        return false;
    }

    // link only if I see him
	if ((m_Aggro & AGGRO_DETECT_SIGHT) || (m_Aggro & AGGRO_DETECT_TRUESIGHT)){

       if(!isFaceing(loc.p, *pos, 40)) return false;
    }

    // link if close enough
    return distance(loc.p, *pos) <= getMobMod(MOBMOD_LINK_RADIUS);
}
Exemplo n.º 16
0
uint8 CMobEntity::TPUseChance()
{
    if (!PBattleAI->GetMobAbilityEnabled())
    {
        return 0;
    }
    if(health.tp < 1000) return 0;

    if(health.tp == 3000 || (GetHPP() <= 25 && health.tp >= 1000))
    {
        return 100;
    }

    return getMobMod(MOBMOD_TP_USE_CHANCE);
}
Exemplo n.º 17
0
bool CMobEntity::CanDetectTarget(CBattleEntity* PTarget, bool forceSight)
{
	if (PTarget->isDead() || m_Aggro == AGGRO_NONE || PTarget->animation == ANIMATION_CHOCOBO) return false;

    float verticalDistance = abs(loc.p.y - PTarget->loc.p.y);

    if(verticalDistance > 8)
    {
        return false;
    }

    float currentDistance = distance(PTarget->loc.p, loc.p) + PTarget->getMod(MOD_STEALTH);

    bool detectSight = (m_Aggro & AGGRO_DETECT_SIGHT) || forceSight;

    if (detectSight && !PTarget->StatusEffectContainer->HasStatusEffectByFlag(EFFECTFLAG_INVISIBLE) && currentDistance < getMobMod(MOBMOD_SIGHT_RANGE) && isFaceing(loc.p, PTarget->loc.p, 40))
    {
        return true;
    }

	if ((m_Aggro & AGGRO_DETECT_TRUESIGHT) && currentDistance < getMobMod(MOBMOD_SIGHT_RANGE) && isFaceing(loc.p, PTarget->loc.p, 40))
    {
        return true;
    }

	if ((m_Aggro & AGGRO_DETECT_TRUEHEARING) && currentDistance < getMobMod(MOBMOD_SOUND_RANGE))
    {
        return true;
    }

	if ((m_Behaviour & BEHAVIOUR_AGGRO_AMBUSH) && currentDistance < 3 && !PTarget->StatusEffectContainer->HasStatusEffect(EFFECT_SNEAK))
    {
        return true;
    }

	if ((m_Aggro & AGGRO_DETECT_HEARING) && currentDistance < getMobMod(MOBMOD_SOUND_RANGE) && !PTarget->StatusEffectContainer->HasStatusEffect(EFFECT_SNEAK))
    {
        return true;
    }

    // everything below require distance to be below 20
    if(currentDistance > 20)
    {
        return false;
    }

	if ((m_Aggro & AGGRO_DETECT_LOWHP) && PTarget->GetHPP() < 75)
    {
        return true;
    }

	if ((m_Aggro & AGGRO_DETECT_MAGIC) && PTarget->PBattleAI->GetCurrentAction() == ACTION_MAGIC_CASTING && PTarget->PBattleAI->GetCurrentSpell()->hasMPCost())
    {
        return true;
    }

	if ((m_Aggro & AGGRO_DETECT_WEAPONSKILL) && PTarget->PBattleAI->GetCurrentAction() == ACTION_WEAPONSKILL_FINISH)
    {
        return true;
    }

	if ((m_Aggro & AGGRO_DETECT_JOBABILITY) && PTarget->PBattleAI->GetCurrentAction() == ACTION_JOBABILITY_FINISH)
    {
        return true;
    }

    return false;
}
Exemplo n.º 18
0
bool CMobEntity::CanRoamHome()
{
    if(speed == 0 && !(m_roamFlags & ROAMFLAG_WORM)) return false;
    return getMobMod(MOBMOD_NO_DESPAWN);
}
Exemplo n.º 19
0
int32 CMobEntity::getBigMobMod(uint16 type)
{
	PROFILE_FUNC();
    return getMobMod(type) * 1000;
}
Exemplo n.º 20
0
void CMobEntity::DropItems()
{
    CCharEntity* PChar = (CCharEntity*)GetEntity(m_OwnerID.targid, TYPE_PC);

    if (PChar != nullptr && PChar->id == m_OwnerID.id)
    {

        loc.zone->PushPacket(this, CHAR_INRANGE, new CMessageBasicPacket(PChar, this, 0, 0, MSGBASIC_DEFEATS_TARG));

        if (!CalledForHelp())
        {
            blueutils::TryLearningSpells(PChar, this);
            m_UsedSkillIds.clear();

            if (m_giveExp)
            {
                charutils::DistributeExperiencePoints(PChar, this);
            }

            DropList_t* DropList = itemutils::GetDropList(m_DropID);
            //ShowDebug(CL_CYAN"DropID: %u dropping with TH Level: %u\n" CL_RESET, PMob->m_DropID, PMob->m_THLvl);

            if (DropList != nullptr && !getMobMod(MOBMOD_NO_DROPS) && DropList->size())
            {
                for (uint8 i = 0; i < DropList->size(); ++i)
                {
                    //THLvl is the number of 'extra chances' at an item. If the item is obtained, then break out.
                    uint8 tries = 0;
                    uint8 maxTries = 1 + (m_THLvl > 2 ? 2 : m_THLvl);
                    uint8 bonus = (m_THLvl > 2 ? (m_THLvl - 2) * 10 : 0);
                    while (tries < maxTries)
                    {
                        if (dsprand::GetRandomNumber(1000) < DropList->at(i).DropRate * map_config.drop_rate_multiplier + bonus)
                        {
                            PChar->PTreasurePool->AddItem(DropList->at(i).ItemID, this);
                            break;
                        }
                        tries++;
                    }
                }
            }

            // check for gil (beastmen drop gil, some NMs drop gil)
            if (CanDropGil() || (map_config.all_mobs_gil_bonus > 0 && getMobMod(MOBMOD_GIL_MAX) >= 0)) // Negative value of MOBMOD_GIL_MAX is used to prevent gil drops in Dynamis/Limbus.
            {
                charutils::DistributeGil(PChar, this); // TODO: REALISATION MUST BE IN TREASUREPOOL
            }
            //check for seal drops
            /* MobLvl >= 1 = Beastmen Seals ID=1126
                      >= 50 = Kindred Seals ID=1127
                      >= 75 = Kindred Crests ID=2955
                      >= 90 = High Kindred Crests ID=2956
            */

            uint16 Pzone = PChar->getZone();

            bool validZone = ((Pzone > 0 && Pzone < 39) || (Pzone > 42 && Pzone < 134) || (Pzone > 135 && Pzone < 185) || (Pzone > 188 && Pzone < 255));

            if (validZone && charutils::GetRealExp(PChar->GetMLevel(), GetMLevel()) > 0)
            {
                if (((PChar->StatusEffectContainer->HasStatusEffect(EFFECT_SIGNET) && conquest::GetInfluenceGraphics(PChar->loc.zone->GetRegionID()) < 64) ||
                    (PChar->StatusEffectContainer->HasStatusEffect(EFFECT_SANCTION) && PChar->loc.zone->GetRegionID() >= 28 && PChar->loc.zone->GetRegionID() <= 32) ||
                    (PChar->StatusEffectContainer->HasStatusEffect(EFFECT_SIGIL) && PChar->loc.zone->GetRegionID() >= 33 && PChar->loc.zone->GetRegionID() <= 40)) &&
                    m_Element > 0 && dsprand::GetRandomNumber(100) < 20) // Need to move to CRYSTAL_CHANCE constant
                {
                    PChar->PTreasurePool->AddItem(4095 + m_Element, this);
                }

                // Todo: Avatarite and Geode drops during day/weather. Much higher chance during weather than day.
                // Item element matches day/weather element, not mob crystal. Lv80+ xp mobs can drop Avatarite.
                // Wiki's have conflicting info on mob lv required for Geodes. One says 50 the other 75. I think 50 is correct.

                if (dsprand::GetRandomNumber(100) < 20 && PChar->PTreasurePool->CanAddSeal() && !getMobMod(MOBMOD_NO_DROPS))
                {
                    //RULES: Only 1 kind may drop per mob
                    if (GetMLevel() >= 75 && luautils::IsExpansionEnabled("ABYSSEA")) //all 4 types
                    {
                        switch (dsprand::GetRandomNumber(4))
                        {
                            case 0:
                                PChar->PTreasurePool->AddItem(1126, this);
                                break;
                            case 1:
                                PChar->PTreasurePool->AddItem(1127, this);
                                break;
                            case 2:
                                PChar->PTreasurePool->AddItem(2955, this);
                                break;
                            case 3:
                                PChar->PTreasurePool->AddItem(2956, this);
                                break;
                        }
                    }
                    else if (GetMLevel() >= 70 && luautils::IsExpansionEnabled("ABYSSEA")) //b.seal & k.seal & k.crest
                    {
                        switch (dsprand::GetRandomNumber(3))
                        {
                            case 0:
                                PChar->PTreasurePool->AddItem(1126, this);
                                break;
                            case 1:
                                PChar->PTreasurePool->AddItem(1127, this);
                                break;
                            case 2:
                                PChar->PTreasurePool->AddItem(2955, this);
                                break;
                        }
                    }
                    else if (GetMLevel() >= 50) //b.seal & k.seal only
                    {
                        if (dsprand::GetRandomNumber(2) == 0)
                        {
                            PChar->PTreasurePool->AddItem(1126, this);
                        }
                        else
                        {
                            PChar->PTreasurePool->AddItem(1127, this);
                        }
                    }
                    else
                    {
                        //b.seal only
                        PChar->PTreasurePool->AddItem(1126, this);
                    }
                }
            }
        }

        PChar->setWeaponSkillKill(false);
        StatusEffectContainer->KillAllStatusEffect();

        // NOTE: this is called for all alliance / party members!
        luautils::OnMobDeath(this, PChar);

    }
    else
    {
        luautils::OnMobDeath(this, nullptr);
    }
}
Exemplo n.º 21
0
float CMobEntity::GetRoamRate()
{
    return (float)getMobMod(MOBMOD_ROAM_RATE) / 10.0f;
}
Exemplo n.º 22
0
bool CMobEntity::CanRoam()
{
    return !(m_roamFlags & ROAMFLAG_EVENT) && PMaster == nullptr && (speed > 0 || (m_roamFlags & ROAMFLAG_WORM)) && getMobMod(MOBMOD_NO_MOVE) == 0;
}
Exemplo n.º 23
0
int32 CMobEntity::getBigMobMod(uint16 type)
{
    return getMobMod(type) * 1000;
}
Exemplo n.º 24
0
float CMobEntity::GetRoamDistance()
{
    return (float)getMobMod(MOBMOD_ROAM_DISTANCE) / 10.0f;
}