Junction Normal rule working In TRS22?

jd_james

Active member
Back in TANE, I heavily used the Juction Normal rule KUID2:44272:90012:2 on all my routes and layouts to set back switches to it's default routing after a train passes by it. After moving everything to TRS22, It seems that it randomly stops working. It is hard to reproduce the bug consisitantly.

I remove the rule from a session. Save it, open it up again and then set the rule again. Drive the route and it seems to work. But after a while it just stops working.

Other times it just won't work at all.

Anyone use this rule and have problems?
 
Update... After doing some tests, It seems it stops working if you switch from controlling a train to another train located in a diffrent part of a map. still hard to consistantly produce it.
 
I must admit to have never heard of this rule until you posted about it.

I am a bit confused on one point. Do you use the rule to reset points after an AI controlled train has passed through (the AI, in my experience, will always reset any points it has changed) or for trains under manual control?

If it is for manually driven trains then I will assume that the Junction Normal Rule is activated to reset the .junctions by the train passing over a Track Trigger object or reaching a Navigation Point (or similar). In my case I use the Set Junction Rule, triggered by Track Triggers and Navigation Points to reset junctions and I have never had any problems.
 
It is used for manuel control. It works well in TANE. You don't need triggers for it. When you set up the rules for a session, you select that and the rule has two modes. You can create a list of junction to set back automaticly, or you can set all junctions to set back automaticly. I always set all of them back automatic once a train passes over the juction.

Setting up triggers for every switch in a large route sounds like a nightmare!
 
I tried to get gemini to look at the script and try to fix it. But it seems to not know what the hell it is doing... but here is the script...

include "ScenarioBehavior.gs"
include "World.gs"
include "World1.gs"
include "Browser.gs"
include "Trackside.gs"
include "Interface.gs"

