Adding support for EXP items

Submit code for osProse project.

Moderators: osRose dev team, ospRose dev team, osiRose dev team, Moderators

Adding support for EXP items

Postby PurpleYouko on Fri May 30, 2008 3:45 pm

here is the code you need to be able to support EXP rate items in your server.
This will be included in the SVN at some point once we are settled into our new project properly and once Drakia and i get the darn skills working properly.
In the mean time, if you want to add this support to osirose or osprose servers (osrose is slightly different + Lmame has already coded it for rev 81) then here it is.

It is pretty basic code but it is spread all over the server so follow carefully.
Some parts are optional but they will be included in a second post.

in chartypes.h, find
  1. unsigned int MaxSummonGauge;
  2.     unsigned int MPReduction;
  3.     unsigned int ExtraDamage;

after, add

This adds a personal xprate multiplier value to your player->stats structure.

in Character.h, find
  1. virtual unsigned int GetDefense( );

after, add
  1. virtual unsigned int GetXPRate( );


in charstats.cpp, find
  1. // virtual [return defense]
  2. unsigned int CCharacter::GetDefense( )
  3. {
  4.     return 0;
  5. }

after, add
  1. // virtual [return xprate]
  2. unsigned int CCharacter::GetXPRate( )
  3. {
  4.     return 0;        
  5. }


in WorldMonster.h, find
  1. unsigned int GetDefense( );

after, add
  1. unsigned int GetXPRate( );


in monsterstats.cpp, find
  1. unsigned int CMonster::GetCritical( )
  2. {
  3.     return 60;  //60 = 20% of 300 our critical probability
  4. }

after, add
  1. unsigned int CMonster::GetXPRate( )
  2. {
  3.     return 0;        
  4. }

Why does a monster need xprate?
it doesn't but the monster and character classes are intricately interwoven and the server will not compile properly unless you add it.

still in monsterstats.cpp, find
  1. Stats->Defense = GetDefense( );

after, add
  1. Stats->xprate = GetXPRate( );


in player.h, find
  1. unsigned int GetDefense( );

after, add
  1. unsigned int GetXPRate( );


in Playerdata.cpp, find
  1. Clan->clanid = atoi(row[26]);
  2.     Clan->clanrank = atoi(row[27]);
  3.     Position->saved = atoi(row[28]);

after, add
  1. Stats->xprate = GetXPRate();


in playerstats.cpp
add this function anywhere you like.
You might as well put it after the one that returns defence just to keep it neat.
  1. // Return XPRate
  2. unsigned int CPlayer::GetXPRate( )
  3. {
  4.     UINT XPRate = 0;
  5.     for(UINT i=1;i<12;i++)
  6.     {
  7.         if( items[i].count != 0 )
  8.         {
  9.             if(items[i].itemtype>9)
  10.             {
  11.                 Log(MSG_WARNING, "Char %s have equip invalid item: %i,%i", CharInfo->charname, items[i].itemtype, items[i].itemnum );
  12.                 continue;
  13.             }            
  14.             if( GServer->EquipList[items[i].itemtype].Index[items[i].itemnum]->stat1[0] == XP_RATE)
  15.             {
  16.                 XPRate += GServer->EquipList[items[i].itemtype].Index[items[i].itemnum]->stat1[1];
  17.                 //Log( MSG_INFO, "XP rate item detected basic stat = %i item number %i", GServer->EquipList[items[i].itemtype].Index[items[i].itemnum]->stat1[1],items[i].itemnum);
  18.                
  19.             }
  20.             if( GServer->EquipList[items[i].itemtype].Index[items[i].itemnum]->stat2[0] == XP_RATE)
  21.             {
  22.                 XPRate += GServer->EquipList[items[i].itemtype].Index[items[i].itemnum]->stat2[1];
  23.                 //Log( MSG_INFO, "XP rate item detected basic stat = %i item number %i", GServer->EquipList[items[i].itemtype].Index[items[i].itemnum]->stat1[2],items[i].itemnum);
  24.                    
  25.             }
  26.             if(items[i].stats>0 && items[i].stats<500)
  27.             {
  28.                 if(GServer->StatsList[items[i].stats].stat[0] == XP_RATE)
  29.                 {
  30.                     XPRate += GServer->StatsList[items[i].stats].value[0];
  31.                     //Log( MSG_INFO, "XP rate item detected. extra stat = %i item number %i", GServer->StatsList[items[i].stats].value[0],items[i].itemnum);
  32.                        
  33.                 }
  34.                 if(GServer->StatsList[items[i].stats].stat[1] == XP_RATE)
  35.                 {
  36.                     XPRate += GServer->StatsList[items[i].stats].value[1];
  37.                     //Log( MSG_INFO, "XP rate item detected. extra stat = %i item number %i", GServer->StatsList[items[i].stats].value[1],items[i].itemnum);
  38.                    
  39.                 }
  40.             }            
  41.         }
  42.     }
  43.     //Log( MSG_INFO, "XP rate rate calculated as = %i", XPRate);
  44.     if(XPRate < 1)
  45.         XPRate=1;
  46.     return XPRate;        
  47. }

 
