Exemplo n.º 1
0
void C4PlayerInfoListAttributeConflictResolver::ResolveInInfo()
{
	// trial-loop for assignment of new player colors/names
	int32_t iTries = 0;
	// original/alternate conflict evaluated once only
	fOriginalConflict = false;
	fAlternateConflict = (eAttr == C4PlayerInfo::PLRATT_Name) || !pResolveInfo->GetAlternateColor(); // mark as conflict if there is no alternate color/name
	for (;;)
	{
		// check against all other player infos, and given info, too (may be redundant)
		fCurrentConflict = false;
		pLowPrioOriginalConflictPacket = pLowPrioAlternateConflictPacket = nullptr;
		MarkConflicts(rPriCheckList, !iTries);
		// check secondary list, too. But only for colors, not for names, because secondary list is Restore list
		// and colors are retained in restore while names are always taken from new joins
		if (eAttr != C4PlayerInfo::PLRATT_Name) MarkConflicts(rSecCheckList, !iTries);
		// and mark conflicts in additional packet that' sbeen passed
		if (pSecPacket) MarkConflicts(*pSecPacket, !iTries);
		// color conflict resolving
		if (eAttr == C4PlayerInfo::PLRATT_Color)
		{
			// original color free but not used?
			if (!iTries)
			{
				if (pResolveInfo->GetColor() != pResolveInfo->GetOriginalColor())
				{
					if (!fOriginalConflict)
					{
						// revert to original color!
						pResolveInfo->SetColor(pResolveInfo->GetOriginalColor());
						// in case a lower priority packet was blocking the attribute, re-check that packet
						// note that the may readd the current resolve packet, but the conflict will occur with the
						// lower priority packet in the next loop
						if (pLowPrioOriginalConflictPacket) ReaddInfoForCheck(pLowPrioOriginalConflictPacket);
						// done with this player (breaking the trial-loop)
						break;
					}
					// neither original nor alternate color used but alternate color free?
					else if (pResolveInfo->GetColor() != pResolveInfo->GetAlternateColor() && !fAlternateConflict)
					{
						// revert to alternate
						pResolveInfo->SetColor(pResolveInfo->GetAlternateColor());
						if (pLowPrioAlternateConflictPacket) ReaddInfoForCheck(pLowPrioAlternateConflictPacket);
						// done with this player (breaking the trial-loop)
						break;
					}
				}
			}
			// conflict found?
			if (!fCurrentConflict)
				// done with this player, then - break the trial-loop
				break;
			// try to get a new, unused player color
			uint32_t dwNewClr;
			if (++iTries > C4MaxPlayerColorChangeTries)
			{
				LogF(LoadResStr("IDS_PRC_NOREPLPLRCLR"), pResolveInfo->GetName() ? pResolveInfo->GetName() : "<NONAME>");
				// since there's a conflict anyway, change to original
				pResolveInfo->SetColor(pResolveInfo->GetOriginalColor());
				break;
			}
			else
				dwNewClr = GenerateRandomPlayerColor(iTries);
			pResolveInfo->SetColor(dwNewClr);
		}
		else // if (eAttr == PLRATT_Name)
		{
			// name conflict resolving
			// original name free but not used?
			if (!SEqualNoCase(pResolveInfo->GetName(), pResolveInfo->GetOriginalName()))
				if (!fOriginalConflict)
				{
					// revert to original name!
					pResolveInfo->SetForcedName(nullptr);
					if (pLowPrioOriginalConflictPacket) ReaddInfoForCheck(pLowPrioOriginalConflictPacket);
					// done with this player (breaking the trial-loop)
					break;
				}
			// conflict found?
			if (!fCurrentConflict)
				// done with this player, then - break the trial-loop
				break;
			// generate new name by appending an index
			if (++iTries > C4MaxPlayerNameChangeTries) break;
			pResolveInfo->SetForcedName(FormatString("%s (%d)", pResolveInfo->GetOriginalName(), iTries+1).getData());
		}
	}
}