After a question once came up on how to do it I tried it myself and I'm actually using this system myself.
Basically what this system does: Pet EXP no longer goes up automatically but instead the player has to kill mobs for pet exp. There's a lot of customization which can be done to change how much exp the pet gets. You can find it in the comments.
if( HasBuff( BUFF_ITEM, II_SYS_SYS_SCR_PET_TONIC_A )
|| HasBuff( BUFF_ITEM, II_SYS_SYS_SCR_PET_TONIC_B )
#ifdef __SYS_PETLEVELING_MOBKILL
|| HasBuff(BUFF_ITEM, II_SYS_SYS_SCR_PETTONIC_C) // This part requires having the pet tonics added to the game
|| HasBuff(BUFF_ITEM, II_SYS_SYS_SCR_PETTONIC_D) // This part requires having the pet tonics added to the game
#endif
) // 펫 전용 영양제(A) // 펫 전용 영양제(B) 사용시 기력 감소 없음.
return;
In
PHP Code:
CMover::ProcessPetExp
Add
PHP Code:
#ifdef __SYS_PETLEVELING_MOBKILL
return;
#endif
right at the start.
Before
PHP Code:
#endif // __WORLDSERVER
#ifdef __CLIENT
void CMover::CreatePetSfx( void )
Add
PHP Code:
#ifdef __SYS_PETLEVELING_MOBKILL
void CMover::AddPetExpOnKill(DWORD dwMonsterRank, int nMonsterLevel, int nLevel)
{
// Initialize Base Values
float nMulti = 1.0f; //Multiplicator for EXP
float nBaseExp = PET_BASE_EXP; // Base EXP (set in VersionCommon.h)
BOOL bInDungeon = FALSE;
// Switch depending on monster rank
switch (dwMonsterRank)
{
case RANK_SUPER:
nBaseExp = 5000.0f; // Bosses always grant 5% of Pet EXP (10% Egg Exp)
break;
case RANK_BOSS:
nMulti *= 1.25f; // Giants grant 25% more
break;
case RANK_LOW:
case RANK_NORMAL:
case RANK_CAPTAIN:
nMulti *= 1.0f;
break;
}
// Calculating level difference.
if (nLevel - 10 > nMonsterLevel)
nBaseExp = 0; // When the monster is 10 levels below your own level, you get no Pet EXP
if (nMonsterLevel - 10 > nLevel)
nMulti *= 1.2; // When the monster is more than 10 levels above your own level, Pet EXP is increased by 20%
// Check if user is in a dungeon
DWORD UserWorldID = GetWorld()->m_dwWorldID;
if (UserWorldID >= 121 && UserWorldID <= 150)
{
if (dwMonsterRank != RANK_SUPER)
nMulti *= 1.25f; // You will get 25% more EXP when killing monsters in a dungeon (Does not count for bosses)
bInDungeon = TRUE; // Set Dungeon Mode to TRUE
}
if (bInDungeon == TRUE ) // Check if the user is in a dungeon
{
if (CParty* pParty = g_PartyMng.GetParty(this->m_idparty)) // Get User's party
{
for (int i = 0; i < pParty->m_nSizeofMember; ++i) // Cycle through every party member
{
CMover *pMember = (CMover*)g_UserMng.GetUserByPlayerID(pParty->m_aMember[i].m_uPlayerId);
if (IsValidObj(pMember)) // Check if party member is a valid obj
{
// Need to check if the member as a pet active and is in the same world
if (pMember->HasActivatedSystemPet() && pMember->GetWorld()->m_dwWorldID == UserWorldID)
{
float nTempMulti = nMulti;
// Check if user has any buff items up
if (pMember->HasBuff(BUFF_ITEM, II_SYS_SYS_SCR_PETTONIC_C))
nTempMulti += 0.25f;
if (pMember->HasBuff(BUFF_ITEM, II_SYS_SYS_SCR_PETTONIC_D))
nTempMulti += 0.5f;
// Get Partymember's Pet
CPet* pPartyPet = pMember->GetPet();
if (pPartyPet)
{
// Get Partymember's Pet Level
BYTE PetLevel = pPartyPet->GetLevel();
// Change Experience gained depending on level
switch (PetLevel)
{
case PL_EGG:
case PL_D:
{
nBaseExp *= 12.5;
}
break;
case PL_C:
{
nBaseExp *= 7;
}
break;
case PL_B:
{
nBaseExp *= 3.5;
}
break;
case PL_A:
{
nBaseExp *= 1;
}
break;
case PL_S:
{
nBaseExp = 0;
}
break;
}
//////////////// AUTOMATED EGG UP ////////////////////
// Check to see if pet's exp is over the limit
if (dwExp > MAX_PET_EXP)
{
dwExp = MAX_PET_EXP;
if (PetLevel != PL_S)
((CUser*)pMember)->AddText("Your pet is ready for leveling up. Bring it to the pet tamer!"); // Let the user know his pet is ready
}
if (!bHatched)
{
pPartyPet->SetExp(dwExp);
((CUser*)pMember)->AddPetSetExp(dwExp);
}
}
}
}
}
}
} else {
// Check if user has active pet
if (!HasActivatedSystemPet())
return;
// Get User Pet
CPet* pPet = this->GetPet();
// Get User Pet Level
if (pPet)
{
BYTE PetLevel = pPet->GetLevel();
// Change Base EXP according to Pet Level
switch (PetLevel)
{
case PL_EGG:
case PL_D:
{
nBaseExp *= 12.5;
}
break;
case PL_C:
{
nBaseExp *= 7;
}
break;
case PL_B:
{
nBaseExp *= 3.5;
}
break;
case PL_A:
{
nBaseExp *= 1;
}
break;
case PL_S:
{
nBaseExp = 0;
}
break;
}
// Check if user has any buff items up
if (HasBuff(BUFF_ITEM, II_SYS_SYS_SCR_PETTONIC_C))
nMulti += 0.25f;
if (HasBuff(BUFF_ITEM, II_SYS_SYS_SCR_PETTONIC_D))
nMulti += 0.5f;
//////////////// AUTOMATED EGG UP ////////////////////
// Check to see if pet's exp is over the limit
if (dwExp > MAX_PET_EXP)
{
dwExp = MAX_PET_EXP;
if (PetLevel != PL_S)
((CUser*)this)->AddText("Your pet is ready for leveling up. Bring it to the pet tamer!"); // Let the user know his pet is ready
}
// Set the Pet's exp (if it wasnt an egg before)
if (!bHatched)
{
pPet->SetExp(dwExp);
((CUser*)this)->AddPetSetExp(dwExp);
}
}
}
#ifdef __SYS_PETLEVELING_MOBKILL
if (pPet->GetLevel() == PL_EGG)
{
pUser->AddText("You can not level eggs with pet feed here. Go kill some monsters!");
return;
}
#endif
You can add the Tonics yourself, just create items with the following Item Kinds: IK1_SYSTEM IK2_SYSTEM IK3_SCROLL
Explanation on modifiers:
In the VersionCommon.h the Base EXP for the pet is defined. It is 25.0f is 0.025% Pet EXP.
Increase this on your behalf, since there are many multiplicators you can change in the Mover.cpp
Just go to the function AddPetExpOnKill and take a look at the values there.
Currently it is set to 5% Pet EXP for a boss kill, x1.2 EXP for a giant kill, x1.2 EXP if the monster is 10 or more levels above the player, x1.25 EXP for dungeon mobs, +25% for the weak Pet Tonics and +50% for the strong Tonic.
All fine and dandy, where you can really make exp explode is what comes next: Differentiating pet levels. Currently Eggs and D-Level get 12.5x Base-EXP, C-Level gets 7x, B-Level 3.5x and A-Level gets base-exp.
Please note that the values for the base-exp can be changed indiviually depending on if the player is in a dungeon or not.
Do whatever you want with this. As always, feedback on how to improve the code is welcome.
I bet there are some flaws or possible optimizations, I'd be glad to hear them.
Sorry for the necro, updated a bug in AttackArbiter.cpp
What did you change? I already had your code implemented, and it's exactly the same. The only thing you changed is where to add the code (before, after). But that's the same spot..
What did you change? I already had your code implemented, and it's exactly the same. The only thing you changed is where to add the code (before, after). But that's the same spot..
In the original release, the AddPetExpOnKill was added in OnDiedPVP, rather than OnDied in AttackArbiter.cpp
In the original release, the AddPetExpOnKill was added in OnDiedPVP, rather than OnDied in AttackArbiter.cpp
Ahh... Now I understand. I already had it added on OnDied, instead of OnDiedPVP, because they have the same code you told me to search for in your original post.
Maybe add: search for "void CAttackArbiter::OnDied()" at the AttackArbiter.cpp part.