still in playerstats.cpp, find
  1. Stats->Defense = GetDefense( );

after, add
  1. Stats->xprate = GetXPRate( );

 
in worldprocesses.cpp, find
  1. thisclient->CharInfo->Exp +=  GetColorExp( thisclient->Stats->Level, thismon->thisnpc->level, exp )

The entire line may be slightly different. i don't have an unmodified version to check against. Either way it should be easy enough to find it.
replace line with
  1. thisclient->CharInfo->Exp +=  GetColorExp( thisclient->Stats->Level, thismon->thisnpc->level, exp ) * thisclient->Stats->xprate;

 
in the same function, find
  1. partyclient->CharInfo->Exp +=  GetColorExp( partyclient->Stats->Level, thismon->Stats->Level, (UINT)round(thisparty->exp / thisparty->num) )

Again this may be slightly different but easy to find.
replace line with
  1. partyclient->CharInfo->Exp +=  GetColorExp( partyclient->Stats->Level, thismon->Stats->Level, (UINT)round(thisparty->exp / thisparty->num) ) * partyclient->Stats->xprate;

 
same function, about 3 lines after teh last change, find
  1. partyclient->CharInfo->Exp +=  GetColorExp( partyclient->Stats->Level, thismon->Stats->Level, (UINT)round(partyclient->Stats->Level * thisparty->exp / thisparty->maxlevel) )

replace line with
  1. partyclient->CharInfo->Exp +=  GetColorExp( partyclient->Stats->Level, thismon->Stats->Level, (UINT)round(partyclient->Stats->Level * thisparty->exp / thisparty->maxlevel) ) * partyclient->Stats->xprate;

 
and finally a little addition to datatypes.h so that the function in playerstats knows what value to look far.
find

after, add


That should be all you need to be able to read back the XP rate of items such as hero medals and so on.
Last edited by PurpleYouko on Fri May 30, 2008 3:54 pm, edited 1 time in total.
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4698
Joined: Fri Aug 10, 2007 2:05 pm

Re: Adding support for EXP items

Postby PurpleYouko on Fri May 30, 2008 3:53 pm

The optional stuff now.
This isn't strictly necessary to make the xprate mod work but may be useful to debug it if it doesn't.
It also adds a log of useful readbacks to your server under a new custom command structure.

