Exemple #1
0
        /// <summary>
        /// Removes an entry from the master dictionary of all-network replacements currently applied to networks.
        /// </summary>
        /// <param name="netPrefab">Network prefab</param>
        /// <param name="target">Target prop info</param>
        /// <param name="laneIndex">Lane index</param>
        /// <param name="propIndex">Prop index</param>
        internal new void RemoveEntry(NetInfo netPrefab, PrefabInfo target, int laneIndex, int propIndex)
        {
            // Check to see if we have an entry for this prefab.
            if (replacements.ContainsKey(target))
            {
                // Yes - iterate through each recorded prop reference.
                for (int i = 0; i < replacements[target].references.Count; ++i)
                {
                    // Look for a network, lane and index match.
                    NetPropReference propReference = replacements[target].references[i];
                    if (propReference.netInfo == netPrefab && propReference.laneIndex == laneIndex && propReference.propIndex == propIndex)
                    {
                        // Got a match!  Revert instance.
                        if (target is PropInfo propTarget)
                        {
                            propReference.netInfo.m_lanes[propReference.laneIndex].m_laneProps.m_props[propReference.propIndex].m_finalProp = propTarget;
                        }
                        else
                        {
                            propReference.netInfo.m_lanes[propReference.laneIndex].m_laneProps.m_props[propReference.propIndex].m_finalTree = (TreeInfo)target;
                        }
                        netPrefab.m_lanes[laneIndex].m_laneProps.m_props[propIndex].m_angle       = propReference.angle;
                        netPrefab.m_lanes[laneIndex].m_laneProps.m_props[propIndex].m_position    = propReference.position;
                        netPrefab.m_lanes[laneIndex].m_laneProps.m_props[propIndex].m_probability = propReference.probability;

                        // Remove this reference and return.
                        replacements[target].references.Remove(replacements[target].references[i]);
                        return;
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Unapplies a particular replacement instance to defer to a higher-priority replacement.
        /// </summary>
        /// <param name="netInfo">Network prefab</param>
        /// <param name="targetInfo">Target prefab</param>
        /// <param name="laneIndex">Lane index</param>
        /// <param name="propIndex">Prop index</param>
        internal void RemoveEntry(NetInfo netInfo, PrefabInfo targetInfo, int laneIndex, int propIndex)
        {
            // Check to see if we have an entry for this prefab and target.
            List <NetPropReference> referenceList = ReferenceList(netInfo, targetInfo, laneIndex, propIndex);

            if (referenceList != null)
            {
                // Got an active reference list; create a variable to store any matching reference for later removal.
                NetPropReference thisPropReference = null;

                // Iterate through each recorded prop reference.
                foreach (NetPropReference propReference in referenceList)
                {
                    // Look for a network, lane and index match.
                    if (propReference.netInfo == netInfo && propReference.laneIndex == laneIndex && propReference.propIndex == propIndex)
                    {
                        // Got a match!  Revert instance.
                        RevertReference(propReference);

                        // Record the matching reference and stop iterating - we're done here.
                        thisPropReference = propReference;
                        break;
                    }
                }

                // Remove replacement if one was found.
                if (thisPropReference != null)
                {
                    referenceList.Remove(thisPropReference);
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Restores a pack replacement, if any (e.g. after a network replacement has been reverted).
        /// </summary>
        /// <param name="netPrefab">Network prefab</param>
        /// <param name="target">Target prop info</param>
        /// <param name="laneIndex">Lane index</param>
        /// <param name="propIndex">Prop index</param>
        /// <returns>True if a restoration was made, false otherwise</returns>
        internal bool Restore(NetInfo netPrefab, PrefabInfo target, int laneIndex, int propIndex)
        {
            // Check to see if we have an entry for this prefab.
            if (replacements.ContainsKey(target))
            {
                // Yes - add reference data to the list.
                NetPropReference newReference = new NetPropReference
                {
                    network   = netPrefab,
                    laneIndex = laneIndex,
                    propIndex = propIndex,
                    angle     = netPrefab.m_lanes[laneIndex].m_laneProps.m_props[propIndex].m_angle,
                    postion   = netPrefab.m_lanes[laneIndex].m_laneProps.m_props[propIndex].m_position
                };

                replacements[target].references.Add(newReference);

                // Apply replacement and return true to indicate restoration.
                NetworkReplacement.instance.ReplaceProp(replacements[target], newReference);
                return(true);
            }

            // If we got here, no restoration was made.
            return(false);
        }
Exemple #4
0
        /// <summary>
        /// Replaces a prop, using a network replacement.
        /// </summary>
        /// <param name="replacement">Network replacement to apply</param>
        /// <param name="propReference">Individual prop reference to apply to</param>
        protected void ReplaceProp(BOBNetReplacement replacement, NetPropReference propReference)
        {
            // If this is a vanilla network, then we've probably got shared NetLaneProp references, so need to copy to a new instance.
            // If the name doesn't contain a period (c.f. 12345.MyNetwok_Data), then assume it's vanilla - may be a mod or not shared, but better safe than sorry.
            if (!propReference.netInfo.name.Contains("."))
            {
                CloneLanePropInstance(propReference.netInfo, propReference.laneIndex);
            }

            // Convert offset to Vector3.
            Vector3 offset = new Vector3
            {
                x = replacement.offsetX,
                y = replacement.offsetY,
                z = replacement.offsetZ
            };

            NetInfo.Lane thisLane = propReference.netInfo.m_lanes[propReference.laneIndex];

            // Apply replacement.
            if (replacement.replacementInfo is PropInfo propInfo)
            {
                thisLane.m_laneProps.m_props[propReference.propIndex].m_prop = propInfo;
            }
            else if (replacement.replacementInfo is TreeInfo treeInfo)
            {
                thisLane.m_laneProps.m_props[propReference.propIndex].m_tree = treeInfo;
            }
            else
            {
                Logging.Error("invalid replacement ", replacement.replacementInfo?.name ?? "null", " passed to NetworkReplacement.ReplaceProp");
                return;
            }

            // Invert x offset to match original prop x position.
            if (thisLane.m_position + propReference.position.x < 0)
            {
                offset.x = 0 - offset.x;
            }

            // Angle and offset.
            thisLane.m_laneProps.m_props[propReference.propIndex].m_angle    = propReference.angle + replacement.angle;
            thisLane.m_laneProps.m_props[propReference.propIndex].m_position = propReference.position + offset;

            // Probability.
            thisLane.m_laneProps.m_props[propReference.propIndex].m_probability = replacement.probability;

            // Update network prop references.
            propReference.netInfo.CheckReferences();

            // Add network to dirty list.
            NetData.DirtyList.Add(propReference.netInfo);
        }
Exemple #5
0
        /// <summary>
        /// Creates a new PropReference from the provided building prefab and prop index.
        /// </summary>
        /// <param name="reference">Referene to revert</param>
        protected void RevertReference(NetPropReference reference)
        {
            // Local reference.
            NetLaneProps.Prop thisProp = reference.netInfo.m_lanes[reference.laneIndex].m_laneProps.m_props?[reference.propIndex];
            if (thisProp != null)
            {
                thisProp.m_prop        = reference.originalProp;
                thisProp.m_tree        = reference.originalTree;
                thisProp.m_angle       = reference.angle;
                thisProp.m_position    = reference.position;
                thisProp.m_probability = reference.probability;

                // Update network.
                reference.netInfo.CheckReferences();
                NetData.DirtyList.Add(reference.netInfo);
            }
        }
Exemple #6
0
        /// <summary>
        /// Adds the given prop reference to the record for the given replacement.
        /// </summary>
        /// <param name="replacement">Replacement reference</param>
        /// <param name="propReference">Pop reference to store</param>
        protected override void AddReference(BOBNetReplacement replacement, NetPropReference propReference)
        {
            // Check to see if we've got an entry for this target prefab in our dictionary, and if not, create one.
            if (!propReferences.ContainsKey(propReference.netInfo))
            {
                propReferences.Add(propReference.netInfo, new Dictionary <PrefabInfo, List <NetPropReference> >());
            }

            // Check to see if we've got an entry for this network prefab in our dictionary entry for this target prefab, and if not, create one.
            if (!propReferences[propReference.netInfo].ContainsKey(replacement.targetInfo))
            {
                propReferences[propReference.netInfo].Add(replacement.targetInfo, new List <NetPropReference>());
            }

            // Add this prop reference to the dictioanry.
            propReferences[propReference.netInfo][replacement.targetInfo].Add(propReference);
        }
Exemple #7
0
        /// <summary>
        /// Restores a pack replacement, if any (e.g. after a network replacement has been reverted).
        /// </summary>
        /// <param name="netPrefab">Network prefab</param>
        /// <param name="target">Target prop info</param>
        /// <param name="laneIndex">Lane index</param>
        /// <param name="propIndex">Prop index</param>
        /// <returns>True if a restoration was made, false otherwise</returns>
        internal new bool Restore(NetInfo netPrefab, PrefabInfo target, int laneIndex, int propIndex)
        {
            // Check to see if we have an entry for this prefab.
            if (replacements.ContainsKey(target))
            {
                // Yes - add reference data to the list.
                NetPropReference newReference = CreateReference(netPrefab, target, laneIndex, propIndex, target is TreeInfo);

                replacements[target].references.Add(newReference);

                // Apply replacement and return true to indicate restoration.
                ReplaceProp(replacements[target], newReference);
                return(true);
            }

            // If we got here, no restoration was made.
            return(false);
        }
Exemple #8
0
        /// <summary>
        /// Restores a replacement, if any (e.g. after a higher-priority replacement has been reverted).
        /// </summary>
        /// <param name="netInfo">Network prefab</param>
        /// <param name="targetInfo">Target prop info</param>
        /// <param name="laneIndex">Lane index</param>
        /// <param name="propIndex">Prop index</param>
        /// <returns>True if a restoration was made, false otherwise</returns>
        internal bool Restore(NetInfo netInfo, PrefabInfo targetInfo, int laneIndex, int propIndex)
        {
            // See if we have a relevant replacement record.
            BOBNetReplacement thisReplacement = EligibileReplacement(netInfo, targetInfo, laneIndex, propIndex);

            if (thisReplacement != null)
            {
                // Yes - add reference data to the list.
                NetPropReference newReference = CreateReference(netInfo, targetInfo, laneIndex, propIndex, thisReplacement.isTree);
                AddReference(thisReplacement, newReference);

                // Apply replacement and return true to indicate restoration.
                ReplaceProp(thisReplacement, newReference);

                return(true);
            }

            // If we got here, no restoration was made.
            return(false);
        }
Exemple #9
0
        /// <summary>
        /// Applies a replacement.
        /// </summary>
        /// <param name="replacement">Replacement record to apply</param>
        protected override void ApplyReplacement(BOBNetReplacement replacement)
        {
            // Don't do anything if prefabs can't be found.
            if (replacement?.targetInfo == null || replacement.replacementInfo == null || replacement.NetInfo == null)
            {
                return;
            }

            // Check lane index.
            NetInfo.Lane thisLane = replacement.NetInfo.m_lanes[replacement.laneIndex];
            if (thisLane == null)
            {
                return;
            }

            // Check prop index.
            NetLaneProps.Prop thisLaneProp = thisLane.m_laneProps.m_props[replacement.propIndex];
            if (thisLaneProp == null)
            {
                return;
            }

            // Reset any pack, network, or all-network replacements first.
            NetworkReplacement.Instance.RemoveEntry(replacement.NetInfo, replacement.targetInfo, replacement.laneIndex, replacement.propIndex);
            AllNetworkReplacement.Instance.RemoveEntry(replacement.NetInfo, replacement.targetInfo, replacement.laneIndex, replacement.propIndex);
            NetworkPackReplacement.Instance.RemoveEntry(replacement.NetInfo, replacement.targetInfo, replacement.laneIndex, replacement.propIndex);

            // Create replacment entry.
            NetPropReference newPropReference = CreateReference(replacement.NetInfo, replacement.targetInfo, replacement.laneIndex, replacement.propIndex, replacement.isTree);

            // Reset replacement list to be only our new replacement entry.
            replacement.references = new List <NetPropReference> {
                newPropReference
            };

            // Apply the replacement.
            ReplaceProp(replacement, newPropReference);
        }
Exemple #10
0
        /// <summary>
        /// Replaces a prop using a network replacement.
        /// </summary>
        /// <param name="netElement">Network replacement element to apply</param>
        /// <param name="propReference">Individual prop reference to apply to</param>
        internal void ReplaceProp(BOBNetReplacement netElement, NetPropReference propReference)
        {
            // Convert offset to Vector3.
            Vector3 offset = new Vector3
            {
                x = netElement.offsetX,
                y = netElement.offsetY,
                z = netElement.offsetZ
            };

            // Apply replacement.
            if (netElement.replacementInfo is PropInfo propInfo)
            {
                propReference.network.m_lanes[propReference.laneIndex].m_laneProps.m_props[propReference.propIndex].m_finalProp = propInfo;
            }
            else
            {
                propReference.network.m_lanes[propReference.laneIndex].m_laneProps.m_props[propReference.propIndex].m_finalTree = (TreeInfo)netElement.replacementInfo;
            }

            // Invert x offset if lane position is negative.
            if (propReference.network.m_lanes[propReference.laneIndex].m_position < 0)
            {
                offset.x = 0 - offset.x;
            }

            // Angle and offset.
            propReference.network.m_lanes[propReference.laneIndex].m_laneProps.m_props[propReference.propIndex].m_angle    = propReference.angle + netElement.angle;
            propReference.network.m_lanes[propReference.laneIndex].m_laneProps.m_props[propReference.propIndex].m_position = propReference.postion + offset;

            // Probability.
            propReference.network.m_lanes[propReference.laneIndex].m_laneProps.m_props[propReference.propIndex].m_probability = netElement.probability;

            // Add network to dirty list.
            NetData.DirtyList.Add(propReference.network);
        }
Exemple #11
0
        /// <summary>
        /// Populates the target fastlist with a list of target-specific trees or props.
        /// </summary>
        protected override void TargetList()
        {
            // Clear current selection.
            targetList.selectedIndex = -1;

            // List of prefabs that have passed filtering.
            List <TargetListItem> itemList = new List <TargetListItem>();

            // Check to see if this building contains any lanes.
            if (SelectedNet?.m_lanes == null || SelectedNet.m_lanes.Length == 0)
            {
                // No lanes - show 'no props' label and return an empty list.
                noPropsLabel.Show();
                targetList.rowsData = new FastList <object>();
                return;
            }

            // Local reference.
            NetInfo.Lane[] lanes = SelectedNet.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.
                    NetTargetListItem targetListItem = new NetTargetListItem();

                    // 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;
                    }

                    // Get original (pre-replacement) tree/prop prefab and current probability (as default original probability).
                    targetListItem.originalPrefab = finalInfo;
                    targetListItem.originalProb   = laneProps[propIndex].m_probability;
                    targetListItem.originalAngle  = laneProps[propIndex].m_angle;

                    // Grouped or individual?
                    if (CurrentMode == (int)ReplacementModes.Individual)
                    {
                        // Individual - set index to the current prop indexes.
                        targetListItem.index = propIndex;
                        targetListItem.lane  = lane;
                    }
                    else
                    {
                        // Grouped - set index to -1 and add to our list of indexes.
                        targetListItem.index = -1;
                        targetListItem.lane  = -1;
                        targetListItem.indexes.Add(propIndex);
                        targetListItem.lanes.Add(lane);
                    }

                    // All-network replacement and original probability (if any).
                    BOBNetReplacement allNetReplacement = AllNetworkReplacement.Instance.ActiveReplacement(SelectedNet, lane, propIndex);
                    if (allNetReplacement != null)
                    {
                        targetListItem.allPrefab = allNetReplacement.replacementInfo;
                        targetListItem.allProb   = allNetReplacement.probability;

                        // Update original prop reference.
                        targetListItem.originalPrefab = allNetReplacement.targetInfo;


                        // See if we can find an active reference.
                        Logging.Message("finding original probability - all-network");
                        NetPropReference originalReference = allNetReplacement?.references?.Find(x => x.netInfo == SelectedNet && x.laneIndex == lane && x.propIndex == propIndex);
                        if (originalReference != null)
                        {
                            // Original reference found; update original probability.
                            targetListItem.originalProb = originalReference.probability;
                        }
                        Logging.Message("original probability not found");
                    }

                    // Network replacement and original probability (if any).
                    BOBNetReplacement netReplacement = NetworkReplacement.Instance.ActiveReplacement(SelectedNet, lane, propIndex);
                    if (netReplacement != null)
                    {
                        targetListItem.replacementPrefab = netReplacement.replacementInfo;
                        targetListItem.replacementProb   = netReplacement.probability;

                        // Update original prop reference.
                        targetListItem.originalPrefab = netReplacement.targetInfo;
                        Logging.Message("finding original probability - grouped");
                        targetListItem.originalProb = netReplacement.references.Find(x => x.laneIndex == lane && x.propIndex == propIndex).probability;
                        Logging.Message("original probability found");
                    }

                    // Individual replacement and original probability (if any).
                    BOBNetReplacement individualReplacement = IndividualNetworkReplacement.Instance.ActiveReplacement(SelectedNet, lane, propIndex);
                    if (individualReplacement != null)
                    {
                        targetListItem.individualPrefab = individualReplacement.replacementInfo;
                        targetListItem.individualProb   = individualReplacement.probability;
                        Logging.Message("finding original probability - individual");
                        targetListItem.originalProb = individualReplacement.references.Find(x => x.laneIndex == lane && x.propIndex == propIndex).probability;
                        Logging.Message("original probability found");

                        // Update original prop reference.
                        targetListItem.originalPrefab = individualReplacement.targetInfo;
                    }

                    // Replacement pack replacement and original probability (if any).
                    BOBNetReplacement packReplacement = NetworkPackReplacement.Instance.ActiveReplacement(SelectedNet, lane, propIndex);
                    if (packReplacement != null)
                    {
                        targetListItem.packagePrefab = packReplacement.replacementInfo;

                        // Update original prop reference.
                        targetListItem.originalPrefab = packReplacement.targetInfo;
                        targetListItem.originalProb   = packReplacement.references.Find(x => x.laneIndex == lane && x.propIndex == propIndex).probability;
                    }

                    // Are we grouping?
                    if (targetListItem.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 (NetTargetListItem item in itemList)
                        {
                            // Check to see if we already have this in the list - matching original prefab, individual replacement prefab, network replacement prefab, all-network replacement prefab, and probability.
                            if (item.originalPrefab == targetListItem.originalPrefab && item.individualPrefab == targetListItem.individualPrefab && item.replacementPrefab == targetListItem.replacementPrefab && targetListItem.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.
                    itemList.Add(targetListItem);
                }
            }

            // Create return fastlist from our filtered list, ordering by name.
            targetList.rowsData = new FastList <object>()
            {
                m_buffer = targetSearchStatus == (int)OrderBy.NameDescending ? itemList.OrderByDescending(item => item.DisplayName).ToArray() : itemList.OrderBy(item => item.DisplayName).ToArray(),
                m_size   = itemList.Count
            };

            targetList.Refresh();

            // If the list is empty, show the 'no props' label; otherwise, hide it.
            if (itemList.Count == 0)
            {
                noPropsLabel.Show();
            }
            else
            {
                noPropsLabel.Hide();
            }
        }
Exemple #12
0
 /// <summary>
 /// Adds the given prop reference to the record for the given replacement.
 /// </summary>
 /// <param name="replacement">Replacement reference</param>
 /// <param name="propReference">Pop reference to store</param>
 protected virtual void AddReference(BOBNetReplacement replacement, NetPropReference propReference) => replacement.references.Add(propReference);