I've quickly thrown together an XP giving script based on BioWare's model that extends XP gain to all involved parties. The only major change I made was to consider all characters as possessing the highest HD in the party.
// Gets the Hit Dice based on XP for player characters
int GetTrueHD(object oCreature)
{
int nHD;
if (GetIsPossessedFamiliar(oCreature) || GetIsDMPossessed(oCreature) ||
(!GetIsPC(oCreature) && !GetIsPossessedFamiliar(GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oCreature))))
return GetHitDice(oCreature);
else
return FloatToInt(sqrt(GetXP(oCreature)/500.0 + 0.25) + 0.5);
}
//Checks to see if there was hostility from the creature's faction
int GetIsInHostileParty(object oHostile, object oTarget = OBJECT_SELF)
{
object oHostilePartyMember;
int nNumInvolved = GetLocalInt(oTarget, "nNumEnemies");
int nNum;
for(nNum = 1; nNum <= nNumInvolved; nNum ++)
{
if(GetFactionEqual(oHostile, GetLocalObject(oTarget, "nEnemy" + IntToString(nNum))))
return TRUE;
}
return FALSE;
}
//Gets the slider setting as a module variable
//The actual slider value cannot be returned by a standard command
float GetXPSliderSetting()
{
return GetLocalFloat(GetModule(), "XP_SLIDER_SETTING");
}
//Gets the Party Size Penalty
float GetPartySizePenalty(int nPartySize)
{
return 4.0/(3 + nPartySize);
}
void main()
{
object oArea = GetArea(OBJECT_SELF);
object oInvolved = GetLastKiller();
object oPC, oFactionMember;
int nNum, nHD;
int nPartySize = 0;
float fXP;
int nHDMax = 0;
int nCR = FloatToInt(GetChallengeRating(OBJECT_SELF));
if(nCR > 40)
nCR = 40;
int nNumInvolved = GetLocalInt(OBJECT_SELF, "nNumEnemies");
if(!GetIsInHostileParty(oInvolved))
{
nNumInvolved++;
SetLocalObject(OBJECT_SELF, "nEnemy" + IntToString(nNumInvolved), oInvolved);
SetLocalInt(OBJECT_SELF, "nNumEnemies", nNumInvolved);
}
for(nNum = 1; nNum <= nNumInvolved; nNum++)
{
oInvolved = GetLocalObject(OBJECT_SELF, "nEnemy" + IntToString(nNumInvolved));
oFactionMember = GetFirstFactionMember(oInvolved);
while (GetIsObjectValid(oFactionMember))
{
if(GetArea(oFactionMember) == oArea && !GetIsDead(oFactionMember))
{
nPartySize++;
nHD = GetTrueHD(oFactionMember);
if(nHDMax < nHD)
nHDMax = nHD;
}
oFactionMember = GetNextFactionMember(oInvolved);
}
}
oInvolved = GetFirstPC();
while(GetIsObjectValid(oInvolved))
{
if(GetIsPossessedFamiliar(oInvolved) || GetIsDMPossessed(oInvolved))
oInvolved = GetMaster(oInvolved);
if(GetIsInHostileParty(oInvolved) && GetArea(oInvolved) == oArea && !GetIsDead(oInvolved))
{
fXP = StringToFloat(Get2DAString("xptable", "C" + IntToString(nCR), nHDMax));
fXP *= 10.0 * GetXPSliderSetting() * GetPartySizePenalty(nPartySize);
GiveXPToCreature(oInvolved, FloatToInt(fXP));
}
oInvolved = GetNextPC();
}
}