class JunctNorm isclass ScenarioBehavior
{

int[] JunctionDirection = new int[0]; // Global variables that are needed
Junction[] Entry = new Junction[0];
StringTable strTable;
string[] JunctNames = new string[0];
bool complete, ControlOrNot;

thread void Runner();

public void Pause (bool paused) // This is the thread that is run at the start
{
if (paused == IsPaused())
return;
SetStateFlags(PAUSED, paused);

if (paused)
{
// immediately hide the existing browser
PostMessage(me, "ControlTypeRule", "Close", 0.0);
}
else
{
Runner(); // Actual controlling thread
}
}

public string GetDescriptionHTML(void) // Description if you click on 'edit'
{
strTable = GetAsset().GetStringTable();
string Cont = "";
string either = "";
string list = "";
string output = "";
int i;
if (complete)
Cont = "All";
else
Cont = "Not All";
if (ControlOrNot)
either = "will";
else
either = "will not";
if (!JunctNames or !JunctNames.size())
{
if (!complete)
{
list = list + "<a href= live://property/add-new> Add Junction </a>";
}
}
else
{
if (!complete)
{
for (i=0;i<JunctNames.size();i++)
{
list = list + "<a href=live://property/junction"+(string)i+"> "+ BrowserInterface.Quote(JunctNames)+"</a><br>";
}
list = list + "<a href= live://property/add-new> Add Junction </a>";
}
}
if (!complete)
output = strTable.GetString1("listing",either);
return "<html><body><font color =#000000>"+strTable.GetString1("default",Cont)+"<br>"+output+"<br>"+list+"</font></body></html>";
}

string GetPropertyDescription(string p_propertyID) // Gets the description of the object.
{
if (p_propertyID == "add-new")
return "Add a junction";
else if (p_propertyID[0,8] == "junction")
return "Remove the junction";
else if (p_propertyID == "new")
return "All or Some controlled";
else if (p_propertyID == "control")
return "Are these controlled or ignored?";
return "<null>";
}

string GetPropertyType(string p_propertyID) // What type of Property are we going to get? I haven't used any other
{ // than list yet. Not sure what is available.
if (p_propertyID == "add-new")
return "list";
else if (p_propertyID[0,8] == "junction")
return "link";
else if (p_propertyID == "new")
return "list";
else if (p_propertyID == "control")
return "list";
return "link";
}

public string GetPropertyValue(string p_propertyID) // Not sure what it does, but this works.
{
return "";
}



void LinkPropertyValue(string p_propertyID) // ALLOWS FOR THE REMOVAL OF ENTRIES
{
string convert = p_propertyID;
convert[0,8]=null;
int index = Str.ToInt(convert);
JunctNames[index, index+1] = null;

}

public string[] GetPropertyElementList(string p_propertyID) // Presents the list of junctions for selection
{
int count,countout;
string[] names = new string[0];
Junction[] junctions = World.GetJunctionList();
if (p_propertyID == "add-new")
{
int i, out = 0;
for (i = 0; i < junctions.size(); i++)
{
if (junctions)
{
string name = junctions.GetLocalisedName();
if (name and name.size())
names[out++] = name;
}
}
if (!JunctNames.size() or !JunctNames or JunctNames.size() == 0)
{
Interface.Log("Error Correction here");
}
else
{
countout = JunctNames.size();
i=0;
while (i < names.size())
{
for (count=0;count<countout;count++)
{
if (names == JunctNames[count])
{
names[i,i+1]=null;
i=0;
break;
}
continue;
}
i = i+1;
}
}
}
else if (p_propertyID == "new")
{
names = new string[2];
names[0] = "All Junctions";
names[1] = "Some Junctions";
}
else if (p_propertyID == "control")
{
names = new string [2];
names[0] = "These will be controlled";
names[1] = "These will be ignored";
}
return names;
}

void SetPropertyValue(string p_propertyID, string p_value) // Set the value to what is selected.
{
Junction junct;
if (p_propertyID == "add-new")
{
JunctNames[JunctNames.size()] = p_value; // Add it to the list
}
else if (p_propertyID == "control")
{
if (p_value == "These will be controlled")
ControlOrNot = true;
else
ControlOrNot = false;
}
else if (p_propertyID == "new")
{
if (p_value == "All Junctions")
complete = true;
else
complete = false;
}
}


public void SetProperties(Soup soup) // Take the stored properties, and set them to the JunctionNames list.
{
inherited(soup);
Junction junct;
int i;
Soup junctions = soup.GetNamedSoup("junctions");
int count = junctions.CountTags();
JunctNames = new string [count];
for (i=0;i<count;++i)
{
JunctNames = junctions.GetNamedTag ((string)i);
}
if (soup.GetNamedTag("AllOrSome")== "true")
complete = true;
else
complete = false;
if (soup.GetNamedTag("ControlledOrNot") == "true")
ControlOrNot = true;
else
ControlOrNot = false;
}

public Soup GetProperties(void) // Save the properties to the soup storage.
{
Soup soup = inherited();
Soup junctions = Constructors.NewSoup();
int i;
int count = JunctNames.size();
for (i=0;i<count;++i)
junctions.SetNamedTag ((string)i,JunctNames); //(string)i converts the interger i to a string number
soup.SetNamedSoup("junctions", junctions); // for example, "1","2",etc
if (complete)
soup.SetNamedTag ("AllOrSome","true");
else
soup.SetNamedTag ("AllOrSome","false");
if (ControlOrNot)
soup.SetNamedTag ("ControlledOrNot","true");
else
soup.SetNamedTag ("ControlledOrNot","false");
return soup;
}



void CallThread (Message msg) // Returns the junction to the orignal state
{
int i,direction;
for (i=0;i<Entry.size();i++)// Find junction in the database
{
if (Entry == cast <Junction> msg.dst) // Is this it?
{
Entry.SetDirection(JunctionDirection);//Yes it is, set junction back to orginal direction
Interface.Log ("Reset Junction " + Entry.GetName());
break;
}
else
continue; //Not right one, look at next position in the list.

}

}

thread void Runner()
{
int i,junctdirection,count,j,countout;
string name;
if (complete)
{
Interface.Log("All Junctions On");
Entry = World.GetJunctionList(); // Get list of junctions (tested up to 55 at one time)
int j;
j=Entry.size();
}
else if (!complete and !ControlOrNot)
{
Interface.Log("Some Junctions OFF");
Entry = World.GetJunctionList(); // Get list of junctions (tested up to 55 at one time)
int j;
j=Entry.size();
if (!JunctNames.size() or !JunctNames or JunctNames.size() == 0)
{
Interface.Log("Error Correction here");
}
else
{
countout = JunctNames.size();
i=0;
while (i < Entry.size())
{
name = Entry.GetLocalisedName();
for (count=0;count<countout;count++)
{
if (name == JunctNames[count])
{
Entry[i,i+1]=null;
i=0;
break;
}
continue;
}
i = i+1;
}
}
}
else if (!complete and ControlOrNot)
{
Interface.Log("Some Junctions ON");
Entry = new Junction[JunctNames.size()];
for (i=0;i<JunctNames.size();i++)
{
Entry = cast <Junction> Router.GetGameObject (JunctNames);
}
}
for (i=0;i<Entry.size();i++)
{
JunctionDirection[JunctionDirection.size()] = Entry.GetDirection(); // Find out the orginial directions
AddHandler (Entry,"Object","InnerLeave","CallThread"); //Watch that junction for a train to leave.
}
Interface.Log("This is the checking section");
for (i=0;i<Entry.size();++i)
{
Interface.Log("Stored " + Entry.GetName() + "In Direction " + JunctionDirection + "Slot " +i);
}

}
};
 
After more testing, one thing that is consistant, even if the switch does not reset under this rule, the sound that the switch is being moved does play. So this means this rule is still active in some way or another. It just does not actively reset the switch.
 
The route is probably broken due to the changes in scripting requirements to increase performance with them. One of the things that got bashed pretty badly in TRS19 and later TRS22 is huge tables created to hold information such as junctions. A script that has a huge table can clog the pipeline causing bad stutters like we saw in TS12 and even T:ANE. The initial fix for that was a timeout. This would explain why the rule works once or twice but not after that.

More recently, there have been other changes but I can't remember what they are. We found out about those the hard way when the changes broke a lot of things including massive quantities of European signals.
 
So, I have attempted to make a whole new system to replace junction normal without going through every single switch on the route. But this system creates derailments

I created a short 150m railway with a trigger in the middle and navigation markers at each end. I set a AI driver to go back and forth this railway every 5 min. When it passes over the trigger, all switches on the route resets to the default setting thanks to a combination of Check Trackside rule and a rule created by a hungarian content creator. The rule is called HoTT Junction Control.

Problem...
When the AI does a run to reset the switches, HoTT Junction control overrides any locked Junction on route. This means if I or any AI is using a junction, it risks derailing the train.

Very frustating!

If a simular rule exists that won't override a locked junction that would be great! I only used this rule because I don't have to go through the list one by one to set what direction the junction should be set!

temp.jpg
 
Back
Top