I need to solve the problem so that the rotation and displacement relative to the track are functional, rotate them 180° because now I don't know why, but the whole model has turned to the opposite side. So that the clicking icons work independently, now it is in collision. 
// Signal Extension Script version 25.1.65A
//*********************************************************************//
//*********************************************************************//
//** **//
//** ALL RIGHTS RESEVED BY DAVID PISTELAK **//
//** ALPINETRAINZ.CZ AND WIKIQUIK.EU **//
//** 2009-2025 **//
//** DO NOT COPY, MODIFY OR DISTRIBUTE THIS CONTENT! **//
//** **//
//*********************************************************************//
//*********************************************************************//
include "signal.gs"
include "library.gs"
include "trackside.gs"
include "Asset.gs"
class SignalExt isclass Signal
{
thread void LampThread(void);
thread void LampFlash(void);
int GetSpeed(bool dir, int indx);
Trackside GetTrackSide(GSTrackSearch GstObj, int index);
Trackside GetTrackSide2(GSTrackSearch GstObj, int index, string kind, float distance);
Trackside GetTrackSideRule(GSTrackSearch GstObj, int index, float distance);
float GetTrackSideSignalDistance(GSTrackSearch GstObj, int index);
string GetRule(bool dir, int indx);
public define int AUTOMATIC = -1; //Signal state is automatically handled by Trainz.
public define int RED = 0; //Signal is red (stop state).
public define int YELLOW = 1; //Signal is yellow (caution state).
public define int GREEN = 2; //Signal is green (clear state).
public define int WHITE = 3; //Signal is white (intended for repetition of the same signal, combination of a call signal, or for moving the locomotive).(*Shift approve.)
public define int BLUE = 4; //Signal is blue (exclusively intended for prohibiting locomotive movement; not a main signal.)(*Stop for shift.)
public define int LAMP_ON = 5;
public define int LAMP_OFF = -2;
public define float FLASH_NONE = 0;
public define float FLASH_SLOW = 0.5;
public define float FLASH_SPEED = 0.25;
// Distances
public define int MINIMUM_SIGNAL_SPACING = 1200; // Signály musí být umístěny více než 1200 m od sebe vzdáleného stavu.
public define int DEFAULT_OVERLAP = 800; // Default. Overridden by 'overlap' in the config.txt. from 25 m to 800 m
int SignalState;
int CachedSignalState;
bool toggle;
bool direction;
int numSignals;
float maxDistance;
bool GetIsRepeater;
bool GetIsHome;
bool GetIsDistant;
int wrnDir = 0; // Směr dalšího signálu.
int wrnDirRpt = 0; // Směr signálu za dalším.
int advWrnState = 0; // Počet signálů, které se hledají pro pokročilé varování.
//Signal m_signal;
float[] flash;
int[] color;
int speedNext;
int speedNow;
int speedLast;
float thread_sleep;
float innerApprDist = 1800;
float outerApprDist = 2800;
string sigTypes;
bool bHasLowSpeed = false;
int ctrlMode; // 0 = Auto, 1 = Cont., 2 = Auto/Cont, 3 = Rptr., 4 = Dist
int routeMax;
bool bEnableDebug = true; // Set to 'true' to enable debug output.
public void PrintDebug(string msg) {
if (bEnableDebug) Interface.Log("[SignalExt] '" + me.GetLocalisedName() + "': " + msg);
}
// ZÁKLADNÍ HODNOTY NASTAVENÍ
//===========================
float m_posX = 2.4f; //default
float m_posY = 0;
float m_posZ = 0;
float m_angX = 0;
float m_angY = 0;
float m_angZ = 0;
//=============================
//=============================
float DegreeToRadian(float degree)
{
return (degree * 3.14159)/180;
}
//=============================
//=============================
// STYLE
string icnAsp;
string helplink;
string icnResul;
string icnNum;
string icnOwn;
string icnauto;
string icndist;
string icnmain;
string icnshif;
string icnspee;
string icnBul;
// SET DISPLAY
int num;
int num_a;
int num_b;
int tabulka_a;
int tabulka_b;
int zebrik;
int tabulka_change;
int light_on;
string descname;
string siglabel;
string displayname;
string m_username;
string strTable;
string Escape;
string SetNamedTag;
int IsAlreadyInList;
string isautomatic;
string isdepar;
string isentry;
string isshift;
string isrepea;
string isfifty;
string isthyrt;
string isop;
string label1;
string username;
string orientation;
// Position
string[] offsetRangeLeft = new string[2];
string[] offsetRangeRight = new string[2];
string[] offsetLimits;
// Nameplate
int nameStyle;
string displayName;
Soup configSoup;
Soup ExtensionsContainer;
Soup ap_signal_container;
Asset m_asset;
string type;
string rule;
// Name: FindRouteDirection
// Desc: Looks for direction targets only. Returns the direction value. This
// is intended to be used when a signal is not locally controled but
// still needs to figure out it's direction.
// Parm: sig - The signal to search from.
public int FindRouteDirection(Signal sig) {
GSTrackSearch myGST = sig.BeginTrackSearch(true);
object nxtObj;
bool bKeepSearching = true;
int dir, objCount;
string sigName = sig.GetLocalisedName();
PrintDebug("[FindRouteDirection] Begin search from '" + sigName + "'...");
while (myGST.SearchNextObject() and bKeepSearching) {
nxtObj = myGST.GetObject();
objCount = objCount + 1;
if (cast<Trackside> nxtObj) {
Trackside nxtTks = cast<Trackside> nxtObj;
string nxtTksName = nxtTks.GetLocalisedName();
string nxtTksType = nxtTks.GetAsset().GetConfigSoup().GetNamedTag("username");
string nxtTksCmd = nxtTks.GetAsset().GetConfigSoup().GetNamedSoup("extensions").GetNamedTag("signalling-target-direction-60850");
int nxtTksDir = nxtTks.GetAsset().GetConfigSoup().GetNamedSoup("extensions").GetNamedTagAsInt("signalling-target-ordinal-60850", 0);
Str.ToLower(nxtTksCmd);
PrintDebug(" Next Object is a Trackside item: '" + nxtTksName + "' ('" + nxtTksType + "')...");
if (nxtTksCmd != "") {
if (myGST.GetFacingRelativeToSearchDirection()) {
if (nxtTksCmd == "straight") {
PrintDebug(" ...it's tagged straight");
dir = 0;
bKeepSearching = false;
} else if (nxtTksCmd = "left") {
PrintDebug(" ...it's tagged left " + nxtTksDir);
dir = dir - nxtTksDir;
bKeepSearching = false;
} else if (nxtTksCmd = "right") {
PrintDebug(" ...it's tagged right " + nxtTksDir);
dir = dir + nxtTksDir;
bKeepSearching = false;
} else PrintDebug(" ...but it's not a valid direction target. Keep looking.");
} else PrintDebug(" ...but it's facing the wrong way. Keep looking.");
} else PrintDebug(" ...but it's not tagged. Keep looking.");
} else if (cast<Signal> nxtObj) {
Signal nxtSig = cast<Signal> nxtObj;
string nxtSigName = nxtSig.GetLocalisedName();
if (myGST.GetFacingRelativeToSearchDirection()) {
PrintDebug(" Next object is a Signal: '" + nxtSigName + "'. No targets found, ending search.");
bKeepSearching = false;
}
}
}
PrintDebug("[FindRouteDirection] Ended search after " + objCount + " objects. Direction is " + dir);
return dir;
}
//---------------------------
//---------------------------
public void Init(Asset asset)
{
inherited(asset);
thread_sleep = 0.03;
flash = new float[16];
color = new int[16];
LampFlash();
LampThread();
m_asset = me.GetAsset();
configSoup = m_asset.GetConfigSoupCached();
ExtensionsContainer = configSoup.GetNamedSoup("extensions");
ap_signal_container = ExtensionsContainer.GetNamedSoup("ap_signal");
type = ap_signal_container.GetNamedTag("type");
SetMeshTranslation("beton",m_posX,m_posY,m_posZ);
SetMeshOrientation("beton",DegreeToRadian(m_angX),DegreeToRadian(m_angY),DegreeToRadian(m_angZ));
}
thread void LampThread()
{
while (true)
{
SignalState = GetSignalState();
if (CachedSignalState != SignalState)
{
CachedSignalState = SignalState;
}
speedNext = GetSpeed(true, 0);
speedNow = GetSpeed(false, 0);
speedLast = GetSpeed(false, 1);
//if(speedNow == 25)
//{
// SetSpeedLimit(6.94);
//}
//else if(speedNow == 40)
//{
// SetSpeedLimit(11.11);
//}
//else if(speedNow == 60)
//{
// SetSpeedLimit(16.66);
//}
//else if(speedNow == 80)
//{
// SetSpeedLimit(22.22);
//}
//else if(speedNow == 100)
//{
// SetSpeedLimit(27.77);
//}
//else
//{
// SetSpeedLimit(16.66);
//}
//Interface.Log("speedNext=" + speedNext + " speedNow=" + speedNow + " speedLast=" + speedLast);
rule = GetRule(true, 0);
int i = 0;
for (i = 0; i < color.size(); i++)
{
color[i] = LAMP_OFF;
}
if(Str.Find("T32A", type, 0) != -1) // AŽD-65-T32A
{
if (SignalState == GREEN)
{
bool change = (speedNow != speedNext);
if (speedNext == 40 and change)
color[1] = YELLOW;
else if (speedNext == 60 and change)
color[1] = YELLOW;
else
color[1] = LAMP_OFF;
if (speedNext == 80)
color[0] = GREEN;
else if (speedNext == 100)
color[0] = GREEN;
else if (!change)
color[0] = GREEN;
else
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
if (speedNext == 40 and change)
flash[1] = FLASH_SLOW;
else if (speedNext == 60 and change)
flash[1] = FLASH_SPEED;
else
flash[1] = FLASH_NONE;
if (speedNext == 80 and change)
flash[0] = FLASH_SLOW;
else if (speedNext == 100 and change)
flash[0] = FLASH_SPEED;
else
flash[0] = FLASH_NONE;
}
if (speedNow == 40 and SignalState == GREEN)
{
SetSpeedLimit(11.11);
color[1] = LAMP_OFF;
color[0] = GREEN;
color[2] = LAMP_OFF;
color[3] = LAMP_OFF;
color[4] = YELLOW;
color[5] = LAMP_OFF;
color[6] = LAMP_OFF;
color[7] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
flash[5] = FLASH_NONE;
flash[6] = FLASH_NONE;
flash[7] = FLASH_NONE;
}
if (rule == "40" and SignalState == GREEN)
{
SetSpeedLimit(11.11);
color[1] = LAMP_OFF;
color[0] = GREEN;
color[2] = LAMP_OFF;
color[3] = LAMP_OFF;
color[4] = YELLOW;
color[5] = LAMP_OFF;
color[6] = LAMP_OFF;
color[7] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
flash[5] = FLASH_NONE;
flash[6] = FLASH_NONE;
flash[7] = FLASH_NONE;
}
if (rule == "40" and SignalState == YELLOW)
{
SetSpeedLimit(11.11);
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = LAMP_OFF;
color[4] = YELLOW;
color[5] = LAMP_OFF;
color[6] = LAMP_OFF;
color[7] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
flash[5] = FLASH_NONE;
flash[6] = FLASH_NONE;
flash[7] = FLASH_NONE;
}
if (rule == "40" and SignalState == YELLOW and rule == "repeat")
{
SetSpeedLimit(11.11);
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
color[4] = YELLOW;
color[5] = LAMP_OFF;
color[6] = LAMP_OFF;
color[7] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
flash[5] = FLASH_NONE;
flash[6] = FLASH_NONE;
flash[7] = FLASH_NONE;
}
if (speedNow == 40 and speedNext == 40 and SignalState == GREEN)
{
SetSpeedLimit(11.11);
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = LAMP_OFF;
color[4] = YELLOW;
flash[1] = FLASH_SLOW;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
}
if (speedNow == 40 and speedNext == 40 and SignalState == GREEN and rule == "repeat")
{
SetSpeedLimit(11.11);
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
color[4] = YELLOW;
flash[1] = FLASH_SLOW;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
}
if (SignalState == YELLOW)
{
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = LAMP_OFF;
color[4] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
}
if (SignalState == YELLOW and rule =="repeat")
{
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
color[4] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
}
if (SignalState == RED)
{
color[1] = LAMP_OFF;
color[0] = LAMP_OFF;
color[2] = RED;
color[3] = LAMP_OFF;
color[4] = LAMP_OFF;
color[5] = LAMP_OFF;
color[6] = LAMP_OFF;
color[7] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
flash[5] = FLASH_NONE;
flash[6] = FLASH_NONE;
flash[7] = FLASH_NONE;
}
if (SignalState == RED and rule == "app")
{
color[1] = LAMP_OFF;
color[0] = LAMP_OFF;
color[2] = RED;
color[3] = WHITE;
color[4] = LAMP_OFF;
color[5] = LAMP_OFF;
color[6] = LAMP_OFF;
color[7] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_SLOW;
flash[4] = FLASH_NONE;
flash[5] = FLASH_NONE;
flash[6] = FLASH_NONE;
flash[7] = FLASH_NONE;
}
if (SignalState == EX_SLOW_APPROACH_RESTRICTED)
{
color[1] = LAMP_OFF;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
color[4] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
}
if (rule == "shift")
{
color[1] = LAMP_OFF;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
color[4] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
flash[4] = FLASH_NONE;
}
}
if(Str.Find("T2P", type, 0) != -1) //AZD-65-T2P + T3OP
{
bool GetIsRepeater;
if (SignalState == GREEN)
{
GetIsRepeater = true;
color[1] = LAMP_OFF;
color[0] = GREEN;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (speedNext == 40 and SignalState == GREEN)
{
GetIsRepeater = true;
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_SLOW;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (speedNext == 60 and SignalState == GREEN)
{
GetIsRepeater = true;
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_SPEED;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (speedNext == 80 and SignalState == GREEN)
{
GetIsRepeater = true;
color[1] = LAMP_OFF;
color[0] = GREEN;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_SLOW;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (speedNext == 100 and SignalState == GREEN)
{
GetIsRepeater = true;
color[1] = LAMP_OFF;
color[0] = GREEN;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_SPEED;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (SignalState == YELLOW)
{
GetIsRepeater = true;
color[1] = LAMP_OFF;
color[0] = GREEN;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (speedNext == 40 and SignalState == YELLOW)
{
GetIsRepeater = true;
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_SLOW;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (speedNext == 60 and SignalState == YELLOW)
{
GetIsRepeater = true;
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_SPEED;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (speedNext == 80 and SignalState == YELLOW)
{
GetIsRepeater = true;
color[1] = LAMP_OFF;
color[0] = GREEN;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_SLOW;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (speedNext == 100 and SignalState == YELLOW)
{
GetIsRepeater = true;
color[1] = LAMP_OFF;
color[0] = GREEN;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_SPEED;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (SignalState == RED)
{
GetIsRepeater = true;
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (SignalState == RED and rule == "app")
{
GetIsRepeater = true;
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (SignalState == RED and rule == "shift")
{
GetIsRepeater = true;
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
if (SignalState == EX_SLOW_APPROACH_RESTRICTED)
{
GetIsRepeater = true;
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
color[3] = WHITE;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
flash[3] = FLASH_NONE;
}
}
if(Str.Find("T2A", type, 0) != -1) // AZD-65-2A
{
GSTrackSearch Gst = BeginTrackSearch(false);
float distance = GetTrackSideSignalDistance(Gst, 0);
Interface.Log("Distance = " + distance);
Train apprTrain = FindApproachingTrain(me, false, 0, distance);
bool trainAppr;
if (apprTrain and apprTrain.GetFrontmostLocomotive())
{
trainAppr = true;
}
else
{
trainAppr = false;
}
if (SignalState == EX_SLOW_APPROACH_RESTRICTED)
{
color[4] = WHITE;
flash[4] = FLASH_NONE;
color[8] = LAMP_OFF;
flash[8] = FLASH_NONE;
}
else if (rule =="shift")
{
color[4] = WHITE;
flash[4] = FLASH_NONE;
color[8] = LAMP_OFF;
flash[8] = FLASH_NONE;
}
else
{
color[4] = LAMP_OFF;
flash[4] = FLASH_NONE;
color[8] = LAMP_OFF;
flash[8] = FLASH_NONE;
}
}
if(Str.Find("T3ATB", type, 0) != -1) // AZD-65-T3ATB AUTOBLOK
{
if (SignalState == GREEN)
{
bool change = (speedNow != speedNext);
if (speedNext == 40 and change)
color[1] = YELLOW;
else if (speedNext == 60 and change)
color[1] = YELLOW;
else if (speedNext == 80 and change)
color[0] = GREEN;
else if (speedNext == 100 and change)
color[0] = GREEN;
else if (!change)
color[0] = GREEN;
else
color[0] = LAMP_OFF;
if (speedNext == 40 and change)
flash[1] = FLASH_SLOW;
else if (speedNext == 60 and change)
flash[1] = FLASH_SPEED;
else if (speedNext == 80 and change)
flash[0] = FLASH_SLOW;
else if (speedNext == 100 and change)
flash[0] = FLASH_SPEED;
else
flash[0] = FLASH_NONE;
}
if (SignalState == YELLOW)
{
color[1] = YELLOW;
color[0] = LAMP_OFF;
color[2] = LAMP_OFF;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
}
if (SignalState == RED)
{
color[1] = LAMP_OFF;
color[0] = LAMP_OFF;
color[2] = RED;
flash[1] = FLASH_NONE;
flash[0] = FLASH_NONE;
flash[2] = FLASH_NONE;
}
}
if (rule == "free")
{
int i = 0;
for (i = 0; i < 16; i++)
{
color[i] = LAMP_OFF;
flash[i] = FLASH_NONE;
}
color[0] = GREEN;
flash[0] = FLASH_NONE;
}
if (rule == "stop")
{
int i = 0;
for (i = 0; i < 16; i++)
{
color[i] = LAMP_OFF;
flash[i] = FLASH_NONE;
}
color[2] = RED;
flash[2] = FLASH_NONE;
}
if (rule == "warning")
{
int i = 0;
for (i = 0; i < 16; i++)
{
color[i] = LAMP_OFF;
flash[i] = FLASH_NONE;
}
color[1] = YELLOW;
flash[1] = FLASH_NONE;
}
else if (rule == "app")
{
int i = 0;
for (i = 0; i < 16; i++)
{
color[i] = LAMP_OFF;
flash[i] = FLASH_NONE;
}
color[2] = RED;
flash[2] = FLASH_NONE;
color[3] = WHITE;
flash[3] = FLASH_SLOW;
}
Sleep(3);
}
}
//Bottom Yellow = Current speed
//Top Yellow = Next (future) speed
thread void LampFlash()
{
bool[] sig;
sig = new bool[16];
while (true)
{
int i = 0;
for (i = 0; i < sig.size(); i++)
{
if (color[i] != LAMP_OFF and HasMesh("lamp" + (string)i))
{
if (flash[i] > 0)
{
sig[i] = !sig[i];
}
else
{
sig[i] = true;
}
SetMeshVisible("lamp" + (string)i, sig[i], 0.2);
Sleep(flash[i] - thread_sleep);
}
else
{
SetMeshVisible("lamp" + (string)i, false, 0.2);
}
}
Sleep(thread_sleep);
}
}
string GetRule(bool dir, int indx)
{
if (BeginTrackSearch(dir))
{
Soup o_configSoup;
Soup o_ExtensionsContainer;
Soup o_ap_signal_container;
string o_rule;
GSTrackSearch Gst = BeginTrackSearch(dir);
Trackside FrontTrackside = GetTrackSideRule(Gst, indx, 2300);
//Interface.Log("RuleA");
if (FrontTrackside and Gst.GetFacingRelativeToSearchDirection())
{
//Interface.Log("RuleC");
o_configSoup = FrontTrackside.GetAsset().GetConfigSoupCached();
o_ExtensionsContainer = o_configSoup.GetNamedSoup("extensions");
o_ap_signal_container = o_ExtensionsContainer.GetNamedSoup("ap_signal");
o_rule = o_ap_signal_container.GetNamedTag("rule");
//Interface.Log("Rule=" + o_rule);
if(o_rule != "")
{
return o_rule;
}
}
}
return "null";
}
int GetSpeed(bool dir, int indx)
{
if (BeginTrackSearch(dir))
{
GSTrackSearch Gst = BeginTrackSearch(dir);
Trackside FrontTrackside = GetTrackSide2(Gst, indx, "Scenery", 2300); // max distance Rule is 2300 m
if (FrontTrackside and (Gst.GetFacingRelativeToSearchDirection() == dir))
{
if (FrontTrackside.GetSpeedLimit())
{
//Interface.Log("SPEED= " + (string)(int)(3.6 * FrontTrackside.GetSpeedLimit() + 0.1));
return (int)(3.6 * FrontTrackside.GetSpeedLimit() + 0.1);
}
}
}
return 1;
}
Trackside GetTrackSide(GSTrackSearch SpeedObj, int index)
{
Trackside foundTrackside;
while (SpeedObj.SearchNextObject())
{
foundTrackside = cast < Trackside > SpeedObj.GetObject();
if (foundTrackside != null)
{
if (index == 0)
{
return foundTrackside;
}
else
{
index = index - 1;
}
}
}
return null;
}
Trackside GetTrackSide2(GSTrackSearch GstObj, int index, string kind, float distance)
{
Trackside foundTrackside;
MapObject nextMapObject;
int i = 0;
while (nextMapObject = GstObj.SearchNext())
{
if(GstObj.GetDistance() < distance)
{
i = i + 1;
if(cast<Vehicle> nextMapObject) //when a train is found between the signals
{
//Interface.Log("Rule VEH");
}
else if(cast<Junction> nextMapObject) //if a junction is found between signals
{
//Interface.Log("Rule JUN");
}
else if(cast<Trackside> nextMapObject)
{
foundTrackside = cast < Trackside > GstObj.GetObject();
Soup o_configSoup = foundTrackside.GetAsset().GetConfigSoupCached();
if(o_configSoup.GetNamedTag("kind") == kind)
{
//Interface.Log("FTS at " + i + " = " + foundTrackside.GetSignalState());
if (index == 0)
{
return foundTrackside;
}
else
{
index = index - 1;
}
}
}
}
}
return null;
}
Trackside GetTrackSideRule(GSTrackSearch GstObj, int index, float distance)
{
Trackside foundTrackside;
MapObject nextMapObject;
while (nextMapObject = GstObj.SearchNext())
{
if(GstObj.GetDistance() < distance)
{
if(cast<Vehicle> nextMapObject) //when a train is found between the signals
{
//Interface.Log("Rule VEH");
}
else if(cast<Junction> nextMapObject) //if a junction is found between signals
{
//Interface.Log("Rule JUN");
}
else if(cast<Trackside> nextMapObject)
{
//Interface.Log("Rule TRK");
if (index == 0)
{
Interface.Log("Rule RETURN");
foundTrackside = cast<Trackside> nextMapObject;
return foundTrackside;
}
else
{
index = index - 1;
}
}
}
}
return null;
}
float GetTrackSideSignalDistance(GSTrackSearch GstObj, int index)
{
Trackside foundTrackside;
MapObject nextMapObject;
while (nextMapObject = GstObj.SearchNext())
{
if(cast<Vehicle> nextMapObject) //when a train is found between the signals
{
//Interface.Log("Rule VEH");
}
else if(cast<Junction> nextMapObject) //if a junction is found between signals
{
//Interface.Log("Rule JUN");
}
else if(cast<Signal> nextMapObject)
{
//Interface.Log("Rule TRK");
if (index == 0)
{
//Interface.Log("Rule RETURN");
foundTrackside = cast<Trackside> nextMapObject;
return GstObj.GetDistance();;
}
else
{
index = index - 1;
}
}
}
return 100.0f;
}
//*************************************
//*************************************
// CHANGE MESH FILES
void affichage (void);
public void Init (void) {
inherited();
affichage();
}
void affichage (void)
{
if (num==0) {
SetMeshVisible("drzak-cisel",true,0);
}
if (num==1){
SetMeshVisible("drzak-cisel",false,0);
}
if (light_on==0) {
SetMeshVisible("kriz",false,0);
SetMeshVisible("lamp0",true,0);
SetMeshVisible("lamp1",true,0);
SetMeshVisible("lamp2",true,0);
SetMeshVisible("lamp3",true,0);
SetMeshVisible("lamp4",true,0);
SetMeshVisible("lamp5",true,0);
SetMeshVisible("lamp6",true,0);
SetMeshVisible("lamp7",true,0);
}
if (light_on==1){
SetMeshVisible("kriz",true,0);
SetMeshVisible("lamp0",false,0);
SetMeshVisible("lamp1",false,0);
SetMeshVisible("lamp2",false,0);
SetMeshVisible("lamp3",false,0);
SetMeshVisible("lamp4",false,0);
SetMeshVisible("lamp5",false,0);
SetMeshVisible("lamp6",false,0);
SetMeshVisible("lamp7",false,0);
}
// The change is only allowed if the model in the configuration file contains models, otherwise it is irrelevant.
if (tabulka_change==0) {
SetMeshVisible("drzak-a",true,0);
SetMeshVisible("drzaka-svorkya",true,0);
SetMeshVisible("terc-pr",true,0);
SetMeshVisible("terc-od",false,0);
SetMeshVisible("drzak-tab",false,0);
SetMeshVisible("drzaka-tab",false,0);
SetMeshVisible("terc-tab",false,0);
}
if (tabulka_change==1){
SetMeshVisible("drzak-a",true,0);
SetMeshVisible("drzaka-svorkya",true,0);
SetMeshVisible("terc-pr",false,0);
SetMeshVisible("terc-od",true,0);
SetMeshVisible("drzak-tab",true,0);
SetMeshVisible("drzaka-tab",true,0);
SetMeshVisible("terc-tab",true,0);
}
// End Change!
if (zebrik==0) {
SetMeshVisible("zebrik",true,0);
SetMeshVisible("drzak-zebrik",true,0);
SetMeshVisible("drzak-zebrik-vrch",true,0);
}
if (zebrik==1){
SetMeshVisible("zebrik",false,0);
SetMeshVisible("drzak-zebrik",false,0);
SetMeshVisible("drzak-zebrik-vrch",false,0);
}
// Chanage Num tables Position A
if (num_a==0) {
SetMeshVisible("num-a-1",true,0);
SetMeshVisible("num-a-2",false,0);
}
if (num_a==1){
SetMeshVisible("num-a-1",false,0);
SetMeshVisible("num-a-2",true,0);
}
// Chanage Num tables Position B
if (num_b==0) {
SetMeshVisible("num-b-1",true,0); //vol1
SetMeshVisible("num-b-2",false,0);
SetMeshVisible("num-b-3",false,0);
SetMeshVisible("num-b-4",false,0);
SetMeshVisible("num-b-5",false,0);
SetMeshVisible("num-b-6",false,0);
SetMeshVisible("num-b-7",false,0);
SetMeshVisible("num-b-8",false,0);
SetMeshVisible("num-b-9",false,0);
}
if (num_b==1){
SetMeshVisible("num-b-1",false,0);
SetMeshVisible("num-b-2",true,0); //vol2
SetMeshVisible("num-b-3",false,0);
SetMeshVisible("num-b-4",false,0);
SetMeshVisible("num-b-5",false,0);
SetMeshVisible("num-b-6",false,0);
SetMeshVisible("num-b-7",false,0);
SetMeshVisible("num-b-8",false,0);
SetMeshVisible("num-b-9",false,0);
}
if (num_b==2){
SetMeshVisible("num-b-1",false,0);
SetMeshVisible("num-b-2",false,0);
SetMeshVisible("num-b-3",true,0); //vol3
SetMeshVisible("num-b-4",false,0);
SetMeshVisible("num-b-5",false,0);
SetMeshVisible("num-b-6",false,0);
SetMeshVisible("num-b-7",false,0);
SetMeshVisible("num-b-8",false,0);
SetMeshVisible("num-b-9",false,0);
}
if (num_b==3){
SetMeshVisible("num-b-1",false,0);
SetMeshVisible("num-b-2",false,0);
SetMeshVisible("num-b-3",false,0);
SetMeshVisible("num-b-4",true,0); //vol4
SetMeshVisible("num-b-5",false,0);
SetMeshVisible("num-b-6",false,0);
SetMeshVisible("num-b-7",false,0);
SetMeshVisible("num-b-8",false,0);
SetMeshVisible("num-b-9",false,0);
}
if (num_b==4){
SetMeshVisible("num-b-1",false,0);
SetMeshVisible("num-b-2",false,0);
SetMeshVisible("num-b-3",false,0);
SetMeshVisible("num-b-4",false,0);
SetMeshVisible("num-b-5",true,0); //vol5
SetMeshVisible("num-b-6",false,0);
SetMeshVisible("num-b-7",false,0);
SetMeshVisible("num-b-8",false,0);
SetMeshVisible("num-b-9",false,0);
}
if (num_b==5){
SetMeshVisible("num-b-1",false,0);
SetMeshVisible("num-b-2",false,0);
SetMeshVisible("num-b-3",false,0);
SetMeshVisible("num-b-4",false,0);
SetMeshVisible("num-b-5",false,0);
SetMeshVisible("num-b-6",true,0); //vol6
SetMeshVisible("num-b-7",false,0);
SetMeshVisible("num-b-8",false,0);
SetMeshVisible("num-b-9",false,0);
}
if (num_b==6){
SetMeshVisible("num-b-1",false,0);
SetMeshVisible("num-b-2",false,0);
SetMeshVisible("num-b-3",false,0);
SetMeshVisible("num-b-4",false,0);
SetMeshVisible("num-b-5",false,0);
SetMeshVisible("num-b-6",false,0);
SetMeshVisible("num-b-7",true,0); //vol7
SetMeshVisible("num-b-8",false,0);
SetMeshVisible("num-b-9",false,0);
}
if (num_b==7){
SetMeshVisible("num-b-1",false,0);
SetMeshVisible("num-b-2",false,0);
SetMeshVisible("num-b-3",false,0);
SetMeshVisible("num-b-4",false,0);
SetMeshVisible("num-b-5",false,0);
SetMeshVisible("num-b-6",false,0);
SetMeshVisible("num-b-7",false,0);
SetMeshVisible("num-b-8",true,0); //vol8
SetMeshVisible("num-b-9",false,0);
}
if (num_b==8){
SetMeshVisible("num-b-1",false,0);
SetMeshVisible("num-b-2",false,0);
SetMeshVisible("num-b-3",false,0);
SetMeshVisible("num-b-4",false,0);
SetMeshVisible("num-b-5",false,0);
SetMeshVisible("num-b-6",false,0);
SetMeshVisible("num-b-7",false,0);
SetMeshVisible("num-b-8",false,0);
SetMeshVisible("num-b-9",true,0); //vol9
}
// End Change!
}
//
// HTML EDITOR
//
// Name: GetDescriptionHTML()
//INFO: Build the information for the properties window
public string GetDescriptionHTML()
{
StringTable strTable = GetAsset().GetStringTable();
//PrintDebug("[GetDescriptionHTML] Building Properties UI...");
// Common
string icnAsp = "<img src=art/asp/seq.png width=704 height=128>";
string icnResul = "<img src=art/resul/resul.png width=500 height=317>";
string icnNum = "<img src=art/resul/num.png width=400 height=200>";
string icnOwn = "<a href=https://alpinetrainz.cz tooltip=Alpinetrainz.cz><img src=art/icon/alpinetrainz.png width=350 height=100></a>";
string icnBul = "<img src=art/com/bulb.png width=50 height=50>";
// Icons
string icnmain = "<img src=art/com/icnmain.png width=18 height=18>";
string icndist = "<img src=art/com/icndist.png width=18 height=18>";
string icnshif = "<img src=art/com/icnshif.png width=18 height=18>";
string icnauto = "<img src=art/com/icnauto.png width=18 height=18>";
string icnspee = "<img src=art/com/icnspee.png width=18 height=18>";
// Display Name
string labelname = "<i>not set (using signal name)</i>";
string offset = "<i>nastavit odsazení</i>";
string rotate = "<i>nastavit úhel</i>";
string username = GetAsset().GetLocalisedName(); // User Name in EN Language
string labelOffset = Str.Tokens(offset, ".")[0];
string MyName = GetName();
if (displayname != "") labelname = displayname;
string descname = "Display Name: <a href=live://property/m_username>" + labelname + "</a>";
string helpLink = "<a href=https://forum.wikiquik.eu/blog/index.php?blog-entry-list/2-a%C5%BEd-70-user-manual tooltip=If_you_don't_know_what_to_do,_try_the_USER_MANUAL> Help me >>> wikiquik.eu/blog <img src=art/com/unknown.png width=16 height=16></a> ";
ExtensionsContainer = configSoup.GetNamedSoup("extensions");
// Build MAIN Properties Layout
//PrintDebug("[GetDescriptionHTML] Done. Presenting UI.");
string rt;
string HTML;
string sLink;
string sHtml = inherited();
rt="<font color=#996666>";
rt=rt+ "<table><tr bgcolor=#1565DF><td width=1%></td><td width=99%><img src=art/icon/logo.png width=128 height=128></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#1565DF><td width=70%><font size=18 color=#DDE5FA locale='english'<b>Signal Setup</b></font><font size=18 color=#DDE5FA locale='czech'><b>Nastavení Návěstidla</b></font>" + displayname + "</td><td width=20% align=center>" + helpLink + "</td><td width=10% align=center>" + icnBul + "</td></tr></table>";
rt=rt+ "<table><tr bgcolor=#1565DF><td width=100% valign=center><font size=4 color=#FFFFFF><b>Type: </b></font><font size=6 color=#ffd100><b>" + username + "</b></font><br></td></tr></table>";
rt=rt+ "<table><br><tr bgcolor=#0c151a><td width=100%><b>Signal function</b></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#1565DF><td width=15% align=right><b>Main Signal</b></td><td width=35% align=right >" + icnmain + "</td><td width=15% valign=center><b>Speed</b></td><td width=35% valign=center>" + icnspee + "</td></tr></table>";
rt=rt+ "<table><tr bgcolor=#1565DF><td width=15% align=right ><b>Distance Signal</b></td><td width=35% align=right >" + icndist + "</td><td width=15% valign=center><b>Main Signal</b></td><td width=35% valign=center>" + icnauto + "</td></tr></table>";
rt=rt+ "<table><tr bgcolor=#1565DF><td width=15% align=right ><b>Shift Signal</b></td><td width=35% align=right >" + icnshif + "</td><td width=15% valign=center><b></b></td><td width=35% valign=center></td></tr></table>";
rt=rt+ "<table><br><tr bgcolor=#0c151a><td width=100%><b>Aspects</b></td></tr><br></table>";
rt=rt+ "<table><br><tr bgcolor=#20283a><td width=100%>" + icnAsp + "</td></tr><br></table>";
rt=rt+ "<table><br><tr bgcolor=#20283a><img src=art/asp/seq.png width=704 height=128></td></tr><br></table>";
rt=rt+ "<table><br><tr bgcolor=#0c151a><td width=100%><b>Can Read The Program</b></td></tr><br></table>";
rt=rt+ "<table><br><tr bgcolor=#20283a><td width=100%><img src=art/misc/65y.png><img src=art/misc/65n.png><img src=art/misc/70y.png><img src=art/misc/70n.png></td></tr><br></table>";
rt=rt+ "<br>";
// Kompatibilita Aspektů
rt=rt+ "<table><tr bgcolor=#354769><td width=100%><b>Supports</b></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#20283a><td width=100%><img src=art/misc/40y.png><img src=art/misc/40n.png><img src=art/misc/60y.png><img src=art/misc/60n.png><img src=art/misc/80y.png><img src=art/misc/80n.png><img src=art/misc/100y.png><img src=art/misc/100n.png></td></tr></table>";
rt=rt+ "<br>";
// Konec Kompatibilita Aspektů
rt=rt+ "<table><tr bgcolor=#354769><td width=50%><b>Offset</b></td><td width=50%><b>Rotate</b></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#20283a><td width=50%>" + offset + "</td><td width=50%>" + rotate + "</td></tr></table>";
rt=rt+ "<table><tr bgcolor=#20283a><td width=50%><font color=#FCFFFD><b> x: </b></font> " + HTMLWindow.MakeLink("live://property/m_posX", m_posX) + "</td><td width=50%><font color=#FCFFFD><b> x°: </b></font> " + HTMLWindow.MakeLink("live://property/m_angX", m_angX) + "</td></tr></table>";
rt=rt+ "<table><tr bgcolor=#20283a><td width=50%><font color=#FCFFFD><b> y: </b></font> " + HTMLWindow.MakeLink("live://property/m_posY", m_posY) + "</td><td width=50%><font color=#FCFFFD><b> y°: </b></font> " + HTMLWindow.MakeLink("live://property/m_angY", m_angY) + "</td></tr></table>";
rt=rt+ "<table><tr bgcolor=#20283a><td width=50%><font color=#FCFFFD><b> z: </b></font> " + HTMLWindow.MakeLink("live://property/m_posZ", m_posZ) + "</td><td width=50%><font color=#FCFFFD><b> z°: </b></font> " + HTMLWindow.MakeLink("live://property/m_angZ", m_angZ) + "</td></tr></table>";
rt=rt+ "<br>";
rt=rt+ "<table><tr bgcolor=#19A04F><td width=100%><b>Set Display</b></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#0F4926><td width=10%>";
rt=rt+ "<br>";
if(num==1) {
rt = rt + "<a href=live://property/num_y><img src=art/misc/num_n.png width=40 height=40></a>";
rt = rt + "<a href=live://property/num_n><img src=art/misc/num_y.png width=40 height=40></a>";
}
if(num==0) {
rt = rt + "<a href=live://property/num_y><img src=art/misc/num_n.png width=40 height=40></a>";
rt = rt + "<a href=live://property/num_n><img src=art/misc/num_y.png width=40 height=40></a>";
}
rt=rt+ "<br></td>";
rt=rt+ "<td width=90% valign=center><font color=#FCFFFD locale='english'><i>Here you can turn on or off the display of the name of the signal (number plate) on the mast. </i></font><font color=#FCFFFD locale='czech'><i>Zde můžete zapnout nebo vypnout zobrazení názvu návěstidla (číselníku) na stožáru. </i></font>";
rt=rt+ "</td></tr></table>";
rt=rt+ "<table><tr bgcolor=#0F4926><td width=10%>";
rt=rt+ "<br>";
if(light_on==1) {
rt = rt + "<a href=live://property/light_on_y><img src=art/misc/lightoff.png width=40 height=40></a>";
rt = rt + "<a href=live://property/light_on_n><img src=art/misc/lighton.png width=40 height=40></a>";
}
if(light_on==0) {
rt = rt + "<a href=live://property/light_on_y><img src=art/misc/lightoff.png width=40 height=40></a>";
rt = rt + "<a href=live://property/light_on_n><img src=art/misc/lighton.png width=40 height=40></a>";
}
rt=rt+ "<br></td>";
rt=rt+ "<td width=90% valign=center><font color=#FCFFFD locale='english'><i>Here you can turn off the signal and replace it with a cross (this signal will be taken out of service) I recommend creating a 'free' or 'warning' rule before this signal so that the driver knows if the signal does not have a 'stop' signaling (Currently this requirement is under development)</i></font><font color=#FCFFFD locale='czech'><i>Zde můžete návěstidlo vypnout a nahradit jej křížem ( toto návěstidlo bude odstaveno z provozu ) Doporučuji před tento signál vytvořit pravidlo 'volno' nebo 'výstraha' aby strojvůdce věděl jestli signál nemá signalizaci 'stůj' ( Momentálně je tento požadavek vy vývoji )</i></font>";
rt=rt+ "</td></tr></table>";
rt=rt+ "<table><tr bgcolor=#0F4926><td width=10%>";
rt=rt+ "<br>";
if(zebrik==1) {
rt = rt + "<a href=live://property/zebrik_y><img src=art/misc/zebrik_n.png width=40 height=40></a>";
rt = rt + "<a href=live://property/zebrik_n><img src=art/misc/zebrik_y.png width=40 height=40></a>";
}
if(zebrik==0) {
rt = rt + "<a href=live://property/zebrik_y><img src=art/misc/zebrik_n.png width=40 height=40></a>";
rt = rt + "<a href=live://property/zebrik_n><img src=art/misc/zebrik_y.png width=40 height=40></a>";
}
rt=rt+ "<br></td>";
rt=rt+ "<td width=90% valign=center><font color=#FCFFFD locale='english'><i>Here you can turn on or off the display of the ladder located on the back of the mast. </i></font><font color=#FCFFFD locale='czech'><i>Zde můžete zapnout nebo vypnout žebřík umístěné na zadní straně stožáru.</i></font>";
rt=rt+ "</td></tr></table>";
rt=rt+ "<table><tr bgcolor=#19A04F><td width=100%><b>Change Styles</b></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#19A04F><td width=100% align=left><font color=#435158 locale='english'><i>Changing the Style is only available if the model contains data.</i></font><font color=#435158 locale='czech'><i>Změna stylu je dostupná pouze v případě, že model obsahuje data.</i></font><br></tr></table>";
rt=rt+ "<table><tr bgcolor=#0F4926><td width=10% valign=center>";
rt=rt+ "<br>";
if(tabulka_change==0) {
rt = rt + "<a href=live://property/tabulka_change_y><img src=art/misc/tabulka-b-n.png width=40 height=40></a>";
rt = rt + "<a href=live://property/tabulka_change_n><img src=art/misc/tabulka-a-y.png width=40 height=40></a>";
}
if(tabulka_change==1) {
rt = rt + "<a href=live://property/tabulka_change_y><img src=art/misc/tabulka-b-y.png width=40 height=40></a>";
rt = rt + "<a href=live://property/tabulka_change_n><img src=art/misc/tabulka-a-n.png width=40 height=40></a>";
}
rt=rt+ "<br></td>";
rt=rt+ "<td width=90% valign=center><font color=#FCFFFD locale='english'><i>Here it is possible to change the display of the supplementary table under the lights, menu only according to signal type. </i></font><font color=#FCFFFD locale='czech'><i>Zde je možné změnit zobrazení doplňkové tabulky pod světly, menu pouze podle typu signálu. </i></font>";
rt=rt+ "<br><br></td></tr></table>";
// Set Relay (zrusene)
rt=rt+ "<table><tr bgcolor=#4B6656><td width=100%><b>Change Relay Styles (Unavailable)</b></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#0F4926><td width=20% valign=center>";
rt=rt+ "<br>";
rt=rt+ "<br></td>";
rt=rt+ "<td width=80% valign=center><font color=#FCFFFD locale='english'><i>Here you can change the style of the relay box. Info: If the options are not displayed, they are not available for this item. Recommendation: To use the winter mode, it is not recommended to change the style of the relay box, it may not work properly! </i></font><font color=#FCFFFD locale='czech'><i>Zde si můžete změnit styl reléové skříňky. Info: Pokud se možnosti nezobrazují, nejsou pro tuto položku dostupné. Doporučení: Pro používání zimního módu se nedoporučuje měnit styl reléové skříňky, nemusí správně fungovat! </i></font>";
rt=rt+ "<br><br></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#19A04F><td width=100%><b> </b></td></tr></table>";
// Set Chanage Num tables
rt=rt+ "<table><tr bgcolor=#3E4A68><td width=100%><b>Signal Naming Settings</b></td></tr><br><br></table>";
rt=rt+ "<table><tr bgcolor=#415CA0><td width=20% valign=center><font color=#FCFFFD locale='english'><b> First Position: </b></font><font color=#FCFFFD locale='czech'><b> První Pozice: </b></font></td>";
rt=rt+ "<td width=80% valign=center><br><br>";
if(num_a==0) {
rt = rt + "<a href=live://property/num_a_vol1><img src=art/misc/num/num-vol0.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_a_vol2><img src=art/misc/num/num-volan.png width=30 height=30></a>";
}
if(num_a==1) {
rt = rt + "<a href=live://property/num_a_vol1><img src=art/misc/num/num-vol0n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_a_vol2><img src=art/misc/num/num-vola.png width=30 height=30></a>";
}
rt=rt+ "<br><br></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#415CA0><td width=20% valign=center><font color=#FCFFFD locale='english'><b> Second Position: </b></font><font color=#FCFFFD locale='czech'><b> Druhá Pozice: </b></font></td>";
rt=rt+ "<td width=80% valign=center><br><br>";
if(num_b==0) {
rt = rt + "<a href=live://property/num_b_vol1><img src=art/misc/num/num-vol1.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol2><img src=art/misc/num/num-vol2n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol3><img src=art/misc/num/num-vol3n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol4><img src=art/misc/num/num-vol4n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol5><img src=art/misc/num/num-vol5n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol6><img src=art/misc/num/num-vol6n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol7><img src=art/misc/num/num-vol7n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol8><img src=art/misc/num/num-vol8n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol9><img src=art/misc/num/num-vol9n.png width=30 height=30></a>";
}
if(num_b==1) {
rt = rt + "<a href=live://property/num_b_vol1><img src=art/misc/num/num-vol1n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol2><img src=art/misc/num/num-vol2.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol3><img src=art/misc/num/num-vol3n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol4><img src=art/misc/num/num-vol4n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol5><img src=art/misc/num/num-vol5n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol6><img src=art/misc/num/num-vol6n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol7><img src=art/misc/num/num-vol7n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol8><img src=art/misc/num/num-vol8n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol9><img src=art/misc/num/num-vol9n.png width=30 height=30></a>";
}
if(num_b==2) {
rt = rt + "<a href=live://property/num_b_vol1><img src=art/misc/num/num-vol1n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol2><img src=art/misc/num/num-vol2n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol3><img src=art/misc/num/num-vol3.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol4><img src=art/misc/num/num-vol4n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol5><img src=art/misc/num/num-vol5n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol6><img src=art/misc/num/num-vol6n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol7><img src=art/misc/num/num-vol7n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol8><img src=art/misc/num/num-vol8n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol9><img src=art/misc/num/num-vol9n.png width=30 height=30></a>";
}
if(num_b==3) {
rt = rt + "<a href=live://property/num_b_vol1><img src=art/misc/num/num-vol1n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol2><img src=art/misc/num/num-vol2n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol3><img src=art/misc/num/num-vol3n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol4><img src=art/misc/num/num-vol4.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol5><img src=art/misc/num/num-vol5n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol6><img src=art/misc/num/num-vol6n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol7><img src=art/misc/num/num-vol7n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol8><img src=art/misc/num/num-vol8n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol9><img src=art/misc/num/num-vol9n.png width=30 height=30></a>";
}
if(num_b==4) {
rt = rt + "<a href=live://property/num_b_vol1><img src=art/misc/num/num-vol1n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol2><img src=art/misc/num/num-vol2n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol3><img src=art/misc/num/num-vol3n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol4><img src=art/misc/num/num-vol4n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol5><img src=art/misc/num/num-vol5.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol6><img src=art/misc/num/num-vol6n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol7><img src=art/misc/num/num-vol7n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol8><img src=art/misc/num/num-vol8n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol9><img src=art/misc/num/num-vol9n.png width=30 height=30></a>";
}
if(num_b==5) {
rt = rt + "<a href=live://property/num_b_vol1><img src=art/misc/num/num-vol1n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol2><img src=art/misc/num/num-vol2n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol3><img src=art/misc/num/num-vol3n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol4><img src=art/misc/num/num-vol4n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol5><img src=art/misc/num/num-vol5n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol6><img src=art/misc/num/num-vol6.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol7><img src=art/misc/num/num-vol7n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol8><img src=art/misc/num/num-vol8n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol9><img src=art/misc/num/num-vol9n.png width=30 height=30></a>";
}
if(num_b==6) {
rt = rt + "<a href=live://property/num_b_vol1><img src=art/misc/num/num-vol1n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol2><img src=art/misc/num/num-vol2n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol3><img src=art/misc/num/num-vol3n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol4><img src=art/misc/num/num-vol4n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol5><img src=art/misc/num/num-vol5n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol6><img src=art/misc/num/num-vol6n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol7><img src=art/misc/num/num-vol7.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol8><img src=art/misc/num/num-vol8n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol9><img src=art/misc/num/num-vol9n.png width=30 height=30></a>";
}
if(num_b==7) {
rt = rt + "<a href=live://property/num_b_vol1><img src=art/misc/num/num-vol1n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol2><img src=art/misc/num/num-vol2n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol3><img src=art/misc/num/num-vol3n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol4><img src=art/misc/num/num-vol4n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol5><img src=art/misc/num/num-vol5n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol6><img src=art/misc/num/num-vol6n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol7><img src=art/misc/num/num-vol7n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol8><img src=art/misc/num/num-vol8.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol9><img src=art/misc/num/num-vol9n.png width=30 height=30></a>";
}
if(num_b==8) {
rt = rt + "<a href=live://property/num_b_vol1><img src=art/misc/num/num-vol1n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol2><img src=art/misc/num/num-vol2n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol3><img src=art/misc/num/num-vol3n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol4><img src=art/misc/num/num-vol4n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol5><img src=art/misc/num/num-vol5n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol6><img src=art/misc/num/num-vol6n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol7><img src=art/misc/num/num-vol7n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol8><img src=art/misc/num/num-vol8n.png width=30 height=30></a>";
rt = rt + "<a href=live://property/num_b_vol9><img src=art/misc/num/num-vol9.png width=30 height=30></a>";
}
rt=rt+ "<br><br></td></tr></table>";
// End Set Chunage Num tables
rt=rt+ "<table><tr bgcolor=#3E4A68><td width=100%><b>Instructions</b></td></tr><br><br></table>";
rt=rt+ "<table><tr bgcolor=#3E4A68><td width=100% valign=center><font color=#FCFFFD locale='english'><i>You can set the dial simply by clicking on a certain number or letter, saving will save the settings. This setting is not used to search for signals, but only to name this signal. For the main traffic lights, the name for the odd direction is the letter 'L' + 'number' and for the even direction the letter 'S' + 'number' and that is a red table with white letters. For the omen, there is a black background with white letters and that is 'Př' + 'number' or repeating the signals 'Př' + 'number' or 'Př' + 'L' / 'S' + 'number' and also for 'Př'. For shift there is a blue background with white lettering 'Se' + 'number' For the Autoblock signal (AB) there is a white background with black lettering. 'Letter' or 'Number'. The setting is created in such a way that there are only two templates for 2 characters and or 5 characters.</i></font><font color=#FCFFFD locale='czech'><i>Číselník nastavíte pouhým kliknutím na určité číslo nebo písmeno, uložením se dané nastavení uloží. Toto nastavení neslouží pro vyhledávání signálů, ale pouze k pojmenování tohoto signálu. Pro hlavní návěstidla je pojmenování pro lichý směr písmeno 'L' + 'číslo' a pro směr sudý písmenu 'S' + 'číslo' a to červená tabulka s bílým písmem. Pro předvěst je černý podklad s bílým písmem a to 'Př' + 'číslo' nebo opakování signálů 'Opř' + 'číslo' a nebo 'Př' + 'L' / 'S' + 'číslo' a to i pro 'Opř'. Pro posun je modrý podklad s bílým písmem 'Se' + 'číslo' Pro signál Autobloku (AB) je bílý podklad s černým písmem. 'Písmeno' nebo 'číslo'. Nastavení je vytvořeno tak, že existují pouze dvě šablony a to pro 2 znaky a nebo 5 znaků. </i></font><br><br></td></tr></table>";
rt=rt+ "<table><tr bgcolor=#3E4A68><td width=100% valign=center>" + icnNum + "</td></tr><br></table>";
rt=rt+ "<table><tr bgcolor=#DF3415><br></tr></table>";
rt=rt+ "<table><tr bgcolor=#0c151a><td width=100%><b>A possible solution</b></td></tr></table>";
rt=rt+ "<br>" + icnResul + "<br><br>";
rt=rt+ "<table><tr bgcolor=#0c151a><td width=100%></td></tr></table><br><br>";
rt=rt+ "<table><tr><td width=60% valign=center></td> <td width=40% valign=center>" + icnOwn + "</td></tr></table>";
rt=rt+ "<font color=#435158 locale='english'><i>AZD-70 SIGNALING SYSTEM CZ-SK ver.: 1.a.24</i></font><font color=#435158 locale='czech'><i>AŽD-70 SYSTÉM SIGNALIZACE ČR-SK ver.: 1.a.24</i></font><br>";
rt=rt+ "<font color=#435158 locale='english'><i>All rights reserved by © Alpinetrainz® & © Wikiquik; Authors: David Pištělák and JBVector</i></font><font color=#435158 locale='czech'><i>Všechna práva vyhrazena © Alpinetrainz® & © Wikiquik; Autoři: David Pištělák a JBVector</i></font><br>";
rt=rt+ "</font></b><font color=#FFFFFF>";
affichage();
return sHtml,"<html><body>" + rt + "</body></html>";
}
//INFO: This method is called by Trainz to retrieve HTML which a player can use to configure the objects properties.
//Any embedded properties should use the live://property/propertyID format, all player readable strings should be sourced
//from the asset string-table, and all player configurable values should be appropriately escaped to avoid HTML corruption.
//The Trainz uses its Mini Browser to display the HTML. See the MiniBrowser page to find supported HTML elements.
string GetPropertyType (string p_ID, string sPropertyId) {
if (p_ID == "num_y" or p_ID == "num_n"){ p_ID = "link"; return p_ID;}return "string,1,30";
if (p_ID == "light_on_y" or p_ID == "light_on_n"){ p_ID = "link"; return p_ID;}return "string,1,30";
if (p_ID == "zebrik_y" or p_ID == "zebrik_n"){ p_ID = "link"; return p_ID;}return "string,1,30";
if (p_ID == "tabulka_change_y" or p_ID == "tabulka_change_n"){ p_ID = "link"; return p_ID;}return "string,1,30";
if (p_ID == "num_a_vol1" or p_ID == "num_a_vol2"){ p_ID = "link"; return p_ID;}return "string,1,30";
if (p_ID == "num_b_vol1" or p_ID == "num_b_vol2" or p_ID == "num_b_vol3" or p_ID == "num_b_vol4" or p_ID == "num_b_vol5" or p_ID == "num_b_vol6" or p_ID == "num_b_vol7" or p_ID == "num_b_vol8" or p_ID == "num_b_vol9"){ p_ID = "link"; return p_ID;}return "string,1,30";
if((sPropertyId == "m_posX") or (sPropertyId == "m_posY") or (sPropertyId == "m_posZ")) return "float,0,0,0";
if((sPropertyId == "m_angX") or (sPropertyId == "m_angY") or (sPropertyId == "m_angZ")) return "float,-180,180,1";
return inherited(p_ID, sPropertyId);
}
public string GetPropertyValue(string sPropertyId) {
if (sPropertyId == "m_posX");
else if (sPropertyId == "m_posY");
else if (sPropertyId == "m_posZ");
else if (sPropertyId == "m_angX");
else if (sPropertyId == "m_angY");
else if (sPropertyId == "m_angZ");
return "zadej hodnotu";
return inherited(sPropertyId);
}
//INFO: Sets a new value for the named property. The variant called depends on the property type, as returned by GetPropertyType().
// *************************************************************
void LinkPropertyValue(string property){
inherited(property);
//
if (property == "num_y") num = 1;
if (property == "num_n") num = 0;
if (property == "light_on_y") light_on = 1;
if (property == "light_on_n") light_on = 0;
if (property == "zebrik_y") zebrik = 1;
if (property == "zebrik_n") zebrik = 0;
if (property == "tabulka_change_y") tabulka_change = 1;
if (property == "tabulka_change_n") tabulka_change = 0;
if (property == "num_a_vol1") num_a = 1;
if (property == "num_a_vol2") num_a = 0;
if (property == "num_b_vol1") num_b = 0;
if (property == "num_b_vol2") num_b = 1;
if (property == "num_b_vol3") num_b = 2;
if (property == "num_b_vol4") num_b = 3;
if (property == "num_b_vol5") num_b = 4;
if (property == "num_b_vol6") num_b = 5;
if (property == "num_b_vol7") num_b = 6;
if (property == "num_b_vol8") num_b = 7;
if (property == "num_b_vol9") num_b = 8;
}
// ************************************************************
public string GetPropertyName(string sPropertyId)
{
if(sPropertyId == "m_posX")
{
return "Set X position";
}
else if(sPropertyId == "m_posY")
{
return "Set Y position";
}
else if(sPropertyId == "m_posZ")
{
return "Set Z position";
}
else if(sPropertyId == "m_angX")
{
return "Set X angle";
}
else if(sPropertyId == "m_angY")
{
return "Set Y angle";
}
else if(sPropertyId == "m_angZ")
{
return "Set Z angle";
}
return inherited(sPropertyId);
}
// ************************************************************
public void SetPropertyValue(string sPropertyId, float iPropertyValue)
{
if(sPropertyId == "m_posX")
{
m_posX = iPropertyValue;
}
else if(sPropertyId == "m_posY")
{
m_posY = iPropertyValue;
}
else if(sPropertyId == "m_posZ")
{
m_posZ = iPropertyValue;
}
else if(sPropertyId == "m_angX")
{
m_angX = iPropertyValue;
}
else if(sPropertyId == "m_angY")
{
m_angY = iPropertyValue;
}
else if(sPropertyId == "m_angZ")
{
m_angZ = iPropertyValue;
}
}
// ************************************************************
public Soup GetProperties(void) {
Soup soup = inherited();
Soup msoup = inherited();
soup.SetNamedTag("USERNAME",username);
soup.SetNamedTag("NUM",num);
soup.SetNamedTag("LIGHTON",light_on);
soup.SetNamedTag("ZEBRIK",zebrik);
soup.SetNamedTag("TABULKACHANGE",tabulka_change);
soup.SetNamedTag("NUMA",num_a);
soup.SetNamedTag("NUMB",num_b);
msoup.SetNamedTag("M_posX", m_posX);
msoup.SetNamedTag("M_posY", m_posY);
msoup.SetNamedTag("M_posZ", m_posZ);
msoup.SetNamedTag("M_angX", m_angX);
msoup.SetNamedTag("M_angY", m_angY);
msoup.SetNamedTag("M_angZ", m_angZ);
return soup;
}
// ************************************************************
public void SetProperties(Soup soup,Soup msoup) {
inherited(soup,msoup);
username = soup.GetNamedTag("USERNAME");
num = soup.GetNamedTagAsInt("NUM");
light_on = soup.GetNamedTagAsInt("LIGHTON");
zebrik = soup.GetNamedTagAsInt("ZEBRIK");
tabulka_change = soup.GetNamedTagAsInt("TABULKACHANGE");
num_a = soup.GetNamedTagAsInt("NUMA");
num_b = soup.GetNamedTagAsInt("NUMB");
m_posX = msoup.GetNamedTagAsFloat("M_posX", m_posX);
m_posY = msoup.GetNamedTagAsFloat("M_posY", m_posY);
m_posZ = msoup.GetNamedTagAsFloat("M_posZ", m_posZ);
m_angX = msoup.GetNamedTagAsFloat("M_angX", m_angX);
m_angY = msoup.GetNamedTagAsFloat("M_angY", m_angY);
m_angZ = msoup.GetNamedTagAsFloat("M_angZ", m_angZ);
SetMeshTranslation("beton",m_posX,m_posY,m_posZ);
SetMeshOrientation("beton",DegreeToRadian(m_angX),DegreeToRadian(m_angY),DegreeToRadian(m_angZ));
affichage();
}
// ************************************************************
// AI Logic
// ************************************************************
//Blokujte vzdálenost k dalšímu absolutnímu signálu
//========================================================================================
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;
}
//========================================================================================
//
// Param: start Signál k zahájení od
// Param: searchDirection Kterým směrem pro vyhledávání 'False' == v zadní části signál, 'True' == před signálem.
// Param: numSignalsToCheck Počet bloků signálu ke skenování 0 pro všechny.
// Param: maxDistance Jak daleko dolů do grafu trati hledat vlak
//
//Zkontroluje, zda je blok aktivní, a vrací odkaz na vlak, pokud je nalezen
//Vlak se nemusí pohybovat, aby aktivoval blok
//========================================================================================
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;
}
//========================================================================================
//Najděte nejbližší blížící se vlak pro konkrétní signál.
//Vlak se musí pohybovat směrem k signálu nebo směřovat ve směru signálu a zastavit se
//========================================================================================
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() + 2000)))
{
//Vlak směřuje od signálu
if(theTrain.GetTrainVelocity() < -0.01) { //Pokud vlak podporuje můj směr
return theTrain;
} else {
return null;
}
} else {
//Vlak jede k signálu
if(theTrain.GetTrainVelocity() > -0.01) { //Pokud se vlak pohybuje vpřed nebo směřuje k mému směru a zastaví se.
return theTrain;
} else {
return null;
}
}
}
}
// State modifiers
bool bShunt = false;
bool bShuntWrn = false; // Pokud další signál zobrazuje posunovací aspekt, je to pravda.
bool bShuntLimit = false; // Při posunování musí signál najít signální nebo limitní značku.
Train apprTrain = null;
int trainAppr = -1;
int StateTrainz = -1;
string rsnMsg;
string rsnWrn;
bool bKeepSearching = true;
bool dbgOutTrain, dbgInnTrain, dbgOvlTrain;
bool bHasDir = false; // Pravda, pokud je detekován směrový cíl.
// Track search
object nxtObj;
Signal tmpSig = null;
float sigDist, maxDist;
JunctionBase firstJct = null;
bool bTrainInPortal;
bool bTrainInOverlap = false;
bool bSignalInOverlap;
// Reason info
string rsnState;
// State modifiers
int myDir = 0; // My direction, 0 for straight, '-' for left and '+' for right.
int wrnDir = 0; // Direction of the next signal.
int wrnDirRpt = 0; // Direction of a signal beyond the next.
int advWrnState = 0; // Number of signals to look past for advanced warning.
bool bHiSpd = false;
bool bReducedOverlap = false; // Automatic detection of reduced overlap distance.
bool bAdvWrn = false; // True if the signal is requested and allowed to display advanced warning indications.
bool bHasInitState = false; // True if the signal is given a Trainz state before finding an exit signal.
bool bLoSpd;
// Debug info
int numSigSkip = 0;
int numError = 0;
int objCount = 0;
bool bFoundSignal = false;
// Rychlá kontrola výběru trasy, pokud máme pouze jednu trasu, nemusíme potvrzovat, jaký směr použít.
if (routeMax == 0) bHasDir = true;
if (ctrlMode == 1) {
//PrintDebug("Jsem řízený signál, kontrolujem, zda se blíží vlak...");
apprTrain = FindApproachingTrain(me, false, 5, outerApprDist); //outerApprDist = vzdálenostní int nastavení
if (apprTrain and apprTrain.GetFrontmostLocomotive()) {
PrintDebug("Našel kontrolovaný vlak '" + apprTrain.GetTrainDisplayName() + "' v přibližovacím limitu.");
trainAppr = 1;
dbgOutTrain = true;
} else {
PrintDebug(" ...Zatím se neblíží žádný vlak (hledaná vzdálenost = " + outerApprDist + ")");
trainAppr = 0;
StateTrainz = RED;
rsnMsg = "Čekání na příjezd vlaku (vnější vzdálenost).";
bKeepSearching = false;
dbgOutTrain = false;
}
}
// Pokud se jedná o posouvací signál, musí být vlak před posunem blíž
if (sigTypes == "shg") {
bShunt = true;
apprTrain = FindApproachingTrain(me, false, 2, innerApprDist); //innerApprDist = vnitřní vzdálenost int nastvení
if (apprTrain and apprTrain.GetFrontmostLocomotive()) {
PrintDebug("Našel kontrolovaný vlak '" + apprTrain.GetTrainDisplayName() + "' v posunovacím limitu.");
trainAppr = 1;
StateTrainz = EX_SLOW_APPROACH_RESTRICTED; //39
rsnMsg = "Pokračujte opatrně, trať před vámi může být obsazena.";
bKeepSearching = true;
dbgInnTrain = true;
} else {
PrintDebug("V limitu přístupu k posunu není žádný vlak. (hledaná vzdálenost = " + innerApprDist + ")");
trainAppr = 0;
StateTrainz = GREEN;
rsnMsg = "Čekání na vlak k přístupu (vnitřní vzdálenost).";
bKeepSearching = false;
dbgInnTrain = false;
}
}
PrintDebug("Signální Data: Type/Mode = " + sigTypes + "/" + ctrlMode + ", Train Approaching = " + trainAppr + ", Low Speed Enabled = " + bHasLowSpeed);
PrintDebug("Začátek Vyhledávání...");
while (myGST.SearchNextObject() and bKeepSearching) {
nxtObj = myGST.GetObject();
objCount = objCount + 1;
PrintDebug("Vyhledávám...");
string tmpName = (cast<MapObject> nxtObj).GetLocalisedName();
PrintDebug(" ...nalezen objekt '" + tmpName + "'");
if (cast<Vehicle> nxtObj) {
Vehicle nxtVeh = cast<Vehicle> nxtObj;
string nxtVehName = nxtVeh.GetLocalisedName();
PrintDebug("<VEH> Dalším objektem je vozidlo: '" + nxtVehName + "'...");
if (!me.GetIsRepeater()) {
rsnWrn = "Trať po směru jízdy OBSASEZNA!";
if (bShunt) {
PrintDebug("<VEH> ...trať obsazená, ale jsem nastaven na posun. Ukončuji vyhledávání zde.");
bKeepSearching = false;
rsnMsg = "Pokračujte opatrně, trať dopředu může být obsazena.";
break;
} else {
PrintDebug("<VEH> ...trať obsazena, tak končím vyhledávání se stavovým stav STŮJ.");
StateTrainz = RED;
SetAutopilotHintObj(nxtVeh);
bKeepSearching = false;
break;
}
} else PrintDebug("<VEH> ...ale já jsem opakovač, takže ignoruj.");
} else if (cast<JunctionBase> nxtObj) {
JunctionBase nxtJct = cast<JunctionBase> nxtObj;
string nxtJctName = nxtJct.GetMapObject().GetLocalisedName();
PrintDebug("<JCT> Dalším objektem je křižovatka (JunctionBase): '" + nxtJctName + "'");
// Signalizace trasy je řízena cíli, ale AI musí být stále informována o křižovatkách
if (!firstJct) firstJct = nxtJct;
SetAutopilotJunction(firstJct);
} else if (cast<Signal> nxtObj) {
Signal nxtSig = null;
Signal tmpSig = cast<Signal> nxtObj;
string nxtSigName = tmpSig.GetLocalisedName();
int sigNxtState = tmpSig.GetSignalStateEx();
float sigNxtDist = myGST.GetDistance();
PrintDebug("<SIG> Next object is a Signal: '" + nxtSigName + "' (dist=" + sigNxtDist + ") with state '" + sigNxtState + "'...");
if (bShunt and bHasDir) {
// Pokud jsme připraveni na posunutí, pak signál ve skutečnosti nezáleží, zacházíme s ním pouze jako s zkratovým limitem
PrintDebug("<SIG> ...Jsem připraven na posunnou cestu a vím, že můj směr, takže zde ukončím vyhledávání.");
bShuntWrn = true;
bKeepSearching = false;
bShuntLimit = true;
break;
} else if (myGST.GetFacingRelativeToSearchDirection()) {
PrintDebug("<SIG> ...A čelí stejným způsobem...");
if (tmpSig.GetIsRepeater()) {
// Next signal is a repeater, we should ignore it
PrintDebug("<SIG> ...Je to však opakovací signál, budu ignorovat a pokračovat v hledání.");
numSigSkip = numSigSkip + 1;
} else if (me.GetIsRepeater()) {
PrintDebug("<SIG> ...sem opakovač, takže budu kopírovat stav tohoto signálu a dokončuji své vyhledávání.");
StateTrainz = sigNxtState;
rsnWrn = "Opakující se stav pro '" + nxtSigName + "'";
bKeepSearching = false;
break;
} else if (tmpSig.GetIsDistant()) {
if (!nxtSig and sigNxtDist > me.GetOverlap() + 20) {
// Pokud je další signál vzdálený signál, pamatujeme si jej na později.
PrintDebug("<SIG> ...je to vzdálený signál, budu si to pamatovat a pokračovat v hledání...");
nxtSig = tmpSig;
numSigSkip = numSigSkip + 1;
}
}
}
}
}
return null;
}
};
Display More