Exemplo n.º 1
0
void Group::SplitExp(uint32 exp, Mob* other) {
	if( other->CastToNPC()->MerchantType != 0 ) // Ensure NPC isn't a merchant
		return;

	if(other->GetOwner() && other->GetOwner()->IsClient()) // Ensure owner isn't pc
		return;

	unsigned int i;
	int8 membercount = 0;
	int8 close_membercount = 0;
	uint8 maxlevel = 1;

	for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
		if (members[i] != nullptr  && members[i]->IsClient()) {
			Client *cmember = members[i]->CastToClient();
			if(cmember->CastToClient()->GetZoneID() == zone->GetZoneID())
			{
				if(members[i]->GetLevel() > maxlevel)
					maxlevel = members[i]->GetLevel();

				if(cmember->GetLevelCon(other->GetLevel()) != CON_GREEN)
				{
					++membercount;
					if(cmember->CastToClient()->IsInRange(other))
						++close_membercount;
				}
			}
		}
	}

	// If the NPC is green to the whole group or they are all out of the kill zone (wipe?) this will return.
	if (membercount <= 0 || close_membercount <= 0)
		return;

	bool isgreen = false;
	int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel());
	if(conlevel == CON_GREEN)
		isgreen = true;

	if(isgreen && !RuleB(AlKabor, GreensGiveXPToGroup))
		return;

	// The first loop grabs the maxlevel, so we need to adjust the count here checking for level range, 
	// before applying xp in the third and final loop.
	for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
		if (members[i] != nullptr && members[i]->IsClient()) // If Group Member is Client
		{
			Client *cmember = members[i]->CastToClient();
			if (!cmember->IsInLevelRange(maxlevel) &&
				cmember->CastToClient()->GetZoneID() == zone->GetZoneID() &&
				cmember->GetLevelCon(other->GetLevel()) != CON_GREEN) 
			{
				if(membercount != 0 && close_membercount != 0)
				{
					--membercount;

					if(cmember->CastToClient()->IsInRange(other))
						--close_membercount;
				}
				else
					return;
			}	
		}
	}

	if (membercount <= 0 || close_membercount <= 0)
		return;

	if(!RuleB(AlKabor, OutOfRangeGroupXPBonus))
		membercount = close_membercount;

	float groupmod = 1.0;
	if (membercount == 2)
		groupmod += 0.20;
	else if(membercount == 3)
		groupmod += 0.40;
	if(RuleB(AlKabor, GroupEXPBonuses))
	{
		if(membercount == 4)
			groupmod += 1.20;
		else if(membercount > 4)
			groupmod += 1.60;
	}
	else
	{
		if(membercount == 4)
			groupmod += 0.60;
		else if(membercount > 4)
			groupmod += 0.80;
	}

	uint32 groupexp = (uint32)((float)exp * groupmod * (RuleR(Character, GroupExpMultiplier)));

	// Give XP to all clients in the group who are close to the kill. 
	if(!RuleB(AlKabor, Count6thGroupMember))
	{
		// 6th member is free for division.
		if(close_membercount == 6)
			close_membercount = 5;
	}

	uint32 splitgroupxp = groupexp / close_membercount;
	if(splitgroupxp < 1)
		splitgroupxp = 1;

	for (i = 0; i < MAX_GROUP_MEMBERS; i++) 
	{
		if (members[i] != nullptr && members[i]->IsClient()) // If Group Member is Client
		{
			Client *cmember = members[i]->CastToClient();
			
			if(cmember->CastToClient()->GetZoneID() == zone->GetZoneID() &&
				cmember->GetLevelCon(other->GetLevel()) != CON_GREEN &&
				cmember->IsInRange(other))
			{
				if (cmember->IsInLevelRange(maxlevel)) 
				{
					if(isgreen)
					{
						// NPCs that are green to some of the group do not split XP.
						cmember->AddEXP(groupexp, cmember->GetLevelCon(other->GetLevel()));
						//_log(_GROUP__LOG, "%s gets non-split green XP worth: %i. You lucky dog.", cmember->GetName(), groupexp);
					}
					else
					{
						cmember->AddEXP(splitgroupxp, conlevel);
						//_log(_GROUP__LOG, "%s splits %i with the rest of the group. Their share: %i", cmember->GetName(), groupexp, splitgroupxp);
						//cmember->Message(CC_Yellow, "Group XP awarded is: %i Total XP is: %i for count: %i total count: %i in_exp is: %i", splitgroupxp, groupexp, close_membercount, membercount, exp);

					}
				}
				else
					Log.Out(Logs::Detail, Logs::Group, "%s is too low in level to gain XP from this group.", cmember->GetName());
			}
			else
				Log.Out(Logs::Detail, Logs::Group, "%s is not in the kill zone, is out of range, or %s is green to them. They won't recieve group XP.", cmember->GetName(), other->GetCleanName());
		}
	}
}