somewhere in gmcmds.cpp, pakGMCommand( CPlayer* thisclient, CPacket* P ) function, add this conditional.
Doesn't matter where as long as it follows the common structure of the function
  1.  
  2. else if(strcmp(command, "mystat")==0)
  3.     {
  4.          if ((tmp = strtok(NULL, " "))==NULL)return true;
  5.          if(strcmp(tmp, "ap")==0)
  6.          {
  7.              char buffer2[200];
  8.              sprintf ( buffer2, "My Attack Power is %i", thisclient->Stats->Attack_Power );
  9.              SendPM(thisclient, buffer2);
  10.          }
  11.          else if(strcmp(tmp, "acc")==0)
  12.          {
  13.              char buffer2[200];
  14.              sprintf ( buffer2, "My Accuracy is %i", thisclient->Stats->Accury );
  15.              SendPM(thisclient, buffer2);
  16.          }
  17.          else if(strcmp(tmp, "hp")==0)
  18.          {
  19.              char buffer2[200];
  20.              sprintf ( buffer2, "My current HP is %i", thisclient->Stats->HP );
  21.              SendPM(thisclient, buffer2);
  22.          }
  23.          else if(strcmp(tmp, "mp")==0)
  24.          {
  25.              char buffer2[200];
  26.              sprintf ( buffer2, "My current MP is %i", thisclient->Stats->MP );
  27.              SendPM(thisclient, buffer2);
  28.          }
  29.          else if(strcmp(tmp, "maxhp")==0)
  30.          {
  31.              char buffer2[200];
  32.              sprintf ( buffer2, "My Maximum HP is %i", thisclient->GetMaxHP());
  33.              SendPM(thisclient, buffer2);
  34.          }
  35.          else if(strcmp(tmp, "maxmp")==0)
  36.          {
  37.              char buffer2[200];
  38.              sprintf ( buffer2, "My maximum MP is %i", thisclient->GetMaxMP());
  39.              SendPM(thisclient, buffer2);
  40.          }
  41.          else if(strcmp(tmp, "dodge")==0)
  42.          {
  43.              char buffer2[200];
  44.              sprintf ( buffer2, "My dodge is %i", thisclient->Stats->Dodge);
  45.              SendPM(thisclient, buffer2);  
  46.          }
  47.          else if(strcmp(tmp, "def")==0)
  48.          {
  49.              char buffer2[200];
  50.              sprintf ( buffer2, "My defense is %i", thisclient->Stats->Defense);
  51.              SendPM(thisclient, buffer2);  
  52.          }
  53.          else if(strcmp(tmp, "mdef")==0)
  54.          {
  55.              char buffer2[200];
  56.              sprintf ( buffer2, "My Magic defense is %i", thisclient->Stats->Magic_Defense);
  57.              SendPM(thisclient, buffer2);  
  58.          }
  59.          else if(strcmp(tmp, "crit")==0)
  60.          {
  61.              char buffer2[200];
  62.              sprintf ( buffer2, "My critical is %i", thisclient->Stats->Critical);
  63.              SendPM(thisclient, buffer2);  
  64.          }
  65.          else if(strcmp(tmp, "mspd")==0)
  66.          {
  67.              char buffer2[200];
  68.              sprintf ( buffer2, "My move speed is %i", thisclient->Stats->Move_Speed);
  69.              SendPM(thisclient, buffer2);  
  70.          }
  71.          else if(strcmp(tmp, "aspd")==0)
  72.          {
  73.              char buffer2[200];
  74.              sprintf ( buffer2, "My attack speed is %i", thisclient->Stats->Attack_Speed);
  75.              SendPM(thisclient, buffer2);  
  76.          }
  77.          else if(strcmp(tmp, "xprate")==0)
  78.          {
  79.              char buffer2[200];
  80.              sprintf ( buffer2, "My xp rate is %i", thisclient->Stats->xprate);
  81.              SendPM(thisclient, buffer2);    
  82.          }
  83.     }

This will add all kinds of feedback so that you can easily compare stats from server side to client side.
use this structure /mystat xprate to read back your current server side XPrate
or /mystat mspd to find out what the server currently calculates your move speed to be.

If you add this without adding the xprate mod in the previous post then you will need to comment out or remove this section
  1. else if(strcmp(tmp, "xprate")==0)
  2.          {
  3.              char buffer2[200];
  4.              sprintf ( buffer2, "My xp rate is %i", thisclient->Stats->xprate);
  5.              SendPM(thisclient, buffer2);    
  6.          }

otherwise you will get compile errors.
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4698
Joined: Fri Aug 10, 2007 2:05 pm


Return to Submit Code

Who is online

Users browsing this forum: No registered users and 6 guests