EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Server Code Submissions (https://www.eqemulator.org/forums/forumdisplay.php?f=669)
-   -   New GetConLevel() for SoF+ clients (https://www.eqemulator.org/forums/showthread.php?t=33590)

Zothen 05-19-2011 04:47 AM

New GetConLevel() for SoF+ clients
 
After I did some testing, I found a formula to calculate the exact conlevels of the mobs according to their color indicator. I added a new conlevel (CON_GRAY) to account for all mob colors the client (SoF+) is showing and a new rule for a green XP modifier.

Well, I am happy with it and would like to share: :)

mob.h
Code:

#define CON_GRAY                1
ruletypes.h
Code:

RULE_INT ( Character, GreenModifier, 20 )
attack.cpp
Death()
Code:

                        if(!IsLdonTreasure) {
                                int conlevel = give_exp->GetLevelCon(GetLevel());
                                if (conlevel != CON_GRAY)       
                                {
                                        if(GetOwner() && GetOwner()->IsClient()){
                                        }
                                        else {
                                                give_exp_client->AddEXP((EXP_FORMULA), conlevel); // Pyro: Comment this if NPC death crashes zone
                                                if(killerMob && (killerMob->GetID() == give_exp_client->GetID() || killerMob->GetUltimateOwner()->GetID() == give_exp_client->GetID()))
                                                        killerMob->TrySpellOnKill();
                                        }
                                }
                        }

bot.cpp
ShowSpawnWindow()
Code:

                                        switch(CurrentCon) {

                                                case CON_GRAY:       
                                                case CON_GREEN: {
                                                        WindowText += "<c \"#00FF00\">";
                                                        break;
                                                }

client.cpp
CheckIncreaseSkill()

Code:

        if(against_who)
        {
                if(against_who->SpecAttacks[IMMUNE_AGGRO] || against_who->IsClient() ||
                        GetLevelCon(against_who->GetLevel()) == CON_GRAY)       
                {
                                return false;
                }
        }

exp.cpp
Group::SplitExp()

Code:

        int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel());
        if (conlevel == CON_GRAY)       
                return;        //no exp for grayies...

exp.cpp
Raid::SplitExp()

Code:

        int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel());
        if(conlevel == CON_GRAY)       
                return;        //no exp for grayies...

fearpath.cpp
Mob::CheckFlee()

Code:

        int32 con = GetLevelCon(hate_top->GetLevel(), GetLevel());
        float run_ratio;
        switch(con) {
                //these values are not 100% researched
                case CON_GRAY:       
                case CON_GREEN:
                        run_ratio = RuleI(Combat, FleeHPRatio);
                        break;

mob.h
Code:

        inline int32 GetLevelCon(int8 iOtherLevel) const { return(this?GetLevelCon(GetLevel(), iOtherLevel):CON_GRAY); }
And the heart of it:

MobAI.cpp
Code:

int32 Mob::GetLevelCon(int8 mylevel, int8 iOtherLevel) {
    sint16 diff = iOtherLevel - mylevel;
        int32 conlevel=0;
        int32 conGrayLvl  = mylevel - (int32)((mylevel + 5)/3);
        int32 conGreenLvl  = mylevel - (int32)((mylevel + 7)/4);

        //_log(LAUNCHER__STATUS, "GetConLevel: mylevel                = %d", mylevel);
        //_log(LAUNCHER__STATUS, "GetConLevel: iOtherLevel        = %d", iOtherLevel);
        //_log(LAUNCHER__STATUS, "GetConLevel: conGrayLvl                = %d", conGrayLvl);
        //_log(LAUNCHER__STATUS, "GetConLevel: conGreenLvl        = %d", conGreenLvl);

    if (diff == 0)
        return CON_WHITE;
    else if (diff >= 1 && diff <= 3)
        return CON_YELLOW;
    else if (diff >= 4)
        return CON_RED;

    if (mylevel <= 15)
    {
        if (diff <= -6)
            conlevel = CON_GRAY;
        else
            conlevel = CON_BLUE;
    }
    else
        if (mylevel <= 20)
        {
        if (iOtherLevel <= conGrayLvl)
            conlevel = CON_GRAY;
        else
                if (iOtherLevel <= conGreenLvl)
            conlevel = CON_GREEN;
        else
            conlevel = CON_BLUE;
        }
    else
        {
        if (iOtherLevel <= conGrayLvl)
            conlevel = CON_GRAY;
        else
                if (iOtherLevel <= conGreenLvl)
            conlevel = CON_GREEN;
        else
                if (diff <= -6)
            conlevel = CON_LIGHTBLUE;
        else
            conlevel = CON_BLUE;
        }
        return conlevel;
}


Zothen 05-19-2011 06:41 AM

Forgot 2 changes for aggro behavior:

aggro.cpp
Mob::CheckWillAggro()

Code:

        if
        (
        //old InZone check taken care of above by !mob->CastToClient()->Connected()
        (
                ( GetINT() <= 75 )
                ||( mob->IsClient() && mob->CastToClient()->IsSitting() )
                ||( mob->GetLevelCon(GetLevel()) != CON_GRAY )               

        )


aggro.cpp
EntityList::GetHatedCount()

Code:

        for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) {

                NPC* mob = iterator.GetData();

                if(!mob || (mob == exclude)) continue;
               
                if(!mob->IsEngaged()) continue;

                if(mob->IsFeared() || mob->IsMezzed()) continue;

                if(attacker->GetLevelCon(mob->GetLevel()) == CON_GRAY) continue;

                if(!mob->CheckAggro(attacker)) continue;

                float AggroRange = mob->GetAggroRange();

                // Square it because we will be using DistNoRoot
                       
                AggroRange = AggroRange * AggroRange;

                if(mob->DistNoRoot(*attacker) > AggroRange) continue;

                Count++;

        }


aggro.cpp
EntityList::AIYellForHelp()

Code:

                        //if they are in range, make sure we are not green...
                        //then jump in if they are our friend
                        if(attacker->GetLevelCon(mob->GetLevel()) != CON_GRAY)       
                        {
                                bool useprimfaction = false;
                                if(mob->GetPrimaryFaction() == sender->CastToNPC()->GetPrimaryFaction())
                                {
                                        const NPCFactionList *cf = database.GetNPCFactionEntry(mob->GetNPCFactionID());
                                        if(cf){
                                                if(cf->assistprimaryfaction != 0)
                                                        useprimfaction = true;
                                        }
                                }


sorvani 05-19-2011 08:25 PM

The con color functions are nice added functionality.

The aggro based on con color would be a good optional rule for the rules table


All times are GMT -4. The time now is 06:35 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.