
Originally Posted by
gustavobm
@
KarLi you were right about exp boost... Is there a way to know the formula for party exp?
'Cause I know that there's "exp settings" for
2 Players in party, 3, 4, 5 and boost for 3, 4 and 5 players, but how to do the math?
I've found this in a post from another member:
Code:
[PartyExp]
NormalParty2Exp = 160
NormalParty3Exp = 180
NormalParty4Exp = 200
NormalParty5Exp = 220
SetParty3Exp = 230
SetParty4Exp = 270
SetParty5Exp = 300
This numbers are the %
Ex:
NormalParty2Exp = 160; 160/2=80% for each party member
With this example, will be 80% of what? Server Exp? NormalParty2Exp?
Thanks in advance again!
80% of the exp obtained from every mob killed goes to each player of the party the same goes for the other formulas, also i think that you might find something related to this in the function gObjExpParty, honestly i couldn't find any other importnat function related to this.
Code:
void __cdecl gObjExpParty(OBJECTSTRUCT *lpObj, OBJECTSTRUCT *lpTargetObj, int AttackDamage, int MSBFlag)
{
int v4; // eax@86
int v5; // [sp+50h] [bp-6Ch]@73
int v6; // [sp+58h] [bp-64h]@13
signed int v7; // [sp+5Ch] [bp-60h]@2
unsigned __int32 *mymaxexp; // [sp+60h] [bp-5Ch]@72
int toplevel; // [sp+64h] [bp-58h]@6
OBJECTSTRUCT *lpPartyObj; // [sp+68h] [bp-54h]@22
OBJECTSTRUCT *lpPartyObja; // [sp+68h] [bp-54h]@70
char bCheckSetParty[5]; // [sp+6Ch] [bp-50h]@17
int bApplaySetParty; // [sp+74h] [bp-48h]@6
int viewpercent; // [sp+78h] [bp-44h]@6
int viewplayer; // [sp+7Ch] [bp-40h]@6
int dis[5]; // [sp+80h] [bp-3Ch]@21
int partycount; // [sp+94h] [bp-28h]@17
int partylevel; // [sp+98h] [bp-24h]@50
int totallevel; // [sp+9Ch] [bp-20h]@6
int partynum; // [sp+A0h] [bp-1Ch]@6
int number; // [sp+A4h] [bp-18h]@8
int level; // [sp+A8h] [bp-14h]@6
int totalexp; // [sp+ACh] [bp-10h]@62
int maxexp; // [sp+B0h] [bp-Ch]@6
int exp; // [sp+B4h] [bp-8h]@72
int n; // [sp+B8h] [bp-4h]@6
if ( lpObj->MapNumber == 9 )
v7 = 1;
else
v7 = lpObj->MapNumber == 32;
if ( v7 )
{
CDevilSquare::gObjExpParty(&g_DevilSquare, lpObj, lpTargetObj, AttackDamage, MSBFlag);
}
else
{
maxexp = 0;
level = lpTargetObj->Level * (lpTargetObj->Level + 25) / 3;
partynum = 0;
totallevel = 0;
viewplayer = 0;
viewpercent = 100;
bApplaySetParty = 0;
partynum = lpObj->PartyNumber;
toplevel = 0;
for ( n = 0; n < 5; ++n )
{
number = gParty.m_PartyS[partynum].Number[n];
if ( number >= 0 && *(&gObj.Level + 3252 * number) > toplevel )
toplevel = *(&gObj.Level + 3252 * number);
}
if ( partynum >= 0 )
v6 = partynum <= 7399;
else
v6 = 0;
if ( v6 )
{
memset(bCheckSetParty, 0, 5u);
partycount = gParty.m_PartyS[partynum].Count;
for ( n = 0; n < 5; ++n )
{
number = gParty.m_PartyS[partynum].Number[n];
if ( number >= 0 && lpTargetObj->MapNumber == *(&gObj.MapNumber + 6504 * number) )
{
dis[n] = gObjCalDistance(lpTargetObj, &gObj + number);
if ( dis[n] < 10 )
{
lpPartyObj = &gObj + number;
if ( toplevel < *(&gObj.Level + 3252 * number) + 200 )
totallevel += lpPartyObj->Level;
else
totallevel += lpPartyObj->Level + 200;
++viewplayer;
bCheckSetParty[lpPartyObj->Class] = 1;
}
}
}
if ( bCheckSetParty[0] && bCheckSetParty[1] && bCheckSetParty[2] )
bApplaySetParty = 1;
if ( viewplayer <= 1 )
{
partylevel = totallevel;
}
else
{
if ( bApplaySetParty )
{
if ( viewplayer == 3 )
{
viewpercent = 230;
}
else if ( viewplayer == 4 )
{
viewpercent = 270;
}
else if ( viewplayer < 5 )
{
viewpercent = 120;
}
else
{
viewpercent = 300;
}
}
else
{
switch ( viewplayer )
{
case 2:
viewpercent = 160;
break;
case 3:
viewpercent = 180;
break;
case 4:
viewpercent = 200;
break;
default:
if ( viewplayer < 5 )
viewpercent = 150;
else
viewpercent = 220;
break;
}
}
partylevel = totallevel / viewplayer;
}
if ( lpTargetObj->Level + 10 < partylevel )
level = level * (lpTargetObj->Level + 10) / partylevel;
if ( lpTargetObj->Level >= 65 )
{
if ( viewplayer == 1 )
level += lpTargetObj->Level / 4 * (lpTargetObj->Level - 64);
else
level = (signed __int64)((double)level + 200.0 - (double)lpObj->Level * 0.2);
}
if ( level <= 0 )
level = 0;
else
maxexp = level / 2;
if ( maxexp >= 1 )
totalexp = rand() % maxexp + level;
else
totalexp = level;
if ( lpTargetObj->Type == 2 )
lpTargetObj->Money = totalexp;
for ( n = 0; n < 5; ++n )
{
number = gParty.m_PartyS[partynum].Number[n];
if ( number >= 0 )
{
lpPartyObja = &gObj + number;
if ( lpTargetObj->MapNumber == *(&gObj.MapNumber + 6504 * number) && dis[n] < 10 )
{
mymaxexp = (&gLevelExperience)[lpPartyObja->Level];
exp = lpPartyObja->Level * viewpercent * totalexp / totallevel / 100;
if ( lpPartyObja->MapNumber >= 11 )
v5 = lpPartyObja->MapNumber <= 17;
else
v5 = 0;
if ( v5 )
exp = 50 * exp / 100;
if ( exp > (unsigned int)mymaxexp )
exp = (int)mymaxexp;
if ( lpPartyObja->Type == 1 && lpTargetObj->Type == 1 )
exp = 0;
exp = (signed __int64)((double)exp * gAddExperience);
if ( (signed int)lpPartyObja->m_wExprienceRate > 0 )
exp = (signed __int64)((double)exp * ((double)lpPartyObja->m_wExprienceRate / 100.0));
if ( CCrywolfSync::GetOccupationState(&g_CrywolfSync) == 1 && g_iCrywolfApplyMvpPenalty )
{
v4 = CCrywolfSync::GetGettingExpPenaltyRate(&g_CrywolfSync);
exp = exp * v4 / 100;
}
if ( exp <= 0 || lpPartyObja->Type != 1 )
goto LABEL_98;
if ( (signed int)lpPartyObja->m_wExprienceRate > 0 )
lpPartyObja->Experience += exp;
if ( gObjLevelUp(lpPartyObja, exp, lpTargetObj->Class, 1) )
{
LABEL_98:
if ( lpPartyObja->Type == 1 && (signed int)lpPartyObja->m_wExprienceRate > 0 )
GCKillPlayerExpSend(lpPartyObja->m_Index, lpTargetObj->m_Index, exp, AttackDamage, MSBFlag);
}
}
}
}
}
else
{
LogAdd(
"error : %s %d",
"D:\\Works\\Mu-Studio\\GameServer_Backup\\1.00.18_ÃÏ+_¦+¦ð+»Àß+¡_+++Õ++¦·+ʢæ÷¦Î+÷-ñ\\Source\\user.cpp",
`gObjExpParty'::`2'::__LINE__Var + 66);
}
}
}