Log in

View Full Version : CharMaxLevel Problem


Lord of Steel
03-11-2014, 07:45 AM
I have implemented the quest globals for CharMaxLevel, but they are behaving a little quirky. The players can ding the max level but can not build EXP into it. They are stuck at zero.

Is there something else i need to configure?

Uleat
03-11-2014, 08:49 AM
Did you increase the max level rule in the db?

I think it's set to 65 by default.

Lord of Steel
03-11-2014, 09:02 AM
There are 2 values, max level and max exp level or something like that. I believe i had 1 set correctly, can't remember if i had the other set correctly when i did my reboot last night. Just trying to get my ducks in a row on this detail to minimize my reboots.

Lord of Steel
03-14-2014, 09:14 PM
I had to redo some of the code in the SetEXP method of exp.cpp.

It seems pretty sloppy in there. You have "normal" code being run after special rules code effectively canceling out the special rule. Then there is code that needs to be duplicated for special rules but isn't.

Kingly_Krab
03-14-2014, 09:18 PM
I had to redo some of the code in the SetEXP method of exp.cpp.

It seems pretty sloppy in there. You have "normal" code being run after special rules code effectively canceling out the special rule. Then there is code that needs to be duplicated for special rules but isn't.
It'd be nice if you could post a diff of your code so they can commit the change to the repository.

sorvani
03-14-2014, 10:12 PM
Or just creat a pull request on the git repo.

Kingly_Krab
03-14-2014, 10:14 PM
Or just creat a pull request on the git repo.
Or that, yes, but I have some custom code, so I'd like to do it manually.

Uleat
03-14-2014, 10:49 PM
You know you can create a diff in TortoiseGit by right-clicking the commit message and saving as unified patch?

You can even select a beginning and ending commit (ctrl-click) and create a range diff :)

Lord of Steel
03-15-2014, 12:07 AM
edit:posted bad code

Lord of Steel
03-15-2014, 12:36 AM
I don't know how to do Git Hub stuff and i don't know if the non special case stuff is correct. I only tested the per character based quest global max level.
here is my new method though. Code that i altered is in red

void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
_log(CLIENT__EXP, "Attempting to Set Exp for %s (XP: %u, AAXP: %u, Rez: %s)", this->GetCleanName(), set_exp, set_aaxp, isrezzexp ? "true" : "false");
//max_AAXP = GetEXPForLevel(52) - GetEXPForLevel(51); //GetEXPForLevel() doesn't depend on class/race, just level, so it shouldn't change between Clients
max_AAXP = RuleI(AA, ExpPerPoint); //this may be redundant since we're doing this in Client::FinishConnState2()
if (max_AAXP == 0 || GetEXPForLevel(GetLevel()) == 0xFFFFFFFF) {
Message(13, "Error in Client::SetEXP. EXP not set.");
return; // Must be invalid class/race
}


if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
if (isrezzexp)
this->Message_StringID(MT_Experience, REZ_REGAIN);
else{
if(this->IsGrouped())
this->Message_StringID(MT_Experience, GAIN_GROUPXP);
else if(IsRaidGrouped())
Message_StringID(MT_Experience, GAIN_RAIDEXP);
else
this->Message_StringID(MT_Experience, GAIN_XP);
}
}
else if((set_exp + set_aaxp) < (m_pp.exp+m_pp.expAA)){ //only loss message if you lose exp, no message if you gained/lost nothing.
Message(15, "You have lost experience.");
}

//check_level represents the level we should be when we have
//this ammount of exp (once these loops complete)
uint16 check_level = GetLevel()+1;
//see if we gained any levels
while (set_exp >= GetEXPForLevel(check_level)) {
check_level++;
if (check_level > 127) { //hard level cap
check_level = 127;
break;
}
if(GetMercID())
UpdateMercLevel();
}
//see if we lost any levels
while (set_exp < GetEXPForLevel(check_level-1)) {
check_level--;
if (check_level < 2) { //hard level minimum
check_level = 2;
break;
}
if(GetMercID())
UpdateMercLevel();
}
check_level--;


