Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions FreightSystemInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.Collections.Generic;
using System;
public interface FreightSystemInterface
{
/// <summary>
/// List of all items that the interface has available to provide to the freight system
/// </summary>
List<FreightListing> FreightOfferings
{
get;
}

/// <summary>
/// List of all items that the interface wants delivered to it by the freight system
/// </summary>
List<FreightListing> FreightRequests
{
get;
}

/// <summary>
/// The freight system calls this when it has an item to offer to the interface
/// </summary>
/// <param name="item">The item being offered to the interface</param>
/// <returns>True if the item is accepted</returns>
bool ReceiveFreight(ItemBase item);

/// <summary>
/// The freight system calls this when requesting an item from the interface
/// </summary>
/// <param name="item">The item the freight system wants the interface to provide</param>
/// <returns>True if the interface successfully provides the item</returns>
bool ProvideFreight(ItemBase item = null);

/// <summary>
/// Determines whether this instance is full.
/// </summary>
/// <returns><c>true</c> if this instance is full; otherwise, <c>false</c>.</returns>
bool IsFull ();
}

/// <summary>
/// Class representing a freight item and offered/requested quantity
/// </summary>
public class FreightListing
{
public ItemBase Item { get; }
public int Quantity { get; set; }

public FreightListing(ItemBase item, int quantity)
{
Item = item;
Quantity = quantity;
}

//Some operator and comparison overrides to make them directly comparable to ItemBase
}
2 changes: 0 additions & 2 deletions SystemMonitorWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,6 @@ private void UpdateStorageInventory()
this.manager.UpdateLabel("iteminfo" + n, iteminfo, Color.white);
}
}
else
this.manager.RedrawWindow();
}
#endregion

Expand Down
127 changes: 77 additions & 50 deletions TrackJunction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using UnityEngine;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.IO;
using System;
Expand All @@ -12,6 +13,14 @@ public class FreightTrackJunction : MachineEntity
public FreightTrackNetwork TrackNetwork;
public FreightTrackJunction[] ConnectedJunctions = new FreightTrackJunction[4];
public FreightTrackSegment[] ConnectedSegments = new FreightTrackSegment[4];
public enum FreightTrackDirectionResults
{
Good,// To another junction
Bad, // Derail any cart that goes this direction
Trap,// Trap any cart in an infinite loop
Self,// Takes you back to here (may have stations that direction)
}
public FreightTrackDirectionResults[] DirectionResults = new FreightTrackDirectionResults[4];
public int JunctionIndex = 0;
public int JunctionID;
public int[] SegmentDistances = new int[4];
Expand Down Expand Up @@ -84,22 +93,25 @@ public override string GetPopupText()
string str = "";
for (int n = 0; n < 4; n++)
{
if (this.ConnectedJunctions[n] != null)
switch (this.DirectionResults [n])
{
case FreightTrackDirectionResults.Good:
count++;
str += SegmentDistances[n].ToString() + ", ";
break;
case FreightTrackDirectionResults.Self:
str += "@";
break;
case FreightTrackDirectionResults.Trap:
str += "L@"; //L for Loop may be easier to understand?
break;
case FreightTrackDirectionResults.Bad:
str += "D@";
break;
}
str += SegmentDistances [n].ToString () + ", ";
}
if (count > 0)
{
str2 = count.ToString() + " valid track connections\n";
str3 = "Track lengths: " + str.Substring(0, str.Length - 2) + "\nPress Q to reset the junction\n";
}
else
{
str2 = "No valid track connections detected\n";
str3 = "";
}
str2 = count.ToString() + " valid track connections\n";
str3 = "Track lengths: " + str.Substring(0, str.Length - 2) + "\nPress Q to reset the junction\n";
if (this.TrackNetwork != null)
{
str4 = "Track Network ID: " + this.TrackNetwork.NetworkID.ToString() + "\nJunction Count: " + this.TrackNetwork.TrackJunctions.Count.ToString() + "\n";
Expand Down Expand Up @@ -142,19 +154,26 @@ public bool TrackFollow(int direction)
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
List<TrackPiece> VisitedTracks = new List<TrackPiece>();
//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 (int n = 0; n < 512; n++)
for (this.SegmentDistances[initialdirection] = 0; this.SegmentDistances[initialdirection] < 2048; this.SegmentDistances[initialdirection]++)
{
switch (direction)
{
Expand Down Expand Up @@ -230,6 +249,8 @@ public bool TrackFollow(int direction)
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);
}
}
Expand Down Expand Up @@ -267,12 +288,11 @@ public bool TrackFollow(int direction)
{
if (lValue1 == CONTROLLOAD || lValue1 == CONTROLUNLOAD || lValue1 == CONTROLTURBO)
{
if ((trackvec == dirvec) || (trackvec == -dirvec))
{
if ((trackvec == dirvec) || (trackvec == -dirvec)) {
//Do nothing... direction doesn't change
}
else
return false;
else
return false;
}
}
//Check for freight stations
Expand Down Expand Up @@ -324,23 +344,33 @@ public bool TrackFollow(int direction)
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, n + 1);
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.SegmentDistances[initialdirection] = n + 1;
this.LinkStatusDirty = true;

//handle the connection for the other junction so we don't need to double the work
//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] = n + 1;
junction.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)
Expand All @@ -362,8 +392,9 @@ public bool TrackFollow(int direction)
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;
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))
Expand All @@ -383,27 +414,23 @@ public bool TrackFollow(int direction)
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;
}
}
//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);
}
VisitedTracks.Add(visitedpiece);
if (n == 511)
Debug.LogWarning("Track Junction Found track length > 512m -> ending search.");
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;
}

Expand Down
Loading