Advertisement
agmike

agmhumpyard.gs

Oct 2nd, 2014
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 43.06 KB | None | 0 0
  1. //
  2. // Hump yard marker
  3.  
  4. include "agmhump.gs"
  5.  
  6.  
  7. class AGMHumpYard isclass TrackMark
  8. {
  9.     public bool RouteScanOverflow = false;
  10.     public int[] RouteScanBadJunctionIds = null;
  11.     public int[] RouteScanCycleJunctionIds = null;
  12.    
  13.     public bool AutoMode = true;
  14.     public bool ManualMode = true;
  15.     public bool RoutingEnabled = true;
  16.    
  17.     public float[] AutoModeCutLengthWeight;
  18.     public float[] AutoModeTrackBaseWeight;
  19.     public float[] AutoModeTrackSelectWeight;
  20.  
  21.     public AGMHumpRouter HumpRouter;
  22.     public AGMHumpDecoupler HumpDecoupler;
  23.     public AGMHumpTasks HumpTasks;
  24.    
  25.     public bool ScanRoutesRunning = false;
  26.     public bool StopUI = false;
  27.    
  28.     public void ReportTaskDone(Vehicle veh, int trackNumber)
  29.     {
  30.         Soup data = Constructors.NewSoup();
  31.         data.SetNamedTag("vehicle-id", veh.GetId());
  32.         data.SetNamedTag("track-number", trackNumber);
  33.         PostMessage(null, "AGMHump-298469.Notify", "TaskDone", data, 0.0);
  34.         Interface.Log("AGMHump-298469.Notify, TaskDone"); LUtil.FlushLog();
  35.     }
  36.    
  37.     public void ReportTaskExpired(Vehicle veh, int trackNumber)
  38.     {
  39.         Soup data = Constructors.NewSoup();
  40.         data.SetNamedTag("vehicle-id", veh.GetId());
  41.         data.SetNamedTag("track-number", trackNumber);
  42.         PostMessage(null, "AGMHump-298469.Notify", "TaskExpired", data, 0.0);
  43.         Interface.Log("AGMHump-298469.Notify, TaskExpired"); LUtil.FlushLog();
  44.     }
  45.    
  46.     public void ReportRoutingFailure(Vehicle veh, int targetTrackNumber, int realTrackNumber, int junctionId)
  47.     {
  48.         Soup data = Constructors.NewSoup();
  49.         data.SetNamedTag("vehicle-id", veh.GetId());
  50.         data.SetNamedTag("target-track-number", targetTrackNumber);
  51.         data.SetNamedTag("real-track-number", realTrackNumber);
  52.         data.SetNamedTag("junction-id", junctionId);
  53.         PostMessage(null, "AGMHump-298469.Notify", "RoutingFailure", data, 0.0);
  54.         Interface.Log("AGMHump-298469.Notify, RoutingFailure"); LUtil.FlushLog();
  55.     }
  56.    
  57.     bool scanRoutesState = false;
  58.     thread void ScanRoutesThread()
  59.     {
  60.         ScanRoutesRunning = true;
  61.         AGMHumpRouteScanResult result = HumpRouter.ScanRoutes();
  62.         RouteScanOverflow = result.Overflow;
  63.         if (result.BadJunctionIds)
  64.             RouteScanBadJunctionIds = result.BadJunctionIds;
  65.         if (result.CyclicJunctionIds)
  66.             RouteScanCycleJunctionIds = result.CyclicJunctionIds;
  67.        
  68.         if (AutoModeTrackBaseWeight.size() != HumpRouter.Tracks.size()) {
  69.             int oldCount = AutoModeTrackBaseWeight.size();
  70.             int newCount = HumpRouter.Tracks.size();
  71.             if (oldCount > newCount)
  72.                 AutoModeTrackBaseWeight[newCount, ] = null;
  73.             else {
  74.                 float[] newWeights = new float[newCount];
  75.                 float lastWeight = 0.0f;
  76.                 int i;
  77.                 for (i = 0; i < oldCount; ++i) {
  78.                     lastWeight = AutoModeTrackBaseWeight[i];
  79.                     newWeights[i] = lastWeight;
  80.                 }
  81.                 for (; i < newCount; ++i)
  82.                     newWeights[i] = lastWeight;
  83.                 AutoModeTrackBaseWeight = newWeights;
  84.             }
  85.         } //*/
  86.        
  87.         LUtil.FlushLog();
  88.         ScanRoutesRunning = false;
  89.        
  90.         scanRoutesState = false;
  91.     }
  92.    
  93.     public void ScanRoutes()
  94.     {
  95.         if (scanRoutesState)
  96.             return;
  97.         scanRoutesState = true;
  98.        
  99.         ScanRoutesThread();
  100.     }
  101.  
  102.     bool decouplerState = false;
  103.     thread void RunDecouplerThread()
  104.     {
  105.         HumpDecoupler.MonitorLoop();
  106.         StopUI = true;
  107.        
  108.         decouplerState = false;
  109.     }
  110.    
  111.     public void RunDecoupler()
  112.     {
  113.         if (decouplerState)
  114.             return;
  115.         decouplerState = true;
  116.        
  117.         RunDecouplerThread();
  118.     }
  119.  
  120.     bool taskMonitorState = false;
  121.     thread void RunTaskMonitorThread()
  122.     {
  123.         HumpTasks.MonitorLoop();
  124.        
  125.         taskMonitorState = false;
  126.     }
  127.  
  128.     public void RunTaskMonitor()
  129.     {
  130.         if (taskMonitorState)
  131.             return;
  132.         taskMonitorState = true;
  133.        
  134.         RunTaskMonitorThread();
  135.     }
  136.    
  137.     bool uiState = false;
  138.     thread void RunUIThread()
  139.     {
  140.         AGMHumpUI ui = new AGMHumpUI();
  141.         ui.Owner = me;
  142.         ui.MainLoop();
  143.        
  144.         uiState = false;
  145.     }
  146.    
  147.     public void RunUI()
  148.     {
  149.         StopUI = false;
  150.         if (uiState)
  151.             return;
  152.         uiState = true;
  153.        
  154.         RunUIThread();
  155.     }
  156.    
  157.     int[] trackRankCars;
  158.     int[] trackIndex;
  159.     int[] rankIndex;
  160.    
  161.     string tos(int[] tracks)
  162.     {
  163.         HTMLBuffer ret = HTMLBufferStatic.Construct();
  164.         int i, count = tracks.size();
  165.         for (i = 0; i < count; ++i) {
  166.             ret.Print(tracks[i]);
  167.             if (i < count - 1)
  168.                 ret.Print("\t");
  169.         }
  170.         return ret.AsString();
  171.     }
  172.    
  173.     string tos(float[] tracks)
  174.     {
  175.         HTMLBuffer ret = HTMLBufferStatic.Construct();
  176.         int i, count = tracks.size();
  177.         for (i = 0; i < count; ++i) {
  178.             ret.Print(tracks[i]);
  179.             if (i < count - 1)
  180.                 ret.Print("\t");
  181.         }
  182.         return ret.AsString();
  183.     }
  184.    
  185.     int SelectRandomTrack(AGMHumpTrackStats[] stats, float cutLength)
  186.     {
  187.         int trackCount = stats.size();
  188.         AGMHumpTrack[] tracks = HumpRouter.Tracks;
  189.        
  190.         if (!trackRankCars or trackRankCars.size() < trackCount) {
  191.             trackRankCars = new int[trackCount];
  192.             trackIndex = new int[trackCount];
  193.             rankIndex = new int[trackCount + 1];
  194.         }
  195.        
  196.         int i;
  197.         for (i = 0; i < trackCount; ++i) {
  198.             trackRankCars[i] = stats[i].CarCount;
  199.             trackIndex[i] = i;
  200.         }
  201.         AGMHumpUtils.Sort(trackRankCars, trackIndex);
  202.        
  203.         Interface.Log("SRT> cars: " + tos(trackRankCars));
  204.         Interface.Log("SRT>   ix: " + tos(trackIndex));
  205.        
  206.         rankIndex[0] = 0;
  207.         int ranksCount = 1;
  208.         int lastRankedTrack = 0;
  209.         for (i = 0; i < trackCount; ++i) {
  210.             int index = trackIndex[i];
  211.             bool notFilled = stats[index].UsedLength + cutLength <= stats[index].Length;
  212.             bool notEqual = i > 0 and stats[lastRankedTrack].CarCount != stats[index].CarCount;
  213.             if (notFilled and notEqual) {
  214.                 lastRankedTrack = index;
  215.                 rankIndex[ranksCount++] = i;
  216.             }
  217.         }
  218.         rankIndex[ranksCount] = trackCount;
  219.        
  220.         Interface.Log("SRT>  rank ix: " + tos(rankIndex));
  221.        
  222.         int weightsCount = AutoModeTrackSelectWeight.size();
  223.         int maxRank = Math.Min(ranksCount, weightsCount);
  224.         int chosenRank = -1;
  225.         bool chosenLastRank = false;
  226.         while (chosenRank < 0) {
  227.             chosenRank = AGMHumpUtils.WeightedRand(AutoModeTrackSelectWeight);
  228.             chosenLastRank = chosenRank == weightsCount - 1;
  229.             // We're reversing rank since we sorted tracks by usage ascending
  230.             // and weights are given by usage descending
  231.             chosenRank = (maxRank - 1) - chosenRank;
  232.         }
  233.         Interface.Log("SRT> rank: " + chosenRank);
  234.        
  235.         int rankIndexStart = rankIndex[chosenRank];
  236.         int rankIndexEnd = rankIndex[chosenRank + 1];
  237.         if (chosenLastRank) {
  238.             rankIndexStart = rankIndex[0];
  239.             rankIndexEnd = rankIndex[(ranksCount - weightsCount) + 1];
  240.         }
  241.         int rankTrackCount = rankIndexEnd - rankIndexStart;
  242.         int chosenRankTrack = 0;
  243.         if (rankTrackCount > 1) {
  244.             float[] rankTrackWeights = new float[rankTrackCount];
  245.             for (i = 0; i < rankTrackCount; ++i) {
  246.                 int index = trackIndex[rankIndexStart + i];
  247.                 rankTrackWeights[i] = AutoModeTrackBaseWeight[index];
  248.             }
  249.             Interface.Log("SRT>  weights: " + tos(rankTrackWeights));
  250.             chosenRankTrack = rankIndexStart + AGMHumpUtils.WeightedRand(rankTrackWeights);
  251.         }
  252.         else
  253.             chosenRankTrack = rankIndexStart;
  254.         Interface.Log("SRT> rank index: " + chosenRankTrack);
  255.         Interface.Log("SRT>      index: " + trackIndex[chosenRankTrack]);
  256.         LUtil.FlushLog();
  257.         return tracks[trackIndex[chosenRankTrack]].Number;
  258.     }
  259.    
  260.     void UpdateTrackStats(AGMHumpTrackStats[] stats, int trackNumber, int cutCount, float cutLength)
  261.     {
  262.         int i, statCount = stats.size();
  263.         for (i = 0; i < statCount; ++i) {
  264.             if (stats[i].TrackNumber == trackNumber) {
  265.                 stats[i].UsedLength = stats[i].UsedLength + cutLength;
  266.                 stats[i].CarCount = stats[i].CarCount + cutCount;
  267.             }
  268.         }
  269.     }
  270.    
  271.     float GetCutLength(Vehicle[] vehs, int first, int last)
  272.     {
  273.         int i = Math.Max(0, Math.Min(first, last));
  274.         int end = Math.Min(vehs.size(), Math.Max(first, last));
  275.         float ret = 0.0f;
  276.         for(; i < end; ++i)
  277.             ret = ret + vehs[i].GetLength();
  278.         return ret;
  279.     }
  280.    
  281.     void CreateRandomTask(Train train)
  282.     {
  283.         Interface.Log("AGMHumpYard.CreateRandomTask"); LUtil.FlushLog();
  284.         AGMHumpTrack[] tracks = HumpRouter.Tracks;
  285.         int trackCount = tracks.size();
  286.        
  287.         Vehicle[] vehs = train.GetVehicles();
  288.         int i, length = vehs.size();
  289.         int start = 0;
  290.         int trainDir = 1;
  291.         if (train.GetFrontmostLocomotive() != vehs[0]) {
  292.             start = length - 1;
  293.             trainDir = -1;
  294.         }
  295.        
  296.         while (Flags.Test(vehs[start].GetVehicleTypeFlags(), Vehicle.TYPE_LOCOMOTIVE)) {
  297.             start = start + trainDir;
  298.             if (start < 0 or start >= length)
  299.                 break;
  300.         }
  301.        
  302.         AGMHumpTrackStats[] trackStats = HumpRouter.GetAllTracksStats();
  303.        
  304.         int cutLength = 0;
  305.         int track = 0;
  306.         for (i = start;
  307.              0 <= i and i < length;
  308.              i = i + trainDir)
  309.         {
  310.             if (cutLength <= 0) {
  311.                 cutLength = 1 + AGMHumpUtils.WeightedRand(AutoModeCutLengthWeight);
  312.                 float cutLengthMeters = GetCutLength(vehs, i, i + trainDir * cutLength);
  313.                 int oldTrack = track;
  314.                 int maxTrials = 10;
  315.                 while (oldTrack == track and --maxTrials >= 0)
  316.                     track = SelectRandomTrack(trackStats, cutLengthMeters);
  317.                 UpdateTrackStats(trackStats, track, cutLength, cutLengthMeters);
  318.             }
  319.             HumpTasks.Add(vehs[i], track, 1200);
  320.             Interface.Log("RandTask: '"+vehs[i].GetLocalisedName()+"' => "+track);
  321.             --cutLength;
  322.         }
  323.     }
  324.    
  325.     void HandleTrainOnHump(Train train)
  326.     {
  327.         Interface.Log("AGMHumpYard.HandleTrainOnHump");
  328.         if (AutoMode and !HumpTasks.ContainsAny(train.GetVehicles()))
  329.             CreateRandomTask(train);
  330.         RunDecoupler();
  331.         if (ManualMode)
  332.             RunUI();
  333.     }
  334.  
  335.     void HandleTrainOnJunction(Train train, Junction jn)
  336.     {
  337.         if (!RoutingEnabled)
  338.             return;
  339.         Vehicle[] vehs = train.GetVehicles();
  340.         Vehicle head = vehs[0];
  341.         int dstTrack = HumpTasks.GetVehicleDestination(head);
  342.         if (dstTrack > 0) {
  343.             bool result = HumpRouter.SetJunctionToTrack(jn.GetId(), dstTrack);
  344.             if (!result)
  345.                 dstTrack = -1;
  346.             Interface.Print("JN '"+jn.GetLocalisedName()+"' -> "+dstTrack);
  347.         }
  348.         int i, count = vehs.size();
  349.         for (i = 0; i < count; ++i) {
  350.             int vehDstTrack = HumpTasks.GetVehicleDestination(vehs[i]);
  351.             if (vehDstTrack != dstTrack) {
  352.                 ReportRoutingFailure(vehs[i], vehDstTrack, dstTrack, jn.GetId());
  353.                 HumpTasks.Remove(vehs[i]);
  354.             }
  355.             HumpTasks.SetFlags(vehs[i], AGMHumpTask.StatusRouting,
  356.                                         AGMHumpTask.StatusRouting);
  357.         }
  358.     }
  359.    
  360.     void HandleTrainOnTrack(Train train, AGMHumpTrackMarker mrk)
  361.     {
  362.         Interface.Log("AGMHumpYard.HandleTrainOnTrack");
  363.         Interface.Log("Train '" + train.GetVehicles()[0].GetLocalisedName() + "', track " + mrk.HumpTrack);
  364.         Vehicle[] vehs = train.GetVehicles();
  365.         int i, length = vehs.size();
  366.         for (i = 0; i < length; ++i) {
  367.             int taskTrack = HumpTasks.GetVehicleDestination(vehs[i]);
  368.             if (taskTrack >= 0) {
  369.                 HumpTasks.Remove(vehs[i]);
  370.                 if (taskTrack == mrk.HumpTrack)
  371.                     ReportTaskDone(vehs[i], taskTrack);
  372.                 else
  373.                     ReportRoutingFailure(vehs[i], taskTrack, mrk.HumpTrack, 0);
  374.             }
  375.         }
  376.     }
  377.  
  378.  
  379.     void OnObjectEnter(Message msg)
  380.     {
  381.         Train src = cast <Train> msg.src;
  382.         if (!src) return;
  383.        
  384.         if (msg.dst == me)
  385.             HandleTrainOnHump(src);
  386.         else if (msg.dst.isclass(Junction)) {
  387.             Junction dst = cast <Junction> msg.dst;
  388.             if (msg.major == "Object" and msg.minor == "InnerEnter")
  389.                 HandleTrainOnJunction(src, dst);
  390.         }
  391.         else if (msg.dst.isclass(AGMHumpTrackMarker)) {
  392.             AGMHumpTrackMarker dst = cast <AGMHumpTrackMarker> msg.dst;
  393.             if (msg.major == "Object" and msg.minor == "Enter")
  394.                 HandleTrainOnTrack(src, dst);
  395.         }
  396.     }
  397.    
  398.     void OnControlAddTask(Soup data)
  399.     {
  400.         Vehicle veh = cast <Vehicle> Router.GetGameObject(data.GetNamedTagAsInt("vehicle-id"));
  401.         if (veh) {
  402.             int trackNumber = data.GetNamedTagAsInt("track-number", 0);
  403.             int ttl = data.GetNamedTagAsInt("time-to-live", 0);
  404.             if (trackNumber > 0 and ttl > 0)
  405.                 HumpTasks.Add(veh, trackNumber, ttl);
  406.         }
  407.     }
  408.    
  409.     void OnControlRemoveTask(Soup data)
  410.     {
  411.         Vehicle veh = cast <Vehicle> Router.GetGameObject(data.GetNamedTagAsInt("vehicle-id"));
  412.         if (veh)
  413.             HumpTasks.Remove(veh);
  414.     }
  415.    
  416.     void OnHumpControl(Message msg)
  417.     {
  418.         if (msg.minor == "AddTask") {
  419.             if (!msg.paramSoup)
  420.                 return;
  421.             OnControlAddTask(msg.paramSoup);
  422.         }
  423.         else if (msg.minor == "AddTasks") {
  424.             Soup data = cast <Soup> msg.paramSoup;
  425.             if (!data)
  426.                 return;
  427.             int i, count = data.CountTags();
  428.             for (i = 0; i < count; ++i)
  429.                 OnControlAddTask(data.GetNamedSoup(i));
  430.         }
  431.         else if (msg.minor == "RemoveTask") {
  432.             Soup data = cast <Soup> msg.paramSoup;
  433.             if (!data)
  434.                 return;
  435.             OnControlRemoveTask(data);
  436.         }
  437.         else if (msg.minor == "RemoveTasks") {
  438.             Soup data = cast <Soup> msg.paramSoup;
  439.             if (!data)
  440.                 return;
  441.             int i, count = data.CountTags();
  442.             for (i = 0; i < count; ++i)
  443.                 OnControlRemoveTask(data.GetNamedSoup(i));
  444.         }
  445.         else if (msg.minor == "ClearTasks") {
  446.             HumpTasks.Clear();
  447.         }
  448.     }
  449.    
  450.  
  451.     bool initialized = false;
  452.    
  453.     void InitHandlers()
  454.     {
  455.         int i, jnCount = HumpRouter.Junctions.size();
  456.         for (i = 0; i < jnCount; ++i) {
  457.             GameObject src = Router.GetGameObject(HumpRouter.Junctions[i].JnId);
  458.             if (src)
  459.                 Sniff(src, "Object", "InnerEnter", true);
  460.         }
  461.        
  462.         int mrkCount = HumpRouter.Tracks.size();
  463.         for (i = 0; i < mrkCount; ++i) {
  464.             GameObject src = Router.GetGameObject(HumpRouter.Tracks[i].MarkerId);
  465.             if (src)
  466.                 Sniff(src, "Object", "Enter", true);
  467.         }
  468.     }
  469.    
  470.     void InitObject()
  471.     {
  472.         Interface.Log("AGMHumpYard.InitObject");
  473.        
  474.         HumpRouter = new AGMHumpRouter();
  475.         HumpRouter.Owner = me;
  476.        
  477.         HumpDecoupler = new AGMHumpDecoupler();
  478.         HumpDecoupler.Owner = me;
  479.        
  480.         HumpTasks = new AGMHumpTasks();
  481.         HumpTasks.Owner = me;
  482.        
  483.         AddHandler(me, "Object", "InnerEnter", "OnObjectEnter");
  484.         AddHandler(me, "Object", "Enter", "OnObjectEnter");
  485.     }
  486.    
  487.     void InitDefaults()
  488.     {
  489.         HumpRouter.Junctions = new AGMHumpJunction[0];
  490.         HumpRouter.Tracks = new AGMHumpTrack[0];
  491.        
  492.         AutoModeCutLengthWeight = new float[10];
  493.         AutoModeCutLengthWeight[0] = 15.38461538f;
  494.         AutoModeCutLengthWeight[1] = 23.07692308f;
  495.         AutoModeCutLengthWeight[2] = 15.38461538f;
  496.         AutoModeCutLengthWeight[3] = 11.15384615f;
  497.         AutoModeCutLengthWeight[4] = 8.846153846f;
  498.         AutoModeCutLengthWeight[5] = 7.307692308f;
  499.         AutoModeCutLengthWeight[6] = 6.153846154f;
  500.         AutoModeCutLengthWeight[7] = 5.000000000f;
  501.         AutoModeCutLengthWeight[8] = 4.230769231f;
  502.         AutoModeCutLengthWeight[9] = 3.461538462f;
  503.        
  504.         AutoModeTrackBaseWeight = new float[0];
  505.        
  506.         AutoModeTrackSelectWeight = new float[6];
  507.         AutoModeTrackSelectWeight[0] = 25.0f;
  508.         AutoModeTrackSelectWeight[1] = 30.0f;
  509.         AutoModeTrackSelectWeight[2] = 35.0f;
  510.         AutoModeTrackSelectWeight[3] = 10.0f;
  511.         AutoModeTrackSelectWeight[4] = 10.0f;
  512.         AutoModeTrackSelectWeight[5] = 20.0f;
  513.     }
  514.  
  515.     void OnWorldModuleInit(Message msg)
  516.     {
  517.         Interface.Log("AGMHumpYard.OnWorldModuleInit, Module = " + World.GetCurrentModule());
  518.        
  519.         if (World.GetCurrentModule() == World.DRIVER_MODULE) {
  520.             InitHandlers();
  521.             RunTaskMonitor();
  522.         }
  523.     }
  524.  
  525.     public void Init(Asset asset)
  526.     {
  527.         inherited(asset);
  528.        
  529.         Interface.Log("AGMHumpYard.Init");
  530.        
  531.         if (!initialized) {
  532.             initialized = true;
  533.             InitObject();
  534.         }
  535.  
  536.         AddHandler(me, "World", "ModuleInit", "OnWorldModuleInit");
  537.         AddHandler(me, "AGMHump-298469.Control", "", "OnHumpControl");
  538.     }
  539.  
  540.     public Soup GetProperties()
  541.     {
  542.         Interface.Log("AGMHumpYard.GetProperties");
  543.         Soup sp = inherited();
  544.         Soup hump = sp.GetNamedSoupAdd("agmhump");
  545.         hump.SetNamedSoup("router", HumpRouter.GetProperties());
  546.         hump.SetNamedSoup("tasks", HumpTasks.GetProperties());
  547.         hump.SetNamedSoup("decoupler", HumpDecoupler.GetProperties());
  548.         hump.SetNamedTag("auto-mode", AutoMode);
  549.         hump.SetNamedTag("manual-mode", ManualMode);
  550.         hump.SetNamedTag("routing", RoutingEnabled);
  551.         hump.SetNamedSoup("auto-mode-cut-length-weight", AGMHumpUtils.ToSoup(AutoModeCutLengthWeight));
  552.         hump.SetNamedSoup("auto-mode-track-base-weight", AGMHumpUtils.ToSoup(AutoModeTrackBaseWeight));
  553.         hump.SetNamedSoup("auto-mode-track-select-weight", AGMHumpUtils.ToSoup(AutoModeTrackSelectWeight));
  554.         return sp;
  555.     }
  556.  
  557.     public void SetProperties(Soup sp)
  558.     {
  559.         Interface.Log("AGMHumpYard.SetProperties");
  560.         inherited(sp);
  561.         Soup hump = sp.GetNamedSoup("agmhump");
  562.         if (hump.CountTags() <= 0) {
  563.             InitDefaults();
  564.             return;
  565.         }
  566.         HumpRouter.SetProperties(hump.GetNamedSoup("router"));
  567.         HumpTasks.SetProperties(hump.GetNamedSoup("tasks"));
  568.         HumpDecoupler.SetProperties(hump.GetNamedSoup("decoupler"));
  569.         AutoMode = hump.GetNamedTagAsBool("auto-mode");
  570.         ManualMode = hump.GetNamedTagAsBool("manual-mode");
  571.         RoutingEnabled = hump.GetNamedTagAsBool("routing");
  572.         AutoModeCutLengthWeight = AGMHumpUtils.ToFloatArray(hump.GetNamedSoup("auto-mode-cut-length-weight"));
  573.         AutoModeTrackBaseWeight = AGMHumpUtils.ToFloatArray(hump.GetNamedSoup("auto-mode-track-base-weight"));
  574.         AutoModeTrackSelectWeight = AGMHumpUtils.ToFloatArray(hump.GetNamedSoup("auto-mode-track-select-weight"));
  575.     }
  576.  
  577.     final string Case(bool cond, string ifTrue, string ifFalse)
  578.     {
  579.         if (cond) return ifTrue;
  580.         return ifFalse;
  581.     }
  582.  
  583.     string TrackString(int[] tracks)
  584.     {
  585.         HTMLBuffer ret = HTMLBufferStatic.Construct();
  586.         int i, count = tracks.size();
  587.         for (i = 0; i < count; ++i) {
  588.             ret.Print(tracks[i]);
  589.             if (i < count - 1)
  590.                 ret.Print(",");
  591.         }
  592.         return ret.AsString();
  593.     }
  594.    
  595.     float Sum(float[] a)
  596.     {
  597.         if (!a)
  598.             return 0.0f;
  599.         int i, len = a.size();
  600.         float sum = 0.0f;
  601.         for (i = 0; i < len; ++i)
  602.             sum = sum + a[i];
  603.         return sum;
  604.     }
  605.    
  606.     string ProbPercent(float w, float sum)
  607.     {
  608.         if (sum == 0.0f)
  609.             return "0";
  610.         return (string) (int) ((w / sum * 100.0f) + 0.5f);
  611.     }
  612.    
  613.     bool HasErrors()
  614.     {
  615.         return RouteScanOverflow or RouteScanBadJunctionIds or RouteScanCycleJunctionIds;
  616.     }
  617.    
  618.     void ClearErrors()
  619.     {
  620.         RouteScanOverflow = false;
  621.         RouteScanBadJunctionIds = null;
  622.         RouteScanCycleJunctionIds = null;
  623.     }
  624.    
  625.     bool ShowRoutesHTML = false;
  626.     bool ShowTracksHTML = false;
  627.     StringTable ST;
  628.    
  629.     final string T(string s)
  630.     {
  631.         return ST.GetString0(s);
  632.         //return "T(\"" + s + "\")";
  633.         //return s;
  634.     }
  635.    
  636.     final string T(string s, string arg0)
  637.     {
  638.         return ST.GetString1(s, arg0);
  639.         //return "T(\"" + s + "\")";
  640.         //return s;
  641.     }
  642.    
  643.     final string P(string pID)
  644.     {
  645.         return "live://property/" + pID;
  646.         //return "live://property/" + pID + "'>&lt;" + pID + "&gt;</a><a href='";
  647.     }
  648.    
  649.     void ModeHTML(HTMLBuffer buf)
  650.     {
  651.         HTMLWindow h = HTMLWindow;
  652.         buf.Print(h.StartTable());
  653.             buf.Print(h.StartRow());
  654.                 buf.Print(h.StartCell());
  655.                     buf.Print(T("html-mode-auto-title"));
  656.                 buf.Print(h.EndCell());
  657.                 buf.Print(h.StartCell());
  658.                     buf.Print(h.CheckBox(P("mode-auto"), AutoMode));
  659.                 buf.Print(h.EndCell());
  660.             buf.Print(h.EndRow());
  661.             buf.Print(h.StartRow());
  662.                 buf.Print(h.StartCell());
  663.                     buf.Print(T("html-mode-manual-title"));
  664.                 buf.Print(h.EndCell());
  665.                 buf.Print(h.StartCell());
  666.                     buf.Print(h.CheckBox(P("mode-manual"), ManualMode));
  667.                 buf.Print(h.EndCell());
  668.             buf.Print(h.EndRow());
  669.             buf.Print(h.StartRow());
  670.                 buf.Print(h.StartCell());
  671.                     buf.Print(T("html-routing-title"));
  672.                 buf.Print(h.EndCell());
  673.                 buf.Print(h.StartCell());
  674.                     buf.Print(h.CheckBox(P("routing"), RoutingEnabled));
  675.                 buf.Print(h.EndCell());
  676.             buf.Print(h.EndRow());
  677.         buf.Print(h.EndTable());
  678.     }
  679.    
  680.     void DecouplerHTML(HTMLBuffer buf)
  681.     {
  682.         HTMLWindow h = HTMLWindow;
  683.         buf.Print(h.StartTable());
  684.             buf.Print(h.StartRow());
  685.                 buf.Print(h.StartCell());
  686.                     buf.Print(T("html-decoupler-max-length-title"));
  687.                 buf.Print(h.EndCell());
  688.                 buf.Print(h.StartCell());
  689.                     buf.Print(h.MakeLink(P("decoupler-max-length"), HumpDecoupler.MaxCutLength));
  690.                 buf.Print(h.EndCell());
  691.             buf.Print(h.EndRow());
  692.             buf.Print(h.StartRow());
  693.                 buf.Print(h.StartCell());
  694.                     buf.Print(T("html-decoupler-max-heading-title"));
  695.                 buf.Print(h.EndCell());
  696.                 buf.Print(h.StartCell());
  697.                     buf.Print(h.MakeLink(P("decoupler-max-heading"), HumpDecoupler.MaxHeading));
  698.                 buf.Print(h.EndCell());
  699.             buf.Print(h.EndRow());
  700.         buf.Print(h.EndTable());
  701.     }
  702.    
  703.     void RouterHTML(HTMLBuffer buf)
  704.     {
  705.         HTMLWindow h = HTMLWindow;
  706.         buf.Print(h.StartTable());
  707.             buf.Print(h.StartRow());
  708.                 buf.Print(h.StartCell());
  709.                     buf.Print(T("html-router-scan-title"));
  710.                 buf.Print(h.EndCell());
  711.                 buf.Print(h.StartCell());
  712.                     if (!ScanRoutesRunning)
  713.                         buf.Print(h.MakeLink(P("router-scan"), T("html-router-scan")));
  714.                     else
  715.                         buf.Print(h.MakeLink(P("router-scan-refresh"), T("html-router-scan-refresh")));
  716.                 buf.Print(h.EndCell());
  717.             buf.Print(h.EndRow());
  718.             buf.Print(h.StartRow());
  719.                 buf.Print(h.StartCell());
  720.                     buf.Print("");
  721.                 buf.Print(h.EndCell());
  722.                 buf.Print(h.StartCell());
  723.                     buf.Print(h.MakeLink(P("router-set-route"), T("html-router-set-route")));
  724.                 buf.Print(h.EndCell());
  725.             buf.Print(h.EndRow());
  726.         buf.Print(h.EndTable());
  727.         if (HasErrors()) {
  728.             buf.Print(h.StartTable("bgcolor=#ff0000"));
  729.                 buf.Print(h.StartRow());
  730.                     buf.Print(h.MakeCell(h.MakeBold(T("html-router-errors"))));
  731.                 buf.Print(h.EndRow());
  732.                 if (RouteScanOverflow) {
  733.                     buf.Print(h.StartRow());
  734.                         buf.Print(h.MakeCell(T("html-router-error-overflow")));
  735.                     buf.Print(h.EndRow());
  736.                 }
  737.                 if (RouteScanBadJunctionIds) {
  738.                     int i, count = RouteScanBadJunctionIds.size();
  739.                     for (i = 0; i < count; ++i) {
  740.                         Junction jn = cast <Junction> Router.GetGameObject(RouteScanBadJunctionIds[i]);
  741.                         string name = Case(jn != null, jn.GetLocalisedName(), "");
  742.                         buf.Print(h.StartRow());
  743.                             buf.Print(h.MakeCell(T("html-router-error-bad-junction", name)));
  744.                         buf.Print(h.EndRow());
  745.                     }
  746.                 }
  747.                 if (RouteScanCycleJunctionIds) {
  748.                     int i, count = RouteScanCycleJunctionIds.size();
  749.                     for (i = 0; i < count; ++i) {
  750.                         Junction jn = cast <Junction> Router.GetGameObject(RouteScanCycleJunctionIds[i]);
  751.                         string name = Case(jn != null, jn.GetLocalisedName(), "");
  752.                         buf.Print(h.StartRow());
  753.                             buf.Print(h.MakeCell(T("html-router-error-cycle-junction", name)));
  754.                         buf.Print(h.EndRow());
  755.                     }
  756.                 }
  757.             buf.Print(h.EndTable());
  758.             ClearErrors();
  759.         }
  760.     }
  761.    
  762.     void RoutesHTML(HTMLBuffer buf)
  763.     {
  764.         HTMLWindow h = HTMLWindow;
  765.         buf.Print(h.StartTable());
  766.             buf.Print(h.StartRow());
  767.                 buf.Print(h.StartCell());
  768.                     buf.Print(T("html-routes-junction-header"));
  769.                 buf.Print(h.EndCell());
  770.                 buf.Print(h.StartCell());
  771.                     buf.Print(T("html-routes-left-tracks-header"));
  772.                 buf.Print(h.EndCell());
  773.                 buf.Print(h.StartCell());
  774.                     buf.Print(T("html-routes-right-tracks-header"));
  775.                 buf.Print(h.EndCell());
  776.             buf.Print(h.EndRow());
  777.             int i, count = HumpRouter.Junctions.size();
  778.             for (i = 0; i < count; ++i) {
  779.                 buf.Print(h.StartRow());
  780.                     buf.Print(h.StartCell());
  781.                         Junction junc = cast <Junction>
  782.                                         Router.GetGameObject(HumpRouter.Junctions[i].JnId);
  783.                         buf.Print(junc.GetLocalisedName());
  784.                     buf.Print(h.EndCell());
  785.                     buf.Print(h.StartCell());
  786.                         buf.Print(TrackString(HumpRouter.Junctions[i].LeftTracks));
  787.                     buf.Print(h.EndCell());
  788.                     buf.Print(h.StartCell());
  789.                         buf.Print(TrackString(HumpRouter.Junctions[i].RightTracks));
  790.                     buf.Print(h.EndCell());
  791.                 buf.Print(h.EndRow());
  792.             }
  793.         buf.Print(h.EndTable());
  794.     }
  795.    
  796.     void TracksHTML(HTMLBuffer buf)
  797.     {
  798.         HTMLWindow h = HTMLWindow;
  799.         buf.Print(h.StartTable());
  800.             buf.Print(h.StartRow());
  801.                 buf.Print(h.StartCell());
  802.                     buf.Print(T("html-tracks-number-header"));
  803.                 buf.Print(h.EndCell());
  804.                 buf.Print(h.StartCell());
  805.                     buf.Print(T("html-tracks-length-header"));
  806.                 buf.Print(h.EndCell());
  807.                 buf.Print(h.StartCell());
  808.                     buf.Print(T("html-tracks-weight-header"));
  809.                 buf.Print(h.EndCell());
  810.             buf.Print(h.EndRow());
  811.             int i, count = HumpRouter.Tracks.size();
  812.             float weightSum = Sum(AutoModeTrackBaseWeight);
  813.             bool baseWeightSet = AutoModeTrackBaseWeight
  814.                              and AutoModeTrackBaseWeight.size() == count;
  815.             for (i = 0; i < count; ++i) {
  816.                 int trackNumber = HumpRouter.Tracks[i].Number;
  817.                 AGMHumpTrackStats stats = HumpRouter.GetTrackStats(trackNumber);
  818.                 buf.Print(h.StartRow());
  819.                     buf.Print(h.StartCell());
  820.                         buf.Print(trackNumber);
  821.                     buf.Print(h.EndCell());
  822.                     buf.Print(h.StartCell());
  823.                         int length = (int) (stats.Length + 0.5f);
  824.                         if (!stats.HasEndMarker)
  825.                             buf.Print(h.MakeItalic(length));
  826.                         else
  827.                             buf.Print(length);
  828.                     buf.Print(h.EndCell());
  829.                     buf.Print(h.StartCell());
  830.                         buf.Print(h.StartLink(P("track-weight#"+i)));
  831.                             buf.Print(AutoModeTrackBaseWeight[i]);
  832.                             buf.Print(" (");
  833.                             buf.Print(ProbPercent(AutoModeTrackBaseWeight[i], weightSum));
  834.                             buf.Print("%)");
  835.                         buf.Print(h.EndLink());
  836.                     buf.Print(h.EndCell());
  837.                 buf.Print(h.EndRow());
  838.             }
  839.         buf.Print(h.EndTable());
  840.     }
  841.    
  842.     void AutoModeHTML(HTMLBuffer buf)
  843.     {
  844.         HTMLWindow h = HTMLWindow;
  845.         buf.Print(h.StartTable());
  846.             buf.Print(h.StartRow());
  847.                 buf.Print(h.StartCell());
  848.                     buf.Print(T("html-auto-track-select-weights-title"));
  849.                 buf.Print(h.EndCell());
  850.                 buf.Print(h.StartCell());
  851.                     int i, count = AutoModeTrackSelectWeight.size();
  852.                     float weightSum = Sum(AutoModeTrackSelectWeight);
  853.                     for (i = 0; i < count; ++i) {
  854.                         buf.Print(h.StartLink(P("auto-track-select-weights#"+i)));
  855.                             buf.Print(AutoModeTrackSelectWeight[i]);
  856.                             buf.Print(" (");
  857.                             buf.Print(ProbPercent(AutoModeTrackSelectWeight[i], weightSum));
  858.                             buf.Print("%)");
  859.                         buf.Print(h.EndLink());
  860.                         if (i < count - 1)
  861.                             buf.Print(", ");
  862.                     }
  863.                     if (count == 0)
  864.                         buf.Print(h.MakeLink(P("auto-track-select-weights#0"), " "));
  865.                 buf.Print(h.EndCell());
  866.             buf.Print(h.EndRow());
  867.             buf.Print(h.StartRow());
  868.                 buf.Print(h.StartCell());
  869.                     buf.Print(T("html-auto-cut-length-weights-title"));
  870.                 buf.Print(h.EndCell());
  871.                 buf.Print(h.StartCell());
  872.                     count = AutoModeCutLengthWeight.size();
  873.                     weightSum = Sum(AutoModeCutLengthWeight);
  874.                     for (i = 0; i < count; ++i) {
  875.                         buf.Print(h.StartLink(P("auto-cut-length-weights#"+i)));
  876.                             buf.Print(AutoModeCutLengthWeight[i]);
  877.                             buf.Print(" (");
  878.                             buf.Print(ProbPercent(AutoModeCutLengthWeight[i], weightSum));
  879.                             buf.Print("%)");
  880.                         buf.Print(h.EndLink());
  881.                         if (i < count - 1)
  882.                             buf.Print(", ");
  883.                     }
  884.                     if (count == 0)
  885.                         buf.Print(h.MakeLink(P("auto-cut-length-weights#0"), " "));
  886.                 buf.Print(h.EndCell());
  887.             buf.Print(h.EndRow());
  888.         buf.Print(h.EndTable());
  889.     }
  890.  
  891.     public string GetDescriptionHTML(void)
  892.     {
  893.         ST = GetAsset().GetStringTable();
  894.         HTMLBuffer buf = HTMLBufferStatic.Construct();
  895.         HTMLWindow h = HTMLWindow;
  896.         StringTable st = GetAsset().GetStringTable();
  897.         buf.Print("<html><body>");
  898.         buf.Print(h.StartTable());
  899.             buf.Print(h.StartRow());
  900.                 buf.Print(h.StartCell());
  901.                     buf.Print(h.MakeBold(h.MakeFontSizeLarge(h.MakeFontColor(T("html-title"), "ff0000"))));
  902.                 buf.Print(h.EndCell());
  903.             buf.Print(h.EndRow());
  904.             buf.Print(h.StartRow());
  905.                 buf.Print(h.StartCell());
  906.                     ModeHTML(buf);
  907.                 buf.Print(h.EndCell());
  908.             buf.Print(h.EndRow());
  909.             buf.Print(h.StartRow());
  910.                 buf.Print(h.StartCell());
  911.                     DecouplerHTML(buf);
  912.                 buf.Print(h.EndCell());
  913.             buf.Print(h.EndRow());
  914.             if (RoutingEnabled) {
  915.                 buf.Print(h.StartRow());
  916.                     buf.Print(h.StartCell());
  917.                         RouterHTML(buf);
  918.                     buf.Print(h.EndCell());
  919.                 buf.Print(h.EndRow());
  920.                 buf.Print(h.StartRow());
  921.                     buf.Print(h.StartCell());
  922.                         buf.Print(h.MakeLink(P("show-routes"), Case(ShowRoutesHTML, T("html-routes-hide"), T("html-routes-show"))));
  923.                     buf.Print(h.EndCell());
  924.                 buf.Print(h.EndRow());
  925.                 if (ShowRoutesHTML) {
  926.                     buf.Print(h.StartRow());
  927.                         buf.Print(h.StartCell());
  928.                             RoutesHTML(buf);
  929.                         buf.Print(h.EndCell());
  930.                     buf.Print(h.EndRow());
  931.                 }
  932.                 buf.Print(h.StartRow());
  933.                     buf.Print(h.StartCell());
  934.                         buf.Print(h.MakeLink(P("show-tracks"), Case(ShowTracksHTML, T("html-tracks-hide"), T("html-tracks-show"))));
  935.                     buf.Print(h.EndCell());
  936.                 buf.Print(h.EndRow());
  937.                 if (ShowTracksHTML) {
  938.                     buf.Print(h.StartRow());
  939.                         buf.Print(h.StartCell());
  940.                             TracksHTML(buf);
  941.                         buf.Print(h.EndCell());
  942.                     buf.Print(h.EndRow());
  943.                 }
  944.                 if (AutoMode) {
  945.                     buf.Print(h.StartRow());
  946.                         buf.Print(h.StartCell());
  947.                             AutoModeHTML(buf);
  948.                         buf.Print(h.EndCell());
  949.                     buf.Print(h.EndRow());
  950.                 }
  951.             }
  952.         buf.Print(h.EndTable());
  953.         buf.Print("</body></html>");
  954.         string ret = buf.AsString();
  955.         LUtil.FlushLog();
  956.         ST = null;
  957.         return ret;
  958.     }
  959.  
  960.     string GetPropertyName(string propertyID)
  961.     {
  962.         if (       propertyID == "decoupler-max-length"
  963.                 or propertyID == "decoupler-max-heading"
  964.                 or propertyID == "router-set-route")
  965.             return GetAsset().GetStringTable().GetString0("desc-" + propertyID);
  966.         else if (  TrainUtil.HasPrefix(propertyID, "track-weight#")
  967.                 or TrainUtil.HasPrefix(propertyID, "auto-track-select-weights#")
  968.                 or TrainUtil.HasPrefix(propertyID, "auto-cut-length-weights#")) {
  969.             string[] parts = Str.Tokens(propertyID, "#");
  970.             propertyID = parts[0];
  971.             int index = Str.ToInt(parts[1]);
  972.             if (propertyID == "track-weight")
  973.                 index = HumpRouter.Tracks[index].Number;
  974.             else if (propertyID == "auto-track-select-weights")
  975.                 index = index + 1;
  976.             else if (propertyID == "auto-cut-length-weights")
  977.                 index = index + 1;
  978.             return GetAsset().GetStringTable().GetString1("desc-" + propertyID, index);
  979.         }
  980.         return inherited(propertyID);
  981.     }
  982.  
  983.     string GetPropertyDescription(string propertyID)
  984.     {
  985.         if (       propertyID == "decoupler-max-length"
  986.                 or propertyID == "decoupler-max-heading"
  987.                 or propertyID == "router-set-route")
  988.             return GetAsset().GetStringTable().GetString0("desc-" + propertyID);
  989.         else if (  TrainUtil.HasPrefix(propertyID, "track-weight#")
  990.                 or TrainUtil.HasPrefix(propertyID, "auto-track-select-weights#")
  991.                 or TrainUtil.HasPrefix(propertyID, "auto-cut-length-weights#")) {
  992.             string[] parts = Str.Tokens(propertyID, "#");
  993.             propertyID = parts[0];
  994.             int index = Str.ToInt(parts[1]);
  995.             if (propertyID == "track-weight")
  996.                 index = HumpRouter.Tracks[index].Number;
  997.             else if (propertyID == "auto-track-select-weights")
  998.                 index = index + 1;
  999.             else if (propertyID == "auto-cut-length-weights")
  1000.                 index = index + 1;
  1001.             return GetAsset().GetStringTable().GetString1("desc-" + propertyID, index);
  1002.         }
  1003.         return inherited(propertyID);
  1004.     }
  1005.  
  1006.     string GetPropertyType(string propertyID)
  1007.     {
  1008.         if (propertyID == "mode-auto")
  1009.             return "link";
  1010.         else if (propertyID == "mode-manual")
  1011.             return "link";
  1012.         else if (propertyID == "routing")
  1013.             return "link";
  1014.         else if (propertyID == "decoupler-max-length")
  1015.             return "int,1,9,1";
  1016.         else if (propertyID == "decoupler-max-heading")
  1017.             return "float,0,100,1";
  1018.         else if (propertyID == "router-scan")
  1019.             return "link";
  1020.         else if (propertyID == "router-scan-refresh")
  1021.             return "link";
  1022.         else if (propertyID == "router-set-route")
  1023.             return "int,1,999,1";
  1024.         else if (propertyID == "show-routes")
  1025.             return "link";
  1026.         else if (propertyID == "show-tracks")
  1027.             return "link";
  1028.         else if (TrainUtil.HasPrefix(propertyID, "track-weight#"))
  1029.             return "float,0,1000,1";
  1030.         else if (TrainUtil.HasPrefix(propertyID, "auto-track-select-weights#"))
  1031.             return "string";
  1032.         else if (TrainUtil.HasPrefix(propertyID, "auto-cut-length-weights#"))
  1033.             return "string";
  1034.         return inherited(propertyID);
  1035.     }
  1036.  
  1037.     string GetPropertyValue(string propertyID)
  1038.     {
  1039.         if (propertyID == "decoupler-max-length")
  1040.             return (string) HumpDecoupler.MaxCutLength;
  1041.         else if (propertyID == "decoupler-max-heading")
  1042.             return (string) HumpDecoupler.MaxHeading;
  1043.         else if (propertyID == "router-set-route")
  1044.             return "";
  1045.         else if (  TrainUtil.HasPrefix(propertyID, "track-weight#")
  1046.                 or TrainUtil.HasPrefix(propertyID, "auto-track-select-weights#")
  1047.                 or TrainUtil.HasPrefix(propertyID, "auto-cut-length-weights#")) {
  1048.             string[] parts = Str.Tokens(propertyID, "#");
  1049.             propertyID = parts[0];
  1050.             int index = Str.ToInt(parts[1]);
  1051.             float[] data;
  1052.             if (propertyID == "track-weight")
  1053.                 data = AutoModeTrackBaseWeight;
  1054.             else if (propertyID == "auto-track-select-weights")
  1055.                 data = AutoModeTrackSelectWeight;
  1056.             else if (propertyID == "auto-cut-length-weights")
  1057.                 data = AutoModeCutLengthWeight;
  1058.             if (index < data.size())
  1059.                 return (string) data[index];
  1060.             return "";
  1061.         }
  1062.         return inherited(propertyID);
  1063.     }
  1064.  
  1065.     void SetPropertyValue(string propertyID, int value)
  1066.     {
  1067.         if (propertyID == "decoupler-max-length") {
  1068.             HumpDecoupler.MaxCutLength = value;
  1069.             return;
  1070.         }
  1071.         else if (propertyID == "router-set-route") {
  1072.             HumpRouter.SetRouteToTrack(value);
  1073.             return;
  1074.         }
  1075.         inherited(propertyID, value);
  1076.     }
  1077.  
  1078.     void SetPropertyValue(string propertyID, float value)
  1079.     {
  1080.         if (propertyID == "decoupler-max-heading") {
  1081.             HumpDecoupler.MaxHeading = value;
  1082.             return;
  1083.         }
  1084.         else if (TrainUtil.HasPrefix(propertyID, "track-weight#")) {
  1085.             string[] parts = Str.Tokens(propertyID, "#");
  1086.             int index = Str.ToInt(parts[1]);
  1087.             AutoModeTrackBaseWeight[index] = value;
  1088.             return;
  1089.         }
  1090.         inherited(propertyID, value);
  1091.     }
  1092.  
  1093.     void SetPropertyValue(string propertyID, string value)
  1094.     {
  1095.         if (       TrainUtil.HasPrefix(propertyID, "auto-track-select-weights#")
  1096.                 or TrainUtil.HasPrefix(propertyID, "auto-cut-length-weights#")) {
  1097.             string[] parts = Str.Tokens(propertyID, "#");
  1098.             propertyID = parts[0];
  1099.             int index = Str.ToInt(parts[1]);
  1100.            
  1101.             float[] data;
  1102.             if (propertyID == "auto-track-select-weights")
  1103.                 data = AutoModeTrackSelectWeight;
  1104.             else if (propertyID == "auto-cut-length-weights")
  1105.                 data = AutoModeCutLengthWeight;
  1106.            
  1107.             string[] valueTokens = Str.Tokens(value, ",");
  1108.             float[] values = new float[valueTokens.size()];
  1109.             int i;
  1110.             for (i = 0; i < valueTokens.size(); ++i)
  1111.                 values[i] = Str.ToFloat(valueTokens[i]);
  1112.            
  1113.             data[index, index + 1] = values;
  1114.             return;
  1115.         }
  1116.         inherited(propertyID, value);
  1117.     }
  1118.  
  1119.     void LinkPropertyValue(string propertyID)
  1120.     {
  1121.         if (propertyID == "mode-auto") {
  1122.             AutoMode = !AutoMode;
  1123.             if (AutoMode)
  1124.                 RoutingEnabled = true;
  1125.             return;
  1126.         }
  1127.         else if (propertyID == "mode-manual") {
  1128.             ManualMode = !ManualMode;
  1129.             if (ManualMode)
  1130.                 RoutingEnabled = true;
  1131.             return;
  1132.         }
  1133.         else if (propertyID == "routing") {
  1134.             RoutingEnabled = !RoutingEnabled;
  1135.             if (!RoutingEnabled) {
  1136.                 AutoMode = false;
  1137.                 ManualMode = false;
  1138.             }
  1139.             return;
  1140.         }
  1141.         else if (propertyID == "router-scan") {
  1142.             ScanRoutes();
  1143.             return;
  1144.         }
  1145.         else if (propertyID == "router-scan-refresh") {
  1146.             return;
  1147.         }
  1148.         else if (propertyID == "show-routes") {
  1149.             ShowRoutesHTML = !ShowRoutesHTML;
  1150.             return;
  1151.         }
  1152.         else if (propertyID == "show-tracks") {
  1153.             ShowTracksHTML = !ShowTracksHTML;
  1154.             return;
  1155.         }
  1156.         inherited(propertyID);
  1157.     } //*/
  1158. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement