1. Dashboard
  2. Articles
  3. Members
    1. Recent Activities
    2. Users Online
    3. Team
    4. Search Members
  4. Blog
    1. Articles
  5. Filebase
    1. Shop "Z"
  6. Forum
  7. Lexicon
    1. Documentation
  8. 🏷️Support
    1. FAQ
    2. Kuid's
  9. Gallery
    1. Albums
  • Login or register
  • Search
Schoolroom
  • Everywhere
  • Schoolroom
  • Articles
  • Pages
  • Blog Articles
  • Files
  • Forum
  • Lexicon
  • Tickets
  • FAQ
  • Gallery
  • More Options
  1. Wikiquik
  2. Articles
  3. Schoolroom

SmartSignal

  • Wikiquik
  • February 8, 2024 at 2:24 AM
  • 770 Views
  • 0 Comments
C++: Introduction
class SmartSignal isclass Signal
{
	//these are the basic signal types
	//01  - n/a
	//02  - n/a
	//03  - absolute signals with slow approach aspects as the highest aspect
	//04  - absolute signal
	//05  - permissive signal
	//06  - double head diverging signal
	//07  - double head converging signal (top head always red)
	//08  - triple head speed interlocking signal
	//081 - triple head speed interlocking signal with approach aspects as highest

	//these are the states that default trainz signalling can understand.
	//0  EX_STOP
	//1  EX_STOP_THEN_CONTINUE
	//4  EX_CAUTION
	//7  EX_ADVANCE_CAUTION
	//8  EX_PROCEED

	//2  EX_CAUTION_LEFT
	//3  EX_CAUTION_RIGHT
	//9  EX_SLOW
	//10  EX_MEDIUM
	//11  EX_ADVANCE_CAUTION_LEFT
	//12  EX_ADVANCE_CAUTION_RIGHT
	//5  EX_PROCEED_LEFT
	//6  EX_PROCEED_RIGHT

	// so I will take thse and make them more understandable for these scripts, which use the aspect slots but change the names.
	// Limited Speed........45mph
	// Medium Speed.........30mph
	// Slow Speed...........15mph
	// Restricted Speed.....15mph

	// not used as a visible state
	public define int SS_DARK                   = 25;  //!< to turn off lens
	// shared states
	public define int SS_STOP                    = 0;   //!< Stop incidcation.
	public define int SS_STOP_THEN_PROCEED       = 1;   //!< Permissive Stop indication.
	public define int SS_APPROACH                = 4;   //!< The next signal is red.
	public define int SS_ADVANCE_APPROACH        = 7;   //!< The next signal is yellow.
	public define int SS_PROCEED                 = 8;   //!< Proceed.

	// 06D and 06
	public define int SS_APPROACH_LIMITED        = 12;  //!< Approach next signal not exceeding Limited Speed.
	public define int SS_APPROACH_MEDIUM			   = 11;  //!< Approach next signal not exceeding Medium Speed.
	// 06 and 08
	public define int SS_LIMITED_CLEAR           = 6;   //!< Limited speed through turnouts, crossovers, sidings, and power operated switches; then proceed at maximum speed permitted.
	public define int SS_MEDIUM_CLEAR            = 5;   //!< Medium speed through turnouts, crossovers, sidings, and power operated switches; then proceed at maximum speed permitted.
	public define int SS_LIMITED_APPROACH        = 2;   //!< Limited speed through turnouts, crossovers, sidings, and power operated switches; then proceed prepared to stop at next signal.
	public define int SS_MEDIUM_APPROACH         = 3;   //!< Medium speed through turnouts, crossovers, sidings, and power operated switches; then proceed prepared to stop at next signal. Diverging Approach.

	// special states
	public define int SS_RESTRICTING						 = 9;   //!< Proceed at restricting speed.
	public define int SS_SLOW										 = 10;  //!< Proceed at Slow speed.

	//B&O 03 CPLs
  public define int SS_SLOW_APPROACH           = 9;   //!<
  public define int SS_SLOW_APPROACH_SLOW      = 7;

	// extended states not understood by default trainz signals... be careful with these.

