Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Bug Reports

Development::Bug Reports Post detailed bug reports and what you would like to see next in the emu here.

Reply
 
Thread Tools Display Modes
  #1  
Old 11-09-2008, 10:34 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Thanks for clearing that up KLS. I don't really know much about the BLOBs and I am guessing that is what pp stuff is. I know level is stored directly in the character_ table, which is why I thought level2 had to be added there. I am still not clear on why there is a level field in the table if it is also in the pp (blob I guess).

Either way, if level2 is already there, then it looks like this should be a simple fix. I will give it a try and see how it tests.

I also think that these 2 lines could be removed:

Code:
        lu->level_old = level;
        level = set_level;
Because I don't see where those are even used anywhere in the code.

I also don't see any use of level_old and can't think of any reason why it would even exist. That is why I thought the packet structure might be wrong. Once I was done posting that, I already knew it had nothing to do with the fix, but it probably doesn't hurt to have the packet structure corrected if it is wrong. I am not saying that it is wrong, but just that I don't know what a level_old would be used for and I don't see it referenced anywhere else, or used anywhere. Just something to consider, anyway.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #2  
Old 11-10-2008, 12:19 AM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default

No leave those in. lu->level_old = level; tells the client what their old level was. Likely the client doctors the You gained a level / you lost a level message via that but I'm not sure.

level = set_level; is what actually sets the level =p
Reply With Quote
  #3  
Old 11-10-2008, 12:54 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Hmm, if "level = set_level;" is setting the character level, then what is "m_pp.level = set_level;" doing? Is that just for updating the BLOB? I don't get the difference. Sorry for my noobishness lol.

I know we generate the leveling message, but there is another message that shows up when you #level that tells you how many levels you gained or lost. I am not at home right now, so I can't check it, but that is the only thing I can think of that level_old could possibly be used for. Not that there is any good reason to remove it (if nothing is broken), but I am just trying to understand what is going on.

No big deal really though, as I am pretty sure we should have this bug cleared up. I will definitely try to get this in tonight and test it out.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #4  
Old 11-10-2008, 01:00 AM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default

You have to understand how the objects work. m_pp basically is the player profile that's what we read back when we log in to get our bearings and what we save() to. But most the time the client/npc tracks it's own data without referencing the player profile. Without that line you wouldn't be that level for things like spell and combat calculations until you zoned because the active client object still thinks your level is the one it got from pp originally.
Reply With Quote
  #5  
Old 11-10-2008, 03:45 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Thanks again KLS. So, that is basically just sending a level update to the client. I understand much better now
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #6  
Old 11-10-2008, 08:27 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Well, I got this tested, and had to adjust how it was written slightly to make sure it included the logging.

Code:
void Client::SetLevel(int8 set_level, bool command)
{
	#ifdef GUILDWARS
		if(set_level > SETLEVEL) {
			Message(0,"You cannot exceed level %i on a GuildWars Server.",SETLEVEL);
			return;
		}
	#endif

	if (GetEXPForLevel(set_level) == 0xFFFFFFFF) {
		LogFile->write(EQEMuLog::Error,"Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level);
		return;
	}

	EQApplicationPacket* outapp = new EQApplicationPacket(OP_LevelUpdate, sizeof(LevelUpdate_Struct));
	LevelUpdate_Struct* lu = (LevelUpdate_Struct*)outapp->pBuffer;
	lu->level = set_level;
	lu->level_old = level;
	level = set_level;

	if(IsRaidGrouped())
	{
		Raid *r = this->GetRaid();
		if(r){
			r->UpdateLevel(GetName(), set_level);
		}
	}

	if (set_level > m_pp.level2) {
		m_pp.points += 5 * (set_level - m_pp.level2);
		m_pp.level2 = set_level;

#ifdef EMBPERL
		((PerlembParser*)parse)->Event(EVENT_LEVEL_UP, 0, "", (NPC*)NULL, this);
#endif
	}

	m_pp.level = set_level;
	if (command){
		m_pp.exp = GetEXPForLevel(set_level);
		Message(15, "Welcome to level %i!", set_level);
		lu->exp = 0;
	}
	else {
		float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) /
						( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel()));
		lu->exp =  (int32)(330.0f * tmpxp);
    }
	QueuePacket(outapp);
	safe_delete(outapp);
	this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change

    LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);

	CalcBonuses();
	if(!RuleB(Character, HealOnLevel))
	{
		int mhp = CalcMaxHP();
		if(GetHP() > mhp)
			SetHP(mhp);
	}
	else
	{
		SetHP(CalcMaxHP());		// Why not, lets give them a free heal
	}

	SendHPUpdate();
	SetMana(CalcMaxMana());
	UpdateWho();
	Save();
}
But, it still doesn't seem to be working, so I am guessing that level2 is either being updated somewhere else to match current level, or the points are being added elsewhere.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #7  
Old 11-10-2008, 09:18 AM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

You need to check if m_pp.level2 is zero, which it will be for any character created before this change, otherwise you will give existing characters lots of extra skill points. The code below works for me, however if you try and train skills after levelling, without zoning, the client will show an extra 5 points, however if you zone first, it seems to display correctly.

Code:
        if(set_level > m_pp.level2)
        {
                printf("m_pp.level2 is %i\n", m_pp.level2); fflush(stdout);
                if(m_pp.level2 == 0)
                        m_pp.points += 5;
                else
                        m_pp.points += (5 * (set_level - m_pp.level2));

                m_pp.level2 = set_level;
        }
        if(set_level > m_pp.level) { // Yes I am aware that you could delevel yourself and relevel this is just to test!

#ifdef EMBPERL
                ((PerlembParser*)parse)->Event(EVENT_LEVEL_UP, 0, "", (NPC*)NULL, this);
#endif
        }

        m_pp.level = set_level;
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 10:25 PM.


 

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 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3