/// <summary> /// Generates and displays a building row. /// </summary> /// <param name="data">Object to list</param> /// <param name="isRowOdd">If the row is an odd-numbered row (for background banding)</param> public void Display(object data, bool isRowOdd) { // Perform initial setup for new rows. if (nameLabel == null) { isVisible = true; canFocus = true; isInteractive = true; width = parent.width; height = RowHeight; // Add object name label. nameLabel = AddUIComponent <UILabel>(); nameLabel.width = this.width - 10f; nameLabel.textScale = TextScale; // Add index text label. indexLabel = AddUIComponent <UILabel>(); indexLabel.width = IndexWidth; indexLabel.textScale = TextScale; indexLabel.relativePosition = new Vector2(IndexLabelX, PaddingY); } // Add line sprite if we need to (initially hidden). if (lineSprite == null) { lineSprite = AddUIComponent <UISprite>(); lineSprite.size = new Vector2(17f, 17f); lineSprite.relativePosition = new Vector2(3f, 3f); lineSprite.Hide(); } // Set initial label position. labelX = LeftMargin; // See if our attached data is a raw PropInfo (e.g an available prop item as opposed to a PropListItem replacment record). thisPrefab = data as PrefabInfo; if (thisPrefab == null) { // Hide any existing line sprites; it will be re-shown as necessary. if (lineSprite != null) { lineSprite.Hide(); // Adjust name label position to accomodate. labelX += PackageMargin; } // Text to display - StringBuilder due to the amount of manipulation we're doing. StringBuilder displayText = new StringBuilder(); // Not a raw PropInfo, so it should be a PropListItem replacement record. // Set local references. thisItem = data as PropListItem; index = thisItem.index; // See if this is a network prop. NetPropListItem thisNetItem = data as NetPropListItem; // Display index number if this is an individual reference. if (thisItem.index >= 0) { indexLabel.text = thisItem.index.ToString(); // Adjust name label position to accomodate. labelX += IndexWidth; } else { indexLabel.text = ""; } bool hasReplacement = false; // Check to see if there's a currently active individual replacement. if (thisItem.individualPrefab != null) { // A replacement is currently active - include it in the text. displayText.Append(PrefabLists.GetDisplayName(thisItem.individualPrefab.name)); // Append probability to the label, if we're showing it. if (thisItem.showProbs) { displayText.Append(" "); displayText.Append(thisItem.individualProb); displayText.Append("%"); } // Set flag. hasReplacement = true; } // If no current individual replacement, check to see if there's a currently active building/network replacement. else if (thisItem.replacementPrefab != null) { // A replacement is currently active - include it in the text. displayText.Append(PrefabLists.GetDisplayName(thisItem.replacementPrefab.name)); // Append probability to the label, if we're showing it. if (thisItem.showProbs) { displayText.Append(" "); displayText.Append(thisItem.replacementProb); displayText.Append("%"); } // Set flag. hasReplacement = true; // Show building replacement sprite. lineSprite.atlas = TextureUtils.LoadSpriteAtlas(thisNetItem == null ? "bob_single_building_small" : "bob_road_small"); lineSprite.spriteName = "normal"; lineSprite.tooltip = Translations.Translate(thisNetItem == null ? "BOB_SPR_SBL" : "BOB_SPR_SNT"); lineSprite.Show(); } // If no current building/network replacement, check to see if any all- replacement is currently active. else if (thisItem.allPrefab != null) { // An all- replacement is currently active; append name to the label. displayText.Append(PrefabLists.GetDisplayName(thisItem.allPrefab.name)); // Append probability if this is not a network item and we're showing probs. if (thisNetItem == null && thisItem.showProbs) { displayText.Append(" "); displayText.Append(thisItem.allProb); displayText.Append("%"); } // Set flag. hasReplacement = true; // Show all- replacement sprite. lineSprite.atlas = TextureUtils.LoadSpriteAtlas(thisNetItem == null ? "bob_buildings_small" : "bob_all_roads_small"); lineSprite.spriteName = "normal"; lineSprite.tooltip = Translations.Translate(thisNetItem == null ? "BOB_SPR_ABL" : "BOB_SPR_ANT"); lineSprite.Show(); } // If no other replacements, chek to see if any pack replacement is currently active else if (thisItem.packagePrefab != null) { // Yes; append name to the label. displayText.Append(PrefabLists.GetDisplayName(thisItem.packagePrefab.name)); // Set flag. hasReplacement = true; // Show package replacement sprite. lineSprite.atlas = TextureUtils.LoadSpriteAtlas("bob_prop_pack_small"); lineSprite.spriteName = "normal"; lineSprite.tooltip = Translations.Translate("BOB_SPR_PCK"); lineSprite.Show(); } // Do we have a replacement? if (hasReplacement) { // Yes; append "was" to the display name. displayText.Append("; "); displayText.Append(Translations.Translate("BOB_ROW_WAS")); displayText.Append(" "); } // Original prefab display name. displayText.Append(PrefabLists.GetDisplayName(thisItem.originalPrefab.name)); // Show original probability in brackets immediately afterwards. if (thisItem.showProbs) { displayText.Append(" ("); displayText.Append(thisItem.originalProb); displayText.Append("%)"); } // Set display text. nameLabel.text = displayText.ToString(); } else { // Attached data is a raw PropInfo; just display its (cleaned-up) name. nameLabel.text = PrefabLists.GetDisplayName(thisPrefab.name); } // Set label position nameLabel.relativePosition = new Vector2(labelX, PaddingY); // Set initial background as deselected state. Deselect(isRowOdd); }
/// <summary> /// Populates the target fastlist with a list of target-specific trees or props. /// </summary> protected override void TargetList() { // List of prefabs that have passed filtering. List <NetPropListItem> propList = new List <NetPropListItem>(); // Check to see if this building contains any props. if (currentNet.m_lanes == null || currentNet.m_lanes.Length == 0) { // No props - show 'no props' label and return an empty list. noPropsLabel.Show(); targetList.m_rowsData = new FastList <object>(); return; } // Local reference. NetInfo.Lane[] lanes = currentNet.m_lanes; // Iterate through each lane. for (int lane = 0; lane < lanes.Length; ++lane) { // Local reference. NetLaneProps.Prop[] laneProps = lanes[lane].m_laneProps?.m_props; // If no props in this lane, skip it and go to the next one. if (laneProps == null) { continue; } // Iterate through each prop in lane. for (int propIndex = 0; propIndex < laneProps.Length; ++propIndex) { // Create new list item. NetPropListItem propListItem = new NetPropListItem(); // Try to get relevant prefab (prop/tree), using finalProp. PrefabInfo finalInfo = IsTree ? (PrefabInfo)laneProps[propIndex]?.m_finalTree : (PrefabInfo)laneProps[propIndex]?.m_finalProp; // Check to see if we were succesful - if not (e.g. we only want trees and this is a prop), continue on to next building prop. if (finalInfo?.name == null) { continue; } // Networks are always grouped - set index and lane to -1 and add to our lists of indexes and lanes. propListItem.index = -1; propListItem.lane = -1; propListItem.indexes.Add(propIndex); propListItem.lanes.Add(lane); // Get original (pre-replacement) tree/prop prefab and current probability (as default original probability). propListItem.originalPrefab = NetworkReplacement.instance.GetOriginal(currentNet, lane, propIndex) ?? AllNetworkReplacement.instance.GetOriginal(currentNet, lane, propIndex) ?? PackReplacement.instance.GetOriginal(currentNet, lane, propIndex) ?? finalInfo; propListItem.originalProb = laneProps[propIndex].m_probability; propListItem.originalAngle = laneProps[propIndex].m_angle; // All-network replacement and original probability (if any). BOBNetReplacement allNetReplacement = AllNetworkReplacement.instance.ActiveReplacement(currentNet, lane, propIndex); if (allNetReplacement != null) { propListItem.allPrefab = allNetReplacement.replacementInfo; propListItem.allProb = allNetReplacement.probability; } // Individual network replacement and original probability (if any). BOBNetReplacement netReplacement = NetworkReplacement.instance.ActiveReplacement(currentNet, lane, propIndex); if (netReplacement != null) { propListItem.replacementPrefab = netReplacement.replacementInfo; propListItem.replacementProb = netReplacement.probability; } // Replacement pack replacement and original probability (if any). BOBNetReplacement packReplacement = PackReplacement.instance.ActiveReplacement(currentNet, lane, propIndex); if (packReplacement != null) { propListItem.packagePrefab = packReplacement.replacementInfo; } // Are we grouping? if (propListItem.index == -1) { // Yes, grouping - initialise a flag to show if we've matched. bool matched = false; // Iterate through each item in our existing list of props. foreach (NetPropListItem item in propList) { // Check to see if we already have this in the list - matching original prefab, building replacement prefab, all-building replacement prefab, and probability. if (item.originalPrefab == propListItem.originalPrefab && item.replacementPrefab == propListItem.replacementPrefab && propListItem.allPrefab == item.allPrefab) { // We've already got an identical grouped instance of this item - add this index and lane to the lists of indexes and lanes under that item and set the flag to indicate that we've done so. item.indexes.Add(propIndex); item.lanes.Add(lane); matched = true; // No point going any further through the list, since we've already found our match. break; } } // Did we get a match? if (matched) { // Yes - continue on to next network prop (without adding this item separately to the list). continue; } } // Add this item to our list. propList.Add(propListItem); } } // Create return fastlist from our filtered list, ordering by name. targetList.m_rowsData = new FastList <object>() { m_buffer = targetSearchStatus == (int)OrderBy.NameDescending ? propList.OrderByDescending(item => item.DisplayName).ToArray() : propList.OrderBy(item => item.DisplayName).ToArray(), m_size = propList.Count }; targetList.Refresh(); // If the list is empty, show the 'no props' label; otherwise, hide it. if (targetList.m_rowsData.m_size == 0) { noPropsLabel.Show(); } else { noPropsLabel.Hide(); } }