	// 08 signals only.
	public define int SS_MED_APPROACH_MEDIUM     = 13;  //!< Medium speed through turnouts, crossovers, sidings, and power operated switches; then proceed approaching next signal not exceeding Medium Speed.
	public define int SS_MED_APPROACH_SLOW       = 14;  //!< Medium speed through turnouts, crossovers, sidings, and power operated switches; then proceed approaching next signal not exceeding Slow Speed.

	public define int SS_APPROACH_RESTRICTING    = 15;   //!< 06d heads only when placed before 06 or 08
	public define int SS_APPROACH_SLOW           = 16;  //08 B&O
	
	//head angle snap amount
	public define int SS_ANGLE_SNAP              = 5;  //degrees
Display More
C++: DescState
public string DescState(int State, StringTable m_textStrings)
	{
		string desc;
		switch (State)
		{
			case SS_STOP:
				desc = m_textStrings.GetString("signal_stop");
				break;
			case SS_STOP_THEN_PROCEED:
				desc = m_textStrings.GetString("signal_stop_proceed");
				break;
			case SS_LIMITED_APPROACH:
				desc = m_textStrings.GetString("signal_limited_approach");
				break;
			case SS_MEDIUM_APPROACH:
				desc = m_textStrings.GetString("signal_medium_approach");
				break;
			case SS_APPROACH:
				desc = m_textStrings.GetString("signal_approach");
				break;
			case SS_MEDIUM_CLEAR:
				desc = m_textStrings.GetString("signal_medium_clear");
				break;
			case SS_LIMITED_CLEAR:
				desc = m_textStrings.GetString("signal_limited_clear");
				break;
			case SS_ADVANCE_APPROACH:
				desc = m_textStrings.GetString("signal_advance_approach");
				break;
			case SS_PROCEED:
				desc = m_textStrings.GetString("signal_clear");
				break;
			case SS_RESTRICTING:
				desc = m_textStrings.GetString("signal_restricting");
				break;
			case SS_SLOW:
				desc = m_textStrings.GetString("signal_slow_clear");
				break;
			case SS_APPROACH_MEDIUM:
				desc = m_textStrings.GetString("signal_approach_medium");
				break;
			case SS_APPROACH_LIMITED:
				desc = m_textStrings.GetString("signal_approach_limited");
				break;
			case SS_MED_APPROACH_MEDIUM:
				desc = m_textStrings.GetString("signal_med_approach_med");
				break;
			case SS_MED_APPROACH_SLOW:
			  desc = m_textStrings.GetString("signal_med_approach_slow");
				break;
			case SS_APPROACH_RESTRICTING:
				desc = m_textStrings.GetString("signal_approach_restr");
				break;
			case SS_APPROACH_SLOW:
				desc = m_textStrings.GetString("signal_approach_slow");
				break;
			default:
				desc = m_textStrings.GetString("signal_error");
		}
		return desc;
	}
};
Display More
  • sets the rotation of the signal head
  • MeshObject a signal is a signal asset
  • plovák headDeflection is the deflection angle in degrees
