// Modified private method ColonistBarDrawLocsFinder.TryDistributeHorizontalSlotsBetweenGroups() /// <summary> /// Trys to distribute horizontal slots between groups based on a per /// row maximum. /// </summary> /// <param name="maxPerGlobalRow">The maximum amount of slots per row.</param> /// <param name="entriesInGroup">The amount of entries per group.</param> /// <param name="horizontalSlotsPerGroup">The result of the distribution.</param> /// <returns>Returns true if successful, otherwise false.</returns> public static bool TryDistributeHorizontalSlotsBetweenGroups(int maxPerGlobalRow, List <int> entriesInGroup, out List <int> horizontalSlotsPerGroup) { horizontalSlotsPerGroup = new List <int>(); int groupsCount = ColonistBarUtility.GetVisibleGroupsCount(); for (int i = 0; i < groupsCount; i++) { horizontalSlotsPerGroup.Add(0); } GenMath.DHondtDistribution(horizontalSlotsPerGroup, (int i) => (float)entriesInGroup[i], maxPerGlobalRow); for (int i = 0; i < horizontalSlotsPerGroup.Count; i++) { if (horizontalSlotsPerGroup[i] == 0) { int num2 = horizontalSlotsPerGroup.Max(); if (num2 <= 1) { return(false); } int num3 = horizontalSlotsPerGroup.IndexOf(num2); List <int> list; // Not my fault int index; (list = horizontalSlotsPerGroup)[index = num3] = list[index] - 1; int index2; (list = horizontalSlotsPerGroup)[index2 = i] = list[index2] + 1; } } return(true); }
/// <summary> /// Flattens the horizontal slots to the lowest between itself and /// relevant counts of entries for a group. /// </summary> /// <param name="entriesInGroup">The amount of entries per group.</param> /// <param name="horizontalSlotsPerGroup">The amount of horizontal slots per group.</param> public static void FlattenHorizontalSlots(List <int> entriesInGroup, List <int> horizontalSlotsPerGroup) { var visibleGroups = ColonistBarUtility.GetVisibleGroups(Find.ColonistBar); foreach (var visibleGroup in visibleGroups) { int index = ColonistBarUtility.GetGroupRelativeToVisible(visibleGroup); horizontalSlotsPerGroup[index] = Mathf.Min(horizontalSlotsPerGroup[index], entriesInGroup[visibleGroup]); } }
// Modified private method ColonistBarDrawLocsFinder.FindBestScale(). /// <summary> /// Returns the best scale for the colonist bar. /// </summary> /// <param name="entriesInGroup">The amount of entries for a given group.</param> /// <param name="onlyOneRow">Whether the colonist bar should use only one row.</param> /// <param name="maxPerGlobalRow">The maximum amounts of entries per row.</param> /// <param name="horizontalSlotsPerGroup">The amount of horizontal slots to use for a given group.</param> /// <returns>The best scale based on the amount of entries per group.</returns> public static float GetBestScale(List <int> entriesInGroup, out bool onlyOneRow, out int maxPerGlobalRow, out List <int> horizontalSlotsPerGroup) { float bestScale = 1f; var entries = ColonistBarUtility.GetVisibleEntries(); int groupsCount = ColonistBarUtility.GetVisibleGroupsCount(); while (true) { float colonistBarWidth = (ColonistBar.BaseSize.x + 24f) * bestScale; float num4 = MaxColonistBarWidth - (float)(groupsCount - 1) * 25f * bestScale; maxPerGlobalRow = Mathf.FloorToInt(num4 / colonistBarWidth); onlyOneRow = true; bool result = TryDistributeHorizontalSlotsBetweenGroups( maxPerGlobalRow, entriesInGroup, out horizontalSlotsPerGroup); if (result) { int allowedRowsCountForScale = GetAllowedRowsCountForScale(bestScale); bool flag = true; int currentGroup = -1; foreach (var entry in entries) { if (currentGroup != entry.group) { currentGroup = entry.group; int rowCount = Mathf.CeilToInt( (float)entriesInGroup[entry.group] / (float)horizontalSlotsPerGroup[ColonistBarUtility.GetGroupRelativeToVisible(entry.group)] ); if (rowCount > 1) { onlyOneRow = false; } if (rowCount > allowedRowsCountForScale) { flag = false; break; } } } if (flag) { break; } } bestScale *= 0.95f; } return(bestScale); }
// Modified private method ColonistBarDrawLocsFinder.CalculateDrawLocs() /// <summary> /// Gets the drawing locations for the provided entries on the colonist bar. /// </summary> /// <param name="scale">The scale of the colonist bar.</param> /// <param name="onlyOneRow">Whether to use only one row for the colonist bar.</param> /// <param name="maxPerGlobalRow">The maximum amount of entries per row.</param> /// <param name="entriesInGroup">The amount of entries in a given group.</param> /// <param name="horizontalSlotsPerGroup">The amount of horizontal slots per group.</param> /// <param name="drawLocs">The drawling locations for the given entries.</param> public static void GetDrawLocs(float scale, bool onlyOneRow, int maxPerGlobalRow, List <int> entriesInGroup, List <int> horizontalSlotsPerGroup, List <Vector2> drawLocs) { if (scale <= 0) { throw new ArgumentOutOfRangeException(nameof(scale)); } drawLocs.Clear(); int entriesCount = maxPerGlobalRow; if (onlyOneRow) { FlattenHorizontalSlots(entriesInGroup, horizontalSlotsPerGroup); entriesCount = ColonistBarUtility.GetVisibleEntriesCount(); } int groupsCount = ColonistBarUtility.GetVisibleGroupsCount(); float num3 = (ColonistBar.BaseSize.x + 24f) * scale; float num4 = (float)entriesCount * num3 + (float)(groupsCount - 1) * 25f * scale; List <ColonistBar.Entry> entries = Find.ColonistBar.Entries; int currentGroup = -1; int numInGroup = -1; float groupStartX = ((float)Verse.UI.screenWidth - num4) / 2f; foreach (var entry in entries) { if (!ColonistBarUtility.IsHidden(entry)) { if (currentGroup != entry.group) { if (currentGroup >= 0) { groupStartX += 25f * scale; groupStartX += (float)horizontalSlotsPerGroup[currentGroup] * scale * (ColonistBar.BaseSize.x + 24f); } numInGroup = 0; currentGroup = entry.group; } else { numInGroup++; } Vector2 drawLoc = GetDrawLoc(groupStartX, 21f, entry.group, numInGroup, scale, entriesInGroup, horizontalSlotsPerGroup); drawLocs.Add(drawLoc); } } }
/// <summary> /// Tries to get the colonist bar entry at the given position. Original public method: <see cref="ColonistBar.TryGetEntryAt(Vector2, out ColonistBar.Entry)"/>. /// </summary> /// <param name="pos">The target position.</param> /// <param name="entry">The result of the search.</param> /// <returns>True if successful, otherwise false.</returns> public static bool TryGetEntryAt(Vector2 pos, out ColonistBar.Entry entry) { List <Vector2> drawLocs = Find.ColonistBar.DrawLocs; var entries = ColonistBarUtility.GetVisibleEntries(); Vector2 size = Find.ColonistBar.Size; for (int i = 0; i < drawLocs.Count; i++) { Rect rect = new Rect(drawLocs[i].x, drawLocs[i].y, size.x, size.y); if (rect.Contains(pos)) { entry = entries[i]; return(true); } } entry = default(ColonistBar.Entry); return(false); }
// Modified private method ColonistBarDrawLocsFinder.CalculateColonistsInGroup() /// <summary> /// Returns a list where list[i] is the amount of entries belonging to group[i]. /// </summary> /// <returns>A list indexed by group, containing the amount of entries for that group.</returns> public static List <int> GetGroupEntryCounts() { var entries = ColonistBarUtility.GetVisibleEntries(); var totalGroupsCount = ColonistBarUtility.GetTotalGroupsCount(); var list = new List <int>(totalGroupsCount); for (int i = 0; i < totalGroupsCount; i++) { list.Add(0); } foreach (var entry in entries) { int group = entry.group; list[group]++; } return(list); }
// Modified private method ColonistBarDrawLocsFinder.GetDrawLoc() /// <summary> /// Gets the drawing location for a given entry. /// </summary> /// <param name="groupStartX">The group's starting x position.</param> /// <param name="groupStartY">The group's starting y position.</param> /// <param name="group">The group of the entry.</param> /// <param name="positionInGroup">The position of the entry in the group.</param> /// <param name="scale">The scale of the colonist bar.</param> /// <param name="entriesInGroup">The amount of entries for a given group.</param> /// <param name="horizontalSlotsPerGroup">The amount of horizontal slots for a given group.</param> /// <returns>The drawing location for a given entry.</returns> public static Vector2 GetDrawLoc(float groupStartX, float groupStartY, int group, int positionInGroup, float scale, List <int> entriesInGroup, List <int> horizontalSlotsPerGroup) { int horizontalSlot = horizontalSlotsPerGroup[ColonistBarUtility.GetGroupRelativeToVisible(group)]; if (horizontalSlot == 0) { throw new ArgumentException("Horizontal slot cannot be equal to zero."); } int entryCountInGroup = entriesInGroup[group]; float x = groupStartX + (float)(positionInGroup % horizontalSlot) * scale * (ColonistBar.BaseSize.x + 24f); float y = groupStartY + (float)(positionInGroup / horizontalSlot) * scale * (ColonistBar.BaseSize.y + 32f); if (positionInGroup >= entryCountInGroup - (entryCountInGroup % horizontalSlot)) { int num2 = horizontalSlot - entryCountInGroup % horizontalSlot; x += (float)num2 * scale * (ColonistBar.BaseSize.x + 24f) * 0.5f; } return(new Vector2(x, y)); }