//see if we gained any AAs
if (set_aaxp >= max_AAXP) {
/*
Note: AA exp is stored differently than normal exp.
Exp points are only stored in m_pp.expAA until you
gain a full AA point, once you gain it, a point is
added to m_pp.aapoints and the ammount needed to gain
that point is subtracted from m_pp.expAA

then, once they spend an AA point, it is subtracted from
m_pp.aapoints. In theory it then goes into m_pp.aapoints_spent,
but im not sure if we have that in the right spot.
*/
//record how many points we have
uint32 last_unspentAA = m_pp.aapoints;

//figure out how many AA points we get from the exp were setting
m_pp.aapoints = set_aaxp / max_AAXP;
_log(CLIENT__EXP, "Calculating additional AA Points from AAXP for %s: %u / %u = %.1f points", this->GetCleanName(), set_aaxp, max_AAXP, (float)set_aaxp / (float)max_AAXP);

//get remainder exp points, set in PP below
set_aaxp = set_aaxp - (max_AAXP * m_pp.aapoints);

//add in how many points we had
m_pp.aapoints += last_unspentAA;
//set_aaxp = m_pp.expAA % max_AAXP;

//figure out how many points were actually gained
/*uint32 gained = m_pp.aapoints - last_unspentAA;*/ //unused

//Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA);
char val1[20]={0};
Message_StringID(MT_Experience, GAIN_ABILITY_POINT,ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
//Message(15, "You now have %d skill points available to spend.", m_pp.aapoints);
}

uint8 maxlevel = RuleI(Character, MaxExpLevel) + 1;

if(maxlevel <= 1)
maxlevel = RuleI(Character, MaxLevel) + 1;

if(check_level > maxlevel) {
check_level = maxlevel;

if(RuleB(Character, KeepLevelOverMax))
{
set_exp = GetEXPForLevel(GetLevel()+1);
}
else
{
set_exp = GetEXPForLevel(maxlevel);
}
}
if(GetLevel() == maxlevel){
uint32 expneeded = GetEXPForLevel(maxlevel+1);
if(set_exp >= expneeded)
{
set_exp = expneeded-100000;
}
}
if(RuleB(Character, PerCharacterQglobalMaxLevel)){
uint32 MaxLevel = GetCharMaxLevelFromQGlobal();
//maxlevel = MaxLevel;
if(MaxLevel)
{

if(GetLevel() == MaxLevel)
{
uint32 expneeded = GetEXPForLevel(MaxLevel+1);

if(set_exp >=expneeded)
{
set_exp = expneeded-100000;
}
}
if(check_level > MaxLevel)
{
check_level = MaxLevel;
if(RuleB(Character, KeepLevelOverMax))
{
set_exp = GetEXPForLevel(GetLevel()+1);
}
else
{
set_exp = GetEXPForLevel(maxlevel);
}
}
}
}

if ((GetLevel() != check_level) && !(check_level >= maxlevel)) {
char val1[20]={0};
if (GetLevel() == check_level-1){
Message_StringID(MT_Experience, GAIN_LEVEL,ConvertArray(check_level,val1));
SendLevelAppearance();
//Message(15, "You have gained a level! Welcome to level %i!", check_level);
}
if (GetLevel() == check_level){
Message_StringID(MT_Experience, LOSE_LEVEL,ConvertArray(check_level,val1));
//Message(15, "You lost a level! You are now level %i!", check_level);
}
else
Message(15, "Welcome to level %i!", check_level);
SetLevel(check_level);
}

//If were at max level then stop gaining experience if we make it to the cap


//set the client's EXP and AAEXP
m_pp.exp = set_exp;
m_pp.expAA = set_aaxp;

if (GetLevel() < 51) {
m_epp.perAA = 0; // turn off aa exp if they drop below 51
} else
SendAAStats(); //otherwise, send them an AA update

//send the expdata in any case so the xp bar isnt stuck after leveling
uint32 tmpxp1 = GetEXPForLevel(GetLevel()+1);
uint32 tmpxp2 = GetEXPForLevel(GetLevel());
// Quag: crash bug fix... Divide by zero when tmpxp1 and 2 equalled each other, most likely the error case from GetEXPForLevel() (invalid class, etc)
if (tmpxp1 != tmpxp2 && tmpxp1 != 0xFFFFFFFF && tmpxp2 != 0xFFFFFFFF) {
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ExpUpdate, sizeof(ExpUpdate_Struct));
ExpUpdate_Struct* eu = (ExpUpdate_Struct*)outapp->pBuffer;
float tmpxp = (float) ( (float) set_exp-tmpxp2 ) / ( (float) tmpxp1-tmpxp2 );
eu->exp = (uint32)(330.0f * tmpxp);
FastQueuePacket(&outapp);
}

