Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

Reply
 
Thread Tools Display Modes
  #1  
Old 08-28-2014, 04:37 PM
noudess
Discordant
 
Join Date: Sep 2012
Location: Upstate NY
Posts: 274
Default 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;
}
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 09:29 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3