public static void AddRightWallLights(this ICollection<NetLaneProps.Prop> props, int xPos = 0) { var wallLightPropInfo = Prefabs.Find<PropInfo>("Wall Light Orange"); var wallLightProp = new NetLaneProps.Prop(); wallLightProp.m_prop = wallLightPropInfo.ShallowClone(); wallLightProp.m_probability = 100; wallLightProp.m_repeatDistance = 20; wallLightProp.m_segmentOffset = 0; wallLightProp.m_angle = 90; wallLightProp.m_position = new Vector3(xPos, 1.5f, 0); props.Add(wallLightProp); }
private static void AddBollards(this NetInfo info, NetInfoVersion version, PropInfo bollardInfo = null, BuildingInfo pillarInfo = null) { if (version == NetInfoVersion.Bridge || version == NetInfoVersion.Elevated) { if (pillarInfo == null) { pillarInfo = Prefabs.Find<BuildingInfo>("Pedestrian Elevated Pillar", false); } var bridgeAI = info.GetComponent<RoadBridgeAI>(); if (pillarInfo != null && bridgeAI != null) { bridgeAI.m_doubleLength = false; bridgeAI.m_bridgePillarInfo = pillarInfo; bridgeAI.m_middlePillarInfo = null; bridgeAI.m_bridgePillarOffset = 0; } } if (bollardInfo != null) { var bollardProp1 = new NetLaneProps.Prop() { m_prop = bollardInfo, m_finalProp = bollardInfo, m_probability = 100, m_segmentOffset = 1, m_minLength = 10, m_endFlagsRequired = NetNode.Flags.Transition }; bollardProp1.m_position.x = -3.5f; bollardProp1.m_position.y = -0.3f; var bollardProp2 = bollardProp1.ShallowClone(); bollardProp2.m_segmentOffset = -1; bollardProp2.m_endFlagsRequired = NetNode.Flags.None; bollardProp2.m_startFlagsRequired = NetNode.Flags.Transition; var bollardProp3 = bollardProp1.ShallowClone(); bollardProp3.m_position.x = 3.5f; var bollardProp4 = bollardProp2.ShallowClone(); bollardProp4.m_position.x = 3.5f; var bollardProp5 = bollardProp1.ShallowClone(); bollardProp5.m_position.x = 0; var bollardProp6 = bollardProp2.ShallowClone(); bollardProp6.m_position.x = 0; var propPedLane = info .m_lanes .First(l => l.m_position == 0f && l.m_laneType == NetInfo.LaneType.Pedestrian); propPedLane.m_laneProps.m_props = propPedLane .m_laneProps .m_props .Union(new[] { bollardProp1, bollardProp2, bollardProp3, bollardProp4, bollardProp5, bollardProp6}) .ToArray(); } }
public static void AddLeftWallLights(this ICollection<NetLaneProps.Prop> props, float pavementWidth) { var wallLightPropInfo = Prefabs.Find<PropInfo>("Wall Light Orange"); var wallLightProp = new NetLaneProps.Prop(); var wallPropXPos = (pavementWidth - 3) * -0.5f; wallLightProp.m_prop = wallLightPropInfo.ShallowClone(); wallLightProp.m_probability = 100; wallLightProp.m_repeatDistance = 20; wallLightProp.m_segmentOffset = 0; wallLightProp.m_angle = 270; wallLightProp.m_position = new Vector3(wallPropXPos, 1.5f, 0); props.Add(wallLightProp); }
public static LaneProp GetMetaData(this NetLaneProps.Prop prop) => (prop as IInfoExtended)?.GetMetaData <LaneProp>();
private void SetNetToolPrefab() { if (trackStyle == 0) { btnModernStyle.color = new Color32(163, 255, 16, 255); btnModernStyle.normalBgSprite = "ButtonMenuFocused"; btnModernStyle.useDropShadow = true; btnModernStyle.opacity = 95; btnClassicStyle.color = new Color32(150, 150, 150, 255); btnClassicStyle.normalBgSprite = "ButtonMenu"; btnClassicStyle.useDropShadow = false; btnClassicStyle.opacity = 75; } else if (trackStyle == 1) { btnClassicStyle.color = new Color32(163, 255, 16, 255); btnClassicStyle.normalBgSprite = "ButtonMenuFocused"; btnClassicStyle.useDropShadow = true; btnClassicStyle.opacity = 95; btnModernStyle.color = new Color32(150, 150, 150, 255); btnModernStyle.normalBgSprite = "ButtonMenu"; btnModernStyle.useDropShadow = false; btnModernStyle.opacity = 75; } if (trackSize == 0) { btnSingleTrack.color = new Color32(163, 255, 16, 255); btnSingleTrack.normalBgSprite = "ButtonMenuFocused"; btnSingleTrack.useDropShadow = true; btnSingleTrack.opacity = 95; btnDoubleTrack.color = new Color32(150, 150, 150, 255); btnDoubleTrack.normalBgSprite = "ButtonMenu"; btnDoubleTrack.useDropShadow = false; btnDoubleTrack.opacity = 75; } else if (trackSize == 1) { btnDoubleTrack.color = new Color32(163, 255, 16, 255); btnDoubleTrack.normalBgSprite = "ButtonMenuFocused"; btnDoubleTrack.useDropShadow = true; btnDoubleTrack.opacity = 95; btnSingleTrack.color = new Color32(150, 150, 150, 255); btnSingleTrack.normalBgSprite = "ButtonMenu"; btnSingleTrack.useDropShadow = false; btnSingleTrack.opacity = 75; } if (trackDirection == 0) { btnOneWay.color = new Color32(163, 255, 16, 255); btnOneWay.normalBgSprite = "ButtonMenuFocused"; btnOneWay.useDropShadow = true; btnOneWay.opacity = 95; btnTwoWay.color = new Color32(150, 150, 150, 255); btnTwoWay.normalBgSprite = "ButtonMenu"; btnOneWay.useDropShadow = false; btnTwoWay.opacity = 75; } else if (trackDirection == 1) { btnTwoWay.color = new Color32(163, 255, 16, 255); btnTwoWay.normalBgSprite = "ButtonMenuFocused"; btnTwoWay.useDropShadow = true; btnTwoWay.opacity = 95; btnOneWay.color = new Color32(150, 150, 150, 255); btnOneWay.normalBgSprite = "ButtonMenu"; btnOneWay.useDropShadow = false; btnOneWay.opacity = 75; } NetInfo prefab = null; switch (trackStyle) { case 0: switch (trackSize) { case 0: { if (trackDirection == 0) { prefab = fence ? concreteSmallPrefab : concreteSmallPrefabNoBar; } else { prefab = fence ? concreteSmallTwoWayPrefab : concreteSmallTwoWayPrefabNoBar; } } break; case 1: { if (trackDirection == 0) { prefab = fence ? concreteTwoLaneOneWayPrefab : concreteTwoLaneOneWayPrefabNoBar; } else { prefab = fence ? concretePrefab : concretePrefabNoBar; } } break; case 2: { if (trackDirection == 0) { } else { prefab = fence ? concreteLargePrefab : concreteLargePrefabNoBar; } } break; } break; case 1: switch (trackSize) { case 0: { if (trackDirection == 0) { prefab = fence ? steelSmallPrefab : steelSmallPrefabNoBar; } else { prefab = fence ? steelSmallTwoWayPrefab : steelSmallTwoWayPrefabNoBar; } } break; case 1: { if (trackDirection == 0) { prefab = fence ? steelTwoLaneOneWayPrefab : steelTwoLaneOneWayPrefabNoBar; } else { prefab = fence ? steelPrefab : steelPrefabNoBar; } } break; case 2: { if (trackDirection == 0) { //prefab = fence ? steelTwoLaneOneWayPrefab : steelTwoLaneOneWayPrefabNoBar; } else { prefab = fence ? steelLargePrefab : steelLargePrefabNoBar; } } break; } break; } if (prefab != null) { m_netTool.m_prefab = prefab; var elevation = m_netTool.GetElevation(); var lanes = m_netTool.m_prefab.m_lanes.ToList(); Next.Debug.Log($"MOM EE lane count: {lanes.Count()}"); var lane = lanes.FirstOrDefault(l => l.m_laneType == NetInfo.LaneType.None); NetLaneProps.Prop prop = null; if (lane != null) { var propList = lane.m_laneProps.m_props?.ToList(); if (propList != null) { Next.Debug.Log($"MOM EE lane found with {propList.Count()} props"); prop = propList.FirstOrDefault(p => p.m_prop.name.ToLower().Contains("l pillar (")); if (prop != null) { Next.Debug.Log($"MOM EE Examining aLane"); var name = prop.m_prop.name; if (extraElevated) { prop.m_probability = 100; Next.Debug.Log("MOM EE Enabled"); } else { prop.m_probability = 0; Next.Debug.Log("MOM EE Disabled"); } var props = lane.m_laneProps.m_props?.ToList(); if (props != null) { var replacementPair = new KeyValuePair <string, PropInfo>(name, prop.m_prop); if (props.Any(p => p.m_prop.name.ToLower().Contains(replacementPair.Key.ToLower()))) { var tempProp = new NetLaneProps.Prop(); var propsToReplace = props.Where(p => p.m_prop.name.ToLower().Contains(replacementPair.Key.ToLower())).ToList(); for (var i = 0; i < propsToReplace.Count; i++) { tempProp = propsToReplace[i].ShallowClone(); props.Remove(propsToReplace[i]); tempProp.m_prop = replacementPair.Value; props.Add(tempProp); } } lane.m_laneProps.m_props = props.ToArray(); } } } } m_netTool.m_prefab.m_lanes = lanes.ToArray(); } }
/// <summary> /// Replaces a prop whose name is contained in the key with the propinfo in the value. /// </summary> /// <param name="props"></param> /// <param name="replacementPairs">key=prop name part to remove, value = propinfo to add</param> public static void ReplacePropInfo(this ICollection<NetLaneProps.Prop> props, KeyValuePair<string, PropInfo> replacementPair) { if (props.Any(p => p.m_prop.name.ToLower().Contains(replacementPair.Key.ToLower()))) { var tempProp = new NetLaneProps.Prop(); var propsToReplace = props.Where(p => p.m_prop.name.ToLower().Contains(replacementPair.Key.ToLower())).ToList(); for (var i = 0; i < propsToReplace.Count; i++) { tempProp = propsToReplace[i].ShallowClone(); props.Remove(propsToReplace[i]); tempProp.m_prop = replacementPair.Value; props.Add(tempProp); } } }
/// <summary> /// Applies an all-building prop 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) { return; } // Create new reference list. List <NetPropReference> referenceList = new List <NetPropReference>(); // Iterate through each loaded network and record props to be replaced. for (int i = 0; i < PrefabCollection <NetInfo> .LoadedCount(); ++i) { // Get local reference. NetInfo netInfo = PrefabCollection <NetInfo> .GetLoaded((uint)i); // Skip any null networks, or netorks without lanes. if (netInfo?.m_lanes == null) { continue; } // Iterate through each lane. for (int laneIndex = 0; laneIndex < netInfo.m_lanes.Length; ++laneIndex) { // Local reference. NetLaneProps.Prop[] theseLaneProps = netInfo.m_lanes[laneIndex]?.m_laneProps?.m_props; // If no props in this lane, skip it and go to the next one. if (theseLaneProps == null) { continue; } // Iterate through each prop in lane. for (int propIndex = 0; propIndex < theseLaneProps.Length; ++propIndex) { // Local reference. NetLaneProps.Prop thisLaneProp = theseLaneProps[propIndex]; // If invalid entry, skip this one. if (thisLaneProp == null) { continue; } // Check for any currently active network or individual replacement. if (NetworkReplacement.Instance.ActiveReplacement(netInfo, laneIndex, propIndex) != null || IndividualNetworkReplacement.Instance.ActiveReplacement(netInfo, laneIndex, propIndex) != null) { // Active network or individual replacement; skip this one. continue; } // Check for any existing pack replacement. PrefabInfo thisProp = NetworkPackReplacement.Instance.ActiveReplacement(netInfo, laneIndex, propIndex)?.targetInfo; if (thisProp == null) { // No active replacement; use current PropInfo. if (replacement.isTree) { thisProp = thisLaneProp.m_finalTree; } else { thisProp = thisLaneProp.m_finalProp; } } // See if this prop matches our replacement. if (thisProp != null && thisProp == replacement.targetInfo) { // Match! Add reference data to the list. referenceList.Add(CreateReference(netInfo, thisProp, laneIndex, propIndex, replacement.isTree)); } } } } // Now, iterate through each entry found and apply the replacement to each one. foreach (NetPropReference propReference in referenceList) { // Remove any pack replacements first. NetworkPackReplacement.Instance.RemoveEntry(propReference.netInfo, replacement.targetInfo, propReference.laneIndex, propReference.propIndex); // Add entry to dictionary. AddReference(replacement, propReference); // Apply the replacement. ReplaceProp(replacement, propReference); } }
/// <summary> /// returns an extended clone of <paramref name="info"/> /// that can accept metadata. /// </summary> public static IInfoExtended <NetLaneProps.Prop> Extend(this NetLaneProps.Prop info) => ExtendPropDelegate(info);
public static void AddProp(this ICollection <NetLaneProps.Prop> props, NetLaneProps.Prop propToAdd) { props.Add(propToAdd.ShallowClone()); }
void RemoveSkippedFromNets(IEnumerator action) { try { NetInfo[] prefabs = netPrefabsField.GetValue(action) as NetInfo[]; if (prefabs == null) { netPrefabsField.SetValue(action, new NetInfo[0]); return; } List <NetLaneProps.Prop> keepThese = new List <NetLaneProps.Prop>(16); //StreamWriter wp = new StreamWriter(Path.Combine(Util.GetSavePath(), "Net-props.txt"), true); foreach (NetInfo info in prefabs) { //wp.WriteLine(info.name); if (info.m_lanes == null) { continue; } for (int i = 0; i < info.m_lanes.Length; i++) { NetLaneProps laneProps = info.m_lanes[i].m_laneProps; if (laneProps == null || laneProps.m_props == null) { continue; } //wp.WriteLine(" --"); bool skippedSome = false; for (int j = 0; j < laneProps.m_props.Length; j++) { NetLaneProps.Prop prop = laneProps.m_props[j]; if (prop == null) { continue; } //if (prop.m_prop != null) // wp.WriteLine(" " + prop.m_prop.name); if (prop.m_prop == null) { keepThese.Add(prop); } else if (Skip(prop.m_prop)) { //Util.DebugPrint(prop.m_prop.name, "-> RemoveSkippedFromNets at", Profiling.Millis, "/", info.name); prop.m_prop = prop.m_finalProp = null; skippedSome = true; } else { keepThese.Add(prop); } } if (skippedSome) { laneProps.m_props = keepThese.ToArray(); } keepThese.Clear(); } } //wp.Close(); } catch (Exception e) { UnityEngine.Debug.LogException(e); } }
public void BuildUp(NetInfo info, NetInfoVersion version) { /////////////////////////// // Template // /////////////////////////// var roadInfo = Prefabs.Find <NetInfo>(NetInfos.Vanilla.ROAD_2L_TREES); var roadTunnelInfo = Prefabs.Find <NetInfo>(NetInfos.Vanilla.ROAD_2L_TUNNEL); info.m_connectGroup = (NetInfo.ConnectGroup) 16; info.m_requireDirectRenderers = true; info.m_nodeConnectGroups = (NetInfo.ConnectGroup) 16; /////////////////////////// // 3DModeling // /////////////////////////// info.Setup16mNoSWMesh(version); /////////////////////////// // Texturing // /////////////////////////// SetupTextures(info, version); /////////////////////////// // Set up // /////////////////////////// info.m_availableIn = ItemClass.Availability.All; info.m_surfaceLevel = 0; info.m_createPavement = true; info.m_createGravel = false; info.m_canCrossLanes = false; //info.m_averageVehicleLaneSpeed = 0.3f; info.m_hasParkingSpaces = false; info.m_hasPedestrianLanes = true; info.m_halfWidth = 8; info.m_UnlockMilestone = roadInfo.m_UnlockMilestone; info.m_pavementWidth = 2; info.m_requireSurfaceMaps = true; info.m_dlcRequired = SteamHelper.DLC_BitMask.AfterDarkDLC; var pedModdedLanes = info.SetRoadLanes(version, new LanesConfiguration() { PedPropOffsetX = 3.5f, LanesToAdd = 2, SpeedLimit = 0.2f }); if (version == NetInfoVersion.Tunnel) { info.m_setVehicleFlags = Vehicle.Flags.Transition; info.m_class = roadTunnelInfo.m_class.Clone("NExtPedRoad16m"); } else { info.m_class = roadInfo.m_class.Clone("NExtPedRoad16m"); } info.m_class.m_level = ItemClass.Level.Level5; // Setting up lanes var vehicleLanes = info.m_lanes.Where(l => l.m_laneType == NetInfo.LaneType.Vehicle).ToList(); var bikeLaneWidth = 2; var bikeLanePosAbs = 1; var sVehicleLaneWidth = 2.5f; var sVehicleLanePosAbs = 4f; var bikeLanes = new List <NetInfo.Lane>(); bikeLanes.AddRange(vehicleLanes.Take(2)); var carLanes = new List <NetInfo.Lane>(); carLanes.AddRange(vehicleLanes.Skip(2)); for (var i = 0; i < bikeLanes.Count; i++) { bikeLanes[i].m_vehicleType = VehicleInfo.VehicleType.Bicycle; bikeLanes[i].m_position = ((i * 2) - 1) * bikeLanePosAbs; bikeLanes[i].m_width = bikeLaneWidth; bikeLanes[i].m_verticalOffset = -0.15f; bikeLanes[i].m_direction = bikeLanes[i].m_position > 0 ? NetInfo.Direction.Forward : NetInfo.Direction.Backward; bikeLanes[i].m_speedLimit = 0.8f; bikeLanes[i].m_stopType = VehicleInfo.VehicleType.None; var tempProps = bikeLanes[i].m_laneProps.m_props.ToList(); tempProps.RemoveProps("arrow"); bikeLanes[i].m_laneProps.m_props = tempProps.ToArray(); } for (int i = 0; i < carLanes.Count; i++) { carLanes[i].m_verticalOffset = 0.05f; var position = ((i * 2) - 1) * sVehicleLanePosAbs; var niLane = new ExtendedNetInfoLane(carLanes[i], ExtendedVehicleType.ServiceVehicles | ExtendedVehicleType.CargoTruck | ExtendedVehicleType.SnowTruck) { m_position = position, m_width = sVehicleLaneWidth, m_verticalOffset = 0.05f, m_direction = position > 0 ? NetInfo.Direction.Forward : NetInfo.Direction.Backward }; carLanes[i] = niLane; var tempProps = carLanes[i].m_laneProps.m_props.ToList(); tempProps.RemoveProps("arrow", "limit"); carLanes[i].m_laneProps.m_props = tempProps.ToArray(); } var pedLanes = new List <NetInfo.Lane>(); pedLanes.AddRange(info.m_lanes.Where(l => l.m_laneType == NetInfo.LaneType.Pedestrian).OrderBy(l => l.m_position)); foreach (var lane in vehicleLanes) { var laneProps = lane.m_laneProps.m_props.ToList(); laneProps.RemoveProps("arrow", "manhole"); lane.m_laneProps.m_props = laneProps.ToArray(); } for (int i = 0; i < pedLanes.Count; i++) { pedLanes[i].m_position = ((i * 2) - 1) * 5; pedLanes[i].m_width = 6; var tempProps = pedLanes[i].m_laneProps.m_props.ToList(); tempProps.RemoveProps("bus", "random", "limit"); var tempPropProps = tempProps.Where(tp => tp.m_prop != null); if (tempPropProps.Any(tp => tp.m_prop.name.ToLower().IndexOf("street light", StringComparison.Ordinal) != -1)) { tempProps.ReplacePropInfo(new KeyValuePair <string, PropInfo>("street light", Prefabs.Find <PropInfo>("StreetLamp02"))); var lightProp = tempProps.First(tp => tp.m_prop.name == "StreetLamp02"); lightProp.m_repeatDistance = 80; lightProp.m_segmentOffset = i; lightProp.m_probability = 100; lightProp.m_position.x = ((i * 2) - 1) * -2.5f; } else { var lightProp = new NetLaneProps.Prop() { m_prop = Prefabs.Find <PropInfo>("StreetLamp02").ShallowClone(), m_repeatDistance = 80, m_segmentOffset = i, m_probability = 100 }; lightProp.m_position.x = ((i * 2) - 1) * -2.5f; tempProps.Add(lightProp); } if (version == NetInfoVersion.Ground) { var treeProp = new NetLaneProps.Prop() { m_tree = Prefabs.Find <TreeInfo>("Tree2variant"), m_repeatDistance = 30, m_probability = 100, }; treeProp.m_position.x = ((i * 2) - 1) * 1.4f; tempProps.Add(treeProp); } else if (version == NetInfoVersion.Elevated || version == NetInfoVersion.Bridge) { var benchProp1 = new NetLaneProps.Prop() { m_prop = Prefabs.Find <PropInfo>("High Bench"), m_repeatDistance = 80, m_segmentOffset = (i - 1) * -0.5f, m_probability = 100, m_angle = 90 + (i * 180) }; benchProp1.m_position.x = ((i * 2) - 1) * 1.8f; tempProps.Add(benchProp1); } pedLanes[i].m_laneProps.m_props = tempProps.ToArray(); } var laneCollection = new List <NetInfo.Lane>(); laneCollection.AddRange(bikeLanes); laneCollection.AddRange(carLanes); laneCollection.AddRange(pedLanes); info.m_lanes = laneCollection.ToArray(); /////////////////////////// // AI // /////////////////////////// var pedestrianVanilla = Prefabs.Find <NetInfo>(NetInfos.Vanilla.PED_PAVEMENT); switch (version) { case NetInfoVersion.Ground: { var vanillaplayerNetAI = pedestrianVanilla.GetComponent <PlayerNetAI>(); var playerNetAI = info.GetComponent <PlayerNetAI>(); if (playerNetAI != null) { playerNetAI.m_constructionCost = vanillaplayerNetAI.m_constructionCost * 2; playerNetAI.m_maintenanceCost = vanillaplayerNetAI.m_maintenanceCost * 2; } } break; } var roadBaseAI = info.GetComponent <RoadBaseAI>(); if (roadBaseAI != null) { roadBaseAI.m_trafficLights = false; roadBaseAI.m_noiseAccumulation = 3; roadBaseAI.m_noiseRadius = 30; } var roadAI = info.GetComponent <RoadAI>(); if (roadAI != null) { roadAI.m_enableZoning = true; } }