C++: Folat
static class SmartSignalCommon
{
	public void SetHeadDeflection(MeshObject signal, float headDeflection)
	{
		float angle = headDeflection * (Math.PI/180);
		if(signal.HasMesh("head_1")) {signal.SetMeshOrientation("head_1", 0, 0, angle);}
		if(signal.HasMesh("head_2")) {signal.SetMeshOrientation("head_2", 0, 0, angle);}
		if(signal.HasMesh("head_3")) {signal.SetMeshOrientation("head_3", 0, 0, angle);}
	}
  • sets the letters of the signal tables
  • p_name: is a mesh board
  • p_color: it must be an alphabetical set of textures listing 1-26, 27-36 because the numbers '0' are empty
  • p_value: is a letter (only one letter is accepted and the string will be truncated to one letter)
C++: SetLatters
public void SetLetters(MeshObject signal, string p_name, Asset p_color , string p_value)
  {
  	Str.ToUpper(p_value);

  	     if (p_value == "N") signal.SetFXTextureReplacement(p_name,p_color,14);
  	else if (p_value == "S") signal.SetFXTextureReplacement(p_name,p_color,19);
  	else if (p_value == "E") signal.SetFXTextureReplacement(p_name,p_color,5);
  	else if (p_value == "W") signal.SetFXTextureReplacement(p_name,p_color,23);
  	else if (p_value == "A") signal.SetFXTextureReplacement(p_name,p_color,1);
  	else if (p_value == "B") signal.SetFXTextureReplacement(p_name,p_color,2);
  	else if (p_value == "C") signal.SetFXTextureReplacement(p_name,p_color,3);
  	else if (p_value == "D") signal.SetFXTextureReplacement(p_name,p_color,4);
  	else if (p_value == "F") signal.SetFXTextureReplacement(p_name,p_color,6);
  	else if (p_value == "G") signal.SetFXTextureReplacement(p_name,p_color,7);
  	else if (p_value == "H") signal.SetFXTextureReplacement(p_name,p_color,8);
  	else if (p_value == "I") signal.SetFXTextureReplacement(p_name,p_color,9);
  	else if (p_value == "J") signal.SetFXTextureReplacement(p_name,p_color,10);
  	else if (p_value == "K") signal.SetFXTextureReplacement(p_name,p_color,11);
  	else if (p_value == "L") signal.SetFXTextureReplacement(p_name,p_color,12);
  	else if (p_value == "M") signal.SetFXTextureReplacement(p_name,p_color,13);
  	else if (p_value == "O") signal.SetFXTextureReplacement(p_name,p_color,15);
  	else if (p_value == "P") signal.SetFXTextureReplacement(p_name,p_color,16);
  	else if (p_value == "Q") signal.SetFXTextureReplacement(p_name,p_color,17);
  	else if (p_value == "R") signal.SetFXTextureReplacement(p_name,p_color,18);
  	else if (p_value == "T") signal.SetFXTextureReplacement(p_name,p_color,20);
  	else if (p_value == "U") signal.SetFXTextureReplacement(p_name,p_color,21);
  	else if (p_value == "V") signal.SetFXTextureReplacement(p_name,p_color,22);
  	else if (p_value == "X") signal.SetFXTextureReplacement(p_name,p_color,24);
  	else if (p_value == "Y") signal.SetFXTextureReplacement(p_name,p_color,25);
  	else if (p_value == "Z") signal.SetFXTextureReplacement(p_name,p_color,26);

  	else if (p_value == "0") signal.SetFXTextureReplacement(p_name,p_color,27);
  	else if (p_value == "1") signal.SetFXTextureReplacement(p_name,p_color,28);
  	else if (p_value == "2") signal.SetFXTextureReplacement(p_name,p_color,29);
  	else if (p_value == "3") signal.SetFXTextureReplacement(p_name,p_color,30);
  	else if (p_value == "4") signal.SetFXTextureReplacement(p_name,p_color,31);
  	else if (p_value == "5") signal.SetFXTextureReplacement(p_name,p_color,32);
  	else if (p_value == "6") signal.SetFXTextureReplacement(p_name,p_color,33);
  	else if (p_value == "7") signal.SetFXTextureReplacement(p_name,p_color,34);
  	else if (p_value == "8") signal.SetFXTextureReplacement(p_name,p_color,35);
  	else if (p_value == "9") signal.SetFXTextureReplacement(p_name,p_color,36);
  	else signal.SetFXTextureReplacement(p_name,p_color,0);

  	//Interface.Log(p_name + ": " + p_value);
  }
Display More

Basic property types for all SmartSignals in Surveyor

C++
	public string SSPropertyTypes(string pID)
	{
		string result;
		if (pID[,6] == "sigNum") result = "string,1,5";
		else if (pID[,8] == "powerNum") result = "int,0,9999,1";
		else if (pID[,9] == "plateType") result = "list";
		else result = "link";
		return result;
	}

Creates an HTML slider

C++: GetSliderHTML
  string GetSliderHTML(string name, int min, int max)
  {
    // Generate a html slider using a horizontal scroll bar
    string html;
    html = html + "<a href='live://property/" + name + "'>";
    html = html + "  <trainz-object id='" + name + "' style=slider horizontal theme=default-slider width=200 height=20 min=" + min + " max=" + max + " page-size=1 draw-line=1 draw-marks=1>";
    html = html + "  </trainz-object>";
    html = html + "</a>";
    return html;
  }

Basic user interface for all SmartSignals in Surveyor

C++: SurveyorHTML
public string SurveyorHTML(StringTable m_textStrings, Soup properties)
	{
		Asset SSAsset = World.FindAsset(properties.GetNamedTagAsKUID("SSkuid"));
		HTMLBuffer Buffer = HTMLBufferStatic.Construct();
  	Buffer.Clear();
  	Buffer.Print("<html><body><font size=3><br>");
  	string type = properties.GetNamedTag("SignalType");
    //--------------------------------signal head angle-----------------------------------
    if (properties.GetNamedTagAsBool("showHeadAngleUI",false))
    { 
    	Buffer.Print("<p>" +  m_textStrings.GetString("cfg_head_angle") + GetSliderHTML("headAngle", -(90 / SmartSignal.SS_ANGLE_SNAP), 90 / SmartSignal.SS_ANGLE_SNAP) + "</p>");
    }
  	//--------------------------------path interface-----------------------------------
	  if (properties.GetNamedTagAsBool("showPathUI",false))
    {
		  string pathStraight = properties.GetNamedTag("pathStraight");
		  string pathImg;
		  KUID kuidImgLeft = SSAsset.LookupKUIDTable("imgLeft");
		  KUID kuidImgRight = SSAsset.LookupKUIDTable("imgRight");
		  KUID kuidImgFwd = SSAsset.LookupKUIDTable("imgFwd");
			int i;
			Buffer.Print("<p>" + m_textStrings.GetString("cfg_define_path") + ": <br>");
      for (i = 0; i < pathStraight.size(); i++)
      {
				if (i > 0) Buffer.Print(" | ");
				//determine the icon to display
				if (pathStraight[i,i + 1] == "L")
				{
					pathImg = kuidImgLeft.GetHTMLString();
				}
				else if (pathStraight[i,i + 1] == "R")
				{
					pathImg = kuidImgRight.GetHTMLString();
				}
				else if (pathStraight[i,i + 1] == "F")
				{
					pathImg = kuidImgFwd.GetHTMLString();
				}
				//display link
				Buffer.Print("<a href=live://property/path" + i + ">");
				Buffer.Print("<img kuid='" + pathImg + "' width=32 height=32>");
				Buffer.Print("</a>");
			}
			Buffer.Print("</p><br>");
			Buffer.Print("<p>" + m_textStrings.GetString("cfg_edit") + ": <a href=live://property/clear>" + m_textStrings.GetString("cfg_clear") + "</a>");
			Buffer.Print(" or <a href=live://property/remove>" + m_textStrings.GetString("cfg_remove") + "</a>");
			Buffer.Print(" or <a href=live://property/add>" + m_textStrings.GetString("cfg_add") + "</a>");
			Buffer.Print("</p><br>");
		}
Display More

Unbound control

C++: unbonded check
		if ((type == "06" or type == "06prr") and (properties.GetNamedTagAsBool("showPathUI",false)))
		{
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/detBond", properties.GetNamedTagAsBool("unbonded",false)) + m_textStrings.GetString("cfg_unbonded") + "</p>");
		}

Activate limited speed

C++: enable limited speed
	  if (properties.GetNamedTagAsBool("showPathUI",false) and (!properties.GetNamedTagAsBool("unbonded",false)) and (
	  	     type == "06"
	  	  or type == "08"
	  	  or type == "08-1"))
    {
    	Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/limited", properties.GetNamedTagAsBool("limitedSpeed",false)) + m_textStrings.GetString("cfg_limited_speed") + "</p>");
    }

Show approach or clear

C++: show advance approach or clear
		if (properties.GetNamedTagAsBool("showAdvAppUI",false))
		{
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/advanceApp", properties.GetNamedTagAsBool("advanceApp",false)) + m_textStrings.GetString("cfg_advance_app") + "</p>");
		}

Display restrictions

C++: restricting display
		if (properties.GetNamedTagAsBool("showRestrictingUI",false))
		{
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/restricting", properties.GetNamedTagAsBool("allowRestricting",false)) + m_textStrings.GetString("cfg_restricting") + "</p>");
		}

Zoom in on lighting and channel

C++: approach lit and channel
bool approachLit = properties.GetNamedTagAsBool("approachLit",false);
		Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/approachLit", approachLit) + m_textStrings.GetString("cfg_approach_lit") + "</p>");
		if (approachLit)
		{
			int gChannel = properties.GetNamedTagAsInt("gChannel",0);
			Buffer.Print("<p>" + m_textStrings.GetString("cfg_approach_lit_channel") + ": <a href=live://property/powerNum>");
			if (gChannel)
			{
	    	Buffer.Print(gChannel);
	    }
	    else
	    {
	    	Buffer.Print(m_textStrings.GetString("cfg_none"));
	    }
	    Buffer.Print("</a></p>");
		}
Display More

Show clearly when idle

C++: show clear when idle
if(  (type == "03")
			or (type == "04")
			or (type == "05")
			or (type == "06")
			or (type == "06D"))
		{
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/idleClear", properties.GetNamedTagAsBool("idleClear",false)) + m_textStrings.GetString("cfg_idle_clear") + "</p>");
		}

Stop type

C++
		if (properties.GetNamedTagAsBool("showPRRstop",false))
		{
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/stopType", properties.GetNamedTagAsBool("stopType",false)) + m_textStrings.GetString("cfg_prr_stop_type") + "</p>");
		}

The train orders a light

C++
		if (properties.GetNamedTagAsBool("showOrderLightUI",false))
		{
			bool showLamp = properties.GetNamedTagAsBool("showOrderLight",false);
			bool onLeft = properties.GetNamedTagAsBool("ordersLightOnLeft",false);
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/orderslight", showLamp)
			                   + m_textStrings.GetString("cfg_show_orders_light"));
			if (showLamp)
			{
				Buffer.Print(": <a href=live://property/olside>");
				if(onLeft)
				{
					Buffer.Print(m_textStrings.GetString("cfg_left"));
				} else {
					Buffer.Print(m_textStrings.GetString("cfg_right"));
				}
				Buffer.Print("</a></p>");
			}
		}
Display More

Setting the tables and markers for the signal

Code
		if (properties.GetNamedTagAsBool("showAbsUI",false))
		{
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/aplate", properties.GetNamedTagAsBool("aplate",false)) + m_textStrings.GetString("cfg_abslt_plate") + "</p>");
		}
		if (properties.GetNamedTagAsBool("showGrdUI",false))
		{
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/gplate", properties.GetNamedTagAsBool("gplate",false)) + m_textStrings.GetString("cfg_grade_plate") + "</p>");
		}
		if (properties.GetNamedTagAsBool("showRplUI",false))
		{
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/rplate", properties.GetNamedTagAsBool("rplate",false)) + m_textStrings.GetString("cfg_restr_plate") + "</p>");
		}
Display More

Marking

C++
		if (properties.GetNamedTagAsBool("showMarkerUI",false))
		{
			Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/marker", properties.GetNamedTagAsBool("marker",false)) + m_textStrings.GetString("cfg_marker") + "</p>");
		}

Number plate

C++: get numberplate style
		if (properties.GetNamedTagAsBool("showPlateUI",false))
		{
			int plateType = properties.GetNamedTagAsInt("plateType");
			string plateDesc = properties.GetNamedTag("plateDesc");
			Buffer.Print(m_textStrings.GetString("cfg_number_plate_type") + ": <a href=live://property/plateType>");
			if (plateType > -1)
	    {
	    	Buffer.Print(plateDesc);
	    }
	    else
	    {
	    	Buffer.Print(m_textStrings.GetString("cfg_default"));
	    }
			Buffer.Print("</a><br>");
Display More
C++: get plate number
			string myNum = properties.GetNamedTag("number");
			Buffer.Print(m_textStrings.GetString("cfg_signal_number") + ": <a href=live://property/sigNum>");
			if (myNum != "")
			{
	    	Buffer.Print(myNum);
	    }
	    else
	    {
	    	Buffer.Print(m_textStrings.GetString("cfg_none"));
	    }
			Buffer.Print("</a><br>");
		}	
Display More

Termination of HTML

C++: End HTML
		Buffer.Print("</font></body></html>");
		return Buffer.AsString();
	}


C++: GetPropValue
	public string SSGetPropValue(StringTable m_textStrings, Soup properties, string pID)
	{
		string result;
		if (pID[,8] == "powerNum")
		{
			int gChannel = properties.GetNamedTagAsInt("gChannel",0);
			if(gChannel >= 0)
			{
				result = gChannel;
			}
			else
			result = "";
		}
		if (pID[,6] == "sigNum")
    {
    	string myNum = properties.GetNamedTag("number");
   		if (myNum != "")
   			{
   				result = myNum;
   			}
   		else
   			result = "";
    }
		return result;
	}
Display More

Basic user interface for all SmartSignals in the controller

C++: DriverHTML
public string DriverHTML(StringTable m_textStrings, Soup properties)
	{
  	HTMLBuffer Buffer = HTMLBufferStatic.Construct();
  	Buffer.Clear();

  	Buffer.Print("<html><body>");
    //can we display restricting override?
    if(properties.GetNamedTagAsBool("show_override",false))
  	{
	    Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/restricting", properties.GetNamedTagAsBool("restricting_override",false))
	                       + m_textStrings.GetString("cfg_toggle_restricting") + "</p>");
  	}
  	//can we display train order indicator
    if(properties.GetNamedTagAsBool("show_orders_toggle",false))
  	{
  		Buffer.Print("<p>" + HTMLWindow.CheckBox("live://property/orders", properties.GetNamedTagAsBool("has_orders",false))
  		                   + m_textStrings.GetString("cfg_toggle_orders") + "</p>");
  	}
    //end html
    Buffer.Print("</body></html>");

		return Buffer.AsString();
	}
