#include "jw_exp_functions" void givexp(object oMob,object oPC) { //KillAndReplaceLootable(OBJECT_SELF, TRUE); float fCR; if (GetLocalInt(OBJECT_SELF,"is_clone")==TRUE) { fCR=IntToFloat(GetHitDice(oMob))-1; if (fCR<1.0) { fCR=1.0; } } else { fCR=GetChallengeRating(oMob); } // nNumber gives you the number of players in the party. No penalty for using summoned mobs // nHDcounter is the total HD of the party (players only) // nHighlevel is the level of the highest person in the party; int nNumber=0; int nHDcounter=0; int nHighlevel=1; int nHD; if (GetIsObjectValid(GetMaster(oPC))) { oPC=GetMaster(oPC); } if (!GetIsPC(oPC)) { oPC=GetTrapCreator(oPC); } if (!GetIsPC(oPC)) { return; } object oObject = GetFirstFactionMember(oPC, TRUE); while (GetIsObjectValid(oObject) == TRUE) { nHD=GetHitDice(oObject); nNumber++; nHDcounter=nHDcounter+nHD; if (nHD>nHighlevel) { nHighlevel=nHD; } oObject = GetNextFactionMember(oPC, TRUE); } // if the party has no members for some reason, return; if (nNumber==0) { return; } /// the average level of the party is the total HD divided by the number of people float fTotalHD=IntToFloat(nHDcounter); float fAvlevel=fTotalHD/nNumber; float fHighlevel=IntToFloat(nHighlevel); float fLevel; // the party level used to generate a level which xp is based on is fLevel. // This is the avererage party level plus the highest level in the party divided by two. // Eg if the average level is 5 but there is a level 10 in there, the party is // treated as being level 7.5. if (fHighlevel>fAvlevel) { fLevel=(fHighlevel+fAvlevel)/2; } else { fLevel=fAvlevel; } // fDifference is the party level we are using minus the challenge rating of the creature. // so a level 7 mob killed by a level 9 group will have an fDifference of two. // This indicates that the mob was a fairly easy challenge. float fDifference=fLevel-fCR; int nDifference=FloatToInt(fDifference); // if the difference was more than 11, nobody gets anything. if (nDifference>11) { oObject = GetFirstFactionMember(oPC, TRUE); while (GetIsObjectValid(oObject) == TRUE) { SendMessageToPC(oObject,"Your party gains no experience from defeating "+GetName(oMob)); oObject = GetNextFactionMember(oPC, TRUE); return; } } // This calls the function at the top to check out how much the xp reward should // be modified, based on fDifference. If fDifference is a positive number, then the // modifier is less than one. // For example, if the difference is four then the party will only get 0.3 experience // for every one point of experience they could have earned if they were the same // level as this mob. // However if they are of a lower level than the mob, they get extra xp. // It is worth fighting mobs of a higher level than yourself. float fModifier = getmodifier(nDifference); // The basic xp of any mob is it's challenge rating times 5.5. Ie first level mob gives 5.5 // second gives 11, 20th gives 110. // A mob which is challenge rating 1/2 or 1/8 (such as kobolds level one and two // or much of crypts level one) gives 5.0. float fBasicxp; if (fCR>=1.0) { fBasicxp=fCR*4.7; } else { fBasicxp=4.3; } // The exp will be shared out among the party. However the total xp pool // is increased if the players are in a party. This is to lessen the bonus given // to people who solo. // A party of two will each get 80 per cent as much xp as either of them would have got for // killing the mob solo. // A party of 3 will each get 73 per cent of the exp which // any of them would have got for killing the mob solo. // solo. A party of six each gets 0.50 per cent of the exp they would have got if // they had killed the mob solo. // This means there is a great advantage to being in a party, as you can kill more mobs // yet still get good exp. // These figures ignore the adjustments from the levels of the players in the party. // if more than four people are in the party, any future people do not add to the bonus. float fPartybonus=1.0; if (nNumber>1) { fPartybonus=(IntToFloat(nNumber)); fPartybonus=fPartybonus-1.0; if (fPartybonus>4.0) { fPartybonus=4.0; } fPartybonus=fPartybonus*0.4; fPartybonus=fPartybonus+1.0; } // the xp to be shared between the party is the xp the mob is worth (challenge rating times 4) // times the modifer for the level difference (up or down depending on mob CR compared to party level) // times any party modifier (up if the players are in a party) float fPartyxp=fBasicxp*fModifier*fPartybonus; // DEBUG //SendMessageToAllDMs("fPartyxp "+FloatToString(fPartyxp)+" =fBasicxp "+FloatToString(fBasicxp)+" *fModifier "+FloatToString(fModifier)+ "*fPartybonus; "+FloatToString(fPartybonus)); // The xp for each player is then the partyxp divided by all the players (summoned // creatures have no effect on this) float fPlayerxp=fPartyxp/(IntToFloat(nNumber)); int nPlayerxp=FloatToInt(fPlayerxp); // however we also want to make sure no players get more xp in a group // than they would have done solo. This could happen if a high level char // adventures with low level chars. // no PC can ever get more exp than the strongest member of the faction could have got // if they fought the mob solo float fTestxp; fDifference=fHighlevel-fCR; nDifference=FloatToInt(fDifference); fTestxp=fBasicxp*getmodifier(nDifference); if (fPlayerxp>fTestxp) { fPlayerxp=fTestxp; nPlayerxp=FloatToInt(fTestxp); } // fPlaydifference is going to be the difference between each PCs level and the highest level // in the party float fPlaydifference; nHighlevel=FloatToInt(fHighlevel); int nPlaylevel; int nXPtogive; float fMaxxp; int nMaxxp; oObject = GetFirstFactionMember(oPC, TRUE); while (GetIsObjectValid(oObject) == TRUE) { // nDifference now is the level of each PC as we go through them in turn // fTestxp is simply what they would have got if they killed the mob solo nPlaylevel=GetHitDice(oObject); nDifference=FloatToInt(IntToFloat(nPlaylevel)-fCR); fTestxp=fPlayerxp; // Work out the max xp a player of that level is allowed to get // This is the xp they would have got for killing something 3 levels above themselves alone fMaxxp=(fBasicxp*(IntToFloat(nPlaylevel)+2.0)); nMaxxp=FloatToInt(fMaxxp); // fTestxp is equal to the XP each player will get if no modifications are needed. // if the difference between the individual character and the mob is more than // six, he gets no XP even if the party does. // This system does leave open the possibility of high level chars helping // low level chars. This is possibly open to abuse but is a deliberate // feature to allow friends to adventure together even if they are of different // levels. if (GetArea(oPC)!=GetArea(oObject)) { } else if (nDifference>11) { SendMessageToPC(oObject,"You cannot gain much experience for defeating "+GetName(oMob)); } else // otherwise, they get the exp we calculated above as long as they are not dead. if (GetCurrentHitPoints(oObject)>=1) { nXPtogive=nPlayerxp; //if (nXPtogive<1) // { // nXPtogive=1; // } // If the character is travelling in a higher level party, they get a penalty if (nPlaylevel<(FloatToInt(fLevel)-8)) { nDifference=FloatToInt(fLevel)-nPlaylevel-8; fPlaydifference=getmodifier(nDifference); fTestxp=fPlayerxp*fPlaydifference; nXPtogive=FloatToInt(fPlayerxp*fPlaydifference); } /* The server seems to be doing this on its own now if (Multipen(oObject)) { nXPtogive=FloatToInt(fTestxp*0.8); SendMessageToPC(oObject,"Multiclass xp penalty affects you"); } */ if (nXPtogive>nMaxxp) { nXPtogive=nMaxxp; } // Now we give a bonus to lowbies if (nPlaylevel<=3) { nXPtogive=nXPtogive*(5-nPlaylevel); } if (nXPtogive<2) { nXPtogive=2; } if (GetIsObjectValid(GetItemPossessedBy(oObject,"jw_exp_book"))) { SendMessageToPC(oObject,"The Scholar's Tome in your inventory ensures you do not gain experience"); } else if ((PCHasExpToLevel(oObject)==TRUE)&&(nPlaylevel<=3)) { SendMessageToPC(oObject,"You cannot gain any more experience this way until you train to your next level."); } else { SendMessageToPC(oObject,"You gain "+IntToString(nXPtogive)+" experience for defeating "+GetName(oMob)); GiveXPToCreature(oObject,nXPtogive); } } oObject = GetNextFactionMember(oPC, TRUE); } }