void C4Team::RecheckColor(C4TeamList &rForList) { // number of times trying new player colors const int32_t C4MaxTeamColorChangeTries = 100; if (!dwClr) { const int defTeamColorCount = 10; DWORD defTeamColorRGB[defTeamColorCount] = { 0xF40000, 0x00C800, 0xFCF41C, 0x2020FF, // red, green, yellow, blue, 0xC48444, 0xFFFFFF, 0x848484, 0xFF00EF, // brown, white, grey, pink, 0x00FFFF, 0x784830 }; // cyan, dk brown // no color assigned yet: Generate by team ID if (iID >=1 && iID <=defTeamColorCount) { // default colors dwClr = defTeamColorRGB[iID-1] | 0xff000000; } else { // find a new, unused color for (int32_t iTry=1; iTry<C4MaxTeamColorChangeTries; ++iTry) { dwClr = GenerateRandomPlayerColor(iTry); int32_t iIdx=0; C4Team *pTeam; bool fOK=true; while ((pTeam = rForList.GetTeamByIndex(iIdx++))) if (pTeam != this) if (IsColorConflict(pTeam->GetColor(), dwClr)) { fOK=false; break; } // color is fine? if (fOK) return; // it's not; try next color } // Giving up: Use last generated color } } }
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()); } } }