Display More


Common logic section of signals

Block distance to the next absolute signal

C++: BlockDistance
public float BlockDistance(Signal start)
	{
		//this returns the block distance to the next absolute signal, and also the junction beyond that one for the opposing trains.
		MapObject dMapObject;
	  GSTrackSearch DGST = start.BeginTrackSearch(true);
	  int cntr = 0;
	  float distance = 0;
	  Signal nextSignal = null;
	  while(dMapObject = DGST.SearchNext())
		{
			if(cast<Signal> dMapObject)
		  {
		  	if(!DGST.GetFacingRelativeToSearchDirection())
		    {
		    	nextSignal = (cast<Signal> dMapObject);
		 			if (nextSignal.CanDisplayStateEx(1))
		  		{
						//Interface.Log("smartsignal.gs: <" + me.GetLocalisedName() + ">: Found intermediate signal.");
		 			}
		 			else
		 			{
						// If the next signal is absolute, set this block distance.
						//This is the determined block length from the start signal to the next opposite facing absolute signal
						distance = DGST.GetDistance();
						break;
					}
		 		}
		 	}
		}
		return distance;
	}
Display More
  • Param: start....The signal to start from
  • Param: searchDirection.....Which direction to search. 'False' == behind the signal, 'True' == before the signal.
  • Param: numSignalsToCheck.....Number of signal blocks to scan. 0 for any.
  • Param: maxDistance.....How far on the track chart to search for a train