if (admin>=100 && GetGM()) {
char val1[20]={0};
char val2[20]={0};
char val3[20]={0};
Message_StringID(MT_Experience, GM_GAINXP,ConvertArray(set_aaxp,val1),ConvertArray (set_exp,val2),ConvertArray(GetEXPForLevel(GetLeve l()+1),val3)); //[GM] You have gained %1 AXP and %2 EXP (%3).
//Message(15, "[GM] You now have %d / %d EXP and %d / %d AA exp.", set_exp, GetEXPForLevel(GetLevel()+1), set_aaxp, max_AAXP);
}
}

Drusillae
06-29-2016, 09:57 PM
I'm not sure what I'm doing really with these things but I managed to get a server up I'm running the UF expansion but I seem to be unable to level a character past 68 which is too low to try UF content what is wrong how do I change the maximum level I can get I looked at this post and have seen it seems to have a level max of 127 my exp file in zone folder looks the same as this. What can I do to fix It.

Maze_EQ
06-29-2016, 10:44 PM
Theres 2 fields in rules_values that you need to change. Default in Akkadius' DB is 68.

Drusillae
06-30-2016, 12:54 AM
As you said im using the Akkadius version of emulater but I still not sure how to change the script and what to then how would I get it to be implemented in the server. I changed script as follows although not sure It made a difference: this is in file 2361_Required_qs_rule_values.sql

-- New Rule Values --
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`) VALUES (1, 'QueryServ:MerchantLogTransactions', 'false');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`) VALUES (1, 'QueryServ:PlayerLogDeletes', 'false');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`) VALUES (1, 'QueryServ:PlayerLogHandins', 'false');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`) VALUES (1, 'QueryServ:PlayerLogMoves', 'false');
UPDATE `rule_values`,`85` SET notes = 'notation' WHERE rule_name = 'Character:MaxLevel';
UPDATE `rule_values`,`85` SET notes = 'Sets the Max Level attainable via Experience' WHERE rule_name = 'Character:MaxExpLevel';

BigBlueWizard
06-30-2016, 01:46 PM
You can do a query to change them, or if you aren't comfortable / experienced in the syntax for that, just open up Heidi that came with the server installation pack, login to your db, go to PEQ, find rules_values, and go to the data tab and scroll through until you find the Character:MaxLevel and Character:MaxExpLevel and simply click on them and change them to 85...
You'll need to do it for each rule set id though... for example, rule set 2 will have both charactermaxlevel and charactermaxexplevel and then rule set id number 10 will also have both that you need to change and so on and so forth.

Kingly_Krab
06-30-2016, 04:45 PM
This is the proper query syntax for updating them both to level 85.
UPDATE `rule_values` SET `rule_value` = '85' WHERE `rule_name` IN ('Character:MaxLevel', 'Character:MaxExpLevel');

Drusillae
06-30-2016, 07:17 PM
Ding 69!
Thank you everyone for all your help :)
I really didn't understand how to use the Heidi program: had to find password eqemu for root. Thank you.

DanCanDo
06-30-2016, 07:52 PM
The players can ding the max level but can not build EXP into it. They are stuck at zero.

Is there something else i need to configure?

When I first noticed that same scenario, long ago, I simply set the character
max level to 65 (on my home server) and set the max exp level to 66.
It fixed the problem for me.