public override void OnUpdateRotation(byte newFlags) { base.OnUpdateRotation(newFlags); this.mFlags = newFlags; this.mForwards = SegmentCustomRenderer.GetRotationQuaternion(this.mFlags) * Vector3.forward; this.mForwards.Normalize(); }
public DigArea(CubeCoord origin, int curHeight, int digRadius, int maxHeight, byte flags) { // Need to know where the block is this.Origin = origin; // Current dig position (offset from block) this.CurHeight = curHeight; // Dig settings this.DigRadius = digRadius; this.MaxHeight = maxHeight; Volume = ((digRadius * 2) + 1) * ((digRadius * 2) + 1) * maxHeight; // We'll need these to math later var rotationQuart = SegmentCustomRenderer.GetRotationQuaternion(flags); vectorUp = rotationQuart * Vector3.up; vectorForward = rotationQuart * Vector3.forward; vectorRight = rotationQuart * Vector3.right; vectorUp.Normalize(); vectorForward.Normalize(); vectorRight.Normalize(); }
public static void FlagsToRelativeForward(Byte flags, out SByte x, out SByte y, out SByte z) { var v = SegmentCustomRenderer.GetRotationQuaternion(flags) * Vector3.forward; x = (SByte)v.x; y = (SByte)v.y; z = (SByte)v.z; }
private void UpdateFaces(Byte flags) { Vector3 vector = Vector3.Normalize(SegmentCustomRenderer.GetRotationQuaternion(flags) * Vector3.down); TargetXOffset = (SByte)vector.x; TargetYOffset = (SByte)vector.y; TargetZOffset = (SByte)vector.z; }
public TourCartStation(ModCreateSegmentEntityParameters parameters) : base(parameters) { this.mbNeedsUnityUpdate = true; this.mbNeedsLowFrequencyUpdate = true; this.mForwards = SegmentCustomRenderer.GetRotationQuaternion(parameters.Flags) * Vector3.forward; this.mForwards.Normalize(); }
public FreightCartFactory(ModCreateSegmentEntityParameters parameters) : base(parameters) { this.mbNeedsLowFrequencyUpdate = true; this.mbNeedsUnityUpdate = false; this.mForwards = SegmentCustomRenderer.GetRotationQuaternion(parameters.Flags) * Vector3.forward; this.mForwards.Normalize(); this.maAttachedHoppers = new StorageMachineInterface[6]; }
private void UpdateFaces(Byte flags) { _targetDirection = Utils.CalcBottomDirection(flags); Vector3 vector = Vector3.Normalize(SegmentCustomRenderer.GetRotationQuaternion(flags) * Vector3.down); _sourceXOffset = (SByte)vector.x; _sourceYOffset = (SByte)vector.y; _sourceZOffset = (SByte)vector.z; }
public override void OnUpdateRotation(byte newFlags) { this.rotation = SegmentCustomRenderer.GetRotationQuaternion(newFlags); //Stupid corner mirroring... if (this.mValue == ScrapCornerVal) { this.rotation *= Quaternion.Euler(Vector3.up * 180); } base.OnUpdateRotation(newFlags); }
//======================================================= // Rotation Handlers //======================================================= public override void OnUpdateRotation(byte newFlags) { base.OnUpdateRotation(newFlags); Quaternion rotation = SegmentCustomRenderer.GetRotationQuaternion(newFlags); Forward = rotation * Vector3.forward; Left = rotation * Vector3.left; Up = rotation * Vector3.up; RotationEvent?.Invoke(this, rotation); }
private void UpdateRotation(Byte flags) { _found = false; _searchDist = MinSearchDist; _forwards = SegmentCustomRenderer.GetRotationQuaternion(flags) * Vector3.forward; _forwards.Normalize(); _xOffset = (SByte)_forwards.x; _yOffset = (SByte)_forwards.y; _zOffset = (SByte)_forwards.z; _targetDirection = Utils.CalcBackDirction(flags); }
public void ResetRotation() { var rotationQuat = SegmentCustomRenderer.GetRotationQuaternion(mFlags); Forward = rotationQuat * Vector3.forward; Right = rotationQuat * Vector3.right; Up = rotationQuat * Vector3.up; // Normalize vectors so we can easily multiply Forward.Normalize(); Right.Normalize(); Up.Normalize(); BoreDistance = 1; }
public static void SetupSidesPositions(byte flags, MachineSides machineSides) { Quaternion rotationQuaternion = SegmentCustomRenderer.GetRotationQuaternion(flags); machineSides.Front = rotationQuaternion * Vector3.forward; machineSides.Front.Normalize(); machineSides.Back = rotationQuaternion * Vector3.back; machineSides.Back.Normalize(); machineSides.Right = rotationQuaternion * Vector3.right; machineSides.Right.Normalize(); machineSides.Left = rotationQuaternion * Vector3.left; machineSides.Left.Normalize(); machineSides.Top = rotationQuaternion * Vector3.up; machineSides.Top.Normalize(); machineSides.Bottom = rotationQuaternion * Vector3.down; machineSides.Bottom.Normalize(); }
public MassGiver(ModCreateSegmentEntityParameters parameters) : base(eSegmentEntity.Mod, SpawnableObjectEnum.MassStorageOutputPort, parameters.X, parameters.Y, parameters.Z, parameters.Cube, parameters.Flags, parameters.Value, parameters.Position, parameters.Segment) { mbNeedsLowFrequencyUpdate = true; mbNeedsUnityUpdate = true; batch = 1; forwards = SegmentCustomRenderer.GetRotationQuaternion(parameters.Flags) * Vector3.forward; forwards.Normalize(); drone = new DroneComputer(droneSpeed); LookForAttachedModules(); droneSize = new Vector3(1, 1, 1); }
public ScrapTrack(ModCreateSegmentEntityParameters parameters) : base(parameters) { mbNeedsUnityUpdate = true; Vector3 lUnityPos = WorldScript.instance.mPlayerFrustrum.GetCoordsToUnity(this.mnX, this.mnY, this.mnZ); lUnityPos.x += 0.5f; lUnityPos.y += 0.5f; lUnityPos.z += 0.5f; this.position = lUnityPos; this.rotation = SegmentCustomRenderer.GetRotationQuaternion(this.mFlags); //Stupid corner mirroring... if (this.mValue == ScrapCornerVal) { this.rotation *= Quaternion.Euler(Vector3.up * 180); } if (this.mValue == ScrapSlopeVal) { this.position.y += 0.46f; } }
public override void UnityUpdate() { if (!mbLinkedToGO) { // Update the instanced version //this.instanceID = FreightCartMod.TrackInstances.TryAdd(); //this.instanceID2 = FreightCartMod.TrackInstances.TryAdd(); //this.UpdateInstancedBase(); //if (instanceID != -1 && instanceID2 != -1) //{ // this.mbLinkedToGO = true; // this.LinkStatusDirty = true; //} if (this.CrossTrack != null || FreightTrackJunction.TrackMesh == null || FreightTrackJunction.TrackMesh2 == null || FreightTrackJunction.TrackMaterial == null) { return; } Quaternion rot = SegmentCustomRenderer.GetRotationQuaternion(this.mFlags); Quaternion rot2 = rot * Quaternion.Euler(Vector3.up * 90); MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock(); materialPropertyBlock.SetColor("_GlowColor", Color.red); materialPropertyBlock.SetFloat("_GlowMult", 5f); this.CrossTrack = new GameObject(); JunctionRenderer ren = this.CrossTrack.AddComponent <JunctionRenderer>(); Vector3 lUnityPos = WorldScript.instance.mPlayerFrustrum.GetCoordsToUnity(this.mnX, this.mnY, this.mnZ); lUnityPos.x += 0.5f; lUnityPos.y += 0.5f; lUnityPos.z += 0.5f; ren.position = lUnityPos; ren.rotation = rot; ren.rotation2 = rot2; ren.mpb = materialPropertyBlock; ren.scrap = this.mValue == FreightTrackJunction.ScrapJunctionVal; ren.enabled = true; ren.gameObject.SetActive(true); this.CrossTrack.SetActive(true); this.TrackRenderer = ren; this.mbLinkedToGO = true; //if (mWrapper == null || mWrapper.mGameObjectList == null || SpawnableObjectManagerScript.instance == null || SpawnableObjectManagerScript.instance.maSpawnableObjects == null || SpawnableObjectManagerScript.instance.maSpawnableObjects[(int)SpawnableObjectEnum.Minecart_Track_Straight] == null) //{ // return; //} //else //{ // //this.CrossTrack = (GameObject)GameObject.Instantiate(SpawnableObjectManagerScript.instance.maSpawnableObjects[(int)SpawnableObjectEnum.Minecart_Track_Straight]); // //this.CrossTrack.transform.parent = mWrapper.mGameObjectList[0].gameObject.transform; // //this.CrossTrack.transform.localPosition = new Vector3(0, 0f, 0);//put in the correct relative position // //mWrapper.mGameObjectList[0].gameObject.transform.eulerAngles = new Vector3(0, 0, 0); // //this.CrossTrack.transform.eulerAngles = new Vector3(0, 90f, 0); // //this.CrossTrack.transform.localScale = new Vector3(0.99f, 0.99f, 0.99f); // //this.CrossTrack.SetActive(true); //} } if (this.mbLinkedToGO && this.LinkStatusDirty) { Color value = Color.red; int links = 0; for (int n = 0; n < 4; n++) { if (this.ConnectedJunctions[n] != null) { links++; } } switch (links) { case 1: value = new Color(1f, 0.3f, 0, 1f); break; case 2: value = Color.yellow; break; case 3: value = Color.green; break; case 4: value = Color.blue; break; } //Renderer[] componentsInChildren = this.CrossTrack.GetComponentsInChildren<Renderer>(); //Renderer[] comp2 = this.mWrapper.mGameObjectList[0].GetComponentsInChildren<Renderer>(); //MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock(); //materialPropertyBlock.SetColor("_GlowColor", value); //materialPropertyBlock.SetFloat("_GlowMult", 5f); //for (int i = 0; i < componentsInChildren.Length; i++) // componentsInChildren[i].SetPropertyBlock(materialPropertyBlock); //for (int i = 0; i < comp2.Length; i++) // comp2[i].SetPropertyBlock(materialPropertyBlock); if (this.TrackRenderer != null) { this.TrackRenderer.mpb.SetColor("_GlowColor", value); } if (this.instanceID != -1 && this.instanceID2 != -1) { //Debug.Log("Setting Track instance color as value: " + value.ToString()); FreightCartMod.TrackInstances.SetCol(this.instanceID, value); FreightCartMod.TrackInstances.SetParamVal(this.instanceID, 1f); FreightCartMod.TrackInstances.SetCol(this.instanceID2, value); FreightCartMod.TrackInstances.SetParamVal(this.instanceID2, 1f); } this.LinkStatusDirty = false; } }
/// <summary> /// Follows a track segment to find all containing stations until it reaches another junction or determines track is invalid /// </summary> /// <param name="direction">0 - 3 representing the four directions out of the junction</param> /// <returns>True if it found complete segment</returns> public bool TrackFollow(int direction) { //Initialize the check from the junction long nextX = this.mnX; long nextY = this.mnY; long nextZ = this.mnZ; Vector3 dirvec = new Vector3(); //Store the initial junction direction for later recording which direction the connected junction is associated with int initialdirection = direction; //List of freight cart stations found on this segment -> to be written to the final constructed FreightTrackSegment List <FreightCartStation> SegmentStations = new List <FreightCartStation>(); //Store visited track pieces for catching when the segment enters a closed loop List <TrackPiece> VisitedTracks = new List <TrackPiece>(); //Add a penalty for pathfinding in certain directions to avoid stations and other undesirable routes int PathfindPenalty = 0; //Begin loop here. Direction can be set and used to check the next location each time through the loop //Allow segments only up to 2048 long due to cost of loop checking - may revise after testing for (int n = 0; n < 2048; n++) { switch (direction) { case 0: nextX++; dirvec = Vector3.right; break; case 1: nextZ++; dirvec = Vector3.forward; break; case 2: nextX--; dirvec = Vector3.left; break; case 3: nextZ--; dirvec = Vector3.back; break; default: nextX++; break; } ushort lValue1 = 0; byte lFlags1 = 0; ushort type = this.GetCube(nextX, nextY, nextZ, out lValue1, out lFlags1); this.mUnderSegment = this.mPrevGetSeg; //Debug.LogWarning("GetCube type: " + type.ToString() + " value: " + lValue1); bool foundslope = false; //Found air and need to check for a downward slope under it if (type == 1) { ushort lValue2 = 0; byte lFlags2 = 0; ushort cube = this.GetCube(nextX, nextY - 1L, nextZ, out lValue2, out lFlags2); Segment segment = this.mPrevGetSeg; type = cube; lFlags1 = lFlags2; lValue1 = lValue2; if ((type == 538 && lValue1 == 2) || (type == ScrapTrackType && lValue1 == ScrapSlopeVal)) { foundslope = true; nextY--; //decrement Y level for next loop through! } else { if (type == 0) { Debug.LogError("Error, track follower has null under segment!"); } if (this.mPrevGetSeg == null) { Debug.LogError("Error, prevseg was null!"); } if (segment == null) { Debug.LogError("Error, old was null!"); } if (this.mPrevGetSeg != segment) { Debug.LogWarning(("Track follower is looking for a slope, and has had to check across segment boundaries for this![Old/New" + segment.GetName() + " -> " + this.mPrevGetSeg.GetName())); } return(false); } } Vector3 trackvec = SegmentCustomRenderer.GetRotationQuaternion(lFlags1) * Vector3.forward; bool oneway = false; trackvec.Normalize(); trackvec.x = trackvec.x >= -0.5 ? (trackvec.x <= 0.5 ? 0.0f : 1f) : -1f; trackvec.y = trackvec.y >= -0.5 ? (trackvec.y <= 0.5 ? 0.0f : 1f) : -1f; trackvec.z = trackvec.z >= -0.5 ? (trackvec.z <= 0.5 ? 0.0f : 1f) : -1f; //Begin checking track type if (type == TRACKTYPE || type == ScrapTrackType) { if ((type == TRACKTYPE && (lValue1 == TRACKSTRAIGHT || lValue1 == TRACKEMPTY || lValue1 == TRACKFULL)) || (type == ScrapTrackType && lValue1 == ScrapStraightVal)) { if (trackvec.y > 0.5 || trackvec.y < -0.5) { return(false); } else if (!(trackvec == dirvec) && !(trackvec == -dirvec)) { dirvec = new Vector3(trackvec.x, 0f, trackvec.z); oneway = true; // Can't set return path as the same -> they're different! } } if ((type == TRACKTYPE && lValue1 == TRACKCORNER) || (type == ScrapTrackType && lValue1 == ScrapCornerVal)) { if (dirvec == new Vector3(-trackvec.z, 0.0f, trackvec.x)) { dirvec = new Vector3(dirvec.z, 0.0f, -dirvec.x); } else if (trackvec == -dirvec) { dirvec = new Vector3(-dirvec.z, 0.0f, dirvec.x); } else { return(false); } } if ((type == TRACKTYPE && lValue1 == TRACKSLOPE) || (type == ScrapTrackType && lValue1 == ScrapSlopeVal)) { Vector3 vector3_2 = trackvec; dirvec.y = 0.0f; dirvec.Normalize(); if (dirvec == trackvec) { if (foundslope) { return(false); } else { nextY++; } } else if (dirvec == -trackvec) { ; } } if (type == TRACKTYPE && lValue1 == TRACKBUFFER) { dirvec = new Vector3(-dirvec.x, 0f, -dirvec.z); } } //Begin checking special types else if (type == CONTROLTYPE) { if (lValue1 == CONTROLLOAD || lValue1 == CONTROLUNLOAD || lValue1 == CONTROLTURBO) { if ((trackvec == dirvec) || (trackvec == -dirvec)) { //Do nothing... direction doesn't change //Except turbo... reduce the penalty for this path! if (lValue1 == CONTROLTURBO) { PathfindPenalty--; } } else { return(false); } } } //Check for freight stations else if (type == FREIGHTSTATIONTYPE) { if ((trackvec == dirvec) || (trackvec == -dirvec)) { Segment segment = this.AttemptGetSegment(nextX, nextY, nextZ); if (segment == null) { segment = WorldScript.instance.GetSegment(nextX, nextY, nextZ); if (segment == null) { Debug.Log((object)"Track junction track follower did not find segment"); return(false); } } FreightCartStation fcs = segment.FetchEntity(eSegmentEntity.Mod, nextX, nextY, nextZ) as FreightCartStation; if (fcs == null) { Debug.LogWarning("Track Junction Track Follower tried to get a freight cart station but got other mod machine instead?"); return(false); } if (!SegmentStations.Contains(fcs)) { SegmentStations.Add(fcs); } fcs.ClosestJunction = this; fcs.JunctionDirection = initialdirection; // Penalize this route for multidirection pathfinding due to the station PathfindPenalty += 5; } else { return(false); } } //Is it a junction? else if (type == JUNCTIONTYPE) { //Debug.LogWarning("Track follower success! Found another junction!"); Segment segment = this.AttemptGetSegment(nextX, nextY, nextZ); if (segment == null) { segment = WorldScript.instance.GetSegment(nextX, nextY, nextZ); if (segment == null) { Debug.Log((object)"Track junction track follower did not find segment"); return(false); } } FreightTrackJunction junction = segment.FetchEntity(eSegmentEntity.Mod, nextX, nextY, nextZ) as FreightTrackJunction; if (junction == null) { Debug.LogWarning("Track Junction Track Follower tried to get a track junction but got other mod machine instead?"); return(false); } this.ConnectedJunctions[initialdirection] = junction; //Don't let segment distance be negative just to be safe! This should rarely happen... if (PathfindPenalty < 0 && Math.Abs(PathfindPenalty) > n) { PathfindPenalty = -n; } FreightTrackSegment tracksegment = new FreightTrackSegment(this, junction, n + 1 + PathfindPenalty); tracksegment.Stations = SegmentStations; //Debug.LogWarning("trackseg station count: " + tracksegment.Stations.Count); this.ConnectedSegments[initialdirection] = tracksegment; this.SegmentDistances[initialdirection] = n + 1; this.LinkStatusDirty = true; //handle the connection for the other junction so we don't need to double the work - only if return path is valid! //Mirror the direction to reflect the correct side of the connecting junction if (!oneway) { int mirroreddir = direction += 2; if (mirroreddir > 3) { mirroreddir -= 4; } junction.ConnectedJunctions[mirroreddir] = this; junction.ConnectedSegments[mirroreddir] = tracksegment; junction.SegmentDistances[mirroreddir] = n + 1; junction.LinkStatusDirty = true; } return(true); } else if (type == TOURSTATIONTYPE) { if (trackvec != -dirvec) { return(false); } Segment segment = this.AttemptGetSegment(nextX, nextY, nextZ); if (segment == null) { segment = WorldScript.instance.GetSegment(nextX, nextY, nextZ); if (segment == null) { Debug.Log((object)"Track junction track follower did not find segment"); return(false); } } TourCartStation station = segment.FetchEntity(eSegmentEntity.Mod, nextX, nextY, nextZ) as TourCartStation; station.TrackNetwork = this.TrackNetwork; station.ClosestJunction = this; station.JunctionDirection = initialdirection; this.ConnectedJunctions[initialdirection] = this; FreightTrackSegment tracksegment = new FreightTrackSegment(this, this, 2 * n + 1); this.SegmentDistances[initialdirection] = 2 * n + 1; this.ConnectedSegments[initialdirection] = tracksegment; this.LinkStatusDirty = true; if (!string.IsNullOrEmpty(station.StationName) && !this.TrackNetwork.TourCartStations.ContainsKey(station.StationName)) { this.TrackNetwork.TourCartStations.Add(station.StationName, station); } return(true); } else { return(false); //Not a track type } //Update the direction int based on the changed direction vector if (dirvec == Vector3.right) { direction = 0; } else if (dirvec == Vector3.forward) { direction = 1; } else if (dirvec == Vector3.left) { direction = 2; } else if (dirvec == Vector3.back) { direction = 3; } TrackPiece visitedpiece = new TrackPiece(new Vector3(nextX - this.mnX, nextY - this.mnY, nextZ - this.mnZ), direction); //Debug.LogWarning("Visited track piece: " + new Vector4(nextX - this.mnX, nextY - mnY, nextZ - mnZ, direction).ToString()); //Store every track piece and check every 10th for monitoring for closed, endless loops of track if (n % 10 == 0) { int count = VisitedTracks.Count; for (int m = 0; m < count; m++) { TrackPiece piece = VisitedTracks[m]; if (piece.Position == visitedpiece.Position && piece.Direction == visitedpiece.Direction) { //Debug.LogWarning("piece position: " + piece.Position.ToString() + " visited: " + visitedpiece.Position.ToString()); Debug.LogWarning("TrackJunction followed track route and found a closed loop. Ending search."); return(false); } } } VisitedTracks.Add(visitedpiece); if (n == 2047) { Debug.LogWarning("Track Junction Found track length > 2048m -> ending search."); } } return(false); }
/// <summary> /// Follows a track segment to find all containing stations until it reaches another junction or determines track is invalid /// </summary> /// <param name="direction">0 - 3 representing the four directions out of the junction</param> /// <returns>True if it found complete segment</returns> public bool TrackFollow(int direction) { //Initialize the check from the junction long nextX = this.mnX; long nextY = this.mnY; long nextZ = this.mnZ; Vector3 dirvec = new Vector3(); bool mirrorOk = true; //Store the initial junction direction for later recording which direction the connected junction is associated with int initialdirection = direction; //There are many ways to derail, so set that result now, and assume it later. Saves much repeat of these lines. this.DirectionResults [initialdirection] = FreightTrackDirectionResults.Bad; this.ConnectedJunctions [initialdirection] = null; this.ConnectedSegments [initialdirection] = null; //List of freight cart stations found on this segment -> to be written to the final constructed FreightTrackSegment List <FreightCartStation> SegmentStations = new List <FreightCartStation>(); //Store visited track pieces for catching when the segment enters a closed loop //We're only testing for a unique key here, so no Tvalue will be used. StringDictionary VisitedTracks = new StringDictionary(); //Begin loop here. Direction can be set and used to check the next location each time through the loop //Allow segments only up to 512m long due to cost of loop checking - may revise after testing for (this.SegmentDistances[initialdirection] = 0; this.SegmentDistances[initialdirection] < 2048; this.SegmentDistances[initialdirection]++) { switch (direction) { case 0: nextX++; dirvec = Vector3.right; break; case 1: nextZ++; dirvec = Vector3.forward; break; case 2: nextX--; dirvec = Vector3.left; break; case 3: nextZ--; dirvec = Vector3.back; break; default: nextX++; break; } ushort lValue1 = 0; byte lFlags1 = 0; ushort type = this.GetCube(nextX, nextY, nextZ, out lValue1, out lFlags1); this.mUnderSegment = this.mPrevGetSeg; //Debug.LogWarning("GetCube type: " + type.ToString() + " value: " + lValue1); bool foundslope = false; //Found air and need to check for a downward slope under it if (type == 1) { ushort lValue2 = 0; byte lFlags2 = 0; ushort cube = this.GetCube(nextX, nextY - 1L, nextZ, out lValue2, out lFlags2); Segment segment = this.mPrevGetSeg; type = cube; lFlags1 = lFlags2; lValue1 = lValue2; if ((type == 538 && lValue1 == 2) || (type == ScrapTrackType && lValue1 == ScrapSlopeVal)) { foundslope = true; nextY--; //decrement Y level for next loop through! } else { if (type == 0) { Debug.LogError("Error, track follower has null under segment!"); } if (this.mPrevGetSeg == null) { Debug.LogError("Error, prevseg was null!"); } if (segment == null) { Debug.LogError("Error, old was null!"); } if (this.mPrevGetSeg != segment) { Debug.LogWarning(("Track follower is looking for a slope, and has had to check across segment boundaries for this![Old/New" + segment.GetName() + " -> " + this.mPrevGetSeg.GetName())); } return(false); } } Vector3 trackvec = SegmentCustomRenderer.GetRotationQuaternion(lFlags1) * Vector3.forward; trackvec.Normalize(); trackvec.x = trackvec.x >= -0.5 ? (trackvec.x <= 0.5 ? 0.0f : 1f) : -1f; trackvec.y = trackvec.y >= -0.5 ? (trackvec.y <= 0.5 ? 0.0f : 1f) : -1f; trackvec.z = trackvec.z >= -0.5 ? (trackvec.z <= 0.5 ? 0.0f : 1f) : -1f; //Begin checking track type if (type == TRACKTYPE || type == ScrapTrackType) { if ((type == TRACKTYPE && (lValue1 == TRACKSTRAIGHT || lValue1 == TRACKEMPTY || lValue1 == TRACKFULL)) || (type == ScrapTrackType && lValue1 == ScrapStraightVal)) { if (trackvec.y > 0.5 || trackvec.y < -0.5) { return(false); } else if (!(trackvec == dirvec) && !(trackvec == -dirvec)) { // Came in from the side, this path is one-way. mirrorOk = false; dirvec = new Vector3(trackvec.x, 0f, trackvec.z); } } if ((type == TRACKTYPE && lValue1 == TRACKCORNER) || (type == ScrapTrackType && lValue1 == ScrapCornerVal)) { if (dirvec == new Vector3(-trackvec.z, 0.0f, trackvec.x)) { dirvec = new Vector3(dirvec.z, 0.0f, -dirvec.x); } else if (trackvec == -dirvec) { dirvec = new Vector3(-dirvec.z, 0.0f, dirvec.x); } else { return(false); } } if ((type == TRACKTYPE && lValue1 == TRACKSLOPE) || (type == ScrapTrackType && lValue1 == ScrapSlopeVal)) { Vector3 vector3_2 = trackvec; dirvec.y = 0.0f; dirvec.Normalize(); if (dirvec == trackvec) { if (foundslope) { return(false); } else { nextY++; } } else if (dirvec == -trackvec) { ; } } if (type == TRACKTYPE && lValue1 == TRACKBUFFER) { dirvec = new Vector3(-dirvec.x, 0f, -dirvec.z); } } //Begin checking special types else if (type == CONTROLTYPE) { if (lValue1 == CONTROLLOAD || lValue1 == CONTROLUNLOAD || lValue1 == CONTROLTURBO) { if ((trackvec == dirvec) || (trackvec == -dirvec)) { //Do nothing... direction doesn't change } else { return(false); } } } //Check for freight stations else if (type == FREIGHTSTATIONTYPE) { if ((trackvec == dirvec) || (trackvec == -dirvec)) { Segment segment = this.AttemptGetSegment(nextX, nextY, nextZ); if (segment == null) { segment = WorldScript.instance.GetSegment(nextX, nextY, nextZ); if (segment == null) { Debug.Log((object)"Track junction track follower did not find segment"); return(false); } } FreightCartStation fcs = segment.FetchEntity(eSegmentEntity.Mod, nextX, nextY, nextZ) as FreightCartStation; if (fcs == null) { Debug.LogWarning("Track Junction Track Follower tried to get a freight cart station but got other mod machine instead?"); return(false); } if (!SegmentStations.Contains(fcs)) { SegmentStations.Add(fcs); } fcs.ClosestJunction = this; fcs.JunctionDirection = initialdirection; } else { return(false); } } //Is it a junction? else if (type == JUNCTIONTYPE) { //Debug.LogWarning("Track follower success! Found another junction!"); Segment segment = this.AttemptGetSegment(nextX, nextY, nextZ); if (segment == null) { segment = WorldScript.instance.GetSegment(nextX, nextY, nextZ); if (segment == null) { Debug.Log((object)"Track junction track follower did not find segment"); return(false); } } FreightTrackJunction junction = segment.FetchEntity(eSegmentEntity.Mod, nextX, nextY, nextZ) as FreightTrackJunction; if (junction == null) { Debug.LogWarning("Track Junction Track Follower tried to get a track junction but got other mod machine instead?"); return(false); } //Mark this segment as a loop coming back to ourselves. if (junction == this) { this.DirectionResults[initialdirection] = FreightTrackDirectionResults.Self; } else { this.DirectionResults[initialdirection] = FreightTrackDirectionResults.Good; } this.SegmentDistances[initialdirection] += 1; // We're going to exit the loop here, messing with loop variable OK'd. this.ConnectedJunctions[initialdirection] = junction; FreightTrackSegment tracksegment = new FreightTrackSegment(this, junction, this.SegmentDistances[initialdirection]); tracksegment.Stations = SegmentStations; //Debug.LogWarning("trackseg station count: " + tracksegment.Stations.Count); this.ConnectedSegments[initialdirection] = tracksegment; this.LinkStatusDirty = true; //If path is bi-directional, handle the connection for the other junction so we don't need to double the work if (mirrorOk) { //Mirror the direction to reflect the correct side of the connecting junction int mirroreddir = direction += 2; if (mirroreddir > 3) { mirroreddir -= 4; } junction.ConnectedJunctions [mirroreddir] = this; junction.ConnectedSegments [mirroreddir] = tracksegment; junction.SegmentDistances [mirroreddir] = this.SegmentDistances[initialdirection]; junction.DirectionResults[mirroreddir] = this.DirectionResults[initialdirection];//Either "Good junction.LinkStatusDirty = true; } return(true); } else if (type == TOURSTATIONTYPE) { if (trackvec != -dirvec) { return(false); } Segment segment = this.AttemptGetSegment(nextX, nextY, nextZ); if (segment == null) { segment = WorldScript.instance.GetSegment(nextX, nextY, nextZ); if (segment == null) { Debug.Log((object)"Track junction track follower did not find segment"); return(false); } } TourCartStation station = segment.FetchEntity(eSegmentEntity.Mod, nextX, nextY, nextZ) as TourCartStation; station.TrackNetwork = this.TrackNetwork; station.ClosestJunction = this; station.JunctionDirection = initialdirection; this.ConnectedJunctions[initialdirection] = this; FreightTrackSegment tracksegment = new FreightTrackSegment(this, this, 2 * this.SegmentDistances[initialdirection] + 1); this.SegmentDistances[initialdirection] *= 2; this.SegmentDistances[initialdirection] += 1; this.ConnectedSegments[initialdirection] = tracksegment; this.LinkStatusDirty = true; if (!string.IsNullOrEmpty(station.StationName) && !this.TrackNetwork.TourCartStations.ContainsKey(station.StationName)) { this.TrackNetwork.TourCartStations.Add(station.StationName, station); } return(true); } else { return(false); //Not a track type } //Update the direction int based on the changed direction vector if (dirvec == Vector3.right) { direction = 0; } else if (dirvec == Vector3.forward) { direction = 1; } else if (dirvec == Vector3.left) { direction = 2; } else if (dirvec == Vector3.back) { direction = 3; } //Store a hash of every track piece to check for getting stuck in endless loops. //HACK Construct a string to be our HashTable Key. //We could implement a fancy struct or something, but this works, and we don't have to make a custom GetHashTag function //(Struct.gethash() is apparently very inefficient) //And the try/catch construct means we only do one hash lookup even. try{ //Build a string which will be unique for this particular track segment and travel direction. Lots and Lots of implicit casting to string on this line. VisitedTracks.Add((nextX - this.mnX) + "," + (nextY - this.mnY) + "," + (nextZ - this.mnZ) + "," + direction, null); } catch { Debug.LogWarning("TrackJunction followed track route and found an infinite loop. Ending search."); this.DirectionResults [initialdirection] = FreightTrackDirectionResults.Trap; return(false); } } Debug.LogWarning("Track Junction Found track length > 512m -> ending search."); return(false); }