It checks if the block is active and returns a reference to the train if found.

The train does not need to move to activate the block.

C++: checkBlockActive
public Train checkBlockActive(Signal start, bool searchDirection, int numSignalsToCheck, float maxDistance)
  {
		GSTrackSearch myGST = start.BeginTrackSearch(searchDirection);
		MapObject nextMapObject;
		int signalCount = 0;
		Vehicle theVeh;

    while(nextMapObject = myGST.SearchNext())
    {
    	if(myGST.GetDistance() > maxDistance)
    	{
	    	return null;
      }
      else if(cast<Signal> nextMapObject)
      {
      	if(!myGST.GetFacingRelativeToSearchDirection())
      	{
      		if((numSignalsToCheck > 0) and (++signalCount > numSignalsToCheck))
      		{
      			return null;
      		}
      	}
      }
      else if(cast<Vehicle> nextMapObject)
      {
      	theVeh = cast<Vehicle> nextMapObject;
      	return theVeh.GetMyTrain();
	    }
    }
    return null;
  }
Display More

Find the closest approaching train for a specific signal

The train must move towards or in the direction of the signal and stop.

C++: TrainMovingTowardSignal
public Train TrainMovingTowardSignal(Signal start, bool searchDirection, int numSignalsToCheck, float maxDistance)
	{
		GSTrackSearch myGST = start.BeginTrackSearch(searchDirection);
		MapObject nextMapObject;
		Vehicle theVeh;
		Train theTrain;
		int signalCount;

    while(nextMapObject = myGST.SearchNext())
    {
    	if(myGST.GetDistance() > maxDistance)
    	{
	    	return null;
      }
      else if(cast<Signal> nextMapObject)
      {
      	if(!myGST.GetFacingRelativeToSearchDirection())
      	{
      		if((numSignalsToCheck > 0) and (++signalCount > numSignalsToCheck))
      		{
      			return null;
      		}
      	}
      }
      else if(cast<Vehicle> nextMapObject)
      {
      	theVeh = cast<Vehicle> nextMapObject;
      	theTrain = theVeh.GetMyTrain();
      	if(!theTrain.TracksideIsInFront(start,(myGST.GetDistance() + 200)))
      	{
      		//train is facing away from signal
      		if(theTrain.GetTrainVelocity() < -0.01) { //if train is backing in my direction
	      		return theTrain;
	      	} else {
	      		return null;
	      	}
      	} else {
      		//train is facing signal
       		if(theTrain.GetTrainVelocity() > -0.01) { //if train is moving forward or facing my direction and stopped.
		      	return theTrain;
		      } else {
		      	return null;
					}
      	}
	    }
    }
    return null;
  }
};
Display More
  • Previous Article DetermineUpdatedState
  • Next Article Basics of HTML - rt

