EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Server Code Submissions (https://www.eqemulator.org/forums/forumdisplay.php?f=669)
-   -   Modified Faction min/max system (https://www.eqemulator.org/forums/showthread.php?t=38685)

noudess 08-28-2014 04:37 PM

Modified Faction min/max system
 
Over in this thread I brought up an issue with the current code.

I brought it up ober on peq and got some input.

I looked at the current code alot, and found some bugs like below, which tries to boundary check, but actually makes the # even smaller if the mod is negative..


Code:

}
                            else if(tmpValue <= MIN_FACTION)
                            {
                                    t = MIN_FACTION - mod;


Based on all that I rewrote this one function (currently in client.cpp for you guys, was in faction.cpp in my version), and changed a couple of constants (features.h for me).

The idea of my changes:
  • each char has a window from +1200 to -3000 to earn for himself against each faction regardless of mods
  • The mods are applied to that value to determine resulting faction.
  • Thie means the range is 1200+mods to -3000 + mods
  • Now, all characters "deeds" matter equally. This solved my issue where my Erudites min faction was only -500 based on the old code, while others could dig a deeprr hole. Now, if my Erudite kills down to -3000 personal, illusion wiont be enough to not be KOS.

I like the new system. I think it is closer to the old system and makes more sense.

Here's the code, up to you if you want it. Not posting as a diff - your filenames have changed and I reformatted. I couldn't really read/understand until I did. It's just the one func + defines, but the func is close to a rewrite. Alot of logic moved around to make it more straight forward.

Code:

// In features.h on my server
#define MIN_PERSONAL_FACTION (-3000)
#define MAX_PERSONAL_FACTION (1200)

// In faction.cpp on my server, client.cpp in recent code base
void  Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity)
{
        _ZP(Client_SetFactionLevel);
        int32 faction_id[MAX_NPC_FACTIONS]={ 0,0,0,0,0,0,0,0,0,0 };
        int32 npc_value[MAX_NPC_FACTIONS]={ 0,0,0,0,0,0,0,0,0,0 };
        uint8 temp[MAX_NPC_FACTIONS]={ 0,0,0,0,0,0,0,0,0,0 };
        int16 mod;
        int16 tmpValue;
        int16 current_value;
        FactionMods fm;
        bool  change=false;
        bool  repair=false;
        char  *msg;

        // Get the npc faction list
        if(!database.GetNPCFactionList(npc_id, faction_id, npc_value, temp))
                return;

        for(int i = 0;i<MAX_NPC_FACTIONS;i++)
                {
                if(faction_id[i] <= 0)
                        continue;

                // Get the faction modifiers
                if(database.GetFactionData(&fm,char_class,char_race,char_deity,faction_id[i]))
                        {
                        // Get the characters current value with that faction
                        current_value = GetCharacterFactionLevel(faction_id[i]);

                        // Modify if we have Heroic Charisma
                        if(this->itembonuses.HeroicCHA)
                                {
                                int faction_mod = itembonuses.HeroicCHA / 5;
                                // If our result isn't truncated, then just do that
                                if(npc_value[i] * faction_mod / 100 != 0)
                                        npc_value[i] += npc_value[i] * faction_mod / 100;
                                // If our result is truncated, then double a mob's value every once
                                // in a while to equal what they would have got
                                else
                                        {
                                        if(MakeRandomInt(0, 100) < faction_mod)
                                                npc_value[i] *= 2;
                                        }
                                }

                        // Set flag when to update db.
                        if (current_value > MAX_PERSONAL_FACTION) // db faction out of line (old code saved it wrong)
                                {
                                repair=true;
                                current_value = MAX_PERSONAL_FACTION;
                                }
                        else if (current_value < MIN_PERSONAL_FACTION) // db faction out of line (old code saved it wrong)
                                {
                                repair=true;
                                current_value = MIN_PERSONAL_FACTION;
                                }
                        // Also update if there's a hit and we're not maxxed or bottomed out or a GM
                        else if(m_pp.gm != 1 && npc_value[i] != 0 &&
                                        (current_value != MAX_PERSONAL_FACTION || current_value != MIN_PERSONAL_FACTION))
                                {
                                change=true;
                                }

                        current_value += npc_value[i];
                       
                        if (current_value < MIN_PERSONAL_FACTION)
                                {
                                current_value = MIN_PERSONAL_FACTION;
                                }
                        else if (current_value > MAX_PERSONAL_FACTION)
                                {
                                current_value = MAX_PERSONAL_FACTION;
                                }

                        if (change || repair)
                                {
                                database.SetCharacterFactionLevel(char_id, faction_id[i],
                                                current_value, temp[i], factionvalues);

                                if (change) // Message only if kill modified faction. Repair silently.
                                        {
                                        //figure out their modifierm buildmessage wants final faction
                                        mod = fm.base + fm.class_mod + fm.race_mod + fm.deity_mod;
                                    tmpValue = current_value + mod + npc_value[i];

                                        msg = BuildFactionMessage(npc_value[i],faction_id[i],tmpValue,temp[i]);
                                        if (msg != 0)
                                                Message(0, msg);
                                        safe_delete_array(msg);
                                        }
                                }

                        }
                }
        return;
}

Then I had to change the message function to use the modifier constant names:

Code:

char* BuildFactionMessage(int32 tmpvalue, int32 faction_id, int32 totalvalue, uint8 temp)
{
/*

This should be replaced to send string-ID based messages using:
#define FACTION_WORST 469 //Your faction standing with %1 could not possibly get any worse.
#define FACTION_WORSE 470 //Your faction standing with %1 got worse.
#define FACTION_BEST 471 //Your faction standing with %1 could not possibly get any better.
#define FACTION_BETTER 472 //Your faction standing with %1 got better.

some day.

*/
        //tmpvalue is the change as best I can tell.
        char *faction_message = 0;

        char name[50];

        if(database.GetFactionName(faction_id, name, sizeof(name)) == false) {
                snprintf(name, sizeof(name),"Faction%i",faction_id);
        }

        if(tmpvalue == 0 || temp == 1 || temp == 2) {
                return 0;
        }
        else if (totalvalue >= MAX_PERSONAL_FACTION) {
                MakeAnyLenString(&faction_message, "Your faction standing with %s could not possibly get any better!", name);
                return faction_message;
        }
        else if(tmpvalue > 0 && totalvalue < MAX_PERSONAL_FACTION) {
                MakeAnyLenString(&faction_message, "Your faction standing with %s has gotten better!", name);
                return faction_message;
        }
        else if(tmpvalue < 0 && totalvalue > MIN_PERSONAL_FACTION) {
                MakeAnyLenString(&faction_message, "Your faction standing with %s has gotten worse!", name);
                return faction_message;
        }
        else if(totalvalue <= MIN_PERSONAL_FACTION) {
                MakeAnyLenString(&faction_message, "Your faction standing with %s could not possibly get any worse!", name);
                return faction_message;
        }
        return 0;
}

And remove the truncation from this function.

Code:

// returns the character's faction level, adjusted for racial, class, and deity modifiers
int32 Client::GetModCharacterFactionLevel(int32 faction_id) {
        int32 Modded = GetCharacterFactionLevel(faction_id);
        FactionMods fm;
        if(database.GetFactionData(&fm,GetClass(),GetRace(),GetDeity(),faction_id))
                Modded += fm.base + fm.class_mod + fm.race_mod + fm.deity_mod;

        return Modded;
}



All times are GMT -4. The time now is 02:28 PM.

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