Comments

  • Smilies
  • Default Category
  • Gif
  • Special
  • Flags
  • Seasonal
  • Office
  • Wikquik
  • :)
  • :(
  • ;)
  • :P
  • ^^
  • :D
  • ;(
  • X(
  • :*
  • :|
  • 8o
  • =O
  • <X
  • ||
  • :/
  • :S
  • X/
  • 8)
  • ?(
  • :huh:
  • :rolleyes:
  • :love:
  • 8|
  • :cursing:
  • :thumbdown:
  • :thumbup:
  • :sleeping:
  • :whistling:
  • :evil:
  • :saint:
  • <3
  • :!:
  • :?:
  • Smilies
  • Default Category
  • Gif
  • Special
  • Flags
  • Seasonal
  • Office
  • Wikquik
  • :)
  • :(
  • ;)
  • :P
  • ^^
  • :D
  • ;(
  • X(
  • :*
  • :|
  • 8o
  • =O
  • <X
  • ||
  • :/
  • :S
  • X/
  • 8)
  • ?(
  • :huh:
  • :rolleyes:
  • :love:
  • 8|
  • :cursing:
  • :thumbdown:
  • :thumbup:
  • :sleeping:
  • :whistling:
  • :evil:
  • :saint:
  • <3
  • :!:
  • :?:

Categories

  1. News 2
  2. Schoolroom 4
  3. Animation 1
  4. 2D Creation 0
  5. 3D Creation 0
  6. Review 1
  7. Buildings and Technology 0
  8. Travel and Learning 2
  9. Reset Filter
  1. Privacy Policy
  2. Contact
  3. Legal Notice
Powered by WoltLab Suite™ 6.0.22