<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.trainzsimulator.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ek.skirl</id>
	<title>TrainzOnline - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.trainzsimulator.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ek.skirl"/>
	<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/wiki/Special:Contributions/Ek.skirl"/>
	<updated>2026-11-05T13:39:10Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Debug_Scripts&amp;diff=44713</id>
		<title>HowTo/Debug Scripts</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Debug_Scripts&amp;diff=44713"/>
		<updated>2025-07-15T08:49:18Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some recommended steps to help with Debugging custom scripts for TRS19 can be found below:&lt;br /&gt;
&lt;br /&gt;
* Configure a minimal test session.&lt;br /&gt;
* Enable developer mode in the Dev tab of the Trainz Settings.&lt;br /&gt;
* Enable script logging in the Dev tab of the Trainz Settings.&lt;br /&gt;
* Enable script message logging in the Dev tab of the Trainz Settings.&lt;br /&gt;
* Enable display of script exceptions in the Dev tab of the Trainz Settings.&lt;br /&gt;
* Restart the game if necessary.&lt;br /&gt;
* Add Interface.Log() statements throughout your code so that you can determine what is being called, and in what order.&lt;br /&gt;
* Log the start of functions and any relevant control flow (if statements, return statements, etc.)&lt;br /&gt;
* Start your log texts with a unique sign group. So you may filter your logs in log window.&lt;br /&gt;
* Clear your logs.&lt;br /&gt;
* Launch directly into your session from CM to avoid unnecessary additional log entries.&lt;br /&gt;
* Proceed until the problem occurs (hopefully this is immediate).&lt;br /&gt;
* Pause the game.&lt;br /&gt;
* Open the logs window.&lt;br /&gt;
* Review the output, to see which of your logs have fired off and which messages have been dispatched.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally for TRS19, with &amp;quot;Maximise Compatibility&amp;quot; enabled in the Dev tab of the Trainz Settings, the script environment will generally be very similar to T:ANE SP2/3 and you shouldn&#039;t need to make any real changes for. &lt;br /&gt;
&lt;br /&gt;
If you run a route that is setup to run in &#039;maximise performance&#039; mode (or have TRS19 set to &#039;maximise performance&#039;), then you may need to make changes to your script. See [[HowTo/Asynchronous_Route_Streaming|Asynchronous Route Streaming]] for further information.&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Debug_Scripts&amp;diff=44712</id>
		<title>HowTo/Debug Scripts</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Debug_Scripts&amp;diff=44712"/>
		<updated>2025-07-15T08:47:32Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Adding a hint (unique sign group)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some recommended steps to help with Debugging custom scripts for TRS19 can be found below:&lt;br /&gt;
&lt;br /&gt;
* Configure a minimal test session.&lt;br /&gt;
* Enable developer mode in the Dev tab of the Trainz Settings.&lt;br /&gt;
* Enable script logging in the Dev tab of the Trainz Settings.&lt;br /&gt;
* Enable script message logging in the Dev tab of the Trainz Settings.&lt;br /&gt;
* Enable display of script exceptions in the Dev tab of the Trainz Settings.&lt;br /&gt;
* Restart the game if necessary.&lt;br /&gt;
* Add Interface.Log() statements throughout your code so that you can determine what is being called, and in what order. Log the start of functions and any relevant control flow (if statements, return statements, etc.)&lt;br /&gt;
* If you start your log texts with a unique sign group you may filter your logs in log window.&lt;br /&gt;
* Clear your logs.&lt;br /&gt;
* Launch directly into your session from CM to avoid unnecessary additional log entries.&lt;br /&gt;
* Proceed until the problem occurs (hopefully this is immediate).&lt;br /&gt;
* Pause the game.&lt;br /&gt;
* Open the logs window.&lt;br /&gt;
* Review the output, to see which of your logs have fired off and which messages have been dispatched.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally for TRS19, with &amp;quot;Maximise Compatibility&amp;quot; enabled in the Dev tab of the Trainz Settings, the script environment will generally be very similar to T:ANE SP2/3 and you shouldn&#039;t need to make any real changes for. &lt;br /&gt;
&lt;br /&gt;
If you run a route that is setup to run in &#039;maximise performance&#039; mode (or have TRS19 set to &#039;maximise performance&#039;), then you may need to make changes to your script. See [[HowTo/Asynchronous_Route_Streaming|Asynchronous Route Streaming]] for further information.&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44441</id>
		<title>HowTo/Installing Trainz at Linux: Debian based Distributions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44441"/>
		<updated>2025-05-02T10:20:51Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See Trainz Forum Discussion Thread  &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/installing-and-running-trainz-at-linux-here-ubuntu-24-04-lts-noble.180950/post-2051072 Installing and running Trainz at Linux, here Ubuntu 24.04 LTS noble - post #1 and #3]&amp;quot; too.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu 24.4 LTS noble ==&lt;br /&gt;
=== The idea ===&lt;br /&gt;
This is a very old idea and often discussed. I searched for a systematic instruction, but I didn&#039;t find one. So I tried to test it and how it runs. Here&#039;s my personal systematic for Debian based Linux systems.&lt;br /&gt;
For my knowledge such systems aren&#039;t able to execute windows programs (*.exe) out of the box. We need some helper apps. In my case I will use WineHQ from an external repository.&lt;br /&gt;
&lt;br /&gt;
=== Install WineHQ ===&lt;br /&gt;
A useful instruction to do so is here (in German): [https://wiki.ubuntuusers.de/Wine/#Fertige-Pakete|ubuntuusers.de Wine Fertige-Pakete] &lt;br /&gt;
in sub chapter &amp;quot;&#039;&#039;&#039;Methode 2 - Wine-Fremdquelle&#039;&#039;&#039;&amp;quot;. Maybe you want to use this script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 sudo dpkg --add-architecture i386     # Only necessary for 64bit systems.&lt;br /&gt;
 sudo mkdir -pm755 /etc/apt/keyrings   # No longer necessary from version 24.04 onwards.&lt;br /&gt;
 sudo wget -nc -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key&lt;br /&gt;
 sudo wget -NP /etc/apt/sources.list.d/ &amp;quot;https://dl.winehq.org/wine-builds/ubuntu/dists/$(lsb_release -c | grep -o &#039;\w*$&#039;)/winehq-$(lsb_release -c | grep -o &#039;\w*$&#039;).sources&amp;quot;&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install --install-recommends winehq-stable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following chapter handles the installation of Trainz instances. The paths in the later following scripts are based on a collecting folder &amp;quot;Wine&amp;quot; in $USER.&lt;br /&gt;
=== Download and unpack the Trainz install files ===&lt;br /&gt;
After downloading the full installer zip files&lt;br /&gt;
&lt;br /&gt;
 * TANE-SP4-Offline-Installer-105766.zip&lt;br /&gt;
 * TRS19-SP4-Offline-Installer-114800.zip&lt;br /&gt;
 * TRS22-Offline-Installer-126273.zip&lt;br /&gt;
 * TrainzPlus-Offline-Installer-128486.zip&lt;br /&gt;
&lt;br /&gt;
and unpacking it into the sub folder looks like this &lt;br /&gt;
&amp;lt;div class=&amp;quot;toccolours mw-collapsible mw-collapsed&amp;quot;&amp;gt;&lt;br /&gt;
hidden collapsed folder file structure (please expand -&amp;gt;):&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 $HOME/Wine/TRSDL/&lt;br /&gt;
 +-- TANESP4_105766&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS19PE_114800&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS22PE_126273&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRSPLUS_128486&lt;br /&gt;
     +-- ...&lt;br /&gt;
     +-- install.exe&lt;br /&gt;
     +-- ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install the Trainz instances ===&lt;br /&gt;
We install every Trainz instance in its own wine prefix. The install statements of the following scripts create the wine prefixes &amp;quot;.TANESP4&amp;quot;, &amp;quot;.TRS19PE&amp;quot;, &amp;quot;.TRS22PE respective &amp;quot;.TRSPLUS&amp;quot; as hidden same named folders.&lt;br /&gt;
Every installation process creates two links at the desktop. I don&#039;t currently know the purpose of the link with the purple circle and a white arrow. The launch link for the Trainz instance with a Trainz icon and a small red dot with a white cross is blocked. By right-clicking it and using the &amp;quot;Allow launching&amp;quot; entry, it will be possible to launch Trainz.&lt;br /&gt;
Maybe you want to use one of this scripts to install a Trainz instance:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation of TANESP4 in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TANESP4 wine $HOME/Wine/TRSDL/TANESP4_105766/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS19PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS19PE wine $HOME/Wine/TRSDL/TRS19PE_114800/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS22PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS22PE wine $HOME/Wine/TRSDL/TRS22PE_126273/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRSPLUS in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRSPLUS wine $HOME/Wine/TRSDL/TRSPLUS_128486/install.exe&lt;br /&gt;
 #=============================================================================== &lt;br /&gt;
&lt;br /&gt;
Good luck and have fun!&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44440</id>
		<title>HowTo/Installing Trainz at Linux: Debian based Distributions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44440"/>
		<updated>2025-05-02T10:06:11Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See Trainz Forum Discussion Thread  &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/installing-and-running-trainz-at-linux-here-ubuntu-24-04-lts-noble.180950/post-2051072 Installing and running Trainz at Linux, here Ubuntu 24.04 LTS noble - post #1 and #3]&amp;quot; too.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu 24.4 LTS noble ==&lt;br /&gt;
=== The idea ===&lt;br /&gt;
This is a very old idea and often discussed. I searched for a systematic instruction, but I didn&#039;t find one. So I tried to test it and how it runs. Here&#039;s my personal systematic for Debian based Linux systems.&lt;br /&gt;
For my knowledge such systems aren&#039;t able to execute windows programs (*.exe) out of the box. We need some helper apps. In my case I will use WineHQ from an external repository.&lt;br /&gt;
=== Install WineHQ ===&lt;br /&gt;
A useful instruction to do so is here (in German):[URL=&#039;https://wiki.ubuntuusers.de/Wine/#Fertige-Pakete&#039;]ubuntuusers.de Wine Fertige-Pakete[/URL] in sub chapter &amp;quot;Methode 2 - Wine-Fremdquelle&amp;quot;. Maybe you want to use this script:&lt;br /&gt;
&lt;br /&gt;
 sudo dpkg --add-architecture i386     # Nur auf 64-Bit-Systemen notwendig.&lt;br /&gt;
 sudo mkdir -pm755 /etc/apt/keyrings   # Ab 22.04 nicht mehr nötig.&lt;br /&gt;
 sudo wget -nc -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key&lt;br /&gt;
 sudo wget -NP /etc/apt/sources.list.d/ &amp;quot;https://dl.winehq.org/wine-builds/ubuntu/dists/$(lsb_release -c | grep -o &#039;\w*$&#039;)/winehq-$(lsb_release -c | grep -o &#039;\w*$&#039;).sources&amp;quot;&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install --install-recommends winehq-stable&lt;br /&gt;
&lt;br /&gt;
The following chapter handles the installation of Trainz instances. The paths in the later following scripts are based on a collecting folder &amp;quot;Wine&amp;quot; in $USER.&lt;br /&gt;
=== Download and unpack the Trainz install files ===&lt;br /&gt;
After downloading the full installer zip files&lt;br /&gt;
&lt;br /&gt;
 * TANE-SP4-Offline-Installer-105766.zip&lt;br /&gt;
 * TRS19-SP4-Offline-Installer-114800.zip&lt;br /&gt;
 * TRS22-Offline-Installer-126273.zip&lt;br /&gt;
 * TrainzPlus-Offline-Installer-128486.zip&lt;br /&gt;
&lt;br /&gt;
and unpacking it into the sub folder looks&lt;br /&gt;
&amp;lt;div class=&amp;quot;toccolours mw-collapsible mw-collapsed&amp;quot;&amp;gt;&lt;br /&gt;
like this: &lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 $HOME/Wine/TRSDL/&lt;br /&gt;
 +-- TANESP4_105766&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS19PE_114800&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS22PE_126273&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRSPLUS_128486&lt;br /&gt;
     +-- ...&lt;br /&gt;
     +-- install.exe&lt;br /&gt;
     +-- ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install the Trainz instances ===&lt;br /&gt;
We install every Trainz instance in its own wine prefix. The install statements of the following scripts create the wine prefixes &amp;quot;.TANESP4&amp;quot;, &amp;quot;.TRS19PE&amp;quot;, &amp;quot;.TRS22PE respective &amp;quot;.TRSPLUS&amp;quot; as hidden same named folders.&lt;br /&gt;
Every installation process creates two links at the desktop. I don&#039;t currently know the purpose of the link with the purple circle and a white arrow. The launch link for the Trainz instance with a Trainz icon and a small red dot with a white cross is blocked. By right-clicking it and using the &amp;quot;Allow launching&amp;quot; entry, it will be possible to launch Trainz.&lt;br /&gt;
Maybe you want to use one of this scripts to install a Trainz instance:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation of TANESP4 in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TANESP4 wine $HOME/Wine/TRSDL/TANESP4_105766/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS19PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS19PE wine $HOME/Wine/TRSDL/TRS19PE_114800/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS22PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS22PE wine $HOME/Wine/TRSDL/TRS22PE_126273/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRSPLUS in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRSPLUS wine $HOME/Wine/TRSDL/TRSPLUS_128486/install.exe&lt;br /&gt;
 #=============================================================================== &lt;br /&gt;
&lt;br /&gt;
Good luck and have fun!&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_portable:_At_external_harddrive&amp;diff=44439</id>
		<title>HowTo/Installing Trainz portable: At external harddrive</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_portable:_At_external_harddrive&amp;diff=44439"/>
		<updated>2025-05-02T09:28:25Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See Trainz Discussion Forum Thread &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/trainz-portable-at-an-external-harddrive.180902/post-2050657 Trainz portable at an external harddrive - post #1]&amp;quot; too.&lt;br /&gt;
&lt;br /&gt;
== The idea​ ==&lt;br /&gt;
In my case I tried to have Trainz installations on a harddrive to use it on any fitting pc/notebook and of course to have all my works with me.&lt;br /&gt;
&lt;br /&gt;
== The use case​ ==&lt;br /&gt;
On any pc/notebook there is a link to start the portable installation and the paths of this installation are added to the profile file inside the AppData folder of Trainz. This link works only if the fitting harddrive is available. Also there are two folders on the portable drive: one for the Trainz apps and one for the Trainz appdata.&lt;br /&gt;
&lt;br /&gt;
== The background informations​ ==&lt;br /&gt;
Each Trainz installation consists of two file folders, a text file, containing the corresponding paths, and of course a link for the launcher on the desktop.&lt;br /&gt;
&lt;br /&gt;
In its properties one will find the installation path of a Trainz installation. In the users appdata folder one will find the absolute path in the &amp;quot;userdata-redirect-map.txt&amp;quot; file as well as the absolute path to the users build folder.&lt;br /&gt;
&lt;br /&gt;
One very important hint: Unlike the paths with backslashes (&amp;quot;\&amp;quot;) that Windows uses, here the folders are separated by slashes (&amp;quot;/&amp;quot;)!&lt;br /&gt;
&lt;br /&gt;
The app-folder is the install folder of the Trainz core code, the data-folder cares about the user&amp;quot;s Trainz instance data and the profile file tells Trainz where the fitting folders are.&lt;br /&gt;
&lt;br /&gt;
This knowledge makes it possible to make Trainz portable.&lt;br /&gt;
&lt;br /&gt;
== The solution draft​ ==&lt;br /&gt;
The Trainz installation folder is that folder with the Trainz start file &amp;quot;TRS22.exe&amp;quot; in case of Trainz 22, in case of Trainz 19 it is &amp;quot;TRS19.exe&amp;quot;. The builds of Trainz 22 and Trainz 19 reside in different subfolders inside the user appdata local N3V Games in the trs22, respective trs19 folder. Following this there are different &amp;quot;userdata-redirect-map.txt&amp;quot; files.&lt;br /&gt;
&lt;br /&gt;
The appdata folders have names similar to &amp;quot;build xxxxxxxxx&amp;quot;. The &amp;quot;xxxxxxxxx&amp;quot; is a cryptic looking, randomly created character array of letters and numbers. Every new or additional installation gets its own randomly created &amp;quot;xxxxxxxxx&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
So very essential at all is to find the fitting folder pairs. Have a look into the &amp;quot;userdata-redirect-map.txt&amp;quot; file inside the user&amp;quot;s appdata folder &amp;quot;%AppData%\..\Local\N3V Games\trs22&amp;quot;, respective &amp;quot;%AppData%\..\Local\N3V Games\trs19&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The fitting path pairs have to be written in the &amp;quot;userdata-redirect-map.txt&amp;quot; file, one pair per line. Firstly, the path to the Trains app and secondly, the path to the build folder.&lt;br /&gt;
&lt;br /&gt;
== Steps for the draft solution​ ==&lt;br /&gt;
The following steps are to be done:&lt;br /&gt;
# Set your harddrive to a fixed drive letter (here: P for portable).&lt;br /&gt;
# Create two folders (here: &amp;quot;P:\TRAINZDATA&amp;quot; and &amp;quot;P:\TRAINZAPPS&amp;quot;).&lt;br /&gt;
# Create in TRAINZDATA an initially empty text file called &amp;quot;userdata-redirect-map.add&amp;quot;.&lt;br /&gt;
# Copy the fitting build folder content to &amp;quot;P:\TRAINZDATA&amp;quot; and the fitting installation folder content to &amp;quot;P:\TRAINZAPPS&amp;quot;.&lt;br /&gt;
# Write into the &amp;quot;userdata-redirect-map.add&amp;quot; file, a line per portable installation path pair, adjusted to &amp;quot;P:\TRAINZAPPS&amp;quot; and &amp;quot;P:\TRAINZDATA&amp;quot;. Remember using the slash instead of backslash. This file is for copy&amp;amp;past the fitting line to append it to the pc/notebook&#039;s &amp;quot;userdata-redirect-map.txt&amp;quot; file.&lt;br /&gt;
# Add per installation one starting link for the desktop with the absolute path to the Trainz start exe file in the copied Trainz app folder at drive P. This link is for copying too.&lt;br /&gt;
&lt;br /&gt;
== Use case pc/notebook without any earlier Trainz installation​ ==&lt;br /&gt;
For now I don&#039;t know if our Trainz copies are running out of the box on a pc/notebook. If not it&#039;s necessary to install a Trainz version.&lt;br /&gt;
&lt;br /&gt;
It looks like the calling of trains will generate the AppData folder, but with the content of the &amp;quot;userdata-redirect-map.txt&amp;quot; file, that has to be adapted to the portable drive.&lt;br /&gt;
&lt;br /&gt;
== Last but not least very important hints​ ==&lt;br /&gt;
Note the content of the original profile file and backup the build folder(s).&lt;br /&gt;
&lt;br /&gt;
Note the fitting Trainz version. Be careful.&lt;br /&gt;
&lt;br /&gt;
The random parts of the build folder are useful to identify the Trainz installations.&lt;br /&gt;
&lt;br /&gt;
Although I have tested the described procedure to the best of my knowledge, I do not provide any guarantee whatsoever.&lt;br /&gt;
&lt;br /&gt;
Please, do the things at your own risk! I expressly disclaim any liability for this.&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44438</id>
		<title>HowTo/Installing Trainz at Linux: Debian based Distributions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44438"/>
		<updated>2025-05-02T09:16:20Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See Trainz Forum Discussion Thread  &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/installing-and-running-trainz-at-linux-here-ubuntu-24-04-lts-noble.180950/post-2051072 Installing and running Trainz at Linux, here Ubuntu 24.04 LTS noble - post #1 and #3]&amp;quot; too.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu 24.4 LTS noble ==&lt;br /&gt;
=== The idea ===&lt;br /&gt;
This is a very old idea and often discussed. I searched for a systematic instruction, but I didn&#039;t find one. So I tried to test it and how it runs. Here&#039;s my personal systematic for Debian based Linux systems.&lt;br /&gt;
For my knowledge such systems aren&#039;t able to execute windows programs (*.exe) out of the box. We need some helper apps. In my case I will use WineHQ from an external repository.&lt;br /&gt;
=== Install WineHQ ===&lt;br /&gt;
A useful instruction to do so is here (in German):[URL=&#039;https://wiki.ubuntuusers.de/Wine/#Fertige-Pakete&#039;]ubuntuusers.de Wine Fertige-Pakete[/URL] in sub chapter &amp;quot;Methode 2 - Wine-Fremdquelle&amp;quot;. Maybe you want to use this script:&lt;br /&gt;
&lt;br /&gt;
 sudo dpkg --add-architecture i386     # Nur auf 64-Bit-Systemen notwendig.&lt;br /&gt;
 sudo mkdir -pm755 /etc/apt/keyrings   # Ab 22.04 nicht mehr nötig.&lt;br /&gt;
 sudo wget -nc -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key&lt;br /&gt;
 sudo wget -NP /etc/apt/sources.list.d/ &amp;quot;https://dl.winehq.org/wine-builds/ubuntu/dists/$(lsb_release -c | grep -o &#039;\w*$&#039;)/winehq-$(lsb_release -c | grep -o &#039;\w*$&#039;).sources&amp;quot;&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install --install-recommends winehq-stable&lt;br /&gt;
&lt;br /&gt;
The following chapter handles the installation of Trainz instances. The paths in the later following scripts are based on a collecting folder &amp;quot;Wine&amp;quot; in $USER.&lt;br /&gt;
=== Download and unpack the Trainz install files ===&lt;br /&gt;
After downloading the full installer zip files&lt;br /&gt;
&lt;br /&gt;
 * TANE-SP4-Offline-Installer-105766.zip&lt;br /&gt;
 * TRS19-SP4-Offline-Installer-114800.zip&lt;br /&gt;
 * TRS22-Offline-Installer-126273.zip&lt;br /&gt;
 * TrainzPlus-Offline-Installer-128486.zip&lt;br /&gt;
&lt;br /&gt;
and unpacking it into the sub folder looks like this:&lt;br /&gt;
&lt;br /&gt;
 $HOME/Wine/TRSDL/&lt;br /&gt;
 +-- TANESP4_105766&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS19PE_114800&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS22PE_126273&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRSPLUS_128486&lt;br /&gt;
     +-- ...&lt;br /&gt;
     +-- install.exe&lt;br /&gt;
     +-- ...&lt;br /&gt;
&lt;br /&gt;
=== Install the Trainz instances ===&lt;br /&gt;
We install every Trainz instance in its own wine prefix. The install statements of the following scripts create the wine prefixes &amp;quot;.TANESP4&amp;quot;, &amp;quot;.TRS19PE&amp;quot;, &amp;quot;.TRS22PE respective &amp;quot;.TRSPLUS&amp;quot; as hidden same named folders.&lt;br /&gt;
Every installation process creates two links at the desktop. I don&#039;t currently know the purpose of the link with the purple circle and a white arrow. The launch link for the Trainz instance with a Trainz icon and a small red dot with a white cross is blocked. By right-clicking it and using the &amp;quot;Allow launching&amp;quot; entry, it will be possible to launch Trainz.&lt;br /&gt;
Maybe you want to use one of this scripts to install a Trainz instance:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation of TANESP4 in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TANESP4 wine $HOME/Wine/TRSDL/TANESP4_105766/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS19PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS19PE wine $HOME/Wine/TRSDL/TRS19PE_114800/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS22PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS22PE wine $HOME/Wine/TRSDL/TRS22PE_126273/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRSPLUS in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRSPLUS wine $HOME/Wine/TRSDL/TRSPLUS_128486/install.exe&lt;br /&gt;
 #=============================================================================== &lt;br /&gt;
&lt;br /&gt;
Good luck and have fun!&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44437</id>
		<title>HowTo/Installing Trainz at Linux: Debian based Distributions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44437"/>
		<updated>2025-05-02T09:15:30Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See Trainz Forum Discussion Thread  &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/installing-and-running-trainz-at-linux-here-ubuntu-24-04-lts-noble.180950/post-2051072 Installing and running Trainz at Linux, here Ubuntu 24.04 LTS noble - post #1 and #3]&amp;quot; too.&lt;br /&gt;
&lt;br /&gt;
==Ubuntu 24.4 LTS noble (Coy&amp;amp;pasted as source code from forum post as suggested in the forum thread)==&lt;br /&gt;
=== The idea ===&lt;br /&gt;
This is a very old idea and often discussed. I searched for a systematic instruction, but I didn&#039;t find one. So I tried to test it and how it runs. Here&#039;s my personal systematic for Debian based Linux systems.&lt;br /&gt;
For my knowledge such systems aren&#039;t able to execute windows programs (*.exe) out of the box. We need some helper apps. In my case I will use WineHQ from an external repository.&lt;br /&gt;
=== Install WineHQ ===&lt;br /&gt;
A useful instruction to do so is here (in German):[URL=&#039;https://wiki.ubuntuusers.de/Wine/#Fertige-Pakete&#039;]ubuntuusers.de Wine Fertige-Pakete[/URL] in sub chapter &amp;quot;Methode 2 - Wine-Fremdquelle&amp;quot;. Maybe you want to use this script:&lt;br /&gt;
&lt;br /&gt;
 sudo dpkg --add-architecture i386     # Nur auf 64-Bit-Systemen notwendig.&lt;br /&gt;
 sudo mkdir -pm755 /etc/apt/keyrings   # Ab 22.04 nicht mehr nötig.&lt;br /&gt;
 sudo wget -nc -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key&lt;br /&gt;
 sudo wget -NP /etc/apt/sources.list.d/ &amp;quot;https://dl.winehq.org/wine-builds/ubuntu/dists/$(lsb_release -c | grep -o &#039;\w*$&#039;)/winehq-$(lsb_release -c | grep -o &#039;\w*$&#039;).sources&amp;quot;&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install --install-recommends winehq-stable&lt;br /&gt;
&lt;br /&gt;
The following chapter handles the installation of Trainz instances. The paths in the later following scripts are based on a collecting folder &amp;quot;Wine&amp;quot; in $USER.&lt;br /&gt;
=== Download and unpack the Trainz install files ===&lt;br /&gt;
After downloading the full installer zip files&lt;br /&gt;
&lt;br /&gt;
 * TANE-SP4-Offline-Installer-105766.zip&lt;br /&gt;
 * TRS19-SP4-Offline-Installer-114800.zip&lt;br /&gt;
 * TRS22-Offline-Installer-126273.zip&lt;br /&gt;
 * TrainzPlus-Offline-Installer-128486.zip&lt;br /&gt;
&lt;br /&gt;
and unpacking it into the sub folder looks like this:&lt;br /&gt;
&lt;br /&gt;
 $HOME/Wine/TRSDL/&lt;br /&gt;
 +-- TANESP4_105766&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS19PE_114800&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS22PE_126273&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRSPLUS_128486&lt;br /&gt;
     +-- ...&lt;br /&gt;
     +-- install.exe&lt;br /&gt;
     +-- ...&lt;br /&gt;
&lt;br /&gt;
=== Install the Trainz instances ===&lt;br /&gt;
We install every Trainz instance in its own wine prefix. The install statements of the following scripts create the wine prefixes &amp;quot;.TANESP4&amp;quot;, &amp;quot;.TRS19PE&amp;quot;, &amp;quot;.TRS22PE respective &amp;quot;.TRSPLUS&amp;quot; as hidden same named folders.&lt;br /&gt;
Every installation process creates two links at the desktop. I don&#039;t currently know the purpose of the link with the purple circle and a white arrow. The launch link for the Trainz instance with a Trainz icon and a small red dot with a white cross is blocked. By right-clicking it and using the &amp;quot;Allow launching&amp;quot; entry, it will be possible to launch Trainz.&lt;br /&gt;
Maybe you want to use one of this scripts to install a Trainz instance:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation of TANESP4 in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TANESP4 wine $HOME/Wine/TRSDL/TANESP4_105766/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS19PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS19PE wine $HOME/Wine/TRSDL/TRS19PE_114800/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS22PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS22PE wine $HOME/Wine/TRSDL/TRS22PE_126273/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRSPLUS in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRSPLUS wine $HOME/Wine/TRSDL/TRSPLUS_128486/install.exe&lt;br /&gt;
 #=============================================================================== &lt;br /&gt;
&lt;br /&gt;
Good luck and have fun!&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44436</id>
		<title>HowTo/Installing Trainz at Linux: Debian based Distributions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44436"/>
		<updated>2025-05-02T09:15:10Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ubuntu 24.4 LTS noble (Original posted as forum thread)==&lt;br /&gt;
See Trainz Forum Discussion Thread  &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/installing-and-running-trainz-at-linux-here-ubuntu-24-04-lts-noble.180950/post-2051072 Installing and running Trainz at Linux, here Ubuntu 24.04 LTS noble - post #1 and #3]&amp;quot; too.&lt;br /&gt;
&lt;br /&gt;
==Ubuntu 24.4 LTS noble (Coy&amp;amp;pasted as source code from forum post as suggested in the forum thread)==&lt;br /&gt;
=== The idea ===&lt;br /&gt;
This is a very old idea and often discussed. I searched for a systematic instruction, but I didn&#039;t find one. So I tried to test it and how it runs. Here&#039;s my personal systematic for Debian based Linux systems.&lt;br /&gt;
For my knowledge such systems aren&#039;t able to execute windows programs (*.exe) out of the box. We need some helper apps. In my case I will use WineHQ from an external repository.&lt;br /&gt;
=== Install WineHQ ===&lt;br /&gt;
A useful instruction to do so is here (in German):[URL=&#039;https://wiki.ubuntuusers.de/Wine/#Fertige-Pakete&#039;]ubuntuusers.de Wine Fertige-Pakete[/URL] in sub chapter &amp;quot;Methode 2 - Wine-Fremdquelle&amp;quot;. Maybe you want to use this script:&lt;br /&gt;
&lt;br /&gt;
 sudo dpkg --add-architecture i386     # Nur auf 64-Bit-Systemen notwendig.&lt;br /&gt;
 sudo mkdir -pm755 /etc/apt/keyrings   # Ab 22.04 nicht mehr nötig.&lt;br /&gt;
 sudo wget -nc -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key&lt;br /&gt;
 sudo wget -NP /etc/apt/sources.list.d/ &amp;quot;https://dl.winehq.org/wine-builds/ubuntu/dists/$(lsb_release -c | grep -o &#039;\w*$&#039;)/winehq-$(lsb_release -c | grep -o &#039;\w*$&#039;).sources&amp;quot;&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install --install-recommends winehq-stable&lt;br /&gt;
&lt;br /&gt;
The following chapter handles the installation of Trainz instances. The paths in the later following scripts are based on a collecting folder &amp;quot;Wine&amp;quot; in $USER.&lt;br /&gt;
=== Download and unpack the Trainz install files ===&lt;br /&gt;
After downloading the full installer zip files&lt;br /&gt;
&lt;br /&gt;
 * TANE-SP4-Offline-Installer-105766.zip&lt;br /&gt;
 * TRS19-SP4-Offline-Installer-114800.zip&lt;br /&gt;
 * TRS22-Offline-Installer-126273.zip&lt;br /&gt;
 * TrainzPlus-Offline-Installer-128486.zip&lt;br /&gt;
&lt;br /&gt;
and unpacking it into the sub folder looks like this:&lt;br /&gt;
&lt;br /&gt;
 $HOME/Wine/TRSDL/&lt;br /&gt;
 +-- TANESP4_105766&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS19PE_114800&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRS22PE_126273&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 |   +-- install.exe&lt;br /&gt;
 |   +-- ...&lt;br /&gt;
 +-- TRSPLUS_128486&lt;br /&gt;
     +-- ...&lt;br /&gt;
     +-- install.exe&lt;br /&gt;
     +-- ...&lt;br /&gt;
&lt;br /&gt;
=== Install the Trainz instances ===&lt;br /&gt;
We install every Trainz instance in its own wine prefix. The install statements of the following scripts create the wine prefixes &amp;quot;.TANESP4&amp;quot;, &amp;quot;.TRS19PE&amp;quot;, &amp;quot;.TRS22PE respective &amp;quot;.TRSPLUS&amp;quot; as hidden same named folders.&lt;br /&gt;
Every installation process creates two links at the desktop. I don&#039;t currently know the purpose of the link with the purple circle and a white arrow. The launch link for the Trainz instance with a Trainz icon and a small red dot with a white cross is blocked. By right-clicking it and using the &amp;quot;Allow launching&amp;quot; entry, it will be possible to launch Trainz.&lt;br /&gt;
Maybe you want to use one of this scripts to install a Trainz instance:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation of TANESP4 in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TANESP4 wine $HOME/Wine/TRSDL/TANESP4_105766/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS19PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS19PE wine $HOME/Wine/TRSDL/TRS19PE_114800/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRS22PE in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRS22PE wine $HOME/Wine/TRSDL/TRS22PE_126273/install.exe&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #===============================================================================&lt;br /&gt;
 # Installation TRSPLUS in Wine on Ubuntu&lt;br /&gt;
 #-------------------------------------------------------------------------------&lt;br /&gt;
 WINEPREFIX=$HOME/Wine/.TRSPLUS wine $HOME/Wine/TRSDL/TRSPLUS_128486/install.exe&lt;br /&gt;
 #=============================================================================== &lt;br /&gt;
&lt;br /&gt;
Good luck and have fun!&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44349</id>
		<title>HowTo/Installing Trainz at Linux: Debian based Distributions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44349"/>
		<updated>2025-04-20T13:51:27Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ubuntu 24.4 LTS noble (Original posted as forum thread)==&lt;br /&gt;
See Trainz Forum Thread  &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/installing-and-running-trainz-at-linux-here-ubuntu-24-04-lts-noble.180950/post-2051072 Installing and running Trainz at Linux, here Ubuntu 24.04 LTS noble - post #1 and #3]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Ubuntu 24.4 LTS noble (Coy&amp;amp;pasted as source code from forum post as suggested in the forum thread)==&lt;br /&gt;
[HEADING=3]The idea[/HEADING]&lt;br /&gt;
This is a very old idea and often discussed. I searched for a systematic instruction, but I didn&#039;t find one. So I tried to test it and how it runs. Here&#039;s my personal systematic for Debian based Linux systems.&lt;br /&gt;
For my knowledge such systems aren&#039;t able to execute windows programs (*.exe) out of the box. We need some helper apps. In my case I will use WineHQ from an external repository.&lt;br /&gt;
[HEADING=3]Install WineHQ[/HEADING]&lt;br /&gt;
A useful instruction to do so is here (in German):[URL=&#039;https://wiki.ubuntuusers.de/Wine/#Fertige-Pakete&#039;]ubuntuusers.de Wine Fertige-Pakete[/URL] in sub chapter &amp;quot;Methode 2 - Wine-Fremdquelle&amp;quot;. Maybe you want to use this script:&lt;br /&gt;
[SPOILER=Installation of WineHQ][CODE]&lt;br /&gt;
sudo dpkg --add-architecture i386     # Nur auf 64-Bit-Systemen notwendig.&lt;br /&gt;
sudo mkdir -pm755 /etc/apt/keyrings   # Ab 22.04 nicht mehr nötig.&lt;br /&gt;
sudo wget -nc -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key&lt;br /&gt;
sudo wget -NP /etc/apt/sources.list.d/ &amp;quot;https://dl.winehq.org/wine-builds/ubuntu/dists/$(lsb_release -c | grep -o &#039;\w*$&#039;)/winehq-$(lsb_release -c | grep -o &#039;\w*$&#039;).sources&amp;quot;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install --install-recommends winehq-stable&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
The following chapter handles the installation of Trainz instances. The paths in the later following scripts are based on a collecting folder &amp;quot;Wine&amp;quot; in $USER.&lt;br /&gt;
[HEADING=3]Download and unpack the Trainz install files[/HEADING]&lt;br /&gt;
After downloading the full installer zip files&lt;br /&gt;
[LIST]&lt;br /&gt;
[*]TANE-SP4-Offline-Installer-105766.zip&lt;br /&gt;
[*]TRS19-SP4-Offline-Installer-114800.zip&lt;br /&gt;
[*]TRS22-Offline-Installer-126273.zip&lt;br /&gt;
[*]TrainzPlus-Offline-Installer-128486.zip&lt;br /&gt;
[/LIST]&lt;br /&gt;
and unpacking it into the sub folder looks like this:&lt;br /&gt;
[SPOILER=Folder structure][CODE]&lt;br /&gt;
$HOME/Wine/TRSDL/&lt;br /&gt;
+-- TANESP4_105766&lt;br /&gt;
|   +-- ...&lt;br /&gt;
|   +-- install.exe&lt;br /&gt;
|   +-- ...&lt;br /&gt;
+-- TRS19PE_114800&lt;br /&gt;
|   +-- ...&lt;br /&gt;
|   +-- install.exe&lt;br /&gt;
|   +-- ...&lt;br /&gt;
+-- TRS22PE_126273&lt;br /&gt;
|   +-- ...&lt;br /&gt;
|   +-- install.exe&lt;br /&gt;
|   +-- ...&lt;br /&gt;
+-- TRSPLUS_128486&lt;br /&gt;
    +-- ...&lt;br /&gt;
    +-- install.exe&lt;br /&gt;
    +-- ...&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
[HEADING=3]Install the Trainz instances[/HEADING]&lt;br /&gt;
We install every Trainz instance in its own wine prefix. The install statements of the following scripts create the wine prefixes &amp;quot;.TANESP4&amp;quot;, &amp;quot;.TRS19PE&amp;quot;, &amp;quot;.TRS22PE respective &amp;quot;.TRSPLUS&amp;quot; as hidden same named folders.&lt;br /&gt;
Every installation process creates two links at the desktop. I don&#039;t currently know the purpose of the link with the purple circle and a white arrow. The launch link for the Trainz instance with a Trainz icon and a small red dot with a white cross is blocked. By right-clicking it and using the &amp;quot;Allow launching&amp;quot; entry, it will be possible to launch Trainz.&lt;br /&gt;
Maybe you want to use one of this scripts to install a Trainz instance:&lt;br /&gt;
[SPOILER=Installation of TANESP4][CODE]&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#===============================================================================&lt;br /&gt;
# Installation of TANESP4 in Wine on Ubuntu&lt;br /&gt;
#-------------------------------------------------------------------------------&lt;br /&gt;
WINEPREFIX=$HOME/Wine/.TANESP4 wine $HOME/Wine/TRSDL/TANESP4_105766/install.exe&lt;br /&gt;
#===============================================================================&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
[SPOILER=Installation of TRS19PE][CODE]&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#===============================================================================&lt;br /&gt;
# Installation TRS19PE in Wine on Ubuntu&lt;br /&gt;
#-------------------------------------------------------------------------------&lt;br /&gt;
WINEPREFIX=$HOME/Wine/.TRS19PE wine $HOME/Wine/TRSDL/TRS19PE_114800/install.exe&lt;br /&gt;
#===============================================================================&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
[SPOILER=Installation of TRS22PE][CODE]&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#===============================================================================&lt;br /&gt;
# Installation TRS22PE in Wine on Ubuntu&lt;br /&gt;
#-------------------------------------------------------------------------------&lt;br /&gt;
WINEPREFIX=$HOME/Wine/.TRS22PE wine $HOME/Wine/TRSDL/TRS22PE_126273/install.exe&lt;br /&gt;
#===============================================================================&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
[SPOILER=Installation of TRSPLUS][CODE]&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#===============================================================================&lt;br /&gt;
# Installation TRSPLUS in Wine on Ubuntu&lt;br /&gt;
#-------------------------------------------------------------------------------&lt;br /&gt;
WINEPREFIX=$HOME/Wine/.TRSPLUS wine $HOME/Wine/TRSDL/TRSPLUS_128486/install.exe&lt;br /&gt;
#===============================================================================&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
Good luck and have fun!&lt;br /&gt;
&lt;br /&gt;
==Ubuntu 24.4 LTS noble (Coy&amp;amp;pasted as text from forum post as suggested in the forum thread)==&lt;br /&gt;
The idea&lt;br /&gt;
This is a very old idea and often discussed. I searched for a systematic instruction, but I didn&#039;t find one. So I tried to test it and how it runs. Here&#039;s my personal systematic for Debian based Linux systems.&lt;br /&gt;
&lt;br /&gt;
For my knowledge such systems aren&#039;t able to execute windows programs (*.exe) out of the box. We need some helper apps. In my case I will use WineHQ from an external repository.&lt;br /&gt;
&lt;br /&gt;
Install WineHQ&lt;br /&gt;
A useful instruction to do so is here (in German):ubuntuusers.de Wine Fertige-Pakete in sub chapter &amp;quot;Methode 2 - Wine-Fremdquelle&amp;quot;. Maybe you want to use this script:&lt;br /&gt;
&lt;br /&gt;
[SPOILER=Installation of WineHQ][CODE]&lt;br /&gt;
&lt;br /&gt;
sudo dpkg --add-architecture i386     # Nur auf 64-Bit-Systemen notwendig.&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -pm755 /etc/apt/keyrings   # Ab 22.04 nicht mehr nötig.&lt;br /&gt;
&lt;br /&gt;
sudo wget -nc -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key&lt;br /&gt;
&lt;br /&gt;
sudo wget -NP /etc/apt/sources.list.d/ &amp;quot;https://dl.winehq.org/wine-builds/ubuntu/dists/$(lsb_release -c | grep -o &#039;\w*$&#039;)/winehq-$(lsb_release -c | grep -o &#039;\w*$&#039;).sources&amp;quot;&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install --install-recommends winehq-stable&lt;br /&gt;
&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
&lt;br /&gt;
The following chapter handles the installation of Trainz instances. The paths in the later following scripts are based on a collecting folder &amp;quot;Wine&amp;quot; in $USER.&lt;br /&gt;
&lt;br /&gt;
Download and unpack the Trainz install files&lt;br /&gt;
After downloading the full installer zip files&lt;br /&gt;
&lt;br /&gt;
TANE-SP4-Offline-Installer-105766.zip&lt;br /&gt;
TRS19-SP4-Offline-Installer-114800.zip&lt;br /&gt;
TRS22-Offline-Installer-126273.zip&lt;br /&gt;
TrainzPlus-Offline-Installer-128486.zip&lt;br /&gt;
and unpacking it into the sub folder looks like this:&lt;br /&gt;
&lt;br /&gt;
[SPOILER=Folder structure][CODE]&lt;br /&gt;
&lt;br /&gt;
$HOME/Wine/TRSDL/&lt;br /&gt;
&lt;br /&gt;
+-- TANESP4_105766&lt;br /&gt;
&lt;br /&gt;
|   +-- ...&lt;br /&gt;
&lt;br /&gt;
|   +-- install.exe&lt;br /&gt;
&lt;br /&gt;
|   +-- ...&lt;br /&gt;
&lt;br /&gt;
+-- TRS19PE_114800&lt;br /&gt;
&lt;br /&gt;
|   +-- ...&lt;br /&gt;
&lt;br /&gt;
|   +-- install.exe&lt;br /&gt;
&lt;br /&gt;
|   +-- ...&lt;br /&gt;
&lt;br /&gt;
+-- TRS22PE_126273&lt;br /&gt;
&lt;br /&gt;
|   +-- ...&lt;br /&gt;
&lt;br /&gt;
|   +-- install.exe&lt;br /&gt;
&lt;br /&gt;
|   +-- ...&lt;br /&gt;
&lt;br /&gt;
+-- TRSPLUS_128486&lt;br /&gt;
&lt;br /&gt;
    +-- ...&lt;br /&gt;
&lt;br /&gt;
    +-- install.exe&lt;br /&gt;
&lt;br /&gt;
    +-- ...&lt;br /&gt;
&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
&lt;br /&gt;
Install the Trainz instances&lt;br /&gt;
We install every Trainz instance in its own wine prefix. The install statements of the following scripts create the wine prefixes &amp;quot;.TANESP4&amp;quot;, &amp;quot;.TRS19PE&amp;quot;, &amp;quot;.TRS22PE respective &amp;quot;.TRSPLUS&amp;quot; as hidden same named folders.&lt;br /&gt;
&lt;br /&gt;
Every installation process creates two links at the desktop. I don&#039;t currently know the purpose of the link with the purple circle and a white arrow. The launch link for the Trainz instance with a Trainz icon and a small red dot with a white cross is blocked. By right-clicking it and using the &amp;quot;Allow launching&amp;quot; entry, it will be possible to launch Trainz.&lt;br /&gt;
&lt;br /&gt;
Maybe you want to use one of this scripts to install a Trainz instance:&lt;br /&gt;
&lt;br /&gt;
[SPOILER=Installation of TANESP4][CODE]&lt;br /&gt;
&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
# Installation of TANESP4 in Wine on Ubuntu&lt;br /&gt;
&lt;br /&gt;
#-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
WINEPREFIX=$HOME/Wine/.TANESP4 wine $HOME/Wine/TRSDL/TANESP4_105766/install.exe&lt;br /&gt;
&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
&lt;br /&gt;
[SPOILER=Installation of TRS19PE][CODE]&lt;br /&gt;
&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
# Installation TRS19PE in Wine on Ubuntu&lt;br /&gt;
&lt;br /&gt;
#-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
WINEPREFIX=$HOME/Wine/.TRS19PE wine $HOME/Wine/TRSDL/TRS19PE_114800/install.exe&lt;br /&gt;
&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
&lt;br /&gt;
[SPOILER=Installation of TRS22PE][CODE]&lt;br /&gt;
&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
# Installation TRS22PE in Wine on Ubuntu&lt;br /&gt;
&lt;br /&gt;
#-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
WINEPREFIX=$HOME/Wine/.TRS22PE wine $HOME/Wine/TRSDL/TRS22PE_126273/install.exe&lt;br /&gt;
&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
&lt;br /&gt;
[SPOILER=Installation of TRSPLUS][CODE]&lt;br /&gt;
&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
# Installation TRSPLUS in Wine on Ubuntu&lt;br /&gt;
&lt;br /&gt;
#-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
WINEPREFIX=$HOME/Wine/.TRSPLUS wine $HOME/Wine/TRSDL/TRSPLUS_128486/install.exe&lt;br /&gt;
&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
[/CODE][/SPOILER]&lt;br /&gt;
&lt;br /&gt;
Good luck and have fun!&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_portable:_At_external_harddrive&amp;diff=44347</id>
		<title>HowTo/Installing Trainz portable: At external harddrive</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_portable:_At_external_harddrive&amp;diff=44347"/>
		<updated>2025-04-19T18:12:54Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See Trainz Forum Thread &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/trainz-portable-at-an-external-harddrive.180902/post-2050657 Trainz portable at an external harddrive - post #1]&amp;quot;&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44346</id>
		<title>HowTo/Installing Trainz at Linux: Debian based Distributions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_at_Linux:_Debian_based_Distributions&amp;diff=44346"/>
		<updated>2025-04-19T18:12:03Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Created page with &amp;quot;==Ubuntu 24.4 LTS noble== See Trainz Forum Thread   &amp;quot;[https://forums.auran.com/threads/installing-and-running-trainz-at-linux-here-ubuntu-24-04-lts-noble.180950/post-2051072 I...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ubuntu 24.4 LTS noble==&lt;br /&gt;
See Trainz Forum Thread  &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/installing-and-running-trainz-at-linux-here-ubuntu-24-04-lts-noble.180950/post-2051072 Installing and running Trainz at Linux, here Ubuntu 24.04 LTS noble - post #1 and #3]&amp;quot;&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_portable:_At_external_harddrive&amp;diff=44345</id>
		<title>HowTo/Installing Trainz portable: At external harddrive</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo/Installing_Trainz_portable:_At_external_harddrive&amp;diff=44345"/>
		<updated>2025-04-19T18:07:34Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Created page with &amp;quot;See Trainz Forum Thread &amp;quot;Trainz portable at an external harddrive&amp;quot; post #1  &amp;quot;[https://forums.auran.com/threads/trainz-portable-at-an-external-harddrive.180902/post-2050657 Tra...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See Trainz Forum Thread &amp;quot;Trainz portable at an external harddrive&amp;quot; post #1 &lt;br /&gt;
&amp;quot;[https://forums.auran.com/threads/trainz-portable-at-an-external-harddrive.180902/post-2050657 Trainz portable at an external harddrive - post #1]&amp;quot;&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=HowTo&amp;diff=44344</id>
		<title>HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=HowTo&amp;diff=44344"/>
		<updated>2025-04-19T17:59:35Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists available &amp;quot;How To&amp;quot; Guides which describe how to achieve certain tasks in Trainz.  &amp;lt;b&amp;gt;HowTo&amp;lt;/b&amp;gt; pages provide much detail on specific actions, whereas &amp;lt;b&amp;gt;Help&amp;lt;/b&amp;gt; pages are intended to respond to in-game needs for help or as quick guides to specific actions. Help pages specifically for &#039;&#039;&#039;Trainz Railroad Simulator 2019&#039;&#039;&#039; or &#039;&#039;&#039;TRS19&#039;&#039;&#039; can be found at &#039;&#039;&#039;[http://online.ts2009.com/mediaWiki/index.php/Category:TRS19 Help:TRS19]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Users are encouraged to add their own guides to this page in a similar fashion, or expand on existing guides. Please keep in mind that this site is dedicated to the current version of Trainz and that techniques used should relate to this version. Editors note: all pages here should fit the pattern &amp;quot;How to X&amp;quot;, as in &amp;quot;How to place signals&amp;quot;. Pages and topics which cannot be phrased in this manner do not belong on this page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The Trainz Channel==&lt;br /&gt;
&lt;br /&gt;
To keep up-to-date with all streams and videos visit our [https://youtube.com/c/n3vgames Youtube Channel].&lt;br /&gt;
There is also some older information under our legacy [[Tutorial Videos]] that might help you learn some of the legacy products and features.&lt;br /&gt;
&lt;br /&gt;
==Installing Trainz==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[HowTo/Installing Trainz portable: At external harddrive|Installing Trainz portable: At external harddrive]]&lt;br /&gt;
* [[HowTo/Installing Trainz at Linux: Debian based Distributions|Installing Trainz at Linux: Debian based Distributions]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Content Creation: Routes==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[/Add Bumpy Track/]]&lt;br /&gt;
* [[/Add thumbnail and preview images to your route/|Add Thumbnail and Preview images to your route]]&lt;br /&gt;
* [[/Configure an iPortal/]]&lt;br /&gt;
* [[/Configure An Interlocking Tower/]]&lt;br /&gt;
* [[How to Create a Picklist|Create a PickList]]&lt;br /&gt;
* [[How to Create a Region Asset|Create a Region Asset]]&lt;br /&gt;
* [[/Create_your_first_Route/]]&lt;br /&gt;
* [[/Create a Route in 10 Minutes/]]&lt;br /&gt;
* [[/Make a Track Cutting/]] &#039;&#039;&#039;(an Undercut)&#039;&#039;&#039;&lt;br /&gt;
* [[How to Make a Screen Shot|Make a Screen Shot]]&lt;br /&gt;
* [[How_To_Make_Scenery|Make Better Scenery]]&lt;br /&gt;
* [[How to Merge Routes|Merge Routes]]&lt;br /&gt;
* [[How to Place and Use a Camera|Place Cameras along a Route]]&lt;br /&gt;
* [[/Place Signals/]]&lt;br /&gt;
* [[/Build a Bridge|Place a Bridge in your Route]]&lt;br /&gt;
* [[/Build a Tunnel|Place a Tunnel in your Route]]&lt;br /&gt;
* [[/Build a Crossing|Place a Crossing in your Route]]&lt;br /&gt;
* [[/Build Catenary|Place Catenary in your Route]]&lt;br /&gt;
* [[Route and Session Basics]]&lt;br /&gt;
* [[How to Use Bulk Asset Update/Replace Tool|Use Bulk Asset Update/Replace Tool]]&lt;br /&gt;
* [[How to Use Layers|Use Layers]]&lt;br /&gt;
* [[How to Manage Filters and Picklists|Use and Manage Filters and Picklists]]&lt;br /&gt;
* [[Use Multiplayer Surveyor]]&lt;br /&gt;
* [[How to Use Portals|Use Portals]]&lt;br /&gt;
* [[How to Use Procedural Track|Use Procedural Track]]&lt;br /&gt;
* [[How_to_Use_the_UDS_Interface|Use the UDS (Unified Driver Surveyor) Interface]]&lt;br /&gt;
* [[How_to_Use_S20_Palettes|Use the Surveyor 2.0/Driver Palettes]] &#039;&#039;&#039;(a large file)&#039;&#039;&#039;&lt;br /&gt;
* [[How_to_Use_S20_Tools|Use the Surveyor 2.0 Tools]] &#039;&#039;&#039;(a very large file)&#039;&#039;&#039;&lt;br /&gt;
* [[/Use Superelevation with Trainz 19 and T:ANE/]]&lt;br /&gt;
* [[/Use Superelevation with Trainz 22/]]&lt;br /&gt;
* [[/Use Trig Stations/]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Content Creation: Sessions==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[How to Use Message Popup Rule|Adding Message Popups]]&lt;br /&gt;
* [[How to Use Message Popup Rule (Applications)|Adding Message Popups - Sample Applications]]&lt;br /&gt;
* [[How to Use Navigation Point Rules|Adding Navigation Points]]&lt;br /&gt;
* [[How to Use Navigation Point Rules (Applications)|Adding Navigation Points - Sample Applications]]&lt;br /&gt;
* [[How to Create a HTML Asset|Adding a Session Introduction Page and In Game Messages]]&lt;br /&gt;
* [[How to Use Driver Setup Rule|Configuring the Driver Setup Rule]]&lt;br /&gt;
* [[How to Use Environment Tools|Configuring the Environment Tools]]&lt;br /&gt;
* [[How to Control Junctions in Sessions|Controlling Junctions in Sessions]]&lt;br /&gt;
* [[How to Control Signals in Sessions|Controlling Signals in Sessions]]&lt;br /&gt;
* [[How to Create a Driver Character|Create a Driver Character]]&lt;br /&gt;
* [[How to Create a Message Popup Icon|Creating a Message Popup Icon]]&lt;br /&gt;
* [[Parent Rule List|List of Parent Rules]]&lt;br /&gt;
* [[How to Use Parent and Child Rules|Parent and Child Rules (Session Editor)]]&lt;br /&gt;
* [[Route and Session Basics]]&lt;br /&gt;
* [[How to Use Portals|Using Portals]]&lt;br /&gt;
* [[How to Manage Filters and Picklists|Using Filters and Picklists]]&lt;br /&gt;
* [[How to Use Session Editor|Using the Session Editor]]&lt;br /&gt;
* [[How_to_Use_the_UDS_Interface|Using the UDS (Unified Driver Surveyor) Interface]]&lt;br /&gt;
* [[How to Use Track Markers|Using Track Markers]]&lt;br /&gt;
* [[How to Use Track Direction Markers|Using Track Direction Markers]]&lt;br /&gt;
* [[How to Use Track Priority Markers|Using Track Priority Markers]]&lt;br /&gt;
* [[How to Use Track Triggers|Using Track Triggers]]&lt;br /&gt;
* [[How to Use Variables in Sessions (Examples)|Using Variables in Sessions - Sample Applications]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using &amp;quot;Manage Content&amp;quot; in TANE or newer==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[/Download an Asset from the Download Station/]]&lt;br /&gt;
* [[/View by thumbnail images/]]&lt;br /&gt;
* [[/Fix Errors and Warnings/]]&lt;br /&gt;
* [[/Finding Missing Dependencies/]]&lt;br /&gt;
* [[How to Backup a Picklist]]&lt;br /&gt;
* [[How to Create a Picklist]]&lt;br /&gt;
* [[How to Manage Backups]]&lt;br /&gt;
* [[How to Manage Filters and Picklists|How to Use and Manage Filters and Picklists]]&lt;br /&gt;
* [[How to Move a Picklist]]&lt;br /&gt;
* [[How to Rename a Picklist]]&lt;br /&gt;
* [[How to Perform Database Repairs]]&lt;br /&gt;
* [[Understand Content Manager Status Labels|How to Understand Content Manager Status Labels]]&lt;br /&gt;
* [[Using Content Manager to Update Assets]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[Help:Content_Manager]]&lt;br /&gt;
&lt;br /&gt;
==Asset Management==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[How to Backup a Picklist]]&lt;br /&gt;
* [[How to Move a Picklist]]&lt;br /&gt;
* [[How to Move Your User Data Folder]]&lt;br /&gt;
* [[How to Perform Database Repairs]]&lt;br /&gt;
* [[Understand Content Manager Status Labels|How to Understand Content Manager Status Labels]]&lt;br /&gt;
* [[How to Create a Clean Install|How to Create a Clean Install and Additional User Data Folders]]&lt;br /&gt;
* [[How to Manage Filters and Picklists|How to Use and Manage Filters and Picklists]]&lt;br /&gt;
* [[Using Content Manager to Update Assets|How to Use Content Manager to Update Assets]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Content Creation: Assets==&lt;br /&gt;
&amp;lt;font size=3&amp;gt;&#039;&#039;&#039;General&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[/Make your first Trainz Asset/]]&lt;br /&gt;
* [[/Build a Car for Traffic (stand-alone version)/]]&lt;br /&gt;
* [[/Build a Car for Traffic (mesh library version)/]]&lt;br /&gt;
* [[/Build a cab interior/]]&lt;br /&gt;
* [[/Build a drivable car/]]&lt;br /&gt;
* [[/Build Passenger Enabled Assets/]]&lt;br /&gt;
* [[/Build a tree with PlantFactory/]]&lt;br /&gt;
* [[/Build a tree/]]&lt;br /&gt;
* [[/Build_a_simple_animated_scenery_asset_in_Blender/|Build a simple animated scenery asset in Blender]]&lt;br /&gt;
* [[/Create a High Voltage Power Line Spline/]]&lt;br /&gt;
* [[/Create a Fence Spline Featuring LOD and Random Meshes/]]&lt;br /&gt;
* [[How to Create a Driver Character|Create a Driver Character]]&lt;br /&gt;
* [[How to Create a Message Popup Icon|Create a Message Popup Icon]]&lt;br /&gt;
* [[How to Create a Region Asset|Create a Region Asset]]&lt;br /&gt;
* [[/Create a Neon Font Effect with PhotoShop C4/]]&lt;br /&gt;
* [[/Build Procedural Track for T:ANE/]]&lt;br /&gt;
* [[/Update your auto-generated next KUID/]]&lt;br /&gt;
* [[How to Create a HTML Asset|Create a HTML Asset (Session Introduction Page and In Game Messages)]]&lt;br /&gt;
* [[Updating_Steam_Locos_to_TC3_Standards]]&lt;br /&gt;
* [[How_to_add_collision_to_an_asset]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;font size=3&amp;gt;&#039;&#039;&#039;Scripting and Config.txt&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[/Localize an Asset/]]&lt;br /&gt;
* [[/Build a scripted asset/]]&lt;br /&gt;
* [[/Example_Vehicle_Config.txt/]]&lt;br /&gt;
* [[/Example_Station_Script/]]&lt;br /&gt;
* [[/Configure a spline for collisions/]]&lt;br /&gt;
* [[Adding the Native Automatic Running Numbers system to a traincar]]&lt;br /&gt;
* [[/Add a config.txt syntax highlighter to Notepad++/]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;font size=3&amp;gt;&#039;&#039;&#039;3D Modelling&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[/Export from 3DS Max using FBX/]]&lt;br /&gt;
* [[/Export from Blender using FBX/|Export from Blender using FBX (Rocks with PBRMetal material)]]&lt;br /&gt;
* [[/Export Blender FBX Animation/|Export Blender FBX Animation (Rotating earth and four rotating cogs)]]&lt;br /&gt;
* [[/Solve Blender Modelling Problems/]]&lt;br /&gt;
* [[/Scaling setup in Blender/]] &lt;br /&gt;
* [[/Build normal maps in Max/]]&lt;br /&gt;
* [[/Render to Texture/]]&lt;br /&gt;
* [[/Build a simple animated scenery asset in Blender/|Build a simple animated scenery asset in Blender (Jumping ball)]]&lt;br /&gt;
* [[/Create transparent windows in Blender/]]&lt;br /&gt;
* [[/Build an animated Neon Sign/]]&lt;br /&gt;
* [[HowTo/Create_a_3D_Avatar|Create a 3D Avatar (Driver Character)]]&lt;br /&gt;
* [[How_To/Use_GIMP_to_create_a_PBRMetal_parameters_image|Create a PBRMetal parameters image in GIMP]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;font size=3&amp;gt;&#039;&#039;&#039;Reskining&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[/Reskin an Asset/]]&lt;br /&gt;
* [[/Reskin an Asset using an alias/]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;font size=3&amp;gt;&#039;&#039;&#039;Content Manager&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[/Create a displacement map/]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;font size=3&amp;gt;&#039;&#039;&#039;Level Of Detail&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [https://online.ts2009.com/mediaWiki/index.php/Level_of_Detail Level of Detail]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;font size=3&amp;gt;&#039;&#039;&#039;Configurations Files&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[/General information for Configuration Files/]]&lt;br /&gt;
&lt;br /&gt;
* [https://online.ts2009.com/mediaWiki/index.php/Index_of_Tags_%26_Containers  List of Tags and Containers]&lt;br /&gt;
* [[https://online.ts2009.com/mediaWiki/index.php/Content_Types#Content_Types Content Types and Config Files]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;font size=3&amp;gt;&#039;&#039;&#039;Content Creation&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [https://online.ts2009.com/mediaWiki/index.php/HowTo/Build_Procedural_Track_for_T:ANE  How to build procedural Track]&lt;br /&gt;
* [[How to Create a Driver Character]]&lt;br /&gt;
* [[How to Create a HTML Asset|How to Create a HTML Asset]]&lt;br /&gt;
* [[How to Create a Message Popup Icon|How to Create a Message Popup Icon]]&lt;br /&gt;
* [[How to Create a Region Asset|How to Create a Region Asset]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Content Creation: Scripting==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[/Your first Trainz Script/|Create your first Trainz script]]&lt;br /&gt;
* [[/Hide- &amp;amp; Unhide Meshes/]]&lt;br /&gt;
* [[/Search for objects in the world/]]&lt;br /&gt;
* [[/Upgrade obsolete script functions/]]&lt;br /&gt;
* [[/Read string table or Config text/]]&lt;br /&gt;
* [[/Search for installed assets/]]&lt;br /&gt;
* [[/Debug Scripts/]]&lt;br /&gt;
* [[Getting_Started_in_TrainzScript|Getting Started in TrainzScript: Engine Shed House&amp;lt;br&amp;gt;(animate doors, hide a mesh, show text, play sound, replace texture ...)&amp;lt;br&amp;gt;needs some small updates, added prequel Blender to Trainz]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== List of Driver Commands==&lt;br /&gt;
*[[Driver_Commands_List|Driver Commands List]]&lt;br /&gt;
&lt;br /&gt;
== List of Session Rules==&lt;br /&gt;
*[[Session Rule List with Parameters|Session Rules (Alphabetical Order)]]&lt;br /&gt;
*[[Session Rules By Categories With Properties|Session Rules (Category Order)]]&lt;br /&gt;
&lt;br /&gt;
==Creating and Configuring Content In-game==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[/Create an Interactive Session/]]&lt;br /&gt;
* [[/Add Carz Traffic to a Route/]]&lt;br /&gt;
* [[/Use Digholes to Create Tunnel entries/]]&lt;br /&gt;
* [[/Tune a Steam Locomotive Enginespec/]]&lt;br /&gt;
* [[/Tune a DCC EngineSpec/]]&lt;br /&gt;
* [[/Tune a Diesel EngineSpec/]]&lt;br /&gt;
* [[/Configure an Interactive Industry/]]&lt;br /&gt;
* [[/Implement a Destination Sign System/]]&lt;br /&gt;
* [[/Upload a new asset to the DownloadStation/]]&lt;br /&gt;
* [[/Update an existing asset on the DownloadStation/]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Documentation Suggestions==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[/Build normal maps in Blender/]]&lt;br /&gt;
* [[/Build a house/]] - See discussion page&lt;br /&gt;
* [[/Build a track/]]&lt;br /&gt;
* [[/Build a tunnel/]]&lt;br /&gt;
* [[/Build a hedge/]]&lt;br /&gt;
* [[/Build a fence/]]&lt;br /&gt;
* [[/Build a road/]]&lt;br /&gt;
* [[/Build a road intersection asset/]]&lt;br /&gt;
* [[/Build a road crossing/]]&lt;br /&gt;
* [[/Build a train car/]]&lt;br /&gt;
* [[/Build a bogey/]]&lt;br /&gt;
* [[/Build a ground texture/]]&lt;br /&gt;
* [[/Build an interactive industry/]]&lt;br /&gt;
* [[/Add attached track/]]&lt;br /&gt;
* [[/Register with Planet Auran/]]&lt;br /&gt;
* [[/Create an Achievement/]]&lt;br /&gt;
* [[/Use a map to create a baseboard/]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Trainz Wiki==&lt;br /&gt;
*[[HowTo/Create_a_Help_Page|How to Create a Trainz Wiki page]]&lt;br /&gt;
&lt;br /&gt;
== See Also==&lt;br /&gt;
&lt;br /&gt;
* [[Content Configuration]] - &#039;&#039;A reference manual covering all content types.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:How-to guides| ]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44137</id>
		<title>CCG/Example: DriverCommand</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44137"/>
		<updated>2025-02-15T18:17:55Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Driver-Command==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Directory Structure===&lt;br /&gt;
A typical asset of this kind has the following File\Directory Structure:&lt;br /&gt;
&lt;br /&gt;
[[Image:CCG_driver_command_dir1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Required Files===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;config.txt&#039;&#039;&#039; - The config file for the asset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;thumb.jpg&#039;&#039;&#039; - The thumbnail image for this asset. A 240x180 jpeg.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.texture.txt&#039;&#039;&#039; - The texture.txt file. See the section on [[Texture_file|Texture.txt]] files for more information.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.tga&#039;&#039;&#039; - The texture file for the drivercommand icon.&lt;br /&gt;
&lt;br /&gt;
[[Image:example_driveto.jpg]] shows image and alpha channel for 64x64 pixel TGA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetocommand.gs&#039;&#039;&#039; - The trainz script file referenced in the config.txt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetoschedulecommand.gs&#039;&#039;&#039; - A trainz script file which is a dependency of &amp;quot;drivercommand.gs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Version hint===&lt;br /&gt;
 !!! This example is an older version without async search of industries and the newer menu building methods !!!&lt;br /&gt;
The current Drive To driver command asset contains a commented newer code version.&lt;br /&gt;
&lt;br /&gt;
===Config.txt File Listing===&lt;br /&gt;
 kuid                           &amp;lt;kuid:56113:1268&amp;gt;&lt;br /&gt;
 trainz-build                   2.5&lt;br /&gt;
 category-class                 &amp;quot;YD&amp;quot;&lt;br /&gt;
 category-region                &amp;quot;00&amp;quot;&lt;br /&gt;
 category-era                   &amp;quot;1800s;1810s;1820s&amp;quot;&lt;br /&gt;
 username                       &amp;quot;testDriverCommand&amp;quot;&lt;br /&gt;
 kind                           &amp;quot;drivercommand&amp;quot;&lt;br /&gt;
 supports-null-driver-character  1&lt;br /&gt;
 script                          &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 class                           &amp;quot;DriveToCommand&amp;quot;&lt;br /&gt;
 description                     &amp;quot;Test command. This does the same thing as `Drive To&#039;.&amp;quot;&lt;br /&gt;
 string-table&lt;br /&gt;
 {&lt;br /&gt;
   description                   &amp;quot;Allows a driver character to take a train either to a &lt;br /&gt;
                                   destination industry or a specific track in a destination industry.&amp;quot;&lt;br /&gt;
   driver_command_drive_to       &amp;quot;Drive To &amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 kuid-table&lt;br /&gt;
 {&lt;br /&gt;
   command-sounds                &amp;lt;kuid:-3:10219&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
 thumbnails&lt;br /&gt;
 {&lt;br /&gt;
   0&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;thumb.jpg&amp;quot;&lt;br /&gt;
       width                     240&lt;br /&gt;
       height                    180&lt;br /&gt;
     }&lt;br /&gt;
   1&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;driveto.tga&amp;quot;&lt;br /&gt;
       width                     64&lt;br /&gt;
       height                    64&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===DriverToCommand.gs File Listing===&lt;br /&gt;
 //&lt;br /&gt;
 // DriverToCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToScheduleCommand.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver command that allows a driver character to take a train either to a destination industry&lt;br /&gt;
 // or a specific track in a destination industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToCommand isclass DriverCommand&lt;br /&gt;
 {&lt;br /&gt;
    //&lt;br /&gt;
    // Initialize parent object and add handlers to process messages for this driver command object.&lt;br /&gt;
    //&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
       inherited(asset);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustry&amp;quot;, null, &amp;quot;DriveTo&amp;quot;);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustryTrack&amp;quot;, null,&amp;quot;DriveToTrack&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Adds industry destination menu items for all industries to the given menu along with submenus of&lt;br /&gt;
    // destination tracks for all industries added.&lt;br /&gt;
    //&lt;br /&gt;
    public void AddCommandMenuItem(DriverCharacter driver,Menu menu)&lt;br /&gt;
    {&lt;br /&gt;
       Train train;&lt;br /&gt;
       if (driver)&lt;br /&gt;
       {&lt;br /&gt;
          train = driver.GetTrain();&lt;br /&gt;
          if (!train) &lt;br /&gt;
             return;&lt;br /&gt;
       }&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       Menu industriesMenu = Constructors.NewMenu();&lt;br /&gt;
       GameObject[] industryList = World.GetIndustryList();&lt;br /&gt;
       int i, industryCount = industryList.size();&lt;br /&gt;
       if (!industryCount)&lt;br /&gt;
          // we dont bother with a `Drive To&#039; command if there are no industries&lt;br /&gt;
          return;&lt;br /&gt;
       for (i = 0; i &amp;lt; industryCount; i++)&lt;br /&gt;
       {&lt;br /&gt;
          Industry industry = cast&amp;lt;Industry&amp;gt;(industryList[i]);&lt;br /&gt;
          string localisedName = industry.GetLocalisedName();&lt;br /&gt;
          string[] locationNames = new string[0];&lt;br /&gt;
          string[] locationTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(locationNames,locationTracks);&lt;br /&gt;
          if (localisedName.size())&lt;br /&gt;
             if (locationNames.size())&lt;br /&gt;
             {&lt;br /&gt;
                Menu submenu = Constructors.NewMenu();&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; locationNames.size(); j++)&lt;br /&gt;
                if (locationNames[j] and locationNames[j].size() and locationTracks[j] and locationTracks[j].size())&lt;br /&gt;
                   submenu.AddItem(locationNames[j], me, &amp;quot;DriveToIndustryTrack&amp;quot;, industry.GetId() + &amp;quot; &amp;quot; + locationTracks[j]);&lt;br /&gt;
                else &lt;br /&gt;
                   if (train)&lt;br /&gt;
                      train.Exception(&amp;quot;Error in `track names&#039; of industry `&amp;quot; + localisedName + &amp;quot;&#039;&amp;quot;);&lt;br /&gt;
                industriesMenu.AddSubmenu(localisedName + &amp;quot; &amp;gt;&amp;quot;,submenu);&lt;br /&gt;
             }&lt;br /&gt;
             else&lt;br /&gt;
                industriesMenu.AddItem(localisedName, me,&amp;quot;DriveToIndustry&amp;quot;, industry.GetName());&lt;br /&gt;
          industriesMenu.SubdivideItems();&lt;br /&gt;
          menu.AddSubmenu(strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + &amp;quot; &amp;gt;&amp;quot;, industriesMenu);&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Called by either DriveTo() or DriveToTrack() to play one of  random driver acknowledgments.&lt;br /&gt;
    //&lt;br /&gt;
    void PlayConfirmation(void)&lt;br /&gt;
    {&lt;br /&gt;
       KUID kuid = GetAsset().LookupKUIDTable(&amp;quot;command-sounds&amp;quot;);&lt;br /&gt;
       Library libCommandSounds = World.GetLibrary(kuid);&lt;br /&gt;
       if (libCommandSounds)&lt;br /&gt;
          libCommandSounds.LibraryCall(&amp;quot;PlayConfirmation&amp;quot;,null, null);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Create the schedule command&lt;br /&gt;
    //&lt;br /&gt;
    DriverScheduleCommand CreateScheduleCommand(DriverCharacter driver, Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       DriveToScheduleCommand cmd = new DriveToScheduleCommand();&lt;br /&gt;
       cmd.Init(driver, me);&lt;br /&gt;
       cmd.SetParent(me);&lt;br /&gt;
       cmd.SetProperties(soup);&lt;br /&gt;
       return cast&amp;lt;DriverScheduleCommand&amp;gt;cmd;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to an industry (no specific destination track though).&lt;br /&gt;
    //&lt;br /&gt;
    void DriveTo(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string industryName = msg.minor;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to a specific track in an industry.&lt;br /&gt;
    //&lt;br /&gt;
    void DriveToTrack(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string msgData = msg.minor;&lt;br /&gt;
       int industryId = Str.UnpackInt(msgData);&lt;br /&gt;
       string trackName = Str.UnpackString(msgData);&lt;br /&gt;
       GameObject industry = Router.GetGameObject(industryId);&lt;br /&gt;
       if (!industry) return;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industry.GetName());&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
And the dependent script&lt;br /&gt;
&lt;br /&gt;
===DriveToScheduleCommand.gs File Fisting===&lt;br /&gt;
 //&lt;br /&gt;
 // DriveToScheduleCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Schedule.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver schedule command used by DriveToCommand to get a driver character to take a train to&lt;br /&gt;
 // a specific track on an industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToScheduleCommand isclass DriverScheduleCommand&lt;br /&gt;
 {&lt;br /&gt;
    public string industryName;   // Name of the industry to drive to.&lt;br /&gt;
    public string trackName;      // Name of the track in the industry to drive to.&lt;br /&gt;
    DriveToCommand parent;&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetParent(DriveToCommand newParent)&lt;br /&gt;
    {&lt;br /&gt;
       parent = newParent;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Starts executing this schedule command on the given driver character.&lt;br /&gt;
    //&lt;br /&gt;
    public bool BeginExecute(DriverCharacter driver)&lt;br /&gt;
    {&lt;br /&gt;
       Train train = driver.GetTrain();&lt;br /&gt;
       if (!train)&lt;br /&gt;
          // cant drive if we dont have a train&lt;br /&gt;
          return false;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (!industry)&lt;br /&gt;
          // cant drive to an industry which doesn&#039;t exist&lt;br /&gt;
          return false;&lt;br /&gt;
       return driver.NavigateToIndustry(industry, trackName);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // we should really implement EndExecute() to allow the game to determine the success of this command&lt;br /&gt;
    //&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Provides an icon for this command so it can be seen on the driver&#039;s schedule. Uses the industry&lt;br /&gt;
    // icon to indicate the destination.&lt;br /&gt;
    //&lt;br /&gt;
    public object GetIcon(void)&lt;br /&gt;
    {&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       return cast&amp;lt;object&amp;gt;industry;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public string GetTooltip(void)&lt;br /&gt;
    {&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       string userTrackName = trackName;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (industry)&lt;br /&gt;
       {&lt;br /&gt;
          string[] destNames = new string[0];&lt;br /&gt;
          string[] destTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(destNames,destTracks);&lt;br /&gt;
          int i;&lt;br /&gt;
          for (i = 0; i &amp;lt; destNames.size(); i++)&lt;br /&gt;
          {&lt;br /&gt;
             if (destTracks[i] == trackName)&lt;br /&gt;
             {&lt;br /&gt;
                userTrackName = destNames[i];&lt;br /&gt;
                break;&lt;br /&gt;
             }&lt;br /&gt;
          }&lt;br /&gt;
       }&lt;br /&gt;
       return strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + industryName + &amp;quot; (&amp;quot; + userTrackName + &amp;quot;)&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public Soup GetProperties(void)&lt;br /&gt;
    {&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       // Save support&lt;br /&gt;
       // Save the properties to the soup, then return the soup&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       return soup;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetProperties(Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       // Load support&lt;br /&gt;
       // Setup the properties from the passed in soup&lt;br /&gt;
       industryName = soup.GetNamedTag(&amp;quot;industryName&amp;quot;);&lt;br /&gt;
       trackName = soup.GetNamedTag(&amp;quot;trackName&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
===Download this asset===&lt;br /&gt;
This asset is available for download from the TRS2006 website at:&lt;br /&gt;
&lt;br /&gt;
Sorry, no download available.&lt;br /&gt;
&lt;br /&gt;
A version of this asset is a &#039;&#039;built-in&#039;&#039; for TS2010, TS12. &lt;br /&gt;
&lt;br /&gt;
==Return to CCG Index==&lt;br /&gt;
[[Content Creator&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
[[CCG/Kind_Examples|Kind Examples]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44136</id>
		<title>CCG/Example: DriverCommand</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44136"/>
		<updated>2025-02-15T17:15:40Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* DriveToScheduleCommand.gs File Fisting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Driver-Command==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Directory Structure===&lt;br /&gt;
A typical asset of this kind has the following File\Directory Structure:&lt;br /&gt;
&lt;br /&gt;
[[Image:CCG_driver_command_dir1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Required Files===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;config.txt&#039;&#039;&#039; - The config file for the asset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;thumb.jpg&#039;&#039;&#039; - The thumbnail image for this asset. A 240x180 jpeg.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.texture.txt&#039;&#039;&#039; - The texture.txt file. See the section on [[Texture_file|Texture.txt]] files for more information.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.tga&#039;&#039;&#039; - The texture file for the drivercommand icon.&lt;br /&gt;
&lt;br /&gt;
[[Image:example_driveto.jpg]] shows image and alpha channel for 64x64 pixel TGA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetocommand.gs&#039;&#039;&#039; - The trainz script file referenced in the config.txt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetoschedulecommand.gs&#039;&#039;&#039; - A trainz script file which is a dependency of &amp;quot;drivercommand.gs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Config.txt File Listing===&lt;br /&gt;
 kuid                           &amp;lt;kuid:56113:1268&amp;gt;&lt;br /&gt;
 trainz-build                   2.5&lt;br /&gt;
 category-class                 &amp;quot;YD&amp;quot;&lt;br /&gt;
 category-region                &amp;quot;00&amp;quot;&lt;br /&gt;
 category-era                   &amp;quot;1800s;1810s;1820s&amp;quot;&lt;br /&gt;
 username                       &amp;quot;testDriverCommand&amp;quot;&lt;br /&gt;
 kind                           &amp;quot;drivercommand&amp;quot;&lt;br /&gt;
 supports-null-driver-character  1&lt;br /&gt;
 script                          &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 class                           &amp;quot;DriveToCommand&amp;quot;&lt;br /&gt;
 description                     &amp;quot;Test command. This does the same thing as `Drive To&#039;.&amp;quot;&lt;br /&gt;
 string-table&lt;br /&gt;
 {&lt;br /&gt;
   description                   &amp;quot;Allows a driver character to take a train either to a &lt;br /&gt;
                                   destination industry or a specific track in a destination industry.&amp;quot;&lt;br /&gt;
   driver_command_drive_to       &amp;quot;Drive To &amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 kuid-table&lt;br /&gt;
 {&lt;br /&gt;
   command-sounds                &amp;lt;kuid:-3:10219&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
 thumbnails&lt;br /&gt;
 {&lt;br /&gt;
   0&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;thumb.jpg&amp;quot;&lt;br /&gt;
       width                     240&lt;br /&gt;
       height                    180&lt;br /&gt;
     }&lt;br /&gt;
   1&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;driveto.tga&amp;quot;&lt;br /&gt;
       width                     64&lt;br /&gt;
       height                    64&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===DriverToCommand.gs File Listing===&lt;br /&gt;
 //&lt;br /&gt;
 // DriverToCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToScheduleCommand.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver command that allows a driver character to take a train either to a destination industry&lt;br /&gt;
 // or a specific track in a destination industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToCommand isclass DriverCommand&lt;br /&gt;
 {&lt;br /&gt;
    //&lt;br /&gt;
    // Initialize parent object and add handlers to process messages for this driver command object.&lt;br /&gt;
    //&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
       inherited(asset);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustry&amp;quot;, null, &amp;quot;DriveTo&amp;quot;);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustryTrack&amp;quot;, null,&amp;quot;DriveToTrack&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Adds industry destination menu items for all industries to the given menu along with submenus of&lt;br /&gt;
    // destination tracks for all industries added.&lt;br /&gt;
    //&lt;br /&gt;
    public void AddCommandMenuItem(DriverCharacter driver,Menu menu)&lt;br /&gt;
    {&lt;br /&gt;
       Train train;&lt;br /&gt;
       if (driver)&lt;br /&gt;
       {&lt;br /&gt;
          train = driver.GetTrain();&lt;br /&gt;
          if (!train) &lt;br /&gt;
             return;&lt;br /&gt;
       }&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       Menu industriesMenu = Constructors.NewMenu();&lt;br /&gt;
       GameObject[] industryList = World.GetIndustryList();&lt;br /&gt;
       int i, industryCount = industryList.size();&lt;br /&gt;
       if (!industryCount)&lt;br /&gt;
          // we dont bother with a `Drive To&#039; command if there are no industries&lt;br /&gt;
          return;&lt;br /&gt;
       for (i = 0; i &amp;lt; industryCount; i++)&lt;br /&gt;
       {&lt;br /&gt;
          Industry industry = cast&amp;lt;Industry&amp;gt;(industryList[i]);&lt;br /&gt;
          string localisedName = industry.GetLocalisedName();&lt;br /&gt;
          string[] locationNames = new string[0];&lt;br /&gt;
          string[] locationTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(locationNames,locationTracks);&lt;br /&gt;
          if (localisedName.size())&lt;br /&gt;
             if (locationNames.size())&lt;br /&gt;
             {&lt;br /&gt;
                Menu submenu = Constructors.NewMenu();&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; locationNames.size(); j++)&lt;br /&gt;
                if (locationNames[j] and locationNames[j].size() and locationTracks[j] and locationTracks[j].size())&lt;br /&gt;
                   submenu.AddItem(locationNames[j], me, &amp;quot;DriveToIndustryTrack&amp;quot;, industry.GetId() + &amp;quot; &amp;quot; + locationTracks[j]);&lt;br /&gt;
                else &lt;br /&gt;
                   if (train)&lt;br /&gt;
                      train.Exception(&amp;quot;Error in `track names&#039; of industry `&amp;quot; + localisedName + &amp;quot;&#039;&amp;quot;);&lt;br /&gt;
                industriesMenu.AddSubmenu(localisedName + &amp;quot; &amp;gt;&amp;quot;,submenu);&lt;br /&gt;
             }&lt;br /&gt;
             else&lt;br /&gt;
                industriesMenu.AddItem(localisedName, me,&amp;quot;DriveToIndustry&amp;quot;, industry.GetName());&lt;br /&gt;
          industriesMenu.SubdivideItems();&lt;br /&gt;
          menu.AddSubmenu(strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + &amp;quot; &amp;gt;&amp;quot;, industriesMenu);&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Called by either DriveTo() or DriveToTrack() to play one of  random driver acknowledgments.&lt;br /&gt;
    //&lt;br /&gt;
    void PlayConfirmation(void)&lt;br /&gt;
    {&lt;br /&gt;
       KUID kuid = GetAsset().LookupKUIDTable(&amp;quot;command-sounds&amp;quot;);&lt;br /&gt;
       Library libCommandSounds = World.GetLibrary(kuid);&lt;br /&gt;
       if (libCommandSounds)&lt;br /&gt;
          libCommandSounds.LibraryCall(&amp;quot;PlayConfirmation&amp;quot;,null, null);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Create the schedule command&lt;br /&gt;
    //&lt;br /&gt;
    DriverScheduleCommand CreateScheduleCommand(DriverCharacter driver, Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       DriveToScheduleCommand cmd = new DriveToScheduleCommand();&lt;br /&gt;
       cmd.Init(driver, me);&lt;br /&gt;
       cmd.SetParent(me);&lt;br /&gt;
       cmd.SetProperties(soup);&lt;br /&gt;
       return cast&amp;lt;DriverScheduleCommand&amp;gt;cmd;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to an industry (no specific destination track though).&lt;br /&gt;
    //&lt;br /&gt;
    void DriveTo(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string industryName = msg.minor;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to a specific track in an industry.&lt;br /&gt;
    //&lt;br /&gt;
    void DriveToTrack(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string msgData = msg.minor;&lt;br /&gt;
       int industryId = Str.UnpackInt(msgData);&lt;br /&gt;
       string trackName = Str.UnpackString(msgData);&lt;br /&gt;
       GameObject industry = Router.GetGameObject(industryId);&lt;br /&gt;
       if (!industry) return;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industry.GetName());&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
And the dependent script&lt;br /&gt;
&lt;br /&gt;
===DriveToScheduleCommand.gs File Fisting===&lt;br /&gt;
 //&lt;br /&gt;
 // DriveToScheduleCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Schedule.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver schedule command used by DriveToCommand to get a driver character to take a train to&lt;br /&gt;
 // a specific track on an industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToScheduleCommand isclass DriverScheduleCommand&lt;br /&gt;
 {&lt;br /&gt;
    public string industryName;   // Name of the industry to drive to.&lt;br /&gt;
    public string trackName;      // Name of the track in the industry to drive to.&lt;br /&gt;
    DriveToCommand parent;&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetParent(DriveToCommand newParent)&lt;br /&gt;
    {&lt;br /&gt;
       parent = newParent;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Starts executing this schedule command on the given driver character.&lt;br /&gt;
    //&lt;br /&gt;
    public bool BeginExecute(DriverCharacter driver)&lt;br /&gt;
    {&lt;br /&gt;
       Train train = driver.GetTrain();&lt;br /&gt;
       if (!train)&lt;br /&gt;
          // cant drive if we dont have a train&lt;br /&gt;
          return false;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (!industry)&lt;br /&gt;
          // cant drive to an industry which doesn&#039;t exist&lt;br /&gt;
          return false;&lt;br /&gt;
       return driver.NavigateToIndustry(industry, trackName);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // we should really implement EndExecute() to allow the game to determine the success of this command&lt;br /&gt;
    //&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Provides an icon for this command so it can be seen on the driver&#039;s schedule. Uses the industry&lt;br /&gt;
    // icon to indicate the destination.&lt;br /&gt;
    //&lt;br /&gt;
    public object GetIcon(void)&lt;br /&gt;
    {&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       return cast&amp;lt;object&amp;gt;industry;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public string GetTooltip(void)&lt;br /&gt;
    {&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       string userTrackName = trackName;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (industry)&lt;br /&gt;
       {&lt;br /&gt;
          string[] destNames = new string[0];&lt;br /&gt;
          string[] destTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(destNames,destTracks);&lt;br /&gt;
          int i;&lt;br /&gt;
          for (i = 0; i &amp;lt; destNames.size(); i++)&lt;br /&gt;
          {&lt;br /&gt;
             if (destTracks[i] == trackName)&lt;br /&gt;
             {&lt;br /&gt;
                userTrackName = destNames[i];&lt;br /&gt;
                break;&lt;br /&gt;
             }&lt;br /&gt;
          }&lt;br /&gt;
       }&lt;br /&gt;
       return strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + industryName + &amp;quot; (&amp;quot; + userTrackName + &amp;quot;)&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public Soup GetProperties(void)&lt;br /&gt;
    {&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       // Save support&lt;br /&gt;
       // Save the properties to the soup, then return the soup&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       return soup;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetProperties(Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       // Load support&lt;br /&gt;
       // Setup the properties from the passed in soup&lt;br /&gt;
       industryName = soup.GetNamedTag(&amp;quot;industryName&amp;quot;);&lt;br /&gt;
       trackName = soup.GetNamedTag(&amp;quot;trackName&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
===Download this asset===&lt;br /&gt;
This asset is available for download from the TRS2006 website at:&lt;br /&gt;
&lt;br /&gt;
Sorry, no download available.&lt;br /&gt;
&lt;br /&gt;
A version of this asset is a &#039;&#039;built-in&#039;&#039; for TS2010, TS12. &lt;br /&gt;
&lt;br /&gt;
==Return to CCG Index==&lt;br /&gt;
[[Content Creator&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
[[CCG/Kind_Examples|Kind Examples]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44135</id>
		<title>CCG/Example: DriverCommand</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44135"/>
		<updated>2025-02-15T17:15:00Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* DriverToCommand.gs File Listing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Driver-Command==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Directory Structure===&lt;br /&gt;
A typical asset of this kind has the following File\Directory Structure:&lt;br /&gt;
&lt;br /&gt;
[[Image:CCG_driver_command_dir1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Required Files===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;config.txt&#039;&#039;&#039; - The config file for the asset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;thumb.jpg&#039;&#039;&#039; - The thumbnail image for this asset. A 240x180 jpeg.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.texture.txt&#039;&#039;&#039; - The texture.txt file. See the section on [[Texture_file|Texture.txt]] files for more information.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.tga&#039;&#039;&#039; - The texture file for the drivercommand icon.&lt;br /&gt;
&lt;br /&gt;
[[Image:example_driveto.jpg]] shows image and alpha channel for 64x64 pixel TGA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetocommand.gs&#039;&#039;&#039; - The trainz script file referenced in the config.txt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetoschedulecommand.gs&#039;&#039;&#039; - A trainz script file which is a dependency of &amp;quot;drivercommand.gs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Config.txt File Listing===&lt;br /&gt;
 kuid                           &amp;lt;kuid:56113:1268&amp;gt;&lt;br /&gt;
 trainz-build                   2.5&lt;br /&gt;
 category-class                 &amp;quot;YD&amp;quot;&lt;br /&gt;
 category-region                &amp;quot;00&amp;quot;&lt;br /&gt;
 category-era                   &amp;quot;1800s;1810s;1820s&amp;quot;&lt;br /&gt;
 username                       &amp;quot;testDriverCommand&amp;quot;&lt;br /&gt;
 kind                           &amp;quot;drivercommand&amp;quot;&lt;br /&gt;
 supports-null-driver-character  1&lt;br /&gt;
 script                          &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 class                           &amp;quot;DriveToCommand&amp;quot;&lt;br /&gt;
 description                     &amp;quot;Test command. This does the same thing as `Drive To&#039;.&amp;quot;&lt;br /&gt;
 string-table&lt;br /&gt;
 {&lt;br /&gt;
   description                   &amp;quot;Allows a driver character to take a train either to a &lt;br /&gt;
                                   destination industry or a specific track in a destination industry.&amp;quot;&lt;br /&gt;
   driver_command_drive_to       &amp;quot;Drive To &amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 kuid-table&lt;br /&gt;
 {&lt;br /&gt;
   command-sounds                &amp;lt;kuid:-3:10219&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
 thumbnails&lt;br /&gt;
 {&lt;br /&gt;
   0&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;thumb.jpg&amp;quot;&lt;br /&gt;
       width                     240&lt;br /&gt;
       height                    180&lt;br /&gt;
     }&lt;br /&gt;
   1&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;driveto.tga&amp;quot;&lt;br /&gt;
       width                     64&lt;br /&gt;
       height                    64&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===DriverToCommand.gs File Listing===&lt;br /&gt;
 //&lt;br /&gt;
 // DriverToCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToScheduleCommand.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver command that allows a driver character to take a train either to a destination industry&lt;br /&gt;
 // or a specific track in a destination industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToCommand isclass DriverCommand&lt;br /&gt;
 {&lt;br /&gt;
    //&lt;br /&gt;
    // Initialize parent object and add handlers to process messages for this driver command object.&lt;br /&gt;
    //&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
       inherited(asset);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustry&amp;quot;, null, &amp;quot;DriveTo&amp;quot;);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustryTrack&amp;quot;, null,&amp;quot;DriveToTrack&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Adds industry destination menu items for all industries to the given menu along with submenus of&lt;br /&gt;
    // destination tracks for all industries added.&lt;br /&gt;
    //&lt;br /&gt;
    public void AddCommandMenuItem(DriverCharacter driver,Menu menu)&lt;br /&gt;
    {&lt;br /&gt;
       Train train;&lt;br /&gt;
       if (driver)&lt;br /&gt;
       {&lt;br /&gt;
          train = driver.GetTrain();&lt;br /&gt;
          if (!train) &lt;br /&gt;
             return;&lt;br /&gt;
       }&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       Menu industriesMenu = Constructors.NewMenu();&lt;br /&gt;
       GameObject[] industryList = World.GetIndustryList();&lt;br /&gt;
       int i, industryCount = industryList.size();&lt;br /&gt;
       if (!industryCount)&lt;br /&gt;
          // we dont bother with a `Drive To&#039; command if there are no industries&lt;br /&gt;
          return;&lt;br /&gt;
       for (i = 0; i &amp;lt; industryCount; i++)&lt;br /&gt;
       {&lt;br /&gt;
          Industry industry = cast&amp;lt;Industry&amp;gt;(industryList[i]);&lt;br /&gt;
          string localisedName = industry.GetLocalisedName();&lt;br /&gt;
          string[] locationNames = new string[0];&lt;br /&gt;
          string[] locationTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(locationNames,locationTracks);&lt;br /&gt;
          if (localisedName.size())&lt;br /&gt;
             if (locationNames.size())&lt;br /&gt;
             {&lt;br /&gt;
                Menu submenu = Constructors.NewMenu();&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; locationNames.size(); j++)&lt;br /&gt;
                if (locationNames[j] and locationNames[j].size() and locationTracks[j] and locationTracks[j].size())&lt;br /&gt;
                   submenu.AddItem(locationNames[j], me, &amp;quot;DriveToIndustryTrack&amp;quot;, industry.GetId() + &amp;quot; &amp;quot; + locationTracks[j]);&lt;br /&gt;
                else &lt;br /&gt;
                   if (train)&lt;br /&gt;
                      train.Exception(&amp;quot;Error in `track names&#039; of industry `&amp;quot; + localisedName + &amp;quot;&#039;&amp;quot;);&lt;br /&gt;
                industriesMenu.AddSubmenu(localisedName + &amp;quot; &amp;gt;&amp;quot;,submenu);&lt;br /&gt;
             }&lt;br /&gt;
             else&lt;br /&gt;
                industriesMenu.AddItem(localisedName, me,&amp;quot;DriveToIndustry&amp;quot;, industry.GetName());&lt;br /&gt;
          industriesMenu.SubdivideItems();&lt;br /&gt;
          menu.AddSubmenu(strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + &amp;quot; &amp;gt;&amp;quot;, industriesMenu);&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Called by either DriveTo() or DriveToTrack() to play one of  random driver acknowledgments.&lt;br /&gt;
    //&lt;br /&gt;
    void PlayConfirmation(void)&lt;br /&gt;
    {&lt;br /&gt;
       KUID kuid = GetAsset().LookupKUIDTable(&amp;quot;command-sounds&amp;quot;);&lt;br /&gt;
       Library libCommandSounds = World.GetLibrary(kuid);&lt;br /&gt;
       if (libCommandSounds)&lt;br /&gt;
          libCommandSounds.LibraryCall(&amp;quot;PlayConfirmation&amp;quot;,null, null);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Create the schedule command&lt;br /&gt;
    //&lt;br /&gt;
    DriverScheduleCommand CreateScheduleCommand(DriverCharacter driver, Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       DriveToScheduleCommand cmd = new DriveToScheduleCommand();&lt;br /&gt;
       cmd.Init(driver, me);&lt;br /&gt;
       cmd.SetParent(me);&lt;br /&gt;
       cmd.SetProperties(soup);&lt;br /&gt;
       return cast&amp;lt;DriverScheduleCommand&amp;gt;cmd;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to an industry (no specific destination track though).&lt;br /&gt;
    //&lt;br /&gt;
    void DriveTo(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string industryName = msg.minor;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to a specific track in an industry.&lt;br /&gt;
    //&lt;br /&gt;
    void DriveToTrack(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string msgData = msg.minor;&lt;br /&gt;
       int industryId = Str.UnpackInt(msgData);&lt;br /&gt;
       string trackName = Str.UnpackString(msgData);&lt;br /&gt;
       GameObject industry = Router.GetGameObject(industryId);&lt;br /&gt;
       if (!industry) return;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industry.GetName());&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
And the dependent script&lt;br /&gt;
&lt;br /&gt;
===DriveToScheduleCommand.gs File Fisting===&lt;br /&gt;
 //&lt;br /&gt;
 // DriveToScheduleCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Schedule.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver schedule command used by DriveToCommand to get a driver character to take a train to&lt;br /&gt;
 // a specific track on an industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToScheduleCommand isclass DriverScheduleCommand&lt;br /&gt;
 {&lt;br /&gt;
    public string industryName;   // Name of the industry to drive to.&lt;br /&gt;
    public string trackName;      // Name of the track in the industry to drive to.&lt;br /&gt;
    DriveToCommand parent;&lt;br /&gt;
&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetParent(DriveToCommand newParent)&lt;br /&gt;
    {&lt;br /&gt;
       parent = newParent;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //&lt;br /&gt;
    // Starts executing this schedule command on the given driver character.&lt;br /&gt;
    //&lt;br /&gt;
    public bool BeginExecute(DriverCharacter driver)&lt;br /&gt;
    {&lt;br /&gt;
       Train train = driver.GetTrain();&lt;br /&gt;
       if (!train)&lt;br /&gt;
          // cant drive if we dont have a train&lt;br /&gt;
          return false;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (!industry)&lt;br /&gt;
          // cant drive to an industry which doesn&#039;t exist&lt;br /&gt;
          return false;&lt;br /&gt;
       return driver.NavigateToIndustry(industry, trackName);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // we should really implement EndExecute() to allow the game to determine the success of this command&lt;br /&gt;
    //&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Provides an icon for this command so it can be seen on the driver&#039;s schedule. Uses the industry&lt;br /&gt;
    // icon to indicate the destination.&lt;br /&gt;
    //&lt;br /&gt;
    public object GetIcon(void)&lt;br /&gt;
    {&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       return cast&amp;lt;object&amp;gt;industry;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public string GetTooltip(void)&lt;br /&gt;
    {&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       string userTrackName = trackName;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (industry)&lt;br /&gt;
       {&lt;br /&gt;
          string[] destNames = new string[0];&lt;br /&gt;
          string[] destTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(destNames,destTracks);&lt;br /&gt;
          int i;&lt;br /&gt;
          for (i = 0; i &amp;lt; destNames.size(); i++)&lt;br /&gt;
          {&lt;br /&gt;
             if (destTracks[i] == trackName)&lt;br /&gt;
             {&lt;br /&gt;
                userTrackName = destNames[i];&lt;br /&gt;
                break;&lt;br /&gt;
             }&lt;br /&gt;
          }&lt;br /&gt;
       }&lt;br /&gt;
       return strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + industryName + &amp;quot; (&amp;quot; + userTrackName + &amp;quot;)&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public Soup GetProperties(void)&lt;br /&gt;
    {&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       // Save support&lt;br /&gt;
       // Save the properties to the soup, then return the soup&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       return soup;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetProperties(Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       // Load support&lt;br /&gt;
       // Setup the properties from the passed in soup&lt;br /&gt;
       industryName = soup.GetNamedTag(&amp;quot;industryName&amp;quot;);&lt;br /&gt;
       trackName = soup.GetNamedTag(&amp;quot;trackName&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
===Download this asset===&lt;br /&gt;
This asset is available for download from the TRS2006 website at:&lt;br /&gt;
&lt;br /&gt;
Sorry, no download available.&lt;br /&gt;
&lt;br /&gt;
A version of this asset is a &#039;&#039;built-in&#039;&#039; for TS2010, TS12. &lt;br /&gt;
&lt;br /&gt;
==Return to CCG Index==&lt;br /&gt;
[[Content Creator&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
[[CCG/Kind_Examples|Kind Examples]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44134</id>
		<title>CCG/Example: DriverCommand</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44134"/>
		<updated>2025-02-15T17:14:25Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* DriverToCommand.gs File Listing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Driver-Command==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Directory Structure===&lt;br /&gt;
A typical asset of this kind has the following File\Directory Structure:&lt;br /&gt;
&lt;br /&gt;
[[Image:CCG_driver_command_dir1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Required Files===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;config.txt&#039;&#039;&#039; - The config file for the asset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;thumb.jpg&#039;&#039;&#039; - The thumbnail image for this asset. A 240x180 jpeg.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.texture.txt&#039;&#039;&#039; - The texture.txt file. See the section on [[Texture_file|Texture.txt]] files for more information.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.tga&#039;&#039;&#039; - The texture file for the drivercommand icon.&lt;br /&gt;
&lt;br /&gt;
[[Image:example_driveto.jpg]] shows image and alpha channel for 64x64 pixel TGA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetocommand.gs&#039;&#039;&#039; - The trainz script file referenced in the config.txt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetoschedulecommand.gs&#039;&#039;&#039; - A trainz script file which is a dependency of &amp;quot;drivercommand.gs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Config.txt File Listing===&lt;br /&gt;
 kuid                           &amp;lt;kuid:56113:1268&amp;gt;&lt;br /&gt;
 trainz-build                   2.5&lt;br /&gt;
 category-class                 &amp;quot;YD&amp;quot;&lt;br /&gt;
 category-region                &amp;quot;00&amp;quot;&lt;br /&gt;
 category-era                   &amp;quot;1800s;1810s;1820s&amp;quot;&lt;br /&gt;
 username                       &amp;quot;testDriverCommand&amp;quot;&lt;br /&gt;
 kind                           &amp;quot;drivercommand&amp;quot;&lt;br /&gt;
 supports-null-driver-character  1&lt;br /&gt;
 script                          &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 class                           &amp;quot;DriveToCommand&amp;quot;&lt;br /&gt;
 description                     &amp;quot;Test command. This does the same thing as `Drive To&#039;.&amp;quot;&lt;br /&gt;
 string-table&lt;br /&gt;
 {&lt;br /&gt;
   description                   &amp;quot;Allows a driver character to take a train either to a &lt;br /&gt;
                                   destination industry or a specific track in a destination industry.&amp;quot;&lt;br /&gt;
   driver_command_drive_to       &amp;quot;Drive To &amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 kuid-table&lt;br /&gt;
 {&lt;br /&gt;
   command-sounds                &amp;lt;kuid:-3:10219&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
 thumbnails&lt;br /&gt;
 {&lt;br /&gt;
   0&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;thumb.jpg&amp;quot;&lt;br /&gt;
       width                     240&lt;br /&gt;
       height                    180&lt;br /&gt;
     }&lt;br /&gt;
   1&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;driveto.tga&amp;quot;&lt;br /&gt;
       width                     64&lt;br /&gt;
       height                    64&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===DriverToCommand.gs File Listing===&lt;br /&gt;
 //&lt;br /&gt;
 // DriverToCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToScheduleCommand.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver command that allows a driver character to take a train either to a destination industry&lt;br /&gt;
 // or a specific track in a destination industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToCommand isclass DriverCommand&lt;br /&gt;
 {&lt;br /&gt;
    //&lt;br /&gt;
    // Initialize parent object and add handlers to process messages for this driver command object.&lt;br /&gt;
    //&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
       inherited(asset);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustry&amp;quot;, null, &amp;quot;DriveTo&amp;quot;);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustryTrack&amp;quot;, null,&amp;quot;DriveToTrack&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Adds industry destination menu items for all industries to the given menu along with submenus of&lt;br /&gt;
    // destination tracks for all industries added.&lt;br /&gt;
    //&lt;br /&gt;
    public void AddCommandMenuItem(DriverCharacter driver,Menu menu)&lt;br /&gt;
    {&lt;br /&gt;
       Train train;&lt;br /&gt;
       if (driver)&lt;br /&gt;
       {&lt;br /&gt;
          train = driver.GetTrain();&lt;br /&gt;
          if (!train) &lt;br /&gt;
             return;&lt;br /&gt;
       }&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       Menu industriesMenu = Constructors.NewMenu();&lt;br /&gt;
       GameObject[] industryList = World.GetIndustryList();&lt;br /&gt;
       int i, industryCount = industryList.size();&lt;br /&gt;
       if (!industryCount)&lt;br /&gt;
          // we dont bother with a `Drive To&#039; command if there are no industries&lt;br /&gt;
          return;&lt;br /&gt;
       for (i = 0; i &amp;lt; industryCount; i++)&lt;br /&gt;
       {&lt;br /&gt;
          Industry industry = cast&amp;lt;Industry&amp;gt;(industryList[i]);&lt;br /&gt;
          string localisedName = industry.GetLocalisedName();&lt;br /&gt;
          string[] locationNames = new string[0];&lt;br /&gt;
          string[] locationTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(locationNames,locationTracks);&lt;br /&gt;
          if (localisedName.size())&lt;br /&gt;
             if (locationNames.size())&lt;br /&gt;
             {&lt;br /&gt;
                Menu submenu = Constructors.NewMenu();&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; locationNames.size(); j++)&lt;br /&gt;
                if (locationNames[j] and locationNames[j].size() and locationTracks[j] and locationTracks[j].size())&lt;br /&gt;
                   submenu.AddItem(locationNames[j], me, &amp;quot;DriveToIndustryTrack&amp;quot;, industry.GetId() + &amp;quot; &amp;quot; + locationTracks[j]);&lt;br /&gt;
                else &lt;br /&gt;
                   if (train)&lt;br /&gt;
                      train.Exception(&amp;quot;Error in `track names&#039; of industry `&amp;quot; + localisedName + &amp;quot;&#039;&amp;quot;);&lt;br /&gt;
                industriesMenu.AddSubmenu(localisedName + &amp;quot; &amp;gt;&amp;quot;,submenu);&lt;br /&gt;
             }&lt;br /&gt;
             else&lt;br /&gt;
                industriesMenu.AddItem(localisedName, me,&amp;quot;DriveToIndustry&amp;quot;, industry.GetName());&lt;br /&gt;
          industriesMenu.SubdivideItems();&lt;br /&gt;
          menu.AddSubmenu(strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + &amp;quot; &amp;gt;&amp;quot;, industriesMenu);&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Called by either DriveTo() or DriveToTrack() to play one of  random driver acknowledgments.&lt;br /&gt;
    //&lt;br /&gt;
    void PlayConfirmation(void)&lt;br /&gt;
    {&lt;br /&gt;
       KUID kuid = GetAsset().LookupKUIDTable(&amp;quot;command-sounds&amp;quot;);&lt;br /&gt;
       Library libCommandSounds = World.GetLibrary(kuid);&lt;br /&gt;
       if (libCommandSounds)&lt;br /&gt;
          libCommandSounds.LibraryCall(&amp;quot;PlayConfirmation&amp;quot;,null, null);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Create the schedule command&lt;br /&gt;
    //&lt;br /&gt;
    DriverScheduleCommand CreateScheduleCommand(DriverCharacter driver, Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       DriveToScheduleCommand cmd = new DriveToScheduleCommand();&lt;br /&gt;
       cmd.Init(driver, me);&lt;br /&gt;
       cmd.SetParent(me);&lt;br /&gt;
       cmd.SetProperties(soup);&lt;br /&gt;
       return cast&amp;lt;DriverScheduleCommand&amp;gt;cmd;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to an industry (no specific destination track though).&lt;br /&gt;
    //&lt;br /&gt;
    void DriveTo(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string industryName = msg.minor;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to a specific track in an industry.&lt;br /&gt;
    //&lt;br /&gt;
    void DriveToTrack(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string msgData = msg.minor;&lt;br /&gt;
       int industryId = Str.UnpackInt(msgData);&lt;br /&gt;
       string trackName = Str.UnpackString(msgData);&lt;br /&gt;
       GameObject industry = Router.GetGameObject(industryId);&lt;br /&gt;
       if (!industry) return;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industry.GetName());&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
And the dependent script&lt;br /&gt;
&lt;br /&gt;
===DriveToScheduleCommand.gs File Fisting===&lt;br /&gt;
 //&lt;br /&gt;
 // DriveToScheduleCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Schedule.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver schedule command used by DriveToCommand to get a driver character to take a train to&lt;br /&gt;
 // a specific track on an industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToScheduleCommand isclass DriverScheduleCommand&lt;br /&gt;
 {&lt;br /&gt;
    public string industryName;   // Name of the industry to drive to.&lt;br /&gt;
    public string trackName;      // Name of the track in the industry to drive to.&lt;br /&gt;
    DriveToCommand parent;&lt;br /&gt;
&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetParent(DriveToCommand newParent)&lt;br /&gt;
    {&lt;br /&gt;
       parent = newParent;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //&lt;br /&gt;
    // Starts executing this schedule command on the given driver character.&lt;br /&gt;
    //&lt;br /&gt;
    public bool BeginExecute(DriverCharacter driver)&lt;br /&gt;
    {&lt;br /&gt;
       Train train = driver.GetTrain();&lt;br /&gt;
       if (!train)&lt;br /&gt;
          // cant drive if we dont have a train&lt;br /&gt;
          return false;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (!industry)&lt;br /&gt;
          // cant drive to an industry which doesn&#039;t exist&lt;br /&gt;
          return false;&lt;br /&gt;
       return driver.NavigateToIndustry(industry, trackName);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // we should really implement EndExecute() to allow the game to determine the success of this command&lt;br /&gt;
    //&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Provides an icon for this command so it can be seen on the driver&#039;s schedule. Uses the industry&lt;br /&gt;
    // icon to indicate the destination.&lt;br /&gt;
    //&lt;br /&gt;
    public object GetIcon(void)&lt;br /&gt;
    {&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       return cast&amp;lt;object&amp;gt;industry;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public string GetTooltip(void)&lt;br /&gt;
    {&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       string userTrackName = trackName;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (industry)&lt;br /&gt;
       {&lt;br /&gt;
          string[] destNames = new string[0];&lt;br /&gt;
          string[] destTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(destNames,destTracks);&lt;br /&gt;
          int i;&lt;br /&gt;
          for (i = 0; i &amp;lt; destNames.size(); i++)&lt;br /&gt;
          {&lt;br /&gt;
             if (destTracks[i] == trackName)&lt;br /&gt;
             {&lt;br /&gt;
                userTrackName = destNames[i];&lt;br /&gt;
                break;&lt;br /&gt;
             }&lt;br /&gt;
          }&lt;br /&gt;
       }&lt;br /&gt;
       return strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + industryName + &amp;quot; (&amp;quot; + userTrackName + &amp;quot;)&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public Soup GetProperties(void)&lt;br /&gt;
    {&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       // Save support&lt;br /&gt;
       // Save the properties to the soup, then return the soup&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       return soup;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetProperties(Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       // Load support&lt;br /&gt;
       // Setup the properties from the passed in soup&lt;br /&gt;
       industryName = soup.GetNamedTag(&amp;quot;industryName&amp;quot;);&lt;br /&gt;
       trackName = soup.GetNamedTag(&amp;quot;trackName&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
===Download this asset===&lt;br /&gt;
This asset is available for download from the TRS2006 website at:&lt;br /&gt;
&lt;br /&gt;
Sorry, no download available.&lt;br /&gt;
&lt;br /&gt;
A version of this asset is a &#039;&#039;built-in&#039;&#039; for TS2010, TS12. &lt;br /&gt;
&lt;br /&gt;
==Return to CCG Index==&lt;br /&gt;
[[Content Creator&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
[[CCG/Kind_Examples|Kind Examples]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44133</id>
		<title>CCG/Example: DriverCommand</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=CCG/Example:_DriverCommand&amp;diff=44133"/>
		<updated>2025-02-15T17:10:27Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Driver-Command==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Directory Structure===&lt;br /&gt;
A typical asset of this kind has the following File\Directory Structure:&lt;br /&gt;
&lt;br /&gt;
[[Image:CCG_driver_command_dir1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Required Files===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;config.txt&#039;&#039;&#039; - The config file for the asset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;thumb.jpg&#039;&#039;&#039; - The thumbnail image for this asset. A 240x180 jpeg.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.texture.txt&#039;&#039;&#039; - The texture.txt file. See the section on [[Texture_file|Texture.txt]] files for more information.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;driveto.tga&#039;&#039;&#039; - The texture file for the drivercommand icon.&lt;br /&gt;
&lt;br /&gt;
[[Image:example_driveto.jpg]] shows image and alpha channel for 64x64 pixel TGA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetocommand.gs&#039;&#039;&#039; - The trainz script file referenced in the config.txt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;drivetoschedulecommand.gs&#039;&#039;&#039; - A trainz script file which is a dependency of &amp;quot;drivercommand.gs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Config.txt File Listing===&lt;br /&gt;
 kuid                           &amp;lt;kuid:56113:1268&amp;gt;&lt;br /&gt;
 trainz-build                   2.5&lt;br /&gt;
 category-class                 &amp;quot;YD&amp;quot;&lt;br /&gt;
 category-region                &amp;quot;00&amp;quot;&lt;br /&gt;
 category-era                   &amp;quot;1800s;1810s;1820s&amp;quot;&lt;br /&gt;
 username                       &amp;quot;testDriverCommand&amp;quot;&lt;br /&gt;
 kind                           &amp;quot;drivercommand&amp;quot;&lt;br /&gt;
 supports-null-driver-character  1&lt;br /&gt;
 script                          &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 class                           &amp;quot;DriveToCommand&amp;quot;&lt;br /&gt;
 description                     &amp;quot;Test command. This does the same thing as `Drive To&#039;.&amp;quot;&lt;br /&gt;
 string-table&lt;br /&gt;
 {&lt;br /&gt;
   description                   &amp;quot;Allows a driver character to take a train either to a &lt;br /&gt;
                                   destination industry or a specific track in a destination industry.&amp;quot;&lt;br /&gt;
   driver_command_drive_to       &amp;quot;Drive To &amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 kuid-table&lt;br /&gt;
 {&lt;br /&gt;
   command-sounds                &amp;lt;kuid:-3:10219&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
 thumbnails&lt;br /&gt;
 {&lt;br /&gt;
   0&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;thumb.jpg&amp;quot;&lt;br /&gt;
       width                     240&lt;br /&gt;
       height                    180&lt;br /&gt;
     }&lt;br /&gt;
   1&lt;br /&gt;
     {&lt;br /&gt;
       image                     &amp;quot;driveto.tga&amp;quot;&lt;br /&gt;
       width                     64&lt;br /&gt;
       height                    64&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===DriverToCommand.gs File Listing===&lt;br /&gt;
 //&lt;br /&gt;
 // DriverToCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToScheduleCommand.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver command that allows a driver character to take a train either to a destination industry&lt;br /&gt;
 // or a specific track in a destination industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToCommand isclass DriverCommand&lt;br /&gt;
 {&lt;br /&gt;
    //&lt;br /&gt;
    // Initialize parent object and add handlers to process messages for this driver command object.&lt;br /&gt;
    //&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
       inherited(asset);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustry&amp;quot;, null, &amp;quot;DriveTo&amp;quot;);&lt;br /&gt;
       AddHandler(me, &amp;quot;DriveToIndustryTrack&amp;quot;, null,&amp;quot;DriveToTrack&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Adds industry destination menu items for all industries to the given menu along with submenus of&lt;br /&gt;
    // destination tracks for all industries added.&lt;br /&gt;
    //&lt;br /&gt;
    public void AddCommandMenuItem(DriverCharacter driver,Menu menu)&lt;br /&gt;
    {&lt;br /&gt;
       Train train;&lt;br /&gt;
       if (driver)&lt;br /&gt;
       {&lt;br /&gt;
          train = driver.GetTrain();&lt;br /&gt;
          if (!train) &lt;br /&gt;
             return;&lt;br /&gt;
       }&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       Menu industriesMenu = Constructors.NewMenu();&lt;br /&gt;
       GameObject[] industryList = World.GetIndustryList();&lt;br /&gt;
       int i, industryCount = industryList.size();&lt;br /&gt;
       if (!industryCount)&lt;br /&gt;
          // we dont bother with a `Drive To&#039; command if there are no industries&lt;br /&gt;
          return;&lt;br /&gt;
       for (i = 0; i &amp;lt; industryCount; i++)&lt;br /&gt;
       {&lt;br /&gt;
          Industry industry = cast&amp;lt;Industry&amp;gt;(industryList[i]);&lt;br /&gt;
          string localisedName = industry.GetLocalisedName();&lt;br /&gt;
          string[] locationNames = new string[0];&lt;br /&gt;
          string[] locationTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(locationNames,locationTracks);&lt;br /&gt;
          if (localisedName.size())&lt;br /&gt;
             if (locationNames.size())&lt;br /&gt;
             {&lt;br /&gt;
                Menu submenu = Constructors.NewMenu();&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; locationNames.size(); j++)&lt;br /&gt;
                if (locationNames[j] and locationNames[j].size() and locationTracks[j] and locationTracks[j].size())&lt;br /&gt;
                   submenu.AddItem(locationNames[j], me, &amp;quot;DriveToIndustryTrack&amp;quot;, industry.GetId() + &amp;quot; &amp;quot; + locationTracks[j]);&lt;br /&gt;
                else &lt;br /&gt;
                   if (train)&lt;br /&gt;
                      train.Exception(&amp;quot;Error in `track names&#039; of industry `&amp;quot; + localisedName + &amp;quot;&#039;&amp;quot;);&lt;br /&gt;
                industriesMenu.AddSubmenu(localisedName + &amp;quot; &amp;gt;&amp;quot;,submenu);&lt;br /&gt;
             }&lt;br /&gt;
             else&lt;br /&gt;
                industriesMenu.AddItem(localisedName, me,&amp;quot;DriveToIndustry&amp;quot;, industry.GetName());&lt;br /&gt;
          }&lt;br /&gt;
          industriesMenu.SubdivideItems();&lt;br /&gt;
          menu.AddSubmenu(strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + &amp;quot; &amp;gt;&amp;quot;, industriesMenu);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Called by either DriveTo() or DriveToTrack() to play one of  random driver acknowledgments.&lt;br /&gt;
    //&lt;br /&gt;
    void PlayConfirmation(void)&lt;br /&gt;
    {&lt;br /&gt;
       KUID kuid = GetAsset().LookupKUIDTable(&amp;quot;command-sounds&amp;quot;);&lt;br /&gt;
       Library libCommandSounds = World.GetLibrary(kuid);&lt;br /&gt;
       if (libCommandSounds)&lt;br /&gt;
          libCommandSounds.LibraryCall(&amp;quot;PlayConfirmation&amp;quot;,null, null);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Create the schedule command&lt;br /&gt;
    //&lt;br /&gt;
    DriverScheduleCommand CreateScheduleCommand(DriverCharacter driver, Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       DriveToScheduleCommand cmd = new DriveToScheduleCommand();&lt;br /&gt;
       cmd.Init(driver, me);&lt;br /&gt;
       cmd.SetParent(me);&lt;br /&gt;
       cmd.SetProperties(soup);&lt;br /&gt;
       return cast&amp;lt;DriverScheduleCommand&amp;gt;cmd;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to an industry (no specific destination track though).&lt;br /&gt;
    //&lt;br /&gt;
    void DriveTo(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string industryName = msg.minor;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    //&lt;br /&gt;
    // Handler method to drive a train to a specific track in an industry.&lt;br /&gt;
    //&lt;br /&gt;
    void DriveToTrack(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
       DriverCommands commands = GetDriverCommands(msg);&lt;br /&gt;
       DriverCharacter driver = cast&amp;lt;DriverCharacter&amp;gt;(msg.src);&lt;br /&gt;
       string msgData = msg.minor;&lt;br /&gt;
       int industryId = Str.UnpackInt(msgData);&lt;br /&gt;
       string trackName = Str.UnpackString(msgData);&lt;br /&gt;
       GameObject industry = Router.GetGameObject(industryId);&lt;br /&gt;
       if (!industry) return;&lt;br /&gt;
       // schedule our command&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industry.GetName());&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       DriveToScheduleCommand cmd = cast&amp;lt;DriveToScheduleCommand&amp;gt;CreateScheduleCommand(driver, soup);&lt;br /&gt;
       commands.AddDriverScheduleCommand(cmd);&lt;br /&gt;
       if (driver) PlayConfirmation();&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
And the dependent script&lt;br /&gt;
&lt;br /&gt;
===DriveToScheduleCommand.gs File Fisting===&lt;br /&gt;
 //&lt;br /&gt;
 // DriveToScheduleCommand.gs&lt;br /&gt;
 //&lt;br /&gt;
 // Copyright (C) 2003 Auran Developments Pty Ltd&lt;br /&gt;
 // All Rights Reserved.&lt;br /&gt;
 //&lt;br /&gt;
 include &amp;quot;DriverCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;World.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Browser.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;KUID.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Industry.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;DriveToCommand.gs&amp;quot;&lt;br /&gt;
 include &amp;quot;Schedule.gs&amp;quot;&lt;br /&gt;
 //&lt;br /&gt;
 // Driver schedule command used by DriveToCommand to get a driver character to take a train to&lt;br /&gt;
 // a specific track on an industry.&lt;br /&gt;
 //&lt;br /&gt;
 class DriveToScheduleCommand isclass DriverScheduleCommand&lt;br /&gt;
 {&lt;br /&gt;
    public string industryName;   // Name of the industry to drive to.&lt;br /&gt;
    public string trackName;      // Name of the track in the industry to drive to.&lt;br /&gt;
    DriveToCommand parent;&lt;br /&gt;
&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetParent(DriveToCommand newParent)&lt;br /&gt;
    {&lt;br /&gt;
       parent = newParent;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //&lt;br /&gt;
    // Starts executing this schedule command on the given driver character.&lt;br /&gt;
    //&lt;br /&gt;
    public bool BeginExecute(DriverCharacter driver)&lt;br /&gt;
    {&lt;br /&gt;
       Train train = driver.GetTrain();&lt;br /&gt;
       if (!train)&lt;br /&gt;
          // cant drive if we dont have a train&lt;br /&gt;
          return false;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (!industry)&lt;br /&gt;
          // cant drive to an industry which doesn&#039;t exist&lt;br /&gt;
          return false;&lt;br /&gt;
       return driver.NavigateToIndustry(industry, trackName);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // we should really implement EndExecute() to allow the game to determine the success of this command&lt;br /&gt;
    //&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    // Provides an icon for this command so it can be seen on the driver&#039;s schedule. Uses the industry&lt;br /&gt;
    // icon to indicate the destination.&lt;br /&gt;
    //&lt;br /&gt;
    public object GetIcon(void)&lt;br /&gt;
    {&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       return cast&amp;lt;object&amp;gt;industry;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public string GetTooltip(void)&lt;br /&gt;
    {&lt;br /&gt;
       StringTable strTable = GetAsset().GetStringTable();&lt;br /&gt;
       string userTrackName = trackName;&lt;br /&gt;
       Industry industry = cast&amp;lt;Industry&amp;gt;(Router.GetGameObject(industryName));&lt;br /&gt;
       if (industry)&lt;br /&gt;
       {&lt;br /&gt;
          string[] destNames = new string[0];&lt;br /&gt;
          string[] destTracks = new string[0];&lt;br /&gt;
          industry.AppendDriverDestinations(destNames,destTracks);&lt;br /&gt;
          int i;&lt;br /&gt;
          for (i = 0; i &amp;lt; destNames.size(); i++)&lt;br /&gt;
          {&lt;br /&gt;
             if (destTracks[i] == trackName)&lt;br /&gt;
             {&lt;br /&gt;
                userTrackName = destNames[i];&lt;br /&gt;
                break;&lt;br /&gt;
             }&lt;br /&gt;
          }&lt;br /&gt;
       }&lt;br /&gt;
       return strTable.GetString(&amp;quot;driver_command_drive_to&amp;quot;) + industryName + &amp;quot; (&amp;quot; + userTrackName + &amp;quot;)&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public Soup GetProperties(void)&lt;br /&gt;
    {&lt;br /&gt;
       Soup soup = Constructors.NewSoup();&lt;br /&gt;
       // Save support&lt;br /&gt;
       // Save the properties to the soup, then return the soup&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;industryName&amp;quot;, industryName);&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;trackName&amp;quot;, trackName);&lt;br /&gt;
       return soup;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    //&lt;br /&gt;
    public void SetProperties(Soup soup)&lt;br /&gt;
    {&lt;br /&gt;
       // Load support&lt;br /&gt;
       // Setup the properties from the passed in soup&lt;br /&gt;
       industryName = soup.GetNamedTag(&amp;quot;industryName&amp;quot;);&lt;br /&gt;
       trackName = soup.GetNamedTag(&amp;quot;trackName&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
===Download this asset===&lt;br /&gt;
This asset is available for download from the TRS2006 website at:&lt;br /&gt;
&lt;br /&gt;
Sorry, no download available.&lt;br /&gt;
&lt;br /&gt;
A version of this asset is a &#039;&#039;built-in&#039;&#039; for TS2010, TS12. &lt;br /&gt;
&lt;br /&gt;
==Return to CCG Index==&lt;br /&gt;
[[Content Creator&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
[[CCG/Kind_Examples|Kind Examples]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=CCG/DriverCommand&amp;diff=44132</id>
		<title>CCG/DriverCommand</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=CCG/DriverCommand&amp;diff=44132"/>
		<updated>2025-02-15T12:22:44Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==KIND: DRIVERCOMMAND==&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
&lt;br /&gt;
A command for the train driver to accomplish a specific task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Container Structure===&lt;br /&gt;
&lt;br /&gt;
A well formed drivercommand kind has the following container structure:&lt;br /&gt;
&lt;br /&gt;
[[Image:CCG_drivercommand_dir.jpg]]&lt;br /&gt;
&lt;br /&gt;
See Chapter 7 for an example asset of this kind. [??LINK??]&lt;br /&gt;
&lt;br /&gt;
See Example [[CCG/Example:_DriverCommand|CCG Example DriverCommand]]&lt;br /&gt;
&lt;br /&gt;
A TYPICAL ASSET OF THIS KIND MAY HAVE THE FOLLOWING TAGS:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;kind                            &#039;&#039;&amp;quot;drivercommand&amp;quot;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
 kuid                            &#039;&#039;kuid&#039;&#039;&lt;br /&gt;
 trainz-build                    &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-class                  &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-region                 &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-era                    &#039;&#039;data&#039;&#039;&lt;br /&gt;
 username                        &#039;&#039;data&#039;&#039;&lt;br /&gt;
 supports-null-driver-character  &#039;&#039;data&#039;&#039;&lt;br /&gt;
 class                           &#039;&#039;data&#039;&#039;&lt;br /&gt;
 script                          &#039;&#039;data&#039;&#039;&lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;thumbnails&amp;lt;/font&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;0&amp;lt;/font&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
   image                         &#039;&#039;file&#039;&#039;&lt;br /&gt;
   width                         &#039;&#039;data&#039;&#039;&lt;br /&gt;
   height                        &#039;&#039;data&#039;&#039;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===TAGS AND CONTAINERS===&lt;br /&gt;
&lt;br /&gt;
The following tags are further defined in Chapter 5:&lt;br /&gt;
&lt;br /&gt;
;kuid&lt;br /&gt;
:Generated automatically by CCP.&lt;br /&gt;
&lt;br /&gt;
;trainz-build&lt;br /&gt;
:Automatically set to 2.9 for 2009 assets.&lt;br /&gt;
&lt;br /&gt;
;category-class&lt;br /&gt;
:Should be &amp;quot;YD&amp;quot; - Driver Command. See the &amp;quot;Maps &amp;amp; Scenarios&amp;quot; section of [[Category Class]].&lt;br /&gt;
&lt;br /&gt;
;category-region&lt;br /&gt;
:See [[Category Region]] for a list of valid category-region values.&lt;br /&gt;
&lt;br /&gt;
;category-era&lt;br /&gt;
:See [[Category Era]] for a list of valid category-era values.&lt;br /&gt;
&lt;br /&gt;
;username&lt;br /&gt;
:Asset username. This will be the name that appears in the driver menu.&lt;br /&gt;
&lt;br /&gt;
;kind&lt;br /&gt;
:Must be &amp;quot;drivercommand&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
;class&lt;br /&gt;
:The name of the scenario class within the script file.&lt;br /&gt;
&lt;br /&gt;
;script&lt;br /&gt;
:The script file (gs or gse file).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Additional Tags===&lt;br /&gt;
&lt;br /&gt;
;supports-null-driver-character&lt;br /&gt;
:Command can be executed without a driver present in the selected loco.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===THIS KIND SUPPORTS THE FOLLOWING:===&lt;br /&gt;
&lt;br /&gt;
;CONTAINERS&lt;br /&gt;
:String Table, Chinese String Table, Czech String Table, Dutch String Table, French String Table, German String Table, Italian String Table, Polish String Table, Russian String Table, Spanish String Table, KUID Table, Obsolete Table, Thumbnails, Privileges, Extensions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;TAGS&lt;br /&gt;
:kuid, trainz-build, category-class, category-region, category-era, username, kind, supports-null-driver-character, author, category-keyword, class, contact-email, contact-website, description, description-cn, description-cz, description-de, description-es, description-fr, description-it, description-pl, description-nl, description-ru, license, organisation, script, username-cn, username-cz, username-de, username-es, username-fr, username-it, username-nl, username-pl, username-ru.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Return to CCG Index==&lt;br /&gt;
[[Content Creator&#039;s Guide]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=CCG/DriverCommand&amp;diff=44131</id>
		<title>CCG/DriverCommand</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=CCG/DriverCommand&amp;diff=44131"/>
		<updated>2025-02-15T12:21:30Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==KIND: DRIVERCOMMAND==&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
&lt;br /&gt;
A command for the train driver to accomplish a specific task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Container Structure===&lt;br /&gt;
&lt;br /&gt;
A well formed drivercommand kind has the following container structure:&lt;br /&gt;
&lt;br /&gt;
[[Image:CCG_drivercommand_dir.jpg]]&lt;br /&gt;
&lt;br /&gt;
See Chapter 7 for an example asset of this kind. [??LINK??]&lt;br /&gt;
&lt;br /&gt;
See Example [[CCG/Example:_DriverCommand|CCG Example DriverCommand]]&lt;br /&gt;
&lt;br /&gt;
A TYPICAL ASSET OF THIS KIND MAY HAVE THE FOLLOWING TAGS:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;kind                            &#039;&#039;&amp;quot;drivercommand&amp;quot;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
 kuid                            &#039;&#039;kuid&#039;&#039;&lt;br /&gt;
 trainz-build                    &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-class                  &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-region                 &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-era                    &#039;&#039;data&#039;&#039;&lt;br /&gt;
 username                        &#039;&#039;data&#039;&#039;&lt;br /&gt;
 supports-null-driver-character  &#039;&#039;data&#039;&#039;&lt;br /&gt;
 class                           &#039;&#039;data&#039;&#039;&lt;br /&gt;
 script                          &#039;&#039;data&#039;&#039;&lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;thumbnails&amp;lt;/font&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;0&amp;lt;/font&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
   image                           &#039;&#039;file&#039;&#039;&lt;br /&gt;
   width                           &#039;&#039;data&#039;&#039;&lt;br /&gt;
   height                          &#039;&#039;data&#039;&#039;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===TAGS AND CONTAINERS===&lt;br /&gt;
&lt;br /&gt;
The following tags are further defined in Chapter 5:&lt;br /&gt;
&lt;br /&gt;
;kuid&lt;br /&gt;
:Generated automatically by CCP.&lt;br /&gt;
&lt;br /&gt;
;trainz-build&lt;br /&gt;
:Automatically set to 2.9 for 2009 assets.&lt;br /&gt;
&lt;br /&gt;
;category-class&lt;br /&gt;
:Should be &amp;quot;YD&amp;quot; - Driver Command. See the &amp;quot;Maps &amp;amp; Scenarios&amp;quot; section of [[Category Class]].&lt;br /&gt;
&lt;br /&gt;
;category-region&lt;br /&gt;
:See [[Category Region]] for a list of valid category-region values.&lt;br /&gt;
&lt;br /&gt;
;category-era&lt;br /&gt;
:See [[Category Era]] for a list of valid category-era values.&lt;br /&gt;
&lt;br /&gt;
;username&lt;br /&gt;
:Asset username. This will be the name that appears in the driver menu.&lt;br /&gt;
&lt;br /&gt;
;kind&lt;br /&gt;
:Must be &amp;quot;drivercommand&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
;class&lt;br /&gt;
:The name of the scenario class within the script file.&lt;br /&gt;
&lt;br /&gt;
;script&lt;br /&gt;
:The script file (gs or gse file).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Additional Tags===&lt;br /&gt;
&lt;br /&gt;
;supports-null-driver-character&lt;br /&gt;
:Command can be executed without a driver present in the selected loco.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===THIS KIND SUPPORTS THE FOLLOWING:===&lt;br /&gt;
&lt;br /&gt;
;CONTAINERS&lt;br /&gt;
:String Table, Chinese String Table, Czech String Table, Dutch String Table, French String Table, German String Table, Italian String Table, Polish String Table, Russian String Table, Spanish String Table, KUID Table, Obsolete Table, Thumbnails, Privileges, Extensions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;TAGS&lt;br /&gt;
:kuid, trainz-build, category-class, category-region, category-era, username, kind, supports-null-driver-character, author, category-keyword, class, contact-email, contact-website, description, description-cn, description-cz, description-de, description-es, description-fr, description-it, description-pl, description-nl, description-ru, license, organisation, script, username-cn, username-cz, username-de, username-es, username-fr, username-it, username-nl, username-pl, username-ru.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Return to CCG Index==&lt;br /&gt;
[[Content Creator&#039;s Guide]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=CCG/DriverCommand&amp;diff=44130</id>
		<title>CCG/DriverCommand</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=CCG/DriverCommand&amp;diff=44130"/>
		<updated>2025-02-15T12:17:53Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==KIND: DRIVERCOMMAND==&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
&lt;br /&gt;
A command for the train driver to accomplish a specific task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Container Structure===&lt;br /&gt;
&lt;br /&gt;
A well formed drivercommand kind has the following container structure:&lt;br /&gt;
&lt;br /&gt;
[[Image:CCG_drivercommand_dir.jpg]]&lt;br /&gt;
&lt;br /&gt;
See Chapter 7 for an example asset of this kind. [??LINK??]&lt;br /&gt;
&lt;br /&gt;
See Example [[CCG/Example:_DriverCommand|CCG Example DriverCommand]]&lt;br /&gt;
&lt;br /&gt;
A TYPICAL ASSET OF THIS KIND MAY HAVE THE FOLLOWING TAGS:&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&lt;br /&gt;
 kind                            &#039;&#039;&amp;quot;drivercommand&amp;quot;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
 kuid                            &#039;&#039;kuid&#039;&#039;&lt;br /&gt;
 trainz-build                    &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-class                  &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-region                 &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-era                    &#039;&#039;data&#039;&#039;&lt;br /&gt;
 username                        &#039;&#039;data&#039;&#039;&lt;br /&gt;
 supports-null-driver-character  &#039;&#039;data&#039;&#039;&lt;br /&gt;
 class                           &#039;&#039;data&#039;&#039;&lt;br /&gt;
 script                          &#039;&#039;data&#039;&#039;&lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;thumbnails&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;0&amp;lt;/font&amp;gt;&lt;br /&gt;
 image                           &#039;&#039;file&#039;&#039;&lt;br /&gt;
 width                           &#039;&#039;data&#039;&#039;&lt;br /&gt;
 height                          &#039;&#039;data&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===TAGS AND CONTAINERS===&lt;br /&gt;
&lt;br /&gt;
The following tags are further defined in Chapter 5:&lt;br /&gt;
&lt;br /&gt;
;kuid&lt;br /&gt;
:Generated automatically by CCP.&lt;br /&gt;
&lt;br /&gt;
;trainz-build&lt;br /&gt;
:Automatically set to 2.9 for 2009 assets.&lt;br /&gt;
&lt;br /&gt;
;category-class&lt;br /&gt;
:Should be &amp;quot;YD&amp;quot; - Driver Command. See the &amp;quot;Maps &amp;amp; Scenarios&amp;quot; section of [[Category Class]].&lt;br /&gt;
&lt;br /&gt;
;category-region&lt;br /&gt;
:See [[Category Region]] for a list of valid category-region values.&lt;br /&gt;
&lt;br /&gt;
;category-era&lt;br /&gt;
:See [[Category Era]] for a list of valid category-era values.&lt;br /&gt;
&lt;br /&gt;
;username&lt;br /&gt;
:Asset username. This will be the name that appears in the driver menu.&lt;br /&gt;
&lt;br /&gt;
;kind&lt;br /&gt;
:Must be &amp;quot;drivercommand&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
;class&lt;br /&gt;
:The name of the scenario class within the script file.&lt;br /&gt;
&lt;br /&gt;
;script&lt;br /&gt;
:The script file (gs or gse file).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Additional Tags===&lt;br /&gt;
&lt;br /&gt;
;supports-null-driver-character&lt;br /&gt;
:Command can be executed without a driver present in the selected loco.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===THIS KIND SUPPORTS THE FOLLOWING:===&lt;br /&gt;
&lt;br /&gt;
;CONTAINERS&lt;br /&gt;
:String Table, Chinese String Table, Czech String Table, Dutch String Table, French String Table, German String Table, Italian String Table, Polish String Table, Russian String Table, Spanish String Table, KUID Table, Obsolete Table, Thumbnails, Privileges, Extensions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;TAGS&lt;br /&gt;
:kuid, trainz-build, category-class, category-region, category-era, username, kind, supports-null-driver-character, author, category-keyword, class, contact-email, contact-website, description, description-cn, description-cz, description-de, description-es, description-fr, description-it, description-pl, description-nl, description-ru, license, organisation, script, username-cn, username-cz, username-de, username-es, username-fr, username-it, username-nl, username-pl, username-ru.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Return to CCG Index==&lt;br /&gt;
[[Content Creator&#039;s Guide]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=CCG/DriverCommand&amp;diff=44129</id>
		<title>CCG/DriverCommand</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=CCG/DriverCommand&amp;diff=44129"/>
		<updated>2025-02-15T12:12:32Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==KIND: DRIVERCOMMAND==&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
&lt;br /&gt;
A command for the train driver to accomplish a specific task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Container Structure===&lt;br /&gt;
&lt;br /&gt;
A well formed drivercommand kind has the following container structure:&lt;br /&gt;
&lt;br /&gt;
[[Image:CCG_drivercommand_dir.jpg]]&lt;br /&gt;
&lt;br /&gt;
See Chapter 7 for an example asset of this kind. [??LINK??]&lt;br /&gt;
&lt;br /&gt;
See Example [[CCG/Example:_DriverCommand|CCG Example DriverCommand]]&lt;br /&gt;
&lt;br /&gt;
A TYPICAL ASSET OF THIS KIND MAY HAVE THE FOLLOWING TAGS:&lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&lt;br /&gt;
 kind                            &#039;&#039;&amp;quot;drivercommand&amp;quot;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
 kuid                            &#039;&#039;kuid&#039;&#039;&lt;br /&gt;
 trainz-build                    &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-class                  &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-region                 &#039;&#039;data&#039;&#039;&lt;br /&gt;
 category-era                    &#039;&#039;data&#039;&#039;&lt;br /&gt;
 username                        &#039;&#039;data&#039;&#039;&lt;br /&gt;
 supports-null-driver-character  &#039;&#039;data&#039;&#039;&lt;br /&gt;
 class                           &#039;&#039;data&#039;&#039;&lt;br /&gt;
 script                          &#039;&#039;data&#039;&#039;&lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;thumbnails&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;0&amp;lt;/font&amp;gt;&lt;br /&gt;
 image                           &#039;&#039;file&#039;&#039;&lt;br /&gt;
 width                           &#039;&#039;data&#039;&#039;&lt;br /&gt;
 height                          &#039;&#039;data&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===TAGS AND CONTAINERS===&lt;br /&gt;
&lt;br /&gt;
The following tags are further defined in Chapter 5:&lt;br /&gt;
&lt;br /&gt;
;kuid&lt;br /&gt;
:Generated automatically by CCP.&lt;br /&gt;
&lt;br /&gt;
;trainz-build&lt;br /&gt;
:Automatically set to 2.9 for 2009 assets.&lt;br /&gt;
&lt;br /&gt;
;category-class&lt;br /&gt;
:Should be &amp;quot;YD&amp;quot; - Driver Command. See the &amp;quot;Maps &amp;amp; Scenarios&amp;quot; section of [[Category Class]].&lt;br /&gt;
&lt;br /&gt;
;category-region&lt;br /&gt;
:See [[Category Region]] for a list of valid category-region values.&lt;br /&gt;
&lt;br /&gt;
;category-era&lt;br /&gt;
:See [[Category Era]] for a list of valid category-era values.&lt;br /&gt;
&lt;br /&gt;
;username&lt;br /&gt;
:Asset username. This will be the name that appears in the driver menu.&lt;br /&gt;
&lt;br /&gt;
;kind&lt;br /&gt;
:Must be &amp;quot;drivercommand&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
;class&lt;br /&gt;
:The name of the scenario class within the script file.&lt;br /&gt;
&lt;br /&gt;
;script&lt;br /&gt;
:The script file (gs or gse file).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Additional Tags===&lt;br /&gt;
&lt;br /&gt;
;supports-null-driver-character&lt;br /&gt;
:Command can be executed without a driver present in the selected loco.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===THIS KIND SUPPORTS THE FOLLOWING:===&lt;br /&gt;
&lt;br /&gt;
;CONTAINERS&lt;br /&gt;
:String Table, Chinese String Table, Czech String Table, Dutch String Table, French String Table, German String Table, Italian String Table, Polish String Table, Russian String Table, Spanish String Table, KUID Table, Obsolete Table, Thumbnails, Privileges, Extensions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;TAGS&lt;br /&gt;
:kuid, trainz-build, category-class, category-region, category-era, username, kind, supports-null-driver-character, author, category-keyword, class, contact-email, contact-website, description, description-cn, description-cz, description-de, description-es, description-fr, description-it, description-pl, description-nl, description-ru, license, organisation, script, username-cn, username-cz, username-de, username-es, username-fr, username-it, username-nl, username-pl, username-ru.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Return to CCG Index==&lt;br /&gt;
[[Content Creator&#039;s Guide]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Container&amp;diff=41034</id>
		<title>Container</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Container&amp;diff=41034"/>
		<updated>2024-04-28T09:11:49Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* Adding a contaiener to a session */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Container objects==&lt;br /&gt;
===Container types===&lt;br /&gt;
There are ten container types used in the aCTS: 10ftsc, 10fthc, 20ftsc, 20fthc, 40ftsc, 40fthc, 45ftsc, 45fthc and 53ftsc, 53fthc. An aCTS usable container is predefined with its origin at the geometrical middle of the bottom face.&lt;br /&gt;
&lt;br /&gt;
A container knows its container stack and its position in it. A container is able to report its parameter soups, including a yet not used virtual list of content to transport within it.&lt;br /&gt;
&lt;br /&gt;
===Container from other asset builder===&lt;br /&gt;
So the container assets of other asset builders need possibly a variant with config setted position and rotation. Additionally the scale may be needed to set for fitting the technical dimensions. &lt;br /&gt;
All containers that don&#039;t fit the technical dimensions and the logical origin position and rotation have a config extensions sub soup with the name &amp;quot;acts.origindelta-251489&amp;quot; and tags for correcting the assets values to the aCTS fitting ones (accuracy 0.1 mm and 0.1 °), looking like follows:&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  acts.delta-251489 {&lt;br /&gt;
    px.delta    0.0&lt;br /&gt;
    py.delta    0.0&lt;br /&gt;
    pz.delta    0.0&lt;br /&gt;
    rx.delta    0.0&lt;br /&gt;
    ry.delta    0.0&lt;br /&gt;
    rz.delta    0.0&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
The values will be used while calculation the location and orientation to posit them into the world by adding them to the normal calculated values. The adding is meant in positiv directin and ccw.&lt;br /&gt;
&lt;br /&gt;
Unfortunately the scale of the mesh may not be corrected by some factor to fit the aCTS dimensions. So for containers with other dimensions one may see a small gap between stacked containers or they run optical into each other.&lt;br /&gt;
&lt;br /&gt;
===Adding a contaiener to a session===&lt;br /&gt;
One problem with such a complex system as aCTS is, to get things running. Thusfor the dispatcher was implemented. &lt;br /&gt;
&lt;br /&gt;
In case of newly added acts containers while surveyor, the dispatcher gets the task to attach and locate them randomly to a stack. &lt;br /&gt;
  &#039;&#039;&#039;TBD: If this isn&#039;t possible anyway, they will be set inactive and stay, where located by the user.&#039;&#039;&#039;&lt;br /&gt;
  &#039;&#039;&#039;TBD: To flag this to the user, possibly set the shown text effect or mark it with some red arrows or so.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Asset files pre version 0.1==&lt;br /&gt;
The files compile errorless and the messaging runs well. No more functionality implemented and tested in this pre version.&lt;br /&gt;
&lt;br /&gt;
===config.txt===&lt;br /&gt;
XY is the KUID part, LL the length and HH or hh the height for the container type.&lt;br /&gt;
 X   1 for 10ft, 2 for 20ft, 3 for 40ft, 4 for 45ft and 5 for 53ft&lt;br /&gt;
 Y   1 for standard height, 2 for heigh cube height&lt;br /&gt;
 LL  the fitting length as 10, 20, 40, 45, 53&lt;br /&gt;
 hh  the fitting height as sc, hc&lt;br /&gt;
 HH  the fitting height as SC, HC&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  kuid               &amp;lt;Kuid2:215489:11002&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;XY&amp;lt;/span&amp;gt;:1&amp;gt;&lt;br /&gt;
  username           &amp;quot;aCTS CONTAINER &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;HH&amp;lt;/span&amp;gt; Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  kind               &amp;quot;Scenery&amp;quot;&lt;br /&gt;
  category-class     &amp;quot;BU&amp;quot;&lt;br /&gt;
  description        &amp;quot;aCTS CONTAINER &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;HH&amp;lt;/span&amp;gt; Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  trainz-build       4.6&lt;br /&gt;
  &lt;br /&gt;
  surveyor-only      0&lt;br /&gt;
  &lt;br /&gt;
  script             &amp;quot;acts_container.gs&amp;quot;&lt;br /&gt;
  class              &amp;quot;acts_container&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  kuid-table &lt;br /&gt;
  {&lt;br /&gt;
    skinskuid        &amp;lt;kuid2:215489:1100200:1&amp;gt;&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  script-include-table &lt;br /&gt;
  {&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  mesh-table-lod-transition-distances    1000&lt;br /&gt;
  mesh-detail-level-count                1&lt;br /&gt;
  &lt;br /&gt;
  mesh-table&lt;br /&gt;
  {&lt;br /&gt;
    cont&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;hh&amp;lt;/span&amp;gt;.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
        namev &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;name&amp;quot;&lt;br /&gt;
          name       &amp;quot;GOIDV&amp;quot;&lt;br /&gt;
          att        &amp;quot;a.namev&amp;quot;&lt;br /&gt;
          font       &amp;quot;swiss&amp;quot;&lt;br /&gt;
          fontsize   0.3&lt;br /&gt;
          fontcolor  1.0,1.0,1.0&lt;br /&gt;
        }&lt;br /&gt;
        nameh &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;name&amp;quot;&lt;br /&gt;
          name       &amp;quot;GOIDH&amp;quot;&lt;br /&gt;
          att        &amp;quot;a.nameh&amp;quot;&lt;br /&gt;
          font       &amp;quot;swiss&amp;quot;&lt;br /&gt;
          fontsize   0.3&lt;br /&gt;
          fontcolor  1.0,1.0,1.0&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  thumbnails&lt;br /&gt;
  {&lt;br /&gt;
    0&lt;br /&gt;
    {&lt;br /&gt;
      image          &amp;quot;acts_cont_&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;hh&amp;lt;/span&amp;gt;_thumb.jpg&amp;quot;&lt;br /&gt;
      width          240&lt;br /&gt;
      height         180&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_container.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_container_script.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Container V0.1 Central Script - acts_container.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // X acts_container             &amp;lt;-- acts_container_script&lt;br /&gt;
  //   acts_container_script      &amp;lt;-- acts_container_skinreplace&lt;br /&gt;
  //   acts_container_skinreplace &amp;lt;-- acts_container_register&lt;br /&gt;
  //   acts_container_register    &amp;lt;-- acts_container_globals&lt;br /&gt;
  //   acts_container_globals     &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_container isclass acts_container_script&lt;br /&gt;
  {&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Mandatory INIT method&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
      inherited(asset);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Make shure that the right module is set for World.GetCurrentModle()&lt;br /&gt;
      // (see world.gs lines 939ff.) to start driver related initiations and&lt;br /&gt;
      // tell me, if my Init and SetProperties methods are finished.&lt;br /&gt;
      // Add handler for my tasks as dispatcher.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      AddHandler(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, &amp;quot;WorldInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;ObjectInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;DISPATCHER&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;DispatcherHandler&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // It&#039;s nessecary to initalise the lib to force subscript preparing&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      //World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;dummylibrary&amp;quot;));&lt;br /&gt;
      dispobj = World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;scriptinclude&amp;quot;));&lt;br /&gt;
      dispgoid = (cast&amp;lt;GameObject&amp;gt;dispobj).GetGameObjectID();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Set asset special initial values&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      contlength = &amp;quot;20ft&amp;quot;;&lt;br /&gt;
      contheight = &amp;quot;sc&amp;quot;;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isInitMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;INIT_FINNISHED&amp;quot;,0.0);   // Init method finnished&lt;br /&gt;
      return;&lt;br /&gt;
    }    &lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_container_script.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_container_globals.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Container V0.1 Central Script - acts_container_script.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_container             &amp;lt;-- acts_container_script&lt;br /&gt;
  // X acts_container_script      &amp;lt;-- acts_container_skinreplace&lt;br /&gt;
  // X acts_container_skinreplace &amp;lt;-- acts_container_register&lt;br /&gt;
  // X acts_container_register    &amp;lt;-- acts_container_globals&lt;br /&gt;
  //   acts_container_globals     &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_register isclass acts_container_globals&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Outsource from acts_container_script&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_skinreplace isclass acts_container_register&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Outsource from acts_container_script&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_script isclass acts_container_skinreplace&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void SetProperties(Soup soup)   // Callback method after Init method&lt;br /&gt;
    {&lt;br /&gt;
      inherited(soup);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      SkinDataSoup.Copy(soup.GetNamedSoup(&amp;quot;SkinData&amp;quot;));&lt;br /&gt;
      ObjectDataSoup.Copy(soup.GetNamedSoup(&amp;quot;ObjectData&amp;quot;));&lt;br /&gt;
      LocationSoup.Copy(soup.GetNamedSoup(&amp;quot;Location&amp;quot;));&lt;br /&gt;
      OrientationSoup.Copy(soup.GetNamedSoup(&amp;quot;Orientation&amp;quot;));&lt;br /&gt;
      ContentDataSoup.Copy(soup.GetNamedSoup(&amp;quot;ContentData&amp;quot;));&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isSetPropertiesMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;SETPROPS_FINNISHED&amp;quot;,0.0);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public Soup GetProperties(void)   // Callback method before closing session &lt;br /&gt;
    {&lt;br /&gt;
      Soup soup = inherited();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
                + &amp;quot; CONTAINER SKINDATASOUP&amp;quot;);&lt;br /&gt;
      if (acts_debug)actsTools.ShowSoup(SkinDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;SkinData&amp;quot;,SkinDataSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;ObjectData&amp;quot;,ObjectDataSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Location&amp;quot;,LocationSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Orientation&amp;quot;,OrientationSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;ContentData&amp;quot;,ContentDataSoup);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return soup;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void WorldInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTAINER GOT WORLDINIT MESSAGE [&amp;quot;&lt;br /&gt;
              + msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      // If one of the two methods (Init or SetProperties) isn&#039;t finished yet, &lt;br /&gt;
      // post &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message a little bit later again.&lt;br /&gt;
      // So it is guaranteed that the Init and SetProperties methods are finished&lt;br /&gt;
      // as well as the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message tells to be save using the &lt;br /&gt;
      // World.GetCurrentModule method.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (!(isSetPropertiesMethodFinnished and isInitMethodFinnished))&lt;br /&gt;
      {&lt;br /&gt;
        PostMessage(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, 0.1);&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isWorldInitFinnished = true;&lt;br /&gt;
      PostMessage(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;WORLD_INIT_FINNISHED&amp;quot;, 0.0);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void ObjectInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Until the Trainz core send the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; was send it is not&lt;br /&gt;
      // guarented to decide with the World.GetCurrentModule method to be in the &lt;br /&gt;
      // returned module! &lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTAINER GOT MESSAGE [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;OBJECTINIT&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        if (msg.minor==&amp;quot;INIT_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Show the goid on both sides of me (for debugging purpose)&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          SetFXNameText(&amp;quot;GOIDV&amp;quot;,&amp;quot;[&amp;quot;+objectgoid.SerialiseToString()+&amp;quot;]&amp;quot;);&lt;br /&gt;
          SetFXNameText(&amp;quot;GOIDH&amp;quot;,&amp;quot;[&amp;quot;+objectgoid.SerialiseToString()+&amp;quot;]&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          skins = GetAsset().FindAsset(&amp;quot;skinskuid&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (msg.minor==&amp;quot;SETPROPS_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Adjust position and rotation to rounded values &lt;br /&gt;
          // (see acts_toolsscript.gs)&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          //Soup sp = actsTools.AutoAdjustMapObject(me);&lt;br /&gt;
          //LocationSoup    = sp.GetNamedSoup(&amp;quot;AdjustedLocationSoup&amp;quot;);&lt;br /&gt;
          //OrientationSoup = sp.GetNamedSoup(&amp;quot;AdjustedOrientationSoup&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Random skin number or load skin number from soup&lt;br /&gt;
          // TBD: Additionally set the skin with the properties browser.&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (SkinDataSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            textcount = 9;&lt;br /&gt;
            skin = Math.Rand(1, textcount+1);&lt;br /&gt;
            skinDescription = &amp;quot;TR_Random_Texture [#&amp;quot;+skin+&amp;quot;]&amp;quot;;&lt;br /&gt;
            SkinDataSoup.SetNamedTag(&amp;quot;skin&amp;quot;,skin);&lt;br /&gt;
            SkinDataSoup.SetNamedTag(&amp;quot;skinDescription&amp;quot;,skinDescription);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            skin            = SkinDataSoup.GetNamedTagAsInt(&amp;quot;skin&amp;quot;);&lt;br /&gt;
            skinDescription = SkinDataSoup.GetNamedTag(&amp;quot;skinDescription&amp;quot;);&lt;br /&gt;
          }&lt;br /&gt;
          if (skin == 0) SetFXTextureReplacement(&amp;quot;skincolor&amp;quot;,null,0);&lt;br /&gt;
          else SetFXTextureReplacement(&amp;quot;skincolor&amp;quot;,skins,skin-1);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                    + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
                    + &amp;quot; CONTAINER SKIN [&amp;quot;+skin+&amp;quot;] [&amp;quot;+skinDescription+&amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(SkinDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
          if (ObjectDataSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadObjectDataInfos(ObjectDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;goid&amp;quot;,objectgoid);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;type&amp;quot;,objecttype);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;length&amp;quot;,contlength);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;height&amp;quot;,contheight);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;regID&amp;quot;,-1);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;active&amp;quot;,false);   // False: Not reachable&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;requested&amp;quot;,false);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;hooked&amp;quot;,false);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot; =&amp;gt;SOUP &#039;ObjectDataSoup&#039;&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
          if (LocationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadLocationDataInfos(LocationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            WorldCoordinate WC = me.GetMapObjectPosition();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bbx&amp;quot;,WC.baseboardX);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bby&amp;quot;,WC.baseboardY);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;px&amp;quot;,WC.x);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;py&amp;quot;,WC.y);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;pz&amp;quot;,WC.z);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (OrientationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadOrientationDataInfos(OrientationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            Orientation OR = me.GetMapObjectOrientation();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rx&amp;quot;,OR.rx);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;ry&amp;quot;,OR.ry);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rz&amp;quot;,OR.rz);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gx&amp;quot;,OR.rx*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gy&amp;quot;,OR.ry*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gz&amp;quot;,OR.rz*180.0/Math.PI);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  public void DispatcherHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;DISPATCHER&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;] [&amp;quot;&lt;br /&gt;
                + &amp;quot; CONTAINER GOT MESSAGE FROM DISPATCHER&amp;quot;&lt;br /&gt;
                + (cast&amp;lt;GameObject&amp;gt;msg.src).GetGameObjectID().SerialiseToString()&lt;br /&gt;
                + &amp;quot;] [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
        //-----------------------------------------------------------------------*/&lt;br /&gt;
        if (msg.minor==&amp;quot;UPDATED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                  + &amp;quot; SOUP CONTENT OF &#039;Updated DataSoup&#039; GOID&amp;quot;&lt;br /&gt;
                  + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;INSERTED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                  + &amp;quot; SOUP CONTENT OF &#039;Inserted DataSoup&#039; GOID&amp;quot;&lt;br /&gt;
                  + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;APPENDED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                  + &amp;quot; SOUP CONTENT OF &#039;Added DataSoup&#039; GOID&amp;quot;&lt;br /&gt;
                  + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------*/&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
===acts_container_globals.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_global_values.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Container V0.1 Central Script - acts_container_script.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_container             &amp;lt;-- acts_container_script&lt;br /&gt;
  //   acts_container_script      &amp;lt;-- acts_container_skinreplace&lt;br /&gt;
  //   acts_container_skinreplace &amp;lt;-- acts_container_register&lt;br /&gt;
  //   acts_container_register    &amp;lt;-- acts_container_globals&lt;br /&gt;
  // X acts_container_globals     &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_globals isclass acts_global_values&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // AssetInstanceSoup {&lt;br /&gt;
    // X ObjectDataSoup { ... },    Only container, contstack, contcrane&lt;br /&gt;
    // X LocationSoup { ... },      Only container, contstack, contcrane&lt;br /&gt;
    // X OrientationSoup { ... },   Only container, contstack, contcrane&lt;br /&gt;
    // X SkinDataSoup { ... },      Only container&lt;br /&gt;
    // X ContentDataSoup { ... },   Only container&lt;br /&gt;
    //   DispatcherDataSoup { ... } Only dispatcher&lt;br /&gt;
    //   ContainerSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContstackSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContcraneSoups  { ... }    Only dispatcher&lt;br /&gt;
    // }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // ObjectDataSoup { goid GameObjectID, type string,&lt;br /&gt;
    //                  length string, height string,  &lt;br /&gt;
    //                  stack goid, place int,           Only container&lt;br /&gt;
    //                  active bool, action string },&lt;br /&gt;
    // activ: true means the object sended a register message while session run&lt;br /&gt;
    //        All objects were set false while initialising dispatcher and if&lt;br /&gt;
    //        they stay false their entries will be deleted next initialising.&lt;br /&gt;
    // actions: [&amp;quot;APPENDED&amp;quot;, &amp;quot;INSERTED&amp;quot;, &amp;quot;UPDATED&amp;quot;];&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup ObjectDataSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // LocationSoup { bbx int, bby int,               // WorlCoordinate parameter&lt;br /&gt;
    //                px float, py float, pz float }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup LocationSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // OrientationSoup { rx float, ry float, rz float,    // in rad &lt;br /&gt;
    //                   gx float, gy float, gz float }   // in 1/10°&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup OrientationSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    GameObjectID objectgoid = me.GetGameObjectID();&lt;br /&gt;
    string       objecttype = &amp;quot;CONTAINER&amp;quot;;&lt;br /&gt;
    string       contlength;&lt;br /&gt;
    string       contheight;&lt;br /&gt;
    Library      dispobj;&lt;br /&gt;
    GameObjectID dispgoid;&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup SkinDataSoup = Constructors.NewSoup();&lt;br /&gt;
    Soup ContentDataSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // Container global variables - Skin Texture Replacement&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    bool isAsyncTextureSearchFinnished = false;&lt;br /&gt;
    int skin = -1;   // ID-number of the current skin&lt;br /&gt;
    string skinDescription = &amp;quot;INITIAL SKIN-DESCRIPTION [Texture #&amp;quot;+skin+&amp;quot;]&amp;quot;;&lt;br /&gt;
    Asset skins;     // Texture library asset object&lt;br /&gt;
    int textcount;&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Container&amp;diff=41033</id>
		<title>Container</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Container&amp;diff=41033"/>
		<updated>2024-04-28T09:00:12Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* Container from other asset builder */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Container objects==&lt;br /&gt;
===Container types===&lt;br /&gt;
There are ten container types used in the aCTS: 10ftsc, 10fthc, 20ftsc, 20fthc, 40ftsc, 40fthc, 45ftsc, 45fthc and 53ftsc, 53fthc. An aCTS usable container is predefined with its origin at the geometrical middle of the bottom face.&lt;br /&gt;
&lt;br /&gt;
A container knows its container stack and its position in it. A container is able to report its parameter soups, including a yet not used virtual list of content to transport within it.&lt;br /&gt;
&lt;br /&gt;
===Container from other asset builder===&lt;br /&gt;
So the container assets of other asset builders need possibly a variant with config setted position and rotation. Additionally the scale may be needed to set for fitting the technical dimensions. &lt;br /&gt;
All containers that don&#039;t fit the technical dimensions and the logical origin position and rotation have a config extensions sub soup with the name &amp;quot;acts.origindelta-251489&amp;quot; and tags for correcting the assets values to the aCTS fitting ones (accuracy 0.1 mm and 0.1 °), looking like follows:&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  acts.delta-251489 {&lt;br /&gt;
    px.delta    0.0&lt;br /&gt;
    py.delta    0.0&lt;br /&gt;
    pz.delta    0.0&lt;br /&gt;
    rx.delta    0.0&lt;br /&gt;
    ry.delta    0.0&lt;br /&gt;
    rz.delta    0.0&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
The values will be used while calculation the location and orientation to posit them into the world by adding them to the normal calculated values. The adding is meant in positiv directin and ccw.&lt;br /&gt;
&lt;br /&gt;
Unfortunately the scale of the mesh may not be corrected by some factor to fit the aCTS dimensions. So for containers with other dimensions one may see a small gap between stacked containers or they run optical into each other.&lt;br /&gt;
&lt;br /&gt;
===Adding a contaiener to a session===&lt;br /&gt;
  TBD: Writing paragraph&#039;s text&lt;br /&gt;
&lt;br /&gt;
==Asset files pre version 0.1==&lt;br /&gt;
The files compile errorless and the messaging runs well. No more functionality implemented and tested in this pre version.&lt;br /&gt;
&lt;br /&gt;
===config.txt===&lt;br /&gt;
XY is the KUID part, LL the length and HH or hh the height for the container type.&lt;br /&gt;
 X   1 for 10ft, 2 for 20ft, 3 for 40ft, 4 for 45ft and 5 for 53ft&lt;br /&gt;
 Y   1 for standard height, 2 for heigh cube height&lt;br /&gt;
 LL  the fitting length as 10, 20, 40, 45, 53&lt;br /&gt;
 hh  the fitting height as sc, hc&lt;br /&gt;
 HH  the fitting height as SC, HC&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  kuid               &amp;lt;Kuid2:215489:11002&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;XY&amp;lt;/span&amp;gt;:1&amp;gt;&lt;br /&gt;
  username           &amp;quot;aCTS CONTAINER &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;HH&amp;lt;/span&amp;gt; Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  kind               &amp;quot;Scenery&amp;quot;&lt;br /&gt;
  category-class     &amp;quot;BU&amp;quot;&lt;br /&gt;
  description        &amp;quot;aCTS CONTAINER &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;HH&amp;lt;/span&amp;gt; Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  trainz-build       4.6&lt;br /&gt;
  &lt;br /&gt;
  surveyor-only      0&lt;br /&gt;
  &lt;br /&gt;
  script             &amp;quot;acts_container.gs&amp;quot;&lt;br /&gt;
  class              &amp;quot;acts_container&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  kuid-table &lt;br /&gt;
  {&lt;br /&gt;
    skinskuid        &amp;lt;kuid2:215489:1100200:1&amp;gt;&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  script-include-table &lt;br /&gt;
  {&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  mesh-table-lod-transition-distances    1000&lt;br /&gt;
  mesh-detail-level-count                1&lt;br /&gt;
  &lt;br /&gt;
  mesh-table&lt;br /&gt;
  {&lt;br /&gt;
    cont&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;hh&amp;lt;/span&amp;gt;.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
        namev &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;name&amp;quot;&lt;br /&gt;
          name       &amp;quot;GOIDV&amp;quot;&lt;br /&gt;
          att        &amp;quot;a.namev&amp;quot;&lt;br /&gt;
          font       &amp;quot;swiss&amp;quot;&lt;br /&gt;
          fontsize   0.3&lt;br /&gt;
          fontcolor  1.0,1.0,1.0&lt;br /&gt;
        }&lt;br /&gt;
        nameh &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;name&amp;quot;&lt;br /&gt;
          name       &amp;quot;GOIDH&amp;quot;&lt;br /&gt;
          att        &amp;quot;a.nameh&amp;quot;&lt;br /&gt;
          font       &amp;quot;swiss&amp;quot;&lt;br /&gt;
          fontsize   0.3&lt;br /&gt;
          fontcolor  1.0,1.0,1.0&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  thumbnails&lt;br /&gt;
  {&lt;br /&gt;
    0&lt;br /&gt;
    {&lt;br /&gt;
      image          &amp;quot;acts_cont_&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;hh&amp;lt;/span&amp;gt;_thumb.jpg&amp;quot;&lt;br /&gt;
      width          240&lt;br /&gt;
      height         180&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_container.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_container_script.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Container V0.1 Central Script - acts_container.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // X acts_container             &amp;lt;-- acts_container_script&lt;br /&gt;
  //   acts_container_script      &amp;lt;-- acts_container_skinreplace&lt;br /&gt;
  //   acts_container_skinreplace &amp;lt;-- acts_container_register&lt;br /&gt;
  //   acts_container_register    &amp;lt;-- acts_container_globals&lt;br /&gt;
  //   acts_container_globals     &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_container isclass acts_container_script&lt;br /&gt;
  {&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Mandatory INIT method&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
      inherited(asset);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Make shure that the right module is set for World.GetCurrentModle()&lt;br /&gt;
      // (see world.gs lines 939ff.) to start driver related initiations and&lt;br /&gt;
      // tell me, if my Init and SetProperties methods are finished.&lt;br /&gt;
      // Add handler for my tasks as dispatcher.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      AddHandler(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, &amp;quot;WorldInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;ObjectInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;DISPATCHER&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;DispatcherHandler&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // It&#039;s nessecary to initalise the lib to force subscript preparing&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      //World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;dummylibrary&amp;quot;));&lt;br /&gt;
      dispobj = World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;scriptinclude&amp;quot;));&lt;br /&gt;
      dispgoid = (cast&amp;lt;GameObject&amp;gt;dispobj).GetGameObjectID();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Set asset special initial values&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      contlength = &amp;quot;20ft&amp;quot;;&lt;br /&gt;
      contheight = &amp;quot;sc&amp;quot;;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isInitMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;INIT_FINNISHED&amp;quot;,0.0);   // Init method finnished&lt;br /&gt;
      return;&lt;br /&gt;
    }    &lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_container_script.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_container_globals.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Container V0.1 Central Script - acts_container_script.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_container             &amp;lt;-- acts_container_script&lt;br /&gt;
  // X acts_container_script      &amp;lt;-- acts_container_skinreplace&lt;br /&gt;
  // X acts_container_skinreplace &amp;lt;-- acts_container_register&lt;br /&gt;
  // X acts_container_register    &amp;lt;-- acts_container_globals&lt;br /&gt;
  //   acts_container_globals     &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_register isclass acts_container_globals&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Outsource from acts_container_script&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_skinreplace isclass acts_container_register&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Outsource from acts_container_script&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_script isclass acts_container_skinreplace&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void SetProperties(Soup soup)   // Callback method after Init method&lt;br /&gt;
    {&lt;br /&gt;
      inherited(soup);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      SkinDataSoup.Copy(soup.GetNamedSoup(&amp;quot;SkinData&amp;quot;));&lt;br /&gt;
      ObjectDataSoup.Copy(soup.GetNamedSoup(&amp;quot;ObjectData&amp;quot;));&lt;br /&gt;
      LocationSoup.Copy(soup.GetNamedSoup(&amp;quot;Location&amp;quot;));&lt;br /&gt;
      OrientationSoup.Copy(soup.GetNamedSoup(&amp;quot;Orientation&amp;quot;));&lt;br /&gt;
      ContentDataSoup.Copy(soup.GetNamedSoup(&amp;quot;ContentData&amp;quot;));&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isSetPropertiesMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;SETPROPS_FINNISHED&amp;quot;,0.0);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public Soup GetProperties(void)   // Callback method before closing session &lt;br /&gt;
    {&lt;br /&gt;
      Soup soup = inherited();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
                + &amp;quot; CONTAINER SKINDATASOUP&amp;quot;);&lt;br /&gt;
      if (acts_debug)actsTools.ShowSoup(SkinDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;SkinData&amp;quot;,SkinDataSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;ObjectData&amp;quot;,ObjectDataSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Location&amp;quot;,LocationSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Orientation&amp;quot;,OrientationSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;ContentData&amp;quot;,ContentDataSoup);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return soup;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void WorldInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTAINER GOT WORLDINIT MESSAGE [&amp;quot;&lt;br /&gt;
              + msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      // If one of the two methods (Init or SetProperties) isn&#039;t finished yet, &lt;br /&gt;
      // post &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message a little bit later again.&lt;br /&gt;
      // So it is guaranteed that the Init and SetProperties methods are finished&lt;br /&gt;
      // as well as the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message tells to be save using the &lt;br /&gt;
      // World.GetCurrentModule method.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (!(isSetPropertiesMethodFinnished and isInitMethodFinnished))&lt;br /&gt;
      {&lt;br /&gt;
        PostMessage(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, 0.1);&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isWorldInitFinnished = true;&lt;br /&gt;
      PostMessage(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;WORLD_INIT_FINNISHED&amp;quot;, 0.0);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void ObjectInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Until the Trainz core send the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; was send it is not&lt;br /&gt;
      // guarented to decide with the World.GetCurrentModule method to be in the &lt;br /&gt;
      // returned module! &lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTAINER GOT MESSAGE [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;OBJECTINIT&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        if (msg.minor==&amp;quot;INIT_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Show the goid on both sides of me (for debugging purpose)&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          SetFXNameText(&amp;quot;GOIDV&amp;quot;,&amp;quot;[&amp;quot;+objectgoid.SerialiseToString()+&amp;quot;]&amp;quot;);&lt;br /&gt;
          SetFXNameText(&amp;quot;GOIDH&amp;quot;,&amp;quot;[&amp;quot;+objectgoid.SerialiseToString()+&amp;quot;]&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          skins = GetAsset().FindAsset(&amp;quot;skinskuid&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (msg.minor==&amp;quot;SETPROPS_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Adjust position and rotation to rounded values &lt;br /&gt;
          // (see acts_toolsscript.gs)&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          //Soup sp = actsTools.AutoAdjustMapObject(me);&lt;br /&gt;
          //LocationSoup    = sp.GetNamedSoup(&amp;quot;AdjustedLocationSoup&amp;quot;);&lt;br /&gt;
          //OrientationSoup = sp.GetNamedSoup(&amp;quot;AdjustedOrientationSoup&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Random skin number or load skin number from soup&lt;br /&gt;
          // TBD: Additionally set the skin with the properties browser.&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (SkinDataSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            textcount = 9;&lt;br /&gt;
            skin = Math.Rand(1, textcount+1);&lt;br /&gt;
            skinDescription = &amp;quot;TR_Random_Texture [#&amp;quot;+skin+&amp;quot;]&amp;quot;;&lt;br /&gt;
            SkinDataSoup.SetNamedTag(&amp;quot;skin&amp;quot;,skin);&lt;br /&gt;
            SkinDataSoup.SetNamedTag(&amp;quot;skinDescription&amp;quot;,skinDescription);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            skin            = SkinDataSoup.GetNamedTagAsInt(&amp;quot;skin&amp;quot;);&lt;br /&gt;
            skinDescription = SkinDataSoup.GetNamedTag(&amp;quot;skinDescription&amp;quot;);&lt;br /&gt;
          }&lt;br /&gt;
          if (skin == 0) SetFXTextureReplacement(&amp;quot;skincolor&amp;quot;,null,0);&lt;br /&gt;
          else SetFXTextureReplacement(&amp;quot;skincolor&amp;quot;,skins,skin-1);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                    + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
                    + &amp;quot; CONTAINER SKIN [&amp;quot;+skin+&amp;quot;] [&amp;quot;+skinDescription+&amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(SkinDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
          if (ObjectDataSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadObjectDataInfos(ObjectDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;goid&amp;quot;,objectgoid);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;type&amp;quot;,objecttype);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;length&amp;quot;,contlength);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;height&amp;quot;,contheight);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;regID&amp;quot;,-1);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;active&amp;quot;,false);   // False: Not reachable&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;requested&amp;quot;,false);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;hooked&amp;quot;,false);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot; =&amp;gt;SOUP &#039;ObjectDataSoup&#039;&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
          if (LocationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadLocationDataInfos(LocationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            WorldCoordinate WC = me.GetMapObjectPosition();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bbx&amp;quot;,WC.baseboardX);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bby&amp;quot;,WC.baseboardY);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;px&amp;quot;,WC.x);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;py&amp;quot;,WC.y);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;pz&amp;quot;,WC.z);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (OrientationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadOrientationDataInfos(OrientationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            Orientation OR = me.GetMapObjectOrientation();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rx&amp;quot;,OR.rx);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;ry&amp;quot;,OR.ry);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rz&amp;quot;,OR.rz);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gx&amp;quot;,OR.rx*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gy&amp;quot;,OR.ry*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gz&amp;quot;,OR.rz*180.0/Math.PI);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  public void DispatcherHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;DISPATCHER&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;] [&amp;quot;&lt;br /&gt;
                + &amp;quot; CONTAINER GOT MESSAGE FROM DISPATCHER&amp;quot;&lt;br /&gt;
                + (cast&amp;lt;GameObject&amp;gt;msg.src).GetGameObjectID().SerialiseToString()&lt;br /&gt;
                + &amp;quot;] [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
        //-----------------------------------------------------------------------*/&lt;br /&gt;
        if (msg.minor==&amp;quot;UPDATED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                  + &amp;quot; SOUP CONTENT OF &#039;Updated DataSoup&#039; GOID&amp;quot;&lt;br /&gt;
                  + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;INSERTED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                  + &amp;quot; SOUP CONTENT OF &#039;Inserted DataSoup&#039; GOID&amp;quot;&lt;br /&gt;
                  + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;APPENDED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                  + &amp;quot; SOUP CONTENT OF &#039;Added DataSoup&#039; GOID&amp;quot;&lt;br /&gt;
                  + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------*/&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
===acts_container_globals.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_global_values.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Container V0.1 Central Script - acts_container_script.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_container             &amp;lt;-- acts_container_script&lt;br /&gt;
  //   acts_container_script      &amp;lt;-- acts_container_skinreplace&lt;br /&gt;
  //   acts_container_skinreplace &amp;lt;-- acts_container_register&lt;br /&gt;
  //   acts_container_register    &amp;lt;-- acts_container_globals&lt;br /&gt;
  // X acts_container_globals     &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_globals isclass acts_global_values&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // AssetInstanceSoup {&lt;br /&gt;
    // X ObjectDataSoup { ... },    Only container, contstack, contcrane&lt;br /&gt;
    // X LocationSoup { ... },      Only container, contstack, contcrane&lt;br /&gt;
    // X OrientationSoup { ... },   Only container, contstack, contcrane&lt;br /&gt;
    // X SkinDataSoup { ... },      Only container&lt;br /&gt;
    // X ContentDataSoup { ... },   Only container&lt;br /&gt;
    //   DispatcherDataSoup { ... } Only dispatcher&lt;br /&gt;
    //   ContainerSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContstackSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContcraneSoups  { ... }    Only dispatcher&lt;br /&gt;
    // }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // ObjectDataSoup { goid GameObjectID, type string,&lt;br /&gt;
    //                  length string, height string,  &lt;br /&gt;
    //                  stack goid, place int,           Only container&lt;br /&gt;
    //                  active bool, action string },&lt;br /&gt;
    // activ: true means the object sended a register message while session run&lt;br /&gt;
    //        All objects were set false while initialising dispatcher and if&lt;br /&gt;
    //        they stay false their entries will be deleted next initialising.&lt;br /&gt;
    // actions: [&amp;quot;APPENDED&amp;quot;, &amp;quot;INSERTED&amp;quot;, &amp;quot;UPDATED&amp;quot;];&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup ObjectDataSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // LocationSoup { bbx int, bby int,               // WorlCoordinate parameter&lt;br /&gt;
    //                px float, py float, pz float }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup LocationSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // OrientationSoup { rx float, ry float, rz float,    // in rad &lt;br /&gt;
    //                   gx float, gy float, gz float }   // in 1/10°&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup OrientationSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    GameObjectID objectgoid = me.GetGameObjectID();&lt;br /&gt;
    string       objecttype = &amp;quot;CONTAINER&amp;quot;;&lt;br /&gt;
    string       contlength;&lt;br /&gt;
    string       contheight;&lt;br /&gt;
    Library      dispobj;&lt;br /&gt;
    GameObjectID dispgoid;&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup SkinDataSoup = Constructors.NewSoup();&lt;br /&gt;
    Soup ContentDataSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // Container global variables - Skin Texture Replacement&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    bool isAsyncTextureSearchFinnished = false;&lt;br /&gt;
    int skin = -1;   // ID-number of the current skin&lt;br /&gt;
    string skinDescription = &amp;quot;INITIAL SKIN-DESCRIPTION [Texture #&amp;quot;+skin+&amp;quot;]&amp;quot;;&lt;br /&gt;
    Asset skins;     // Texture library asset object&lt;br /&gt;
    int textcount;&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Container&amp;diff=41032</id>
		<title>Container</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Container&amp;diff=41032"/>
		<updated>2024-04-28T08:59:10Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Container objects==&lt;br /&gt;
===Container types===&lt;br /&gt;
There are ten container types used in the aCTS: 10ftsc, 10fthc, 20ftsc, 20fthc, 40ftsc, 40fthc, 45ftsc, 45fthc and 53ftsc, 53fthc. An aCTS usable container is predefined with its origin at the geometrical middle of the bottom face.&lt;br /&gt;
&lt;br /&gt;
A container knows its container stack and its position in it. A container is able to report its parameter soups, including a yet not used virtual list of content to transport within it.&lt;br /&gt;
&lt;br /&gt;
===Container from other asset builder===&lt;br /&gt;
So the container assets of other asset builders need possibly a variant with config setted position and rotation. Additionally the scale may be needed to set for fitting the technical dimensions. &lt;br /&gt;
All containers that don&#039;t fit the technical dimensions and the logical origin position and rotation have a config extensions sub soup with the name &amp;quot;acts.origindelta-251489&amp;quot; and tags for correcting the assets values to the aCTS fitting ones (accuracy 0.1 mm and 0.1 °), looking like follows:&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  acts.delta-251489 {&lt;br /&gt;
    px.delta    0.0&lt;br /&gt;
    py.delta    0.0&lt;br /&gt;
    pz.delta    0.0&lt;br /&gt;
    rx.delta    0.0&lt;br /&gt;
    ry.delta    0.0&lt;br /&gt;
    rz.delta    0.0&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
The values will be used while calculation the location and orientation to posit them into the world by adding them to the normal calculated values. The adding is meant in positiv directin and ccw.&lt;br /&gt;
&lt;br /&gt;
Unfortunately the scale of the mesh may not be corrected by some factor to fit the aCTS dimensions. So for containers with other dimensions one may see a small gap between stacked containers or they run optical into each other.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Asset files pre version 0.1==&lt;br /&gt;
The files compile errorless and the messaging runs well. No more functionality implemented and tested in this pre version.&lt;br /&gt;
&lt;br /&gt;
===config.txt===&lt;br /&gt;
XY is the KUID part, LL the length and HH or hh the height for the container type.&lt;br /&gt;
 X   1 for 10ft, 2 for 20ft, 3 for 40ft, 4 for 45ft and 5 for 53ft&lt;br /&gt;
 Y   1 for standard height, 2 for heigh cube height&lt;br /&gt;
 LL  the fitting length as 10, 20, 40, 45, 53&lt;br /&gt;
 hh  the fitting height as sc, hc&lt;br /&gt;
 HH  the fitting height as SC, HC&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  kuid               &amp;lt;Kuid2:215489:11002&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;XY&amp;lt;/span&amp;gt;:1&amp;gt;&lt;br /&gt;
  username           &amp;quot;aCTS CONTAINER &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;HH&amp;lt;/span&amp;gt; Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  kind               &amp;quot;Scenery&amp;quot;&lt;br /&gt;
  category-class     &amp;quot;BU&amp;quot;&lt;br /&gt;
  description        &amp;quot;aCTS CONTAINER &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft &amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;HH&amp;lt;/span&amp;gt; Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  trainz-build       4.6&lt;br /&gt;
  &lt;br /&gt;
  surveyor-only      0&lt;br /&gt;
  &lt;br /&gt;
  script             &amp;quot;acts_container.gs&amp;quot;&lt;br /&gt;
  class              &amp;quot;acts_container&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  kuid-table &lt;br /&gt;
  {&lt;br /&gt;
    skinskuid        &amp;lt;kuid2:215489:1100200:1&amp;gt;&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  script-include-table &lt;br /&gt;
  {&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  mesh-table-lod-transition-distances    1000&lt;br /&gt;
  mesh-detail-level-count                1&lt;br /&gt;
  &lt;br /&gt;
  mesh-table&lt;br /&gt;
  {&lt;br /&gt;
    cont&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;hh&amp;lt;/span&amp;gt;.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
        namev &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;name&amp;quot;&lt;br /&gt;
          name       &amp;quot;GOIDV&amp;quot;&lt;br /&gt;
          att        &amp;quot;a.namev&amp;quot;&lt;br /&gt;
          font       &amp;quot;swiss&amp;quot;&lt;br /&gt;
          fontsize   0.3&lt;br /&gt;
          fontcolor  1.0,1.0,1.0&lt;br /&gt;
        }&lt;br /&gt;
        nameh &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;name&amp;quot;&lt;br /&gt;
          name       &amp;quot;GOIDH&amp;quot;&lt;br /&gt;
          att        &amp;quot;a.nameh&amp;quot;&lt;br /&gt;
          font       &amp;quot;swiss&amp;quot;&lt;br /&gt;
          fontsize   0.3&lt;br /&gt;
          fontcolor  1.0,1.0,1.0&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  thumbnails&lt;br /&gt;
  {&lt;br /&gt;
    0&lt;br /&gt;
    {&lt;br /&gt;
      image          &amp;quot;acts_cont_&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;LL&amp;lt;/span&amp;gt;ft&amp;lt;span style=&amp;quot;background:#FF0000&amp;quot;&amp;gt;hh&amp;lt;/span&amp;gt;_thumb.jpg&amp;quot;&lt;br /&gt;
      width          240&lt;br /&gt;
      height         180&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_container.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_container_script.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Container V0.1 Central Script - acts_container.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // X acts_container             &amp;lt;-- acts_container_script&lt;br /&gt;
  //   acts_container_script      &amp;lt;-- acts_container_skinreplace&lt;br /&gt;
  //   acts_container_skinreplace &amp;lt;-- acts_container_register&lt;br /&gt;
  //   acts_container_register    &amp;lt;-- acts_container_globals&lt;br /&gt;
  //   acts_container_globals     &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_container isclass acts_container_script&lt;br /&gt;
  {&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Mandatory INIT method&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
      inherited(asset);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Make shure that the right module is set for World.GetCurrentModle()&lt;br /&gt;
      // (see world.gs lines 939ff.) to start driver related initiations and&lt;br /&gt;
      // tell me, if my Init and SetProperties methods are finished.&lt;br /&gt;
      // Add handler for my tasks as dispatcher.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      AddHandler(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, &amp;quot;WorldInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;ObjectInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;DISPATCHER&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;DispatcherHandler&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // It&#039;s nessecary to initalise the lib to force subscript preparing&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      //World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;dummylibrary&amp;quot;));&lt;br /&gt;
      dispobj = World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;scriptinclude&amp;quot;));&lt;br /&gt;
      dispgoid = (cast&amp;lt;GameObject&amp;gt;dispobj).GetGameObjectID();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Set asset special initial values&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      contlength = &amp;quot;20ft&amp;quot;;&lt;br /&gt;
      contheight = &amp;quot;sc&amp;quot;;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isInitMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;INIT_FINNISHED&amp;quot;,0.0);   // Init method finnished&lt;br /&gt;
      return;&lt;br /&gt;
    }    &lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_container_script.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_container_globals.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Container V0.1 Central Script - acts_container_script.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_container             &amp;lt;-- acts_container_script&lt;br /&gt;
  // X acts_container_script      &amp;lt;-- acts_container_skinreplace&lt;br /&gt;
  // X acts_container_skinreplace &amp;lt;-- acts_container_register&lt;br /&gt;
  // X acts_container_register    &amp;lt;-- acts_container_globals&lt;br /&gt;
  //   acts_container_globals     &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_register isclass acts_container_globals&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Outsource from acts_container_script&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_skinreplace isclass acts_container_register&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Outsource from acts_container_script&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_script isclass acts_container_skinreplace&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void SetProperties(Soup soup)   // Callback method after Init method&lt;br /&gt;
    {&lt;br /&gt;
      inherited(soup);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      SkinDataSoup.Copy(soup.GetNamedSoup(&amp;quot;SkinData&amp;quot;));&lt;br /&gt;
      ObjectDataSoup.Copy(soup.GetNamedSoup(&amp;quot;ObjectData&amp;quot;));&lt;br /&gt;
      LocationSoup.Copy(soup.GetNamedSoup(&amp;quot;Location&amp;quot;));&lt;br /&gt;
      OrientationSoup.Copy(soup.GetNamedSoup(&amp;quot;Orientation&amp;quot;));&lt;br /&gt;
      ContentDataSoup.Copy(soup.GetNamedSoup(&amp;quot;ContentData&amp;quot;));&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isSetPropertiesMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;SETPROPS_FINNISHED&amp;quot;,0.0);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public Soup GetProperties(void)   // Callback method before closing session &lt;br /&gt;
    {&lt;br /&gt;
      Soup soup = inherited();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
                + &amp;quot; CONTAINER SKINDATASOUP&amp;quot;);&lt;br /&gt;
      if (acts_debug)actsTools.ShowSoup(SkinDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;SkinData&amp;quot;,SkinDataSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;ObjectData&amp;quot;,ObjectDataSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Location&amp;quot;,LocationSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Orientation&amp;quot;,OrientationSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;ContentData&amp;quot;,ContentDataSoup);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return soup;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void WorldInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTAINER GOT WORLDINIT MESSAGE [&amp;quot;&lt;br /&gt;
              + msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      // If one of the two methods (Init or SetProperties) isn&#039;t finished yet, &lt;br /&gt;
      // post &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message a little bit later again.&lt;br /&gt;
      // So it is guaranteed that the Init and SetProperties methods are finished&lt;br /&gt;
      // as well as the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message tells to be save using the &lt;br /&gt;
      // World.GetCurrentModule method.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (!(isSetPropertiesMethodFinnished and isInitMethodFinnished))&lt;br /&gt;
      {&lt;br /&gt;
        PostMessage(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, 0.1);&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isWorldInitFinnished = true;&lt;br /&gt;
      PostMessage(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;WORLD_INIT_FINNISHED&amp;quot;, 0.0);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void ObjectInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Until the Trainz core send the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; was send it is not&lt;br /&gt;
      // guarented to decide with the World.GetCurrentModule method to be in the &lt;br /&gt;
      // returned module! &lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTAINER GOT MESSAGE [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;OBJECTINIT&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        if (msg.minor==&amp;quot;INIT_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Show the goid on both sides of me (for debugging purpose)&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          SetFXNameText(&amp;quot;GOIDV&amp;quot;,&amp;quot;[&amp;quot;+objectgoid.SerialiseToString()+&amp;quot;]&amp;quot;);&lt;br /&gt;
          SetFXNameText(&amp;quot;GOIDH&amp;quot;,&amp;quot;[&amp;quot;+objectgoid.SerialiseToString()+&amp;quot;]&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          skins = GetAsset().FindAsset(&amp;quot;skinskuid&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (msg.minor==&amp;quot;SETPROPS_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Adjust position and rotation to rounded values &lt;br /&gt;
          // (see acts_toolsscript.gs)&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          //Soup sp = actsTools.AutoAdjustMapObject(me);&lt;br /&gt;
          //LocationSoup    = sp.GetNamedSoup(&amp;quot;AdjustedLocationSoup&amp;quot;);&lt;br /&gt;
          //OrientationSoup = sp.GetNamedSoup(&amp;quot;AdjustedOrientationSoup&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Random skin number or load skin number from soup&lt;br /&gt;
          // TBD: Additionally set the skin with the properties browser.&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (SkinDataSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            textcount = 9;&lt;br /&gt;
            skin = Math.Rand(1, textcount+1);&lt;br /&gt;
            skinDescription = &amp;quot;TR_Random_Texture [#&amp;quot;+skin+&amp;quot;]&amp;quot;;&lt;br /&gt;
            SkinDataSoup.SetNamedTag(&amp;quot;skin&amp;quot;,skin);&lt;br /&gt;
            SkinDataSoup.SetNamedTag(&amp;quot;skinDescription&amp;quot;,skinDescription);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            skin            = SkinDataSoup.GetNamedTagAsInt(&amp;quot;skin&amp;quot;);&lt;br /&gt;
            skinDescription = SkinDataSoup.GetNamedTag(&amp;quot;skinDescription&amp;quot;);&lt;br /&gt;
          }&lt;br /&gt;
          if (skin == 0) SetFXTextureReplacement(&amp;quot;skincolor&amp;quot;,null,0);&lt;br /&gt;
          else SetFXTextureReplacement(&amp;quot;skincolor&amp;quot;,skins,skin-1);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                    + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
                    + &amp;quot; CONTAINER SKIN [&amp;quot;+skin+&amp;quot;] [&amp;quot;+skinDescription+&amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(SkinDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
          if (ObjectDataSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadObjectDataInfos(ObjectDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;goid&amp;quot;,objectgoid);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;type&amp;quot;,objecttype);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;length&amp;quot;,contlength);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;height&amp;quot;,contheight);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;regID&amp;quot;,-1);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;active&amp;quot;,false);   // False: Not reachable&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;requested&amp;quot;,false);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;hooked&amp;quot;,false);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot; =&amp;gt;SOUP &#039;ObjectDataSoup&#039;&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
          if (LocationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadLocationDataInfos(LocationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            WorldCoordinate WC = me.GetMapObjectPosition();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bbx&amp;quot;,WC.baseboardX);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bby&amp;quot;,WC.baseboardY);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;px&amp;quot;,WC.x);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;py&amp;quot;,WC.y);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;pz&amp;quot;,WC.z);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (OrientationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadOrientationDataInfos(OrientationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            Orientation OR = me.GetMapObjectOrientation();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rx&amp;quot;,OR.rx);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;ry&amp;quot;,OR.ry);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rz&amp;quot;,OR.rz);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gx&amp;quot;,OR.rx*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gy&amp;quot;,OR.ry*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gz&amp;quot;,OR.rz*180.0/Math.PI);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  public void DispatcherHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;DISPATCHER&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;] [&amp;quot;&lt;br /&gt;
                + &amp;quot; CONTAINER GOT MESSAGE FROM DISPATCHER&amp;quot;&lt;br /&gt;
                + (cast&amp;lt;GameObject&amp;gt;msg.src).GetGameObjectID().SerialiseToString()&lt;br /&gt;
                + &amp;quot;] [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
        //-----------------------------------------------------------------------*/&lt;br /&gt;
        if (msg.minor==&amp;quot;UPDATED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                  + &amp;quot; SOUP CONTENT OF &#039;Updated DataSoup&#039; GOID&amp;quot;&lt;br /&gt;
                  + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;INSERTED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                  + &amp;quot; SOUP CONTENT OF &#039;Inserted DataSoup&#039; GOID&amp;quot;&lt;br /&gt;
                  + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;APPENDED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          if (acts_debug)Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                  + &amp;quot; SOUP CONTENT OF &#039;Added DataSoup&#039; GOID&amp;quot;&lt;br /&gt;
                  + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;);&lt;br /&gt;
          if (acts_debug)actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------*/&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
===acts_container_globals.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_global_values.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Container V0.1 Central Script - acts_container_script.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_container             &amp;lt;-- acts_container_script&lt;br /&gt;
  //   acts_container_script      &amp;lt;-- acts_container_skinreplace&lt;br /&gt;
  //   acts_container_skinreplace &amp;lt;-- acts_container_register&lt;br /&gt;
  //   acts_container_register    &amp;lt;-- acts_container_globals&lt;br /&gt;
  // X acts_container_globals     &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_container_globals isclass acts_global_values&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // AssetInstanceSoup {&lt;br /&gt;
    // X ObjectDataSoup { ... },    Only container, contstack, contcrane&lt;br /&gt;
    // X LocationSoup { ... },      Only container, contstack, contcrane&lt;br /&gt;
    // X OrientationSoup { ... },   Only container, contstack, contcrane&lt;br /&gt;
    // X SkinDataSoup { ... },      Only container&lt;br /&gt;
    // X ContentDataSoup { ... },   Only container&lt;br /&gt;
    //   DispatcherDataSoup { ... } Only dispatcher&lt;br /&gt;
    //   ContainerSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContstackSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContcraneSoups  { ... }    Only dispatcher&lt;br /&gt;
    // }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // ObjectDataSoup { goid GameObjectID, type string,&lt;br /&gt;
    //                  length string, height string,  &lt;br /&gt;
    //                  stack goid, place int,           Only container&lt;br /&gt;
    //                  active bool, action string },&lt;br /&gt;
    // activ: true means the object sended a register message while session run&lt;br /&gt;
    //        All objects were set false while initialising dispatcher and if&lt;br /&gt;
    //        they stay false their entries will be deleted next initialising.&lt;br /&gt;
    // actions: [&amp;quot;APPENDED&amp;quot;, &amp;quot;INSERTED&amp;quot;, &amp;quot;UPDATED&amp;quot;];&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup ObjectDataSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // LocationSoup { bbx int, bby int,               // WorlCoordinate parameter&lt;br /&gt;
    //                px float, py float, pz float }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup LocationSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // OrientationSoup { rx float, ry float, rz float,    // in rad &lt;br /&gt;
    //                   gx float, gy float, gz float }   // in 1/10°&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup OrientationSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    GameObjectID objectgoid = me.GetGameObjectID();&lt;br /&gt;
    string       objecttype = &amp;quot;CONTAINER&amp;quot;;&lt;br /&gt;
    string       contlength;&lt;br /&gt;
    string       contheight;&lt;br /&gt;
    Library      dispobj;&lt;br /&gt;
    GameObjectID dispgoid;&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup SkinDataSoup = Constructors.NewSoup();&lt;br /&gt;
    Soup ContentDataSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // Container global variables - Skin Texture Replacement&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    bool isAsyncTextureSearchFinnished = false;&lt;br /&gt;
    int skin = -1;   // ID-number of the current skin&lt;br /&gt;
    string skinDescription = &amp;quot;INITIAL SKIN-DESCRIPTION [Texture #&amp;quot;+skin+&amp;quot;]&amp;quot;;&lt;br /&gt;
    Asset skins;     // Texture library asset object&lt;br /&gt;
    int textcount;&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ContainerBridgeCrane&amp;diff=40981</id>
		<title>ContainerBridgeCrane</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ContainerBridgeCrane&amp;diff=40981"/>
		<updated>2024-04-27T18:35:34Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* Moving Containers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Container Bridge Crane==&lt;br /&gt;
A bridge crane consists of several running parts. This parts are some kind of parented. The locical hirarchy of this parts look like this:&lt;br /&gt;
&lt;br /&gt;
 cranebase--&amp;gt;cranebridge(py)--&amp;gt;trolley(px)--&amp;gt;lift(sz,pz)--&amp;gt;rotor(rz)--&amp;gt;gear(sx)&lt;br /&gt;
   px, py, pz   animation move in x, y, z direction (moving in 1 mm steps)&lt;br /&gt;
   rx, ry, rz   animation rotation around x, y, z direction (rotation in 0.1° steps from -90.0° to +90.0° and zeroframe as -90.0°)&lt;br /&gt;
   sx, sy, sz   animation scale in x, y, z direction (zeroframe as 1.0 iss mandatory)&lt;br /&gt;
&lt;br /&gt;
===Reachable area===&lt;br /&gt;
The special reacharea parameters for the bridge crane prototype looking like follows:&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  acts.reacharea-251489 {&lt;br /&gt;
    reacharea.dimension.x       30000&lt;br /&gt;
    reacharea.dimension.y      100000&lt;br /&gt;
    reacharea.dimension.z       26000&lt;br /&gt;
    reacharea.origin_inset.x    15000&lt;br /&gt;
    reacharea.origin_inset.y    50000&lt;br /&gt;
    reacharea.origin_inset.z     5000&lt;br /&gt;
    max_container_count             7&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
This data are for this prototype bridge crane.&lt;br /&gt;
&lt;br /&gt;
===Animation frames===&lt;br /&gt;
The list of animation steps and values looks lik follows:&lt;br /&gt;
  Bridge (py)  100,001 Frames over     140m with BlenderFrames [1 .. 100001] for [  0,000 (  1  ) 100,000] in mm&lt;br /&gt;
  Trolley (px)  30,001 Frames over      30m with BlenderFrames [1 ..  30001] for [-15,000 (  1  ) +15,000] in mm&lt;br /&gt;
  Lift (sz)     25,001 Frames over     1-26 with BlenderFrames [1 ..  25001] for [  1.000 (0.001)  26.000]&lt;br /&gt;
  Lift (pz)     25,001 Frames over      25m with BlenderFrames [1 ..  25001] for [+21,000 (  1  )  -5,000] in mm&lt;br /&gt;
  Rotor (rz)     1,801 Frames over     180° with BlenderFrames [1 ..   1801] for [  -90.0 ( 0.1 )   +90.0] in ° (decimal grade)&lt;br /&gt;
  Gear (sy)     15,155 Frames over  16.154m with BlenderFrames [1 ..  15155] for [  1.000 (0.001)  16.154]&lt;br /&gt;
  ----------------------------------------------------------------------&lt;br /&gt;
  Containertype                  10ft    20ft     40ft     45ft     53ft&lt;br /&gt;
  Gear scale/length    1.000m  2.991m  6.058m  12.192m  13.716m  16.154m&lt;br /&gt;
&lt;br /&gt;
===Moving Containers===&lt;br /&gt;
The task to move a container from one stack to another is written as following:&lt;br /&gt;
  # move crane (gear) to the &amp;quot;fromStack&amp;quot;: stackWC,containerPosition and hook container&lt;br /&gt;
  # move crane (gear) to the &amp;quot;destStack&amp;quot;: stackWC,containerPosition and dehook container&lt;br /&gt;
&lt;br /&gt;
For calculating the frames see [[MovingProcedure#Calculating_the_frames_the_animation_should_move_to|Calculating the frames the animation should move to]]&lt;br /&gt;
&lt;br /&gt;
==Asset files pre version 0.1==&lt;br /&gt;
The files compile errorless and the messaging runs well. No more functionality implemented and tested in this pre version.&lt;br /&gt;
&lt;br /&gt;
===config.txt===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  kuid               &amp;lt;kuid2:215489:110041:1&amp;gt;&lt;br /&gt;
  username           &amp;quot;aCTS CONTCRANE Animated Bridge Crane Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  kind               &amp;quot;Scenery&amp;quot;&lt;br /&gt;
  category-class     &amp;quot;BU&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  description        &amp;quot;aCTS CONTCRANE Animated Bridge Crane Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  trainz-build       4.6&lt;br /&gt;
  &lt;br /&gt;
  script             &amp;quot;acts_bridgecrane.gs&amp;quot;&lt;br /&gt;
  class              &amp;quot;acts_bridgecrane&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  surveyor-only      0&lt;br /&gt;
  &lt;br /&gt;
  mesh-table-lod-transition-distances    1000&lt;br /&gt;
  mesh-detail-level-count                1&lt;br /&gt;
  &lt;br /&gt;
  kuid-table {&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
    skinskuid        &amp;lt;kuid2:215489:1100200:1&amp;gt;&lt;br /&gt;
    cont10ftsc       &amp;lt;kuid2:215489:1100211:1&amp;gt;&lt;br /&gt;
    cont10fthc       &amp;lt;kuid2:215489:1100212:1&amp;gt;&lt;br /&gt;
    cont20ftsc       &amp;lt;kuid2:215489:1100221:1&amp;gt;&lt;br /&gt;
    cont20fthc       &amp;lt;kuid2:215489:1100222:1&amp;gt;&lt;br /&gt;
    cont40ftsc       &amp;lt;kuid2:215489:1100231:1&amp;gt;&lt;br /&gt;
    cont40fthc       &amp;lt;kuid2:215489:1100232:1&amp;gt;&lt;br /&gt;
    cont45ftsc       &amp;lt;kuid2:215489:1100241:1&amp;gt;&lt;br /&gt;
    cont45fthc       &amp;lt;kuid2:215489:1100242:1&amp;gt;&lt;br /&gt;
    cont53ftsc       &amp;lt;kuid2:215489:1100251:1&amp;gt;&lt;br /&gt;
    cont53fthc       &amp;lt;kuid2:215489:1100252:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  script-include-table {&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
    skincolor        &amp;lt;kuid2:215489:1100200:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  extensions&lt;br /&gt;
  {&lt;br /&gt;
    reacharea-215489&lt;br /&gt;
    {&lt;br /&gt;
      cranebase_dimension_x       30000&lt;br /&gt;
      cranebase_dimension_y      100000&lt;br /&gt;
      cranebase_dimension_z       26000&lt;br /&gt;
      cranebase_origin_inset_x    15000&lt;br /&gt;
      cranebase_origin_inset_y    50000&lt;br /&gt;
      cranebase_origin_inset_z     5000&lt;br /&gt;
      max_container_count             7&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  mesh-table&lt;br /&gt;
  {&lt;br /&gt;
    cranebase-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cranebase.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
    }&lt;br /&gt;
    bridge-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_bridge.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att-parent             &amp;quot;cranebase-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_bridge_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    trolley-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_trolley.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.bridge&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;bridge-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_trolley_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    lift-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_lift.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.trolley&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;trolley-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_lift_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    rotor-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_rotor.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.lift&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;lift-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_rotor_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    gear-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_gear.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.rotor&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;rotor-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_gear_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   1.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    cont10ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_10ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100211:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor10ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont10fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_10fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100212:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor10fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont20ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_20ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100221:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor20ftsc&lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont20fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_20fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100222:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor20fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont40ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_40ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100231:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor40ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont40fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_40fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100232:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor40fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont45ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_45ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100241:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor45ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont45fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_45fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100242:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor45fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont53ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_53ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100251:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor53ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont53fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_53fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100252:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor53fthc&lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  thumbnails&lt;br /&gt;
  {&lt;br /&gt;
    0&lt;br /&gt;
    {&lt;br /&gt;
      image                  &amp;quot;acts_bridgecrane_thumb.jpg&amp;quot;&lt;br /&gt;
      width                  240&lt;br /&gt;
      height                 180&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrane.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_bridgecrane_script.gs&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // X acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  //   acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  //   acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  //   acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  //   acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  //   acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane isclass acts_bridgecrane_script&lt;br /&gt;
  {&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Mandatory INIT method&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
      inherited(asset);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Make shure that the right module is set for World.GetCurrentModle()&lt;br /&gt;
      // (see world.gs lines 939ff.) to start driver related initiations and&lt;br /&gt;
      // tell me, if my Init and SetProperties methods are finished.&lt;br /&gt;
      // Add handler for my tasks as dispatcher.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      AddHandler(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, &amp;quot;WorldInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;ObjectInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;DISPATCHER&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;DispatcherHandler&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // It&#039;s nessecary to initalise the lib to force subscript preparing&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      //World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;dummylibrary&amp;quot;));&lt;br /&gt;
      dispobj = World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;scriptinclude&amp;quot;));&lt;br /&gt;
      dispgoid = (cast&amp;lt;GameObject&amp;gt;dispobj).GetGameObjectID();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Load reacharea and other values from extension soup in my config.txt&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      Soup csp = me.GetAsset().GetConfigSoupCached();&lt;br /&gt;
      csp = csp.GetNamedSoup(&amp;quot;extensions&amp;quot;);&lt;br /&gt;
      csp = csp.GetNamedSoup(&amp;quot;reacharea-215489&amp;quot;);&lt;br /&gt;
      cranebase_reacharea_x    = csp.GetNamedTagAsInt(&amp;quot;cranebase_dimension_x&amp;quot;   );&lt;br /&gt;
      cranebase_reacharea_y    = csp.GetNamedTagAsInt(&amp;quot;cranebase_dimension_y&amp;quot;   );&lt;br /&gt;
      cranebase_reacharea_z    = csp.GetNamedTagAsInt(&amp;quot;cranebase_dimension_z&amp;quot;   );&lt;br /&gt;
      cranebase_origin_inset_x = csp.GetNamedTagAsInt(&amp;quot;cranebase_origin_inset_x&amp;quot;);&lt;br /&gt;
      cranebase_origin_inset_y = csp.GetNamedTagAsInt(&amp;quot;cranebase_origin_inset_y&amp;quot;);&lt;br /&gt;
      cranebase_origin_inset_z = csp.GetNamedTagAsInt(&amp;quot;cranebase_origin_inset_z&amp;quot;);&lt;br /&gt;
      max_container_count      = csp.GetNamedTagAsInt(&amp;quot;max_container_count&amp;quot;     );&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      moveCranePartsToZeroframe();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isInitMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;INIT_FINNISHED&amp;quot;,0);   // Init method finnished&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }    &lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrane_script.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_bridgecrane_reachable.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_script.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  // X acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  // X acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  //   acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  //   acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  //   acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_register isclass acts_bridgecrane_reachable&lt;br /&gt;
  {&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Outsource from acts_bridgecrane_script&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_script isclass acts_bridgecrane_register&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // public void SetProperties(Soup soup) ....................... ca. line  23&lt;br /&gt;
    // public Soup GetProperties(void) ............................ ca. line  85&lt;br /&gt;
    // public void ObjectInitHandler(Message msg) ................. ca. line 100&lt;br /&gt;
    // public void WorldInitHandler(Message msg) .................. ca. line 132&lt;br /&gt;
    // public void DispatcherHandler(Message msg) ................. ca. line 183&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void SetProperties(Soup soup)   // Callback method after Init method&lt;br /&gt;
    {&lt;br /&gt;
      inherited(soup);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      ObjectDataSoup.Copy(soup.GetNamedSoup(&amp;quot;ObjectData&amp;quot;));&lt;br /&gt;
      LocationSoup.Copy(soup.GetNamedSoup(&amp;quot;Location&amp;quot;));&lt;br /&gt;
      OrientationSoup.Copy(soup.GetNamedSoup(&amp;quot;Orientation&amp;quot;)) ;&lt;br /&gt;
      /*/-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot;CONTCRANE SETPROPERTIES SOUPS&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(ObjectDataSoup,&amp;quot;ObjDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(LocationSoup,&amp;quot;LocDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(OrientationSoup,&amp;quot;OriDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      isSetPropertiesMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;SETPROPS_FINNISHED&amp;quot;,0.0);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public Soup GetProperties(void)   // Callback method before closing session&lt;br /&gt;
    {&lt;br /&gt;
      Soup soup = inherited();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;ObjectData&amp;quot;,ObjectDataSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Location&amp;quot;,LocationSoup    );&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Orientation&amp;quot;,OrientationSoup );&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot;CONTCRANE GETPROPERTIES SOUPS&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(ObjectDataSoup,&amp;quot;ObjDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(LocationSoup,&amp;quot;LocDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(OrientationSoup,&amp;quot;OriDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      return soup;&lt;br /&gt;
    } &lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void WorldInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTCRANE GOT WORLDINIT MESSAGE [&amp;quot;&lt;br /&gt;
              + msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      // If one of the two methods (Init or SetProperties) isn&#039;t finished yet, &lt;br /&gt;
      // post &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message a little bit later again.&lt;br /&gt;
      // So it is guaranteed that the Init and SetProperties methods are finished&lt;br /&gt;
      // as well as the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message tells to be save using the &lt;br /&gt;
      // World.GetCurrentModule method.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (!(isSetPropertiesMethodFinnished and isInitMethodFinnished))&lt;br /&gt;
      {&lt;br /&gt;
        PostMessage(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, 0.2);&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isWorldInitFinnished = true;&lt;br /&gt;
      PostMessage(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;WORLD_INIT_FINNISHED&amp;quot;, 0.0);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void ObjectInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Until the Trainz core send the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; was send it is not&lt;br /&gt;
      // guarented to decide with the World.GetCurrentModule method to be in the &lt;br /&gt;
      // returned module! &lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTCRANE GOT MESSAGE [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;OBJECTINIT&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        if (msg.minor==&amp;quot;INIT_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // Not used yet&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (msg.minor==&amp;quot;SETPROPS_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          if (ObjectDataSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadObjectDataInfos(ObjectDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;goid&amp;quot;,objectgoid);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;type&amp;quot;,objecttype);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;regID&amp;quot;,-1);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;active&amp;quot;,false);&lt;br /&gt;
            //ObjectDataSoup.SetNamedTag(&amp;quot;requested&amp;quot;,false);&lt;br /&gt;
            //ObjectDataSoup.SetNamedTag(&amp;quot;hooked&amp;quot;,false);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_reacharea_x&amp;quot;,cranebase_reacharea_x);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_reacharea_y&amp;quot;,cranebase_reacharea_y);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_reacharea_z&amp;quot;,cranebase_reacharea_z);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_origin_inset_x&amp;quot;,cranebase_origin_inset_x);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_origin_inset_y&amp;quot;,cranebase_origin_inset_y);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_origin_inset_z&amp;quot;,cranebase_origin_inset_z);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;max_container_count&amp;quot;,max_container_count);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot; =&amp;gt; SOUP &#039;ObjectDataSoup&#039;&amp;quot;);&lt;br /&gt;
          if (acts_debug) actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
          if (LocationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadLocationDataInfos(LocationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            WorldCoordinate WC = me.GetMapObjectPosition();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bbx&amp;quot;,WC.baseboardX);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bby&amp;quot;,WC.baseboardY);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;px&amp;quot;,WC.x);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;py&amp;quot;,WC.y);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;pz&amp;quot;,WC.z);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (OrientationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadOrientationDataInfos(OrientationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            Orientation OR = me.GetMapObjectOrientation();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rx&amp;quot;,OR.rx);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;ry&amp;quot;,OR.ry);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rz&amp;quot;,OR.rz);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gx&amp;quot;,OR.rx*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gy&amp;quot;,OR.ry*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gz&amp;quot;,OR.rz*180.0/Math.PI);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // TBD: Adjust position and rotation to rounded values and handle&lt;br /&gt;
          //      the different pssibilities.&lt;br /&gt;
          //      (some methods see acts_tools_script.gs)&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Soup sp = actsTools.AutoAdjustMapObject(cast&amp;lt;MapObject&amp;gt;(me));&lt;br /&gt;
          // LocationSoup    = sp.GetNamedSoup(&amp;quot;AdjustedLocationSoup&amp;quot;);&lt;br /&gt;
          // OrientationSoup = sp.GetNamedSoup(&amp;quot;AdjustedOrientationSoup&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (msg.minor==&amp;quot;WORLD_INIT_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Do no module only, driver module only or surveyor module only&lt;br /&gt;
          // related initiations&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (World.GetCurrentModule() == World.DRIVER_MODULE)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            PostMessage(cast&amp;lt;GameObject&amp;gt;dispobj,&lt;br /&gt;
                                 &amp;quot;REGISTER&amp;quot;, &amp;quot;REGISTER_ME&amp;quot;, ObjectDataSoup, 0.0);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (World.GetCurrentModule() == World.SURVEYOR_MODULE)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // Not used yet&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (World.GetCurrentModule() == World.NO_MODULE)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // Not used yet&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void DispatcherHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;DISPATCHER&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;] [&amp;quot;&lt;br /&gt;
                + &amp;quot; CONTCRANE GOT MESSAGE FROM DISPATCHER&amp;quot;&lt;br /&gt;
                + (cast&amp;lt;GameObject&amp;gt;msg.src).GetGameObjectID().SerialiseToString()&lt;br /&gt;
                + &amp;quot;] [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
        //-----------------------------------------------------------------------*/&lt;br /&gt;
        if (msg.minor==&amp;quot;OBJECTSOUP_UPDATED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;OBJECTSOUP_INSERTED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;OBJECTSOUP_APPENDED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrane_reachable.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_bridgecrane_globals.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_reachable.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  //   acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  //   acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  // X acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  // X acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  //   acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_moving isclass acts_bridgecrane_globals&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // Set zeroframe translations for the asset parts&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int bridge_zeroframe  = cranebase_origin_inset_y;&lt;br /&gt;
    int trolley_zeroframe = cranebase_origin_inset_x;&lt;br /&gt;
    int lift_zeroframe  = 0;     // Scale 1.000..25.000 (cranebase_reacharea_z)&lt;br /&gt;
    int rotor_zeroframe = 900;   // Decimal degree -90.0..+90.0 (precision 0.1°)&lt;br /&gt;
    int gear_zeroframe  = 2991;  // Scale 1.000-2.991-6.058-12.192-13.716-16.154&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    void moveCranePartsToZeroframe(void)&lt;br /&gt;
    {&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;bridge-lod0&amp;quot;,  bridge_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;trolley-lod0&amp;quot;, trolley_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;lift-lod0&amp;quot;,    lift_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;rotor-lod0&amp;quot;,   rotor_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;gear-lod0&amp;quot;,    gear_zeroframe);&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Where and when setting the fitting containers skin?&lt;br /&gt;
    //      Asset skins = GetAsset().FindAsset(&amp;quot;skinskuid&amp;quot;);&lt;br /&gt;
    //      SetFXTextureReplacement(&amp;quot;skincolor40ftsc&amp;quot;,skins,8);&lt;br /&gt;
    //      SetMeshVisible(&amp;quot;cont40ftsc-lod0&amp;quot;, true);&lt;br /&gt;
    //      me.SetMeshAnimationFrame(&amp;quot;gear-lod0&amp;quot;, 12191.0, 3.0);&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  /******************************************************************************&lt;br /&gt;
    -----------------------------------------------------------------------------&lt;br /&gt;
    In conjunction with the rotation of the cranearea there ar four cases to&lt;br /&gt;
    know about if a point lies within the reacharea, bounding edges are assumed&lt;br /&gt;
    to be outside.&lt;br /&gt;
    &lt;br /&gt;
     A B    B    &lt;br /&gt;
     D C   A C     0° ≤ w &amp;lt; 90°   CD &amp;lt; py &amp;lt; AB and AD &amp;lt; px &amp;lt; BC&lt;br /&gt;
            D&lt;br /&gt;
    &lt;br /&gt;
     B C    C&lt;br /&gt;
     A D   B D   90° ≤ w &amp;lt; 180°   AD &amp;lt; py &amp;lt; BC and AB &amp;lt; px &amp;lt; CD&lt;br /&gt;
            A&lt;br /&gt;
    &lt;br /&gt;
     C D    D &lt;br /&gt;
     B A   C A  180° ≤ w &amp;lt; 270°   AB &amp;lt; py &amp;lt; CD and BC &amp;lt; px &amp;lt; AD   &lt;br /&gt;
            B&lt;br /&gt;
  &lt;br /&gt;
     D A    A    &lt;br /&gt;
     C B   D B  270° ≤ w &amp;lt; 360°   BC &amp;lt; py &amp;lt; AD and CD &amp;lt; px &amp;lt; AB&lt;br /&gt;
            C&lt;br /&gt;
    -----------------------------------------------------------------------------&lt;br /&gt;
  *******************************************************************************/&lt;br /&gt;
  class acts_bridgecrane_reachable isclass acts_bridgecrane_moving&lt;br /&gt;
  {&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Loading values from config.txt extensions-219486 cranedata soup&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    void LoadCraneDataInfos(Soup sp)&lt;br /&gt;
    {&lt;br /&gt;
      cranebase_reacharea_x          &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_reacharea_x&amp;quot;,0);&lt;br /&gt;
      cranebase_reacharea_y          &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_reacharea_y&amp;quot;,0);&lt;br /&gt;
      cranebase_reacharea_z          &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_reacharea_z&amp;quot;,0);&lt;br /&gt;
      cranebase_origin_inset_x              &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_inset_x&amp;quot;,0);&lt;br /&gt;
      cranebase_origin_inset_y              &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_inset_y&amp;quot;,0);&lt;br /&gt;
      cranebase_origin_inset_z              &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_inset_z&amp;quot;,0);&lt;br /&gt;
      trolley_bottom_height   &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;trolley_bottom_height&amp;quot;,0);&lt;br /&gt;
      lift_bottom_height &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;lift_bottom_height&amp;quot;,0);&lt;br /&gt;
      gear_bottom_height &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;gear_bottom_height&amp;quot;,0);&lt;br /&gt;
      max_container_count&lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;max_container_count&amp;quot;,0);&lt;br /&gt;
    }&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Returns the vertices of the reacharea rectangle. The insets and dimensions&lt;br /&gt;
    // where deliverd over a objects config extension subsoup. Rotations x and y &lt;br /&gt;
    // are zero.&lt;br /&gt;
    //  A---+-----B&lt;br /&gt;
    //  |   ix    |   ix insetx, iy insety&lt;br /&gt;
    //  |iy-O-----+   dx=AD=BC dimensionx, dy=AB=CD dimensiony&lt;br /&gt;
    //  |   |     |   RC[0..3]&amp;lt;=&amp;gt;ABCD &lt;br /&gt;
    //  D---+-----C&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public WorldCoordinate[] GetReachareaCorners()&lt;br /&gt;
    {&lt;br /&gt;
      WorldCoordinate[] RC = new WorldCoordinate[4];    // Reacharea corners ABCD&lt;br /&gt;
      WorldCoordinate OR = me.GetMapObjectPosition();   // Origin of crane OR&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[0].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[0].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[0].x = OR.x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[0].y = OR.y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[0].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[1].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[1].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[1].x = OR.x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[1].y = OR.y + cranebase_reacharea_y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[1].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[2].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[2].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[2].x = OR.x + cranebase_reacharea_x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[2].y = OR.y + cranebase_reacharea_y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[2].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[3].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[3].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[3].x = OR.x + cranebase_reacharea_x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[3].y = OR.y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[3].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return RC;&lt;br /&gt;
    }&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // The two point straight line formulas for x and y for the points A and B:&lt;br /&gt;
    //       (by-ay)                        (bx-ax)&lt;br /&gt;
    //   y = ------- * (x-ax) + by      x = ------- * (y-ay) + bx&lt;br /&gt;
    //       (bx-ax)                        (by-ay)&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public float ValueXStraightline(&lt;br /&gt;
                   WorldCoordinate P, WorldCoordinate A, WorldCoordinate B)&lt;br /&gt;
    { if (A.y==B.y) return A.y;&lt;br /&gt;
      else return cast&amp;lt;float&amp;gt;((B.x-A.x)*(P.y-A.y)/(B.y-A.y)); &lt;br /&gt;
      return 0.0;&lt;br /&gt;
    }&lt;br /&gt;
    public float ValueYStraightline(&lt;br /&gt;
                   WorldCoordinate P, WorldCoordinate A, WorldCoordinate B)&lt;br /&gt;
    { if (A.x==B.x) return A.x;&lt;br /&gt;
      else return cast&amp;lt;float&amp;gt;((B.y-A.y)*(P.x-A.x)/(B.x-A.x));&lt;br /&gt;
      return 0.0;&lt;br /&gt;
    }&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // InsideReacharea returns true if the point is reachable, otherwise false.&lt;br /&gt;
    // Edges of the reacharea rectangle are assumed outside.&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public bool InsideReacharea(WorldCoordinate P, WorldCoordinate[] W)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Adjust the point to the same baseboard as the container crane&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      WorldCoordinate SP = actsTools.WCoordAdjustBaseboard(P,me.GetMapObjectPosition());&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Calculate the case to proof&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      float rz = me.GetMapObjectOrientation().rz;&lt;br /&gt;
      int wi = cast&amp;lt;int&amp;gt;(rz*180*100/Math.PI);     // int rounded to 1/100&lt;br /&gt;
      int ri = wi/(90*100);&lt;br /&gt;
      while (ri&amp;lt;0) ri=ri+4;&lt;br /&gt;
      while (ri&amp;gt;3) ri=ri-4;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Values of the edges (straight ölines) for the point coordinates&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      float xAB = ValueXStraightline(P, W[0], W[1]);&lt;br /&gt;
      float yAB = ValueYStraightline(P, W[0], W[1]);&lt;br /&gt;
      float xBC = ValueXStraightline(P, W[1], W[2]);&lt;br /&gt;
      float yBC = ValueYStraightline(P, W[1], W[2]);&lt;br /&gt;
      float xCD = ValueXStraightline(P, W[2], W[3]);&lt;br /&gt;
      float yCD = ValueYStraightline(P, W[2], W[3]);&lt;br /&gt;
      float xAD = ValueXStraightline(P, W[0], W[3]);&lt;br /&gt;
      float yAD = ValueYStraightline(P, W[0], W[3]);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Calculating the resulting bool value&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      switch(ri)&lt;br /&gt;
      {&lt;br /&gt;
        case 0:  //  0° &amp;lt;= rz° &amp;lt;  90°&lt;br /&gt;
          if(yCD &amp;lt; P.y and P.y &amp;lt; yAB and xAD &amp;lt; P.x and P.x &amp;lt; xBC) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        case 1:  //  90° &amp;lt;= rz° &amp;lt; 180°&lt;br /&gt;
          if(yAD &amp;lt; P.y and P.y &amp;lt; yBC and xAB &amp;lt; P.x and P.x &amp;lt; xCD) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        case 2:  // 180° &amp;lt;= rz° &amp;lt; 270°&lt;br /&gt;
          if(yAB &amp;lt; P.y and P.y &amp;lt; yCD and xBC &amp;lt; P.x and P.x &amp;lt; xAD) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        case 3:  // 270° &amp;lt;= rz° &amp;lt; 360°&lt;br /&gt;
          if(yBC &amp;lt; P.y and P.y &amp;lt; yAD and xCD &amp;lt; P.x and P.x &amp;lt; xAB) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        default:&lt;br /&gt;
          return false;&lt;br /&gt;
      }&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    &lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrain_globals.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_global_values.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //---------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_globals.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  //   acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  //   acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  //   acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  //   acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  // X acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_globals isclass acts_global_values&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // AssetInstanceSoup {&lt;br /&gt;
    // X ObjectDataSoup { ... },    Only container, contstack, contcrane&lt;br /&gt;
    // X LocationSoup { ... },      Only container, contstack, contcrane&lt;br /&gt;
    // X OrientationSoup { ... },   Only container, contstack, contcrane&lt;br /&gt;
    //   SkinDataSoup { ... },      Only container&lt;br /&gt;
    //   ContentDataSoup { ... },   Only container&lt;br /&gt;
    //   DispatcherDataSoup { ... } Only dispatcher&lt;br /&gt;
    //   ContainerSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContstackSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContcraneSoups  { ... }    Only dispatcher&lt;br /&gt;
    // }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // ObjectDataSoup { goid GameObjectID, type string,&lt;br /&gt;
    //                  length string, height string,  &lt;br /&gt;
    //                  stack goid, place int,           Only container&lt;br /&gt;
    //                  active bool, action string },&lt;br /&gt;
    // activ: true means the object sended a register message while session run&lt;br /&gt;
    //        All objects were set false while initialising dispatcher and if&lt;br /&gt;
    //        they stay false their entries will be deleted next initialising.&lt;br /&gt;
    // actions: [&amp;quot;APPENDED&amp;quot;, &amp;quot;INSERTED&amp;quot;, &amp;quot;UPDATED&amp;quot;];&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup ObjectDataSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // LocationSoup { bbx int, bby int,               // WorlCoordinate parameter&lt;br /&gt;
    //                px float, py float, pz float }&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    Soup LocationSoup = Constructors.NewSoup();&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    // OrientationSoup { rx float, ry float, rz float,    // in rad &lt;br /&gt;
    //                   gx float, gy float, gz float }   // in 1/10°&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    Soup OrientationSoup = Constructors.NewSoup();&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    GameObjectID objectgoid = me.GetGameObjectID();&lt;br /&gt;
    string       objecttype = &amp;quot;CONTCRANE&amp;quot;;&lt;br /&gt;
    Library      dispobj;&lt;br /&gt;
    GameObjectID dispgoid;&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // Reach area values of the bridge crane will be loaded from this assets&lt;br /&gt;
    // config.txt file &lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int cranebase_reacharea_x;      //  30000 in [mm]&lt;br /&gt;
    int cranebase_reacharea_y;      // 100000 in [mm]&lt;br /&gt;
    int cranebase_reacharea_z;      //  26000 in [mm]&lt;br /&gt;
    int cranebase_origin_inset_x;   //  15000 in [mm]&lt;br /&gt;
    int cranebase_origin_inset_y;   //  50000 in [mm]&lt;br /&gt;
    int cranebase_origin_inset_z;   //   5000 in [mm]&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int lift_zero_length = 1000;   // 1000 in [mm] mandatory length for animation&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int trolley_bottom_height;   // in [mm]&lt;br /&gt;
    int lift_bottom_height;      // in [mm] with lift z width as 1,000 [mm]&lt;br /&gt;
    int rotor_bottom_height;     // in [mm] with rotor z width as 500 [mm]&lt;br /&gt;
    int gear_bottom_height;      // in [mm] with gear z width as 500 [mm]&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: And not proofed yet. Differntiate between maximum container count&lt;br /&gt;
    //      for high cube and standard cube containers.&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // For now the maximum count is calculated from reacharea z dimension minus&lt;br /&gt;
    // one hc height to ensure the movement of containers by the crane. Because&lt;br /&gt;
    // of possibly different base heights of the stacks inside the crane&#039;s&lt;br /&gt;
    // reacharea, there are some more different (possibly smaller) maximum&lt;br /&gt;
    // stackheights.&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    int max_container_count;     // Construction based max stackable containers&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  /* ****************************************************************************&lt;br /&gt;
     This is the scripted bridge crane object for an active container terminal&lt;br /&gt;
     system (aCTS). It is a kind of prototype of a bridge crane to let&lt;br /&gt;
     constructors know how the things are fitting and working for aCTS.&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Some hints here too (see config description too):&lt;br /&gt;
     * The script logs dependin on the acts_debug variable (See&lt;br /&gt;
       acts.global_values.gs). So the script contains some overhead for testing&lt;br /&gt;
       informations. &lt;br /&gt;
     * Animations from Blender fbx runs from frame 1 ... n in Blender and fbx&lt;br /&gt;
       file. The import to Trainz will change this to frame 0 ... n-1, what is&lt;br /&gt;
       essential to know for precise transformations (moving and rotating) per&lt;br /&gt;
       animation frame.&lt;br /&gt;
     * The logical mesh hierarchy is as follows: cranebase--&amp;gt;&lt;br /&gt;
       --&amp;gt;cranebridge(py)--&amp;gt;trolley(px)--&amp;gt;lift(sz,pz)--&amp;gt;rotor(rz)--&amp;gt;gear(sx)&lt;br /&gt;
     * The cranes parts are imported to Trainz as own (animated) mesh objects&lt;br /&gt;
       with its respective origins at zero and its parented attachment points.&lt;br /&gt;
       All script calculations are based on this origin and the gaps to the&lt;br /&gt;
       attachment points for attaching the child meshes. The assets orientation&lt;br /&gt;
       is zero for x and y orientation.&lt;br /&gt;
     * The parent child hierarchy is realised within the mesh-table container.&lt;br /&gt;
     * The extensions values are in mm and define the reachable area of the&lt;br /&gt;
       cranes container gear. The dimensions x, y, z describe the cuboid&lt;br /&gt;
       length&#039;s, the gear may move and the insets x, y, z describes the location&lt;br /&gt;
       of the cranes origin within there.&lt;br /&gt;
     * The animations minimum frame 0 (resp. 1 in Blender) represents the locale&lt;br /&gt;
       relative minimal position (p = -inset) and the maximum frame (n = &lt;br /&gt;
       dimension) the maximal position p=dimension-inset. Example: &lt;br /&gt;
         dimension 80&lt;br /&gt;
         inset     30&lt;br /&gt;
         Trainz frames    0  10  20 30  40  50  60  70  80&lt;br /&gt;
         Blender frames   1  11  21 31  41  51  61  71  81&lt;br /&gt;
         Position       -30 -20 -10  0  10  20  30  40  50&lt;br /&gt;
     * The crane object (as well as the other object types) adjusts location to&lt;br /&gt;
       even mm and the orientation to 0.1 decimal degrees.&lt;br /&gt;
     * The movements of the cranes sub meshes will be realised with animation&lt;br /&gt;
       frame methods *MeshAnimation* from the MeshObject class in mashobject.gs&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Technical parameters for calculating script values 1 [mm] and 0.1 [°]&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Bridge  [BPY: 100,001F:    140m] BF[1 .. 100001] [0mm(1)100,000mm]&lt;br /&gt;
     Trolley [TPX:  30,001F:     30m] BF[1 ..  30001] [-15,000mm(1)+15,000mm]&lt;br /&gt;
     Lift    [LSZ:  25,001F:    1-26] BF[1 ..  25001] [1.000(0.001)26.000]&lt;br /&gt;
             [LPZ:  25,001F:     25m] BF[1 ..  25001] [+21,000mm(1)-5,000mm]&lt;br /&gt;
     Rotor   [ROZ:   1,801F:    180°] BF[1 ..   1801] [-90.0°(0.1)+90.0°]&lt;br /&gt;
     Gear    [GSY:  15,155F: 16.192m] BF[1 ..  16155] [1.000(0.001)16.154]&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Containertype                      10ft    20ft     40ft     45ft     53ft&lt;br /&gt;
     Gear scale scale/length  1.000m  2.991m  6.058m  12.192m  13.716m  16.154m&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     More informations are documented within the config.txt and script comments.&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     **************************************************************************** */&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=MovingProcedure&amp;diff=40980</id>
		<title>MovingProcedure</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=MovingProcedure&amp;diff=40980"/>
		<updated>2024-04-27T18:32:46Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==&#039;&#039;Moving procedure for a container from one stack to another&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
This version uses meshes from a list of possible (prepared) containers. There are no queues or industrial parts, only asset instances and their meshes.&lt;br /&gt;
&lt;br /&gt;
This process knows the necessary GOIDs and the necessary config container names.&lt;br /&gt;
===The steps to go===&lt;br /&gt;
====If the container to move is not the top container, break the task with error report====&lt;br /&gt;
The error returned should lead into tasks to shift the disturbing containers to other stacks.&lt;br /&gt;
====If the destination stack&#039;s top isn&#039;t free, break the task with error report====&lt;br /&gt;
The error returned should lead into tasks to shift the disturbing container to other stacks or to change the destination or to cancel the task.&lt;br /&gt;
====Move the crane parts to the container stack&#039;s top container to move====&lt;br /&gt;
This movement is visualized by animations of the carne&#039;s parented parts bridge, trolley, lift, rotor, gear and hooked meshes (GOID of the container stack is known).&lt;br /&gt;
====Hook the container to the gear====&lt;br /&gt;
Get the texture id of the container to move (GOID and fitting soups of the container are known).&lt;br /&gt;
&lt;br /&gt;
Set the texture of the fitting invisible mesh of the gear to the fitting texture.&lt;br /&gt;
&lt;br /&gt;
Make the fitting mesh visible (Mesh config container name is known).&lt;br /&gt;
&lt;br /&gt;
Make the top container&#039;s mesh invisible (GOID and config mesh name is known).&lt;br /&gt;
Move the invisible top container to the destination stack&#039;s top (The GOID is known).&lt;br /&gt;
====Move the crane parts to the container&#039;s destination stack&#039;s top free position====&lt;br /&gt;
This movement is visualized by animations of the carne&#039;s parented parts bridge, trolley, lift, rotor, gear and hooked meshes (GOID of the container stack is known).&lt;br /&gt;
====Dehook the container from the gear====&lt;br /&gt;
Make the top container&#039;s mesh visible (GOID and config mesh name is known).&lt;br /&gt;
&lt;br /&gt;
Make the fitting crane&#039;s mesh invisible (config container mesh name is known).&lt;br /&gt;
&lt;br /&gt;
===Calculating the frames the animation should move to===&lt;br /&gt;
To calculate the destination frames we need the distance vector from the crane&#039;s frame zero location to the top of the container position at the stack. Since the location is used as WorldCoordinate and the stack and crane may reside in different baseboards, the first step is to &amp;quot;normalize&amp;quot; the baseboards. In the following this is agreed.&lt;br /&gt;
&lt;br /&gt;
The crane&#039;s frame zero location is defined by the reacharea inset and will be calculated by containerStackTopWC minus craneOriginWC. The containerStackTopWC will be calculated by stackOriginWC plus stackPositionHeight. The stackPositionHeight is the sum of all stacked container&#039;s heights.&lt;br /&gt;
&lt;br /&gt;
As moving speed in x, y, z direction of the crane parts we will use 5.4 km/h (~3.35 mi/s). Thus deltaFrameCount/1500 calculates the duration of the movement in seconds.&lt;br /&gt;
&lt;br /&gt;
Now we are able to get the current frames list, the fromStack&#039;s frame list and the destStack&#039;s frame list to move the crane.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=MovingProcedure&amp;diff=40979</id>
		<title>MovingProcedure</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=MovingProcedure&amp;diff=40979"/>
		<updated>2024-04-27T18:29:11Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* Calculating the frames the animation should move to */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==&#039;&#039;Moving procedure for a container from one stack to another&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
This version uses meshes from a list of possible (prepared) containers. There are no queues or industrial parts, only asset instances and their meshes.&lt;br /&gt;
&lt;br /&gt;
This process knows the necessary GOIDs and the necessary config container names:&lt;br /&gt;
==== 1. If the container to move is not the top container, break the task with error report====&lt;br /&gt;
The error returned should lead into tasks to shift the disturbing containers to other stacks.&lt;br /&gt;
==== 2. If the destination stack&#039;s top isn&#039;t free, break the task with error report====&lt;br /&gt;
The error returned should lead into tasks to shift the disturbing container to other stacks or to change the destination or to cancel the task.&lt;br /&gt;
==== 3. Move the crane parts to the container stack&#039;s top container to move====&lt;br /&gt;
This movement is visualized by animations of the carne&#039;s parented parts bridge, trolley, lift, rotor, gear and hooked meshes (GOID of the container stack is known).&lt;br /&gt;
==== 4. Hook the container to the gear====&lt;br /&gt;
Get the texture id of the container to move (GOID and fitting soups of the container are known).&lt;br /&gt;
&lt;br /&gt;
Set the texture of the fitting invisible mesh of the gear to the fitting texture.&lt;br /&gt;
&lt;br /&gt;
Make the fitting mesh visible (Mesh config container name is known).&lt;br /&gt;
&lt;br /&gt;
Make the top container&#039;s mesh invisible (GOID and config mesh name is known).&lt;br /&gt;
Move the invisible top container to the destination stack&#039;s top (The GOID is known).&lt;br /&gt;
==== 5. Move the crane parts to the container&#039;s destination stack&#039;s top free position====&lt;br /&gt;
This movement is visualized by animations of the carne&#039;s parented parts bridge, trolley, lift, rotor, gear and hooked meshes (GOID of the container stack is known).&lt;br /&gt;
==== 6. Dehook the container from the gear====&lt;br /&gt;
Make the top container&#039;s mesh visible (GOID and config mesh name is known).&lt;br /&gt;
&lt;br /&gt;
Make the fitting crane&#039;s mesh invisible (config container mesh name is known).&lt;br /&gt;
&lt;br /&gt;
===Calculating the frames the animation should move to===&lt;br /&gt;
To calculate the destination frames we need the distance vector from the crane&#039;s frame zero location to the top of the container position at the stack. Since the location is used as WorldCoordinate and the stack and crane may reside in different baseboards, the first step is to &amp;quot;normalize&amp;quot; the baseboards. In the following this is agreed.&lt;br /&gt;
&lt;br /&gt;
The crane&#039;s frame zero location is defined by the reacharea inset and will be calculated by containerStackTopWC minus craneOriginWC. The containerStackTopWC will be calculated by stackOriginWC plus stackPositionHeight. The stackPositionHeight is the sum of all stacked container&#039;s heights.&lt;br /&gt;
&lt;br /&gt;
As moving speed in x, y, z direction of the crane parts we will use 5.4 km/h (~3.35 mi/s). Thus deltaFrameCount/1500 calculates the duration of the movement in seconds.&lt;br /&gt;
&lt;br /&gt;
Now we are able to get the current frames list, the fromStack&#039;s frame list and the destStack&#039;s frame list to move the crane.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=MovingProcedure&amp;diff=40978</id>
		<title>MovingProcedure</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=MovingProcedure&amp;diff=40978"/>
		<updated>2024-04-27T18:28:17Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* Moving procedure for a container from one stack to another */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==&#039;&#039;Moving procedure for a container from one stack to another&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
This version uses meshes from a list of possible (prepared) containers. There are no queues or industrial parts, only asset instances and their meshes.&lt;br /&gt;
&lt;br /&gt;
This process knows the necessary GOIDs and the necessary config container names:&lt;br /&gt;
==== 1. If the container to move is not the top container, break the task with error report====&lt;br /&gt;
The error returned should lead into tasks to shift the disturbing containers to other stacks.&lt;br /&gt;
==== 2. If the destination stack&#039;s top isn&#039;t free, break the task with error report====&lt;br /&gt;
The error returned should lead into tasks to shift the disturbing container to other stacks or to change the destination or to cancel the task.&lt;br /&gt;
==== 3. Move the crane parts to the container stack&#039;s top container to move====&lt;br /&gt;
This movement is visualized by animations of the carne&#039;s parented parts bridge, trolley, lift, rotor, gear and hooked meshes (GOID of the container stack is known).&lt;br /&gt;
==== 4. Hook the container to the gear====&lt;br /&gt;
Get the texture id of the container to move (GOID and fitting soups of the container are known).&lt;br /&gt;
&lt;br /&gt;
Set the texture of the fitting invisible mesh of the gear to the fitting texture.&lt;br /&gt;
&lt;br /&gt;
Make the fitting mesh visible (Mesh config container name is known).&lt;br /&gt;
&lt;br /&gt;
Make the top container&#039;s mesh invisible (GOID and config mesh name is known).&lt;br /&gt;
Move the invisible top container to the destination stack&#039;s top (The GOID is known).&lt;br /&gt;
==== 5. Move the crane parts to the container&#039;s destination stack&#039;s top free position====&lt;br /&gt;
This movement is visualized by animations of the carne&#039;s parented parts bridge, trolley, lift, rotor, gear and hooked meshes (GOID of the container stack is known).&lt;br /&gt;
==== 6. Dehook the container from the gear====&lt;br /&gt;
Make the top container&#039;s mesh visible (GOID and config mesh name is known).&lt;br /&gt;
&lt;br /&gt;
Make the fitting crane&#039;s mesh invisible (config container mesh name is known).&lt;br /&gt;
&lt;br /&gt;
===Calculating the frames the animation should move to===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ContainerStackFilesV0.1&amp;diff=40977</id>
		<title>ContainerStackFilesV0.1</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ContainerStackFilesV0.1&amp;diff=40977"/>
		<updated>2024-04-27T18:22:16Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Created page with &amp;quot; ==Container Stack Files V0.1==  Category:ACTS&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Container Stack Files V0.1==&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=DispatcherFilesV0.1&amp;diff=40976</id>
		<title>DispatcherFilesV0.1</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=DispatcherFilesV0.1&amp;diff=40976"/>
		<updated>2024-04-27T18:21:06Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Created page with &amp;quot; ==Dispatcher Files V0.1==  Category:ACTS&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Dispatcher Files V0.1==&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ContainerFilesV0.1&amp;diff=40975</id>
		<title>ContainerFilesV0.1</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ContainerFilesV0.1&amp;diff=40975"/>
		<updated>2024-04-27T18:19:10Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Created page with &amp;quot; ==Container Files V0.1==  Category:ACTS&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Container Files V0.1==&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ContainerBridgeCraneFilesV0.1&amp;diff=40974</id>
		<title>ContainerBridgeCraneFilesV0.1</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ContainerBridgeCraneFilesV0.1&amp;diff=40974"/>
		<updated>2024-04-27T18:16:47Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Created page with &amp;quot; ==Container Bridge Crane Files V0.1==  Category:ACTS&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Container Bridge Crane Files V0.1==&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ContainerBridgeCrane&amp;diff=40973</id>
		<title>ContainerBridgeCrane</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ContainerBridgeCrane&amp;diff=40973"/>
		<updated>2024-04-27T18:09:35Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* Moving Containers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Container Bridge Crane==&lt;br /&gt;
A bridge crane consists of several running parts. This parts are some kind of parented. The locical hirarchy of this parts look like this:&lt;br /&gt;
&lt;br /&gt;
 cranebase--&amp;gt;cranebridge(py)--&amp;gt;trolley(px)--&amp;gt;lift(sz,pz)--&amp;gt;rotor(rz)--&amp;gt;gear(sx)&lt;br /&gt;
   px, py, pz   animation move in x, y, z direction (moving in 1 mm steps)&lt;br /&gt;
   rx, ry, rz   animation rotation around x, y, z direction (rotation in 0.1° steps from -90.0° to +90.0° and zeroframe as -90.0°)&lt;br /&gt;
   sx, sy, sz   animation scale in x, y, z direction (zeroframe as 1.0 iss mandatory)&lt;br /&gt;
&lt;br /&gt;
===Reachable area===&lt;br /&gt;
The special reacharea parameters for the bridge crane prototype looking like follows:&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  acts.reacharea-251489 {&lt;br /&gt;
    reacharea.dimension.x       30000&lt;br /&gt;
    reacharea.dimension.y      100000&lt;br /&gt;
    reacharea.dimension.z       26000&lt;br /&gt;
    reacharea.origin_inset.x    15000&lt;br /&gt;
    reacharea.origin_inset.y    50000&lt;br /&gt;
    reacharea.origin_inset.z     5000&lt;br /&gt;
    max_container_count             7&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
This data are for this prototype bridge crane.&lt;br /&gt;
&lt;br /&gt;
===Animation frames===&lt;br /&gt;
The list of animation steps and values looks lik follows:&lt;br /&gt;
  Bridge (py)  100,001 Frames over     140m with BlenderFrames [1 .. 100001] for [  0,000 (  1  ) 100,000] in mm&lt;br /&gt;
  Trolley (px)  30,001 Frames over      30m with BlenderFrames [1 ..  30001] for [-15,000 (  1  ) +15,000] in mm&lt;br /&gt;
  Lift (sz)     25,001 Frames over     1-26 with BlenderFrames [1 ..  25001] for [  1.000 (0.001)  26.000]&lt;br /&gt;
  Lift (pz)     25,001 Frames over      25m with BlenderFrames [1 ..  25001] for [+21,000 (  1  )  -5,000] in mm&lt;br /&gt;
  Rotor (rz)     1,801 Frames over     180° with BlenderFrames [1 ..   1801] for [  -90.0 ( 0.1 )   +90.0] in ° (decimal grade)&lt;br /&gt;
  Gear (sy)     15,155 Frames over  16.154m with BlenderFrames [1 ..  15155] for [  1.000 (0.001)  16.154]&lt;br /&gt;
  ----------------------------------------------------------------------&lt;br /&gt;
  Containertype                  10ft    20ft     40ft     45ft     53ft&lt;br /&gt;
  Gear scale/length    1.000m  2.991m  6.058m  12.192m  13.716m  16.154m&lt;br /&gt;
&lt;br /&gt;
===Moving Containers===&lt;br /&gt;
The task to move a container from one stack to another is written as following:&lt;br /&gt;
  # move crane (gear) to the &amp;quot;fromStack&amp;quot;: stackWC,containerPosition and hook container&lt;br /&gt;
  # move crane (gear) to the &amp;quot;destStack&amp;quot;: stackWC,containerPosition and dehook container&lt;br /&gt;
To calculate the destination frames we need the distance vector from the crane&#039;s frame zero location to the top of the container position at the stack. Since the location is used as WorldCoordinate and the stack and crane may reside in different baseboards, the first step is to &amp;quot;normalize&amp;quot; the baseboards. In the following this is agreed.&lt;br /&gt;
&lt;br /&gt;
The crane&#039;s frame zero location is defined by the reacharea inset and will be calculated by containerStackTopWC minus craneOriginWC. The containerStackTopWC will be calculated by stackOriginWC plus stackPositionHeight. The stackPositionHeight is the sum of all stacked container&#039;s heights.&lt;br /&gt;
&lt;br /&gt;
As moving speed in x, y, z direction of the crane parts we will use 5.4 km/h (~3.35 mi/s). Thus deltaFrameCount/1500 calculates the duration of the movement in seconds.&lt;br /&gt;
&lt;br /&gt;
Now we are able to get the current frames list, the fromStack&#039;s frame list and the destStack&#039;s frame list to move the crane.&lt;br /&gt;
&lt;br /&gt;
==Asset files pre version 0.1==&lt;br /&gt;
The files compile errorless and the messaging runs well. No more functionality implemented and tested in this pre version.&lt;br /&gt;
&lt;br /&gt;
===config.txt===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  kuid               &amp;lt;kuid2:215489:110041:1&amp;gt;&lt;br /&gt;
  username           &amp;quot;aCTS CONTCRANE Animated Bridge Crane Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  kind               &amp;quot;Scenery&amp;quot;&lt;br /&gt;
  category-class     &amp;quot;BU&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  description        &amp;quot;aCTS CONTCRANE Animated Bridge Crane Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  trainz-build       4.6&lt;br /&gt;
  &lt;br /&gt;
  script             &amp;quot;acts_bridgecrane.gs&amp;quot;&lt;br /&gt;
  class              &amp;quot;acts_bridgecrane&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  surveyor-only      0&lt;br /&gt;
  &lt;br /&gt;
  mesh-table-lod-transition-distances    1000&lt;br /&gt;
  mesh-detail-level-count                1&lt;br /&gt;
  &lt;br /&gt;
  kuid-table {&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
    skinskuid        &amp;lt;kuid2:215489:1100200:1&amp;gt;&lt;br /&gt;
    cont10ftsc       &amp;lt;kuid2:215489:1100211:1&amp;gt;&lt;br /&gt;
    cont10fthc       &amp;lt;kuid2:215489:1100212:1&amp;gt;&lt;br /&gt;
    cont20ftsc       &amp;lt;kuid2:215489:1100221:1&amp;gt;&lt;br /&gt;
    cont20fthc       &amp;lt;kuid2:215489:1100222:1&amp;gt;&lt;br /&gt;
    cont40ftsc       &amp;lt;kuid2:215489:1100231:1&amp;gt;&lt;br /&gt;
    cont40fthc       &amp;lt;kuid2:215489:1100232:1&amp;gt;&lt;br /&gt;
    cont45ftsc       &amp;lt;kuid2:215489:1100241:1&amp;gt;&lt;br /&gt;
    cont45fthc       &amp;lt;kuid2:215489:1100242:1&amp;gt;&lt;br /&gt;
    cont53ftsc       &amp;lt;kuid2:215489:1100251:1&amp;gt;&lt;br /&gt;
    cont53fthc       &amp;lt;kuid2:215489:1100252:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  script-include-table {&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
    skincolor        &amp;lt;kuid2:215489:1100200:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  extensions&lt;br /&gt;
  {&lt;br /&gt;
    reacharea-215489&lt;br /&gt;
    {&lt;br /&gt;
      cranebase_dimension_x       30000&lt;br /&gt;
      cranebase_dimension_y      100000&lt;br /&gt;
      cranebase_dimension_z       26000&lt;br /&gt;
      cranebase_origin_inset_x    15000&lt;br /&gt;
      cranebase_origin_inset_y    50000&lt;br /&gt;
      cranebase_origin_inset_z     5000&lt;br /&gt;
      max_container_count             7&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  mesh-table&lt;br /&gt;
  {&lt;br /&gt;
    cranebase-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cranebase.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
    }&lt;br /&gt;
    bridge-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_bridge.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att-parent             &amp;quot;cranebase-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_bridge_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    trolley-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_trolley.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.bridge&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;bridge-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_trolley_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    lift-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_lift.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.trolley&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;trolley-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_lift_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    rotor-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_rotor.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.lift&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;lift-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_rotor_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    gear-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_gear.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.rotor&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;rotor-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_gear_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   1.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    cont10ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_10ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100211:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor10ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont10fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_10fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100212:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor10fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont20ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_20ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100221:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor20ftsc&lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont20fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_20fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100222:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor20fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont40ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_40ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100231:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor40ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont40fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_40fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100232:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor40fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont45ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_45ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100241:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor45ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont45fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_45fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100242:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor45fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont53ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_53ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100251:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor53ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont53fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_53fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100252:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor53fthc&lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  thumbnails&lt;br /&gt;
  {&lt;br /&gt;
    0&lt;br /&gt;
    {&lt;br /&gt;
      image                  &amp;quot;acts_bridgecrane_thumb.jpg&amp;quot;&lt;br /&gt;
      width                  240&lt;br /&gt;
      height                 180&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrane.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_bridgecrane_script.gs&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // X acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  //   acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  //   acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  //   acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  //   acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  //   acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane isclass acts_bridgecrane_script&lt;br /&gt;
  {&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Mandatory INIT method&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
      inherited(asset);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Make shure that the right module is set for World.GetCurrentModle()&lt;br /&gt;
      // (see world.gs lines 939ff.) to start driver related initiations and&lt;br /&gt;
      // tell me, if my Init and SetProperties methods are finished.&lt;br /&gt;
      // Add handler for my tasks as dispatcher.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      AddHandler(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, &amp;quot;WorldInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;ObjectInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;DISPATCHER&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;DispatcherHandler&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // It&#039;s nessecary to initalise the lib to force subscript preparing&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      //World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;dummylibrary&amp;quot;));&lt;br /&gt;
      dispobj = World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;scriptinclude&amp;quot;));&lt;br /&gt;
      dispgoid = (cast&amp;lt;GameObject&amp;gt;dispobj).GetGameObjectID();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Load reacharea and other values from extension soup in my config.txt&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      Soup csp = me.GetAsset().GetConfigSoupCached();&lt;br /&gt;
      csp = csp.GetNamedSoup(&amp;quot;extensions&amp;quot;);&lt;br /&gt;
      csp = csp.GetNamedSoup(&amp;quot;reacharea-215489&amp;quot;);&lt;br /&gt;
      cranebase_reacharea_x    = csp.GetNamedTagAsInt(&amp;quot;cranebase_dimension_x&amp;quot;   );&lt;br /&gt;
      cranebase_reacharea_y    = csp.GetNamedTagAsInt(&amp;quot;cranebase_dimension_y&amp;quot;   );&lt;br /&gt;
      cranebase_reacharea_z    = csp.GetNamedTagAsInt(&amp;quot;cranebase_dimension_z&amp;quot;   );&lt;br /&gt;
      cranebase_origin_inset_x = csp.GetNamedTagAsInt(&amp;quot;cranebase_origin_inset_x&amp;quot;);&lt;br /&gt;
      cranebase_origin_inset_y = csp.GetNamedTagAsInt(&amp;quot;cranebase_origin_inset_y&amp;quot;);&lt;br /&gt;
      cranebase_origin_inset_z = csp.GetNamedTagAsInt(&amp;quot;cranebase_origin_inset_z&amp;quot;);&lt;br /&gt;
      max_container_count      = csp.GetNamedTagAsInt(&amp;quot;max_container_count&amp;quot;     );&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      moveCranePartsToZeroframe();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isInitMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;INIT_FINNISHED&amp;quot;,0);   // Init method finnished&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }    &lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrane_script.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_bridgecrane_reachable.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_script.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  // X acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  // X acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  //   acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  //   acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  //   acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_register isclass acts_bridgecrane_reachable&lt;br /&gt;
  {&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Outsource from acts_bridgecrane_script&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_script isclass acts_bridgecrane_register&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // public void SetProperties(Soup soup) ....................... ca. line  23&lt;br /&gt;
    // public Soup GetProperties(void) ............................ ca. line  85&lt;br /&gt;
    // public void ObjectInitHandler(Message msg) ................. ca. line 100&lt;br /&gt;
    // public void WorldInitHandler(Message msg) .................. ca. line 132&lt;br /&gt;
    // public void DispatcherHandler(Message msg) ................. ca. line 183&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void SetProperties(Soup soup)   // Callback method after Init method&lt;br /&gt;
    {&lt;br /&gt;
      inherited(soup);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      ObjectDataSoup.Copy(soup.GetNamedSoup(&amp;quot;ObjectData&amp;quot;));&lt;br /&gt;
      LocationSoup.Copy(soup.GetNamedSoup(&amp;quot;Location&amp;quot;));&lt;br /&gt;
      OrientationSoup.Copy(soup.GetNamedSoup(&amp;quot;Orientation&amp;quot;)) ;&lt;br /&gt;
      /*/-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot;CONTCRANE SETPROPERTIES SOUPS&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(ObjectDataSoup,&amp;quot;ObjDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(LocationSoup,&amp;quot;LocDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(OrientationSoup,&amp;quot;OriDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      isSetPropertiesMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;SETPROPS_FINNISHED&amp;quot;,0.0);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public Soup GetProperties(void)   // Callback method before closing session&lt;br /&gt;
    {&lt;br /&gt;
      Soup soup = inherited();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;ObjectData&amp;quot;,ObjectDataSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Location&amp;quot;,LocationSoup    );&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Orientation&amp;quot;,OrientationSoup );&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot;CONTCRANE GETPROPERTIES SOUPS&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(ObjectDataSoup,&amp;quot;ObjDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(LocationSoup,&amp;quot;LocDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(OrientationSoup,&amp;quot;OriDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      return soup;&lt;br /&gt;
    } &lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void WorldInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTCRANE GOT WORLDINIT MESSAGE [&amp;quot;&lt;br /&gt;
              + msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      // If one of the two methods (Init or SetProperties) isn&#039;t finished yet, &lt;br /&gt;
      // post &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message a little bit later again.&lt;br /&gt;
      // So it is guaranteed that the Init and SetProperties methods are finished&lt;br /&gt;
      // as well as the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message tells to be save using the &lt;br /&gt;
      // World.GetCurrentModule method.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (!(isSetPropertiesMethodFinnished and isInitMethodFinnished))&lt;br /&gt;
      {&lt;br /&gt;
        PostMessage(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, 0.2);&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isWorldInitFinnished = true;&lt;br /&gt;
      PostMessage(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;WORLD_INIT_FINNISHED&amp;quot;, 0.0);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void ObjectInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Until the Trainz core send the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; was send it is not&lt;br /&gt;
      // guarented to decide with the World.GetCurrentModule method to be in the &lt;br /&gt;
      // returned module! &lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTCRANE GOT MESSAGE [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;OBJECTINIT&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        if (msg.minor==&amp;quot;INIT_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // Not used yet&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (msg.minor==&amp;quot;SETPROPS_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          if (ObjectDataSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadObjectDataInfos(ObjectDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;goid&amp;quot;,objectgoid);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;type&amp;quot;,objecttype);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;regID&amp;quot;,-1);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;active&amp;quot;,false);&lt;br /&gt;
            //ObjectDataSoup.SetNamedTag(&amp;quot;requested&amp;quot;,false);&lt;br /&gt;
            //ObjectDataSoup.SetNamedTag(&amp;quot;hooked&amp;quot;,false);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_reacharea_x&amp;quot;,cranebase_reacharea_x);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_reacharea_y&amp;quot;,cranebase_reacharea_y);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_reacharea_z&amp;quot;,cranebase_reacharea_z);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_origin_inset_x&amp;quot;,cranebase_origin_inset_x);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_origin_inset_y&amp;quot;,cranebase_origin_inset_y);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_origin_inset_z&amp;quot;,cranebase_origin_inset_z);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;max_container_count&amp;quot;,max_container_count);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot; =&amp;gt; SOUP &#039;ObjectDataSoup&#039;&amp;quot;);&lt;br /&gt;
          if (acts_debug) actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
          if (LocationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadLocationDataInfos(LocationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            WorldCoordinate WC = me.GetMapObjectPosition();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bbx&amp;quot;,WC.baseboardX);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bby&amp;quot;,WC.baseboardY);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;px&amp;quot;,WC.x);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;py&amp;quot;,WC.y);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;pz&amp;quot;,WC.z);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (OrientationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadOrientationDataInfos(OrientationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            Orientation OR = me.GetMapObjectOrientation();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rx&amp;quot;,OR.rx);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;ry&amp;quot;,OR.ry);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rz&amp;quot;,OR.rz);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gx&amp;quot;,OR.rx*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gy&amp;quot;,OR.ry*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gz&amp;quot;,OR.rz*180.0/Math.PI);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // TBD: Adjust position and rotation to rounded values and handle&lt;br /&gt;
          //      the different pssibilities.&lt;br /&gt;
          //      (some methods see acts_tools_script.gs)&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Soup sp = actsTools.AutoAdjustMapObject(cast&amp;lt;MapObject&amp;gt;(me));&lt;br /&gt;
          // LocationSoup    = sp.GetNamedSoup(&amp;quot;AdjustedLocationSoup&amp;quot;);&lt;br /&gt;
          // OrientationSoup = sp.GetNamedSoup(&amp;quot;AdjustedOrientationSoup&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (msg.minor==&amp;quot;WORLD_INIT_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Do no module only, driver module only or surveyor module only&lt;br /&gt;
          // related initiations&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (World.GetCurrentModule() == World.DRIVER_MODULE)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            PostMessage(cast&amp;lt;GameObject&amp;gt;dispobj,&lt;br /&gt;
                                 &amp;quot;REGISTER&amp;quot;, &amp;quot;REGISTER_ME&amp;quot;, ObjectDataSoup, 0.0);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (World.GetCurrentModule() == World.SURVEYOR_MODULE)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // Not used yet&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (World.GetCurrentModule() == World.NO_MODULE)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // Not used yet&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void DispatcherHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;DISPATCHER&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;] [&amp;quot;&lt;br /&gt;
                + &amp;quot; CONTCRANE GOT MESSAGE FROM DISPATCHER&amp;quot;&lt;br /&gt;
                + (cast&amp;lt;GameObject&amp;gt;msg.src).GetGameObjectID().SerialiseToString()&lt;br /&gt;
                + &amp;quot;] [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
        //-----------------------------------------------------------------------*/&lt;br /&gt;
        if (msg.minor==&amp;quot;OBJECTSOUP_UPDATED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;OBJECTSOUP_INSERTED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;OBJECTSOUP_APPENDED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrane_reachable.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_bridgecrane_globals.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_reachable.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  //   acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  //   acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  // X acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  // X acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  //   acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_moving isclass acts_bridgecrane_globals&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // Set zeroframe translations for the asset parts&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int bridge_zeroframe  = cranebase_origin_inset_y;&lt;br /&gt;
    int trolley_zeroframe = cranebase_origin_inset_x;&lt;br /&gt;
    int lift_zeroframe  = 0;     // Scale 1.000..25.000 (cranebase_reacharea_z)&lt;br /&gt;
    int rotor_zeroframe = 900;   // Decimal degree -90.0..+90.0 (precision 0.1°)&lt;br /&gt;
    int gear_zeroframe  = 2991;  // Scale 1.000-2.991-6.058-12.192-13.716-16.154&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    void moveCranePartsToZeroframe(void)&lt;br /&gt;
    {&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;bridge-lod0&amp;quot;,  bridge_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;trolley-lod0&amp;quot;, trolley_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;lift-lod0&amp;quot;,    lift_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;rotor-lod0&amp;quot;,   rotor_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;gear-lod0&amp;quot;,    gear_zeroframe);&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Where and when setting the fitting containers skin?&lt;br /&gt;
    //      Asset skins = GetAsset().FindAsset(&amp;quot;skinskuid&amp;quot;);&lt;br /&gt;
    //      SetFXTextureReplacement(&amp;quot;skincolor40ftsc&amp;quot;,skins,8);&lt;br /&gt;
    //      SetMeshVisible(&amp;quot;cont40ftsc-lod0&amp;quot;, true);&lt;br /&gt;
    //      me.SetMeshAnimationFrame(&amp;quot;gear-lod0&amp;quot;, 12191.0, 3.0);&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  /******************************************************************************&lt;br /&gt;
    -----------------------------------------------------------------------------&lt;br /&gt;
    In conjunction with the rotation of the cranearea there ar four cases to&lt;br /&gt;
    know about if a point lies within the reacharea, bounding edges are assumed&lt;br /&gt;
    to be outside.&lt;br /&gt;
    &lt;br /&gt;
     A B    B    &lt;br /&gt;
     D C   A C     0° ≤ w &amp;lt; 90°   CD &amp;lt; py &amp;lt; AB and AD &amp;lt; px &amp;lt; BC&lt;br /&gt;
            D&lt;br /&gt;
    &lt;br /&gt;
     B C    C&lt;br /&gt;
     A D   B D   90° ≤ w &amp;lt; 180°   AD &amp;lt; py &amp;lt; BC and AB &amp;lt; px &amp;lt; CD&lt;br /&gt;
            A&lt;br /&gt;
    &lt;br /&gt;
     C D    D &lt;br /&gt;
     B A   C A  180° ≤ w &amp;lt; 270°   AB &amp;lt; py &amp;lt; CD and BC &amp;lt; px &amp;lt; AD   &lt;br /&gt;
            B&lt;br /&gt;
  &lt;br /&gt;
     D A    A    &lt;br /&gt;
     C B   D B  270° ≤ w &amp;lt; 360°   BC &amp;lt; py &amp;lt; AD and CD &amp;lt; px &amp;lt; AB&lt;br /&gt;
            C&lt;br /&gt;
    -----------------------------------------------------------------------------&lt;br /&gt;
  *******************************************************************************/&lt;br /&gt;
  class acts_bridgecrane_reachable isclass acts_bridgecrane_moving&lt;br /&gt;
  {&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Loading values from config.txt extensions-219486 cranedata soup&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    void LoadCraneDataInfos(Soup sp)&lt;br /&gt;
    {&lt;br /&gt;
      cranebase_reacharea_x          &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_reacharea_x&amp;quot;,0);&lt;br /&gt;
      cranebase_reacharea_y          &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_reacharea_y&amp;quot;,0);&lt;br /&gt;
      cranebase_reacharea_z          &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_reacharea_z&amp;quot;,0);&lt;br /&gt;
      cranebase_origin_inset_x              &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_inset_x&amp;quot;,0);&lt;br /&gt;
      cranebase_origin_inset_y              &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_inset_y&amp;quot;,0);&lt;br /&gt;
      cranebase_origin_inset_z              &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_inset_z&amp;quot;,0);&lt;br /&gt;
      trolley_bottom_height   &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;trolley_bottom_height&amp;quot;,0);&lt;br /&gt;
      lift_bottom_height &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;lift_bottom_height&amp;quot;,0);&lt;br /&gt;
      gear_bottom_height &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;gear_bottom_height&amp;quot;,0);&lt;br /&gt;
      max_container_count&lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;max_container_count&amp;quot;,0);&lt;br /&gt;
    }&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Returns the vertices of the reacharea rectangle. The insets and dimensions&lt;br /&gt;
    // where deliverd over a objects config extension subsoup. Rotations x and y &lt;br /&gt;
    // are zero.&lt;br /&gt;
    //  A---+-----B&lt;br /&gt;
    //  |   ix    |   ix insetx, iy insety&lt;br /&gt;
    //  |iy-O-----+   dx=AD=BC dimensionx, dy=AB=CD dimensiony&lt;br /&gt;
    //  |   |     |   RC[0..3]&amp;lt;=&amp;gt;ABCD &lt;br /&gt;
    //  D---+-----C&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public WorldCoordinate[] GetReachareaCorners()&lt;br /&gt;
    {&lt;br /&gt;
      WorldCoordinate[] RC = new WorldCoordinate[4];    // Reacharea corners ABCD&lt;br /&gt;
      WorldCoordinate OR = me.GetMapObjectPosition();   // Origin of crane OR&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[0].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[0].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[0].x = OR.x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[0].y = OR.y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[0].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[1].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[1].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[1].x = OR.x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[1].y = OR.y + cranebase_reacharea_y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[1].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[2].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[2].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[2].x = OR.x + cranebase_reacharea_x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[2].y = OR.y + cranebase_reacharea_y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[2].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[3].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[3].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[3].x = OR.x + cranebase_reacharea_x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[3].y = OR.y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[3].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return RC;&lt;br /&gt;
    }&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // The two point straight line formulas for x and y for the points A and B:&lt;br /&gt;
    //       (by-ay)                        (bx-ax)&lt;br /&gt;
    //   y = ------- * (x-ax) + by      x = ------- * (y-ay) + bx&lt;br /&gt;
    //       (bx-ax)                        (by-ay)&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public float ValueXStraightline(&lt;br /&gt;
                   WorldCoordinate P, WorldCoordinate A, WorldCoordinate B)&lt;br /&gt;
    { if (A.y==B.y) return A.y;&lt;br /&gt;
      else return cast&amp;lt;float&amp;gt;((B.x-A.x)*(P.y-A.y)/(B.y-A.y)); &lt;br /&gt;
      return 0.0;&lt;br /&gt;
    }&lt;br /&gt;
    public float ValueYStraightline(&lt;br /&gt;
                   WorldCoordinate P, WorldCoordinate A, WorldCoordinate B)&lt;br /&gt;
    { if (A.x==B.x) return A.x;&lt;br /&gt;
      else return cast&amp;lt;float&amp;gt;((B.y-A.y)*(P.x-A.x)/(B.x-A.x));&lt;br /&gt;
      return 0.0;&lt;br /&gt;
    }&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // InsideReacharea returns true if the point is reachable, otherwise false.&lt;br /&gt;
    // Edges of the reacharea rectangle are assumed outside.&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public bool InsideReacharea(WorldCoordinate P, WorldCoordinate[] W)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Adjust the point to the same baseboard as the container crane&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      WorldCoordinate SP = actsTools.WCoordAdjustBaseboard(P,me.GetMapObjectPosition());&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Calculate the case to proof&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      float rz = me.GetMapObjectOrientation().rz;&lt;br /&gt;
      int wi = cast&amp;lt;int&amp;gt;(rz*180*100/Math.PI);     // int rounded to 1/100&lt;br /&gt;
      int ri = wi/(90*100);&lt;br /&gt;
      while (ri&amp;lt;0) ri=ri+4;&lt;br /&gt;
      while (ri&amp;gt;3) ri=ri-4;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Values of the edges (straight ölines) for the point coordinates&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      float xAB = ValueXStraightline(P, W[0], W[1]);&lt;br /&gt;
      float yAB = ValueYStraightline(P, W[0], W[1]);&lt;br /&gt;
      float xBC = ValueXStraightline(P, W[1], W[2]);&lt;br /&gt;
      float yBC = ValueYStraightline(P, W[1], W[2]);&lt;br /&gt;
      float xCD = ValueXStraightline(P, W[2], W[3]);&lt;br /&gt;
      float yCD = ValueYStraightline(P, W[2], W[3]);&lt;br /&gt;
      float xAD = ValueXStraightline(P, W[0], W[3]);&lt;br /&gt;
      float yAD = ValueYStraightline(P, W[0], W[3]);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Calculating the resulting bool value&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      switch(ri)&lt;br /&gt;
      {&lt;br /&gt;
        case 0:  //  0° &amp;lt;= rz° &amp;lt;  90°&lt;br /&gt;
          if(yCD &amp;lt; P.y and P.y &amp;lt; yAB and xAD &amp;lt; P.x and P.x &amp;lt; xBC) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        case 1:  //  90° &amp;lt;= rz° &amp;lt; 180°&lt;br /&gt;
          if(yAD &amp;lt; P.y and P.y &amp;lt; yBC and xAB &amp;lt; P.x and P.x &amp;lt; xCD) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        case 2:  // 180° &amp;lt;= rz° &amp;lt; 270°&lt;br /&gt;
          if(yAB &amp;lt; P.y and P.y &amp;lt; yCD and xBC &amp;lt; P.x and P.x &amp;lt; xAD) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        case 3:  // 270° &amp;lt;= rz° &amp;lt; 360°&lt;br /&gt;
          if(yBC &amp;lt; P.y and P.y &amp;lt; yAD and xCD &amp;lt; P.x and P.x &amp;lt; xAB) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        default:&lt;br /&gt;
          return false;&lt;br /&gt;
      }&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    &lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrain_globals.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_global_values.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //---------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_globals.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  //   acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  //   acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  //   acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  //   acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  // X acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_globals isclass acts_global_values&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // AssetInstanceSoup {&lt;br /&gt;
    // X ObjectDataSoup { ... },    Only container, contstack, contcrane&lt;br /&gt;
    // X LocationSoup { ... },      Only container, contstack, contcrane&lt;br /&gt;
    // X OrientationSoup { ... },   Only container, contstack, contcrane&lt;br /&gt;
    //   SkinDataSoup { ... },      Only container&lt;br /&gt;
    //   ContentDataSoup { ... },   Only container&lt;br /&gt;
    //   DispatcherDataSoup { ... } Only dispatcher&lt;br /&gt;
    //   ContainerSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContstackSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContcraneSoups  { ... }    Only dispatcher&lt;br /&gt;
    // }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // ObjectDataSoup { goid GameObjectID, type string,&lt;br /&gt;
    //                  length string, height string,  &lt;br /&gt;
    //                  stack goid, place int,           Only container&lt;br /&gt;
    //                  active bool, action string },&lt;br /&gt;
    // activ: true means the object sended a register message while session run&lt;br /&gt;
    //        All objects were set false while initialising dispatcher and if&lt;br /&gt;
    //        they stay false their entries will be deleted next initialising.&lt;br /&gt;
    // actions: [&amp;quot;APPENDED&amp;quot;, &amp;quot;INSERTED&amp;quot;, &amp;quot;UPDATED&amp;quot;];&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup ObjectDataSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // LocationSoup { bbx int, bby int,               // WorlCoordinate parameter&lt;br /&gt;
    //                px float, py float, pz float }&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    Soup LocationSoup = Constructors.NewSoup();&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    // OrientationSoup { rx float, ry float, rz float,    // in rad &lt;br /&gt;
    //                   gx float, gy float, gz float }   // in 1/10°&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    Soup OrientationSoup = Constructors.NewSoup();&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    GameObjectID objectgoid = me.GetGameObjectID();&lt;br /&gt;
    string       objecttype = &amp;quot;CONTCRANE&amp;quot;;&lt;br /&gt;
    Library      dispobj;&lt;br /&gt;
    GameObjectID dispgoid;&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // Reach area values of the bridge crane will be loaded from this assets&lt;br /&gt;
    // config.txt file &lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int cranebase_reacharea_x;      //  30000 in [mm]&lt;br /&gt;
    int cranebase_reacharea_y;      // 100000 in [mm]&lt;br /&gt;
    int cranebase_reacharea_z;      //  26000 in [mm]&lt;br /&gt;
    int cranebase_origin_inset_x;   //  15000 in [mm]&lt;br /&gt;
    int cranebase_origin_inset_y;   //  50000 in [mm]&lt;br /&gt;
    int cranebase_origin_inset_z;   //   5000 in [mm]&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int lift_zero_length = 1000;   // 1000 in [mm] mandatory length for animation&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int trolley_bottom_height;   // in [mm]&lt;br /&gt;
    int lift_bottom_height;      // in [mm] with lift z width as 1,000 [mm]&lt;br /&gt;
    int rotor_bottom_height;     // in [mm] with rotor z width as 500 [mm]&lt;br /&gt;
    int gear_bottom_height;      // in [mm] with gear z width as 500 [mm]&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: And not proofed yet. Differntiate between maximum container count&lt;br /&gt;
    //      for high cube and standard cube containers.&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // For now the maximum count is calculated from reacharea z dimension minus&lt;br /&gt;
    // one hc height to ensure the movement of containers by the crane. Because&lt;br /&gt;
    // of possibly different base heights of the stacks inside the crane&#039;s&lt;br /&gt;
    // reacharea, there are some more different (possibly smaller) maximum&lt;br /&gt;
    // stackheights.&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    int max_container_count;     // Construction based max stackable containers&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  /* ****************************************************************************&lt;br /&gt;
     This is the scripted bridge crane object for an active container terminal&lt;br /&gt;
     system (aCTS). It is a kind of prototype of a bridge crane to let&lt;br /&gt;
     constructors know how the things are fitting and working for aCTS.&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Some hints here too (see config description too):&lt;br /&gt;
     * The script logs dependin on the acts_debug variable (See&lt;br /&gt;
       acts.global_values.gs). So the script contains some overhead for testing&lt;br /&gt;
       informations. &lt;br /&gt;
     * Animations from Blender fbx runs from frame 1 ... n in Blender and fbx&lt;br /&gt;
       file. The import to Trainz will change this to frame 0 ... n-1, what is&lt;br /&gt;
       essential to know for precise transformations (moving and rotating) per&lt;br /&gt;
       animation frame.&lt;br /&gt;
     * The logical mesh hierarchy is as follows: cranebase--&amp;gt;&lt;br /&gt;
       --&amp;gt;cranebridge(py)--&amp;gt;trolley(px)--&amp;gt;lift(sz,pz)--&amp;gt;rotor(rz)--&amp;gt;gear(sx)&lt;br /&gt;
     * The cranes parts are imported to Trainz as own (animated) mesh objects&lt;br /&gt;
       with its respective origins at zero and its parented attachment points.&lt;br /&gt;
       All script calculations are based on this origin and the gaps to the&lt;br /&gt;
       attachment points for attaching the child meshes. The assets orientation&lt;br /&gt;
       is zero for x and y orientation.&lt;br /&gt;
     * The parent child hierarchy is realised within the mesh-table container.&lt;br /&gt;
     * The extensions values are in mm and define the reachable area of the&lt;br /&gt;
       cranes container gear. The dimensions x, y, z describe the cuboid&lt;br /&gt;
       length&#039;s, the gear may move and the insets x, y, z describes the location&lt;br /&gt;
       of the cranes origin within there.&lt;br /&gt;
     * The animations minimum frame 0 (resp. 1 in Blender) represents the locale&lt;br /&gt;
       relative minimal position (p = -inset) and the maximum frame (n = &lt;br /&gt;
       dimension) the maximal position p=dimension-inset. Example: &lt;br /&gt;
         dimension 80&lt;br /&gt;
         inset     30&lt;br /&gt;
         Trainz frames    0  10  20 30  40  50  60  70  80&lt;br /&gt;
         Blender frames   1  11  21 31  41  51  61  71  81&lt;br /&gt;
         Position       -30 -20 -10  0  10  20  30  40  50&lt;br /&gt;
     * The crane object (as well as the other object types) adjusts location to&lt;br /&gt;
       even mm and the orientation to 0.1 decimal degrees.&lt;br /&gt;
     * The movements of the cranes sub meshes will be realised with animation&lt;br /&gt;
       frame methods *MeshAnimation* from the MeshObject class in mashobject.gs&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Technical parameters for calculating script values 1 [mm] and 0.1 [°]&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Bridge  [BPY: 100,001F:    140m] BF[1 .. 100001] [0mm(1)100,000mm]&lt;br /&gt;
     Trolley [TPX:  30,001F:     30m] BF[1 ..  30001] [-15,000mm(1)+15,000mm]&lt;br /&gt;
     Lift    [LSZ:  25,001F:    1-26] BF[1 ..  25001] [1.000(0.001)26.000]&lt;br /&gt;
             [LPZ:  25,001F:     25m] BF[1 ..  25001] [+21,000mm(1)-5,000mm]&lt;br /&gt;
     Rotor   [ROZ:   1,801F:    180°] BF[1 ..   1801] [-90.0°(0.1)+90.0°]&lt;br /&gt;
     Gear    [GSY:  15,155F: 16.192m] BF[1 ..  16155] [1.000(0.001)16.154]&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Containertype                      10ft    20ft     40ft     45ft     53ft&lt;br /&gt;
     Gear scale scale/length  1.000m  2.991m  6.058m  12.192m  13.716m  16.154m&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     More informations are documented within the config.txt and script comments.&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     **************************************************************************** */&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ContainerBridgeCrane&amp;diff=40972</id>
		<title>ContainerBridgeCrane</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ContainerBridgeCrane&amp;diff=40972"/>
		<updated>2024-04-27T18:07:40Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* Animation frames */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Container Bridge Crane==&lt;br /&gt;
A bridge crane consists of several running parts. This parts are some kind of parented. The locical hirarchy of this parts look like this:&lt;br /&gt;
&lt;br /&gt;
 cranebase--&amp;gt;cranebridge(py)--&amp;gt;trolley(px)--&amp;gt;lift(sz,pz)--&amp;gt;rotor(rz)--&amp;gt;gear(sx)&lt;br /&gt;
   px, py, pz   animation move in x, y, z direction (moving in 1 mm steps)&lt;br /&gt;
   rx, ry, rz   animation rotation around x, y, z direction (rotation in 0.1° steps from -90.0° to +90.0° and zeroframe as -90.0°)&lt;br /&gt;
   sx, sy, sz   animation scale in x, y, z direction (zeroframe as 1.0 iss mandatory)&lt;br /&gt;
&lt;br /&gt;
===Reachable area===&lt;br /&gt;
The special reacharea parameters for the bridge crane prototype looking like follows:&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  acts.reacharea-251489 {&lt;br /&gt;
    reacharea.dimension.x       30000&lt;br /&gt;
    reacharea.dimension.y      100000&lt;br /&gt;
    reacharea.dimension.z       26000&lt;br /&gt;
    reacharea.origin_inset.x    15000&lt;br /&gt;
    reacharea.origin_inset.y    50000&lt;br /&gt;
    reacharea.origin_inset.z     5000&lt;br /&gt;
    max_container_count             7&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
This data are for this prototype bridge crane.&lt;br /&gt;
&lt;br /&gt;
===Animation frames===&lt;br /&gt;
The list of animation steps and values looks lik follows:&lt;br /&gt;
  Bridge (py)  100,001 Frames over     140m with BlenderFrames [1 .. 100001] for [  0,000 (  1  ) 100,000] in mm&lt;br /&gt;
  Trolley (px)  30,001 Frames over      30m with BlenderFrames [1 ..  30001] for [-15,000 (  1  ) +15,000] in mm&lt;br /&gt;
  Lift (sz)     25,001 Frames over     1-26 with BlenderFrames [1 ..  25001] for [  1.000 (0.001)  26.000]&lt;br /&gt;
  Lift (pz)     25,001 Frames over      25m with BlenderFrames [1 ..  25001] for [+21,000 (  1  )  -5,000] in mm&lt;br /&gt;
  Rotor (rz)     1,801 Frames over     180° with BlenderFrames [1 ..   1801] for [  -90.0 ( 0.1 )   +90.0] in ° (decimal grade)&lt;br /&gt;
  Gear (sy)     15,155 Frames over  16.154m with BlenderFrames [1 ..  15155] for [  1.000 (0.001)  16.154]&lt;br /&gt;
  ----------------------------------------------------------------------&lt;br /&gt;
  Containertype                  10ft    20ft     40ft     45ft     53ft&lt;br /&gt;
  Gear scale/length    1.000m  2.991m  6.058m  12.192m  13.716m  16.154m&lt;br /&gt;
&lt;br /&gt;
===Moving Containers===&lt;br /&gt;
The task to move a container from one stack to another is written as following:&lt;br /&gt;
  # move crane (gear) to the &amp;quot;fromStack&amp;quot;: stackWC,containerPosition and hook container&lt;br /&gt;
  # move crane (gear) to the &amp;quot;destStack&amp;quot;: stackWC,containerPosition and dehook container&lt;br /&gt;
To calculate the destination frames we need the distance vector from the crane&#039;s frame zero location to the top of the container position at the stack. Since the location is used as WorldCoordinate and the stack and crane may reside in different baseboards, the first step is to &amp;quot;normalize&amp;quot; the baseboards. In the following this is agreed.&lt;br /&gt;
&lt;br /&gt;
The crane&#039;s frame zero location is defined by the reacharea inset and will be calculated by containerStackTopWC minus craneOriginWC. The containerStackTopWC will be calculated by stackOriginWC plus stackPositionHeight. The stackPositionHeight is the sum of all stacked container&#039;s heights.&lt;br /&gt;
&lt;br /&gt;
As moving speed in x, y, z direction of the crane parts we will use 5.4 km/h (~3.35 mi/s). This leads to frameCount/1500 to calculate the duration in seconds.&lt;br /&gt;
&lt;br /&gt;
Now we are able to get the current frames list, the fromStack&#039;s frame list and the destStack&#039;s frame list to move the crane.&lt;br /&gt;
&lt;br /&gt;
==Asset files pre version 0.1==&lt;br /&gt;
The files compile errorless and the messaging runs well. No more functionality implemented and tested in this pre version.&lt;br /&gt;
&lt;br /&gt;
===config.txt===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  kuid               &amp;lt;kuid2:215489:110041:1&amp;gt;&lt;br /&gt;
  username           &amp;quot;aCTS CONTCRANE Animated Bridge Crane Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  kind               &amp;quot;Scenery&amp;quot;&lt;br /&gt;
  category-class     &amp;quot;BU&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  description        &amp;quot;aCTS CONTCRANE Animated Bridge Crane Scenery Utility V0.1&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  trainz-build       4.6&lt;br /&gt;
  &lt;br /&gt;
  script             &amp;quot;acts_bridgecrane.gs&amp;quot;&lt;br /&gt;
  class              &amp;quot;acts_bridgecrane&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  surveyor-only      0&lt;br /&gt;
  &lt;br /&gt;
  mesh-table-lod-transition-distances    1000&lt;br /&gt;
  mesh-detail-level-count                1&lt;br /&gt;
  &lt;br /&gt;
  kuid-table {&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
    skinskuid        &amp;lt;kuid2:215489:1100200:1&amp;gt;&lt;br /&gt;
    cont10ftsc       &amp;lt;kuid2:215489:1100211:1&amp;gt;&lt;br /&gt;
    cont10fthc       &amp;lt;kuid2:215489:1100212:1&amp;gt;&lt;br /&gt;
    cont20ftsc       &amp;lt;kuid2:215489:1100221:1&amp;gt;&lt;br /&gt;
    cont20fthc       &amp;lt;kuid2:215489:1100222:1&amp;gt;&lt;br /&gt;
    cont40ftsc       &amp;lt;kuid2:215489:1100231:1&amp;gt;&lt;br /&gt;
    cont40fthc       &amp;lt;kuid2:215489:1100232:1&amp;gt;&lt;br /&gt;
    cont45ftsc       &amp;lt;kuid2:215489:1100241:1&amp;gt;&lt;br /&gt;
    cont45fthc       &amp;lt;kuid2:215489:1100242:1&amp;gt;&lt;br /&gt;
    cont53ftsc       &amp;lt;kuid2:215489:1100251:1&amp;gt;&lt;br /&gt;
    cont53fthc       &amp;lt;kuid2:215489:1100252:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  script-include-table {&lt;br /&gt;
    scriptinclude    &amp;lt;kuid2:215489:110000:1&amp;gt;&lt;br /&gt;
    skincolor        &amp;lt;kuid2:215489:1100200:1&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  extensions&lt;br /&gt;
  {&lt;br /&gt;
    reacharea-215489&lt;br /&gt;
    {&lt;br /&gt;
      cranebase_dimension_x       30000&lt;br /&gt;
      cranebase_dimension_y      100000&lt;br /&gt;
      cranebase_dimension_z       26000&lt;br /&gt;
      cranebase_origin_inset_x    15000&lt;br /&gt;
      cranebase_origin_inset_y    50000&lt;br /&gt;
      cranebase_origin_inset_z     5000&lt;br /&gt;
      max_container_count             7&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  mesh-table&lt;br /&gt;
  {&lt;br /&gt;
    cranebase-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cranebase.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
    }&lt;br /&gt;
    bridge-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_bridge.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att-parent             &amp;quot;cranebase-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_bridge_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    trolley-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_trolley.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.bridge&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;bridge-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_trolley_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    lift-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_lift.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.trolley&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;trolley-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_lift_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    rotor-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_rotor.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.lift&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;lift-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_rotor_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   0.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    gear-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_gear.trainzmesh&amp;quot;&lt;br /&gt;
      auto-create            1&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.rotor&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;rotor-lod0&amp;quot;&lt;br /&gt;
      anim                   &amp;quot;acts_gear_scene.kin&amp;quot;&lt;br /&gt;
      animation-loop-speed   1.0&lt;br /&gt;
      critical-animation     0&lt;br /&gt;
    }&lt;br /&gt;
    cont10ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_10ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100211:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor10ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont10fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_10fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100212:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor10fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont20ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_20ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100221:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor20ftsc&lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont20fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_20fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100222:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor20fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont40ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_40ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100231:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor40ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont40fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_40fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100232:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor40fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont45ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_45ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100241:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor45ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont45fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_45fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100242:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor45fthc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont53ftsc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_53ftsc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100251:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.sccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor53ftsc &lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    cont53fthc-lod0&lt;br /&gt;
    {&lt;br /&gt;
      mesh                   &amp;quot;acts_cont_53fthc.trainzmesh&amp;quot;&lt;br /&gt;
      mesh-asset             &amp;lt;kuid2:215489:1100252:1&amp;gt;&lt;br /&gt;
      auto-create            0&lt;br /&gt;
      lod-level              0&lt;br /&gt;
      att                    &amp;quot;a.queue.hccontainer&amp;quot;&lt;br /&gt;
      att-parent             &amp;quot;gear-lod0&amp;quot;&lt;br /&gt;
      effects &lt;br /&gt;
      {&lt;br /&gt;
        skincolor53fthc&lt;br /&gt;
        {&lt;br /&gt;
          kind       &amp;quot;texture-replacement&amp;quot;&lt;br /&gt;
          texture    &amp;quot;acts_container_allinone.texture&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  thumbnails&lt;br /&gt;
  {&lt;br /&gt;
    0&lt;br /&gt;
    {&lt;br /&gt;
      image                  &amp;quot;acts_bridgecrane_thumb.jpg&amp;quot;&lt;br /&gt;
      width                  240&lt;br /&gt;
      height                 180&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrane.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_bridgecrane_script.gs&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // X acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  //   acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  //   acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  //   acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  //   acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  //   acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane isclass acts_bridgecrane_script&lt;br /&gt;
  {&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Mandatory INIT method&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    public void Init(Asset asset)&lt;br /&gt;
    {&lt;br /&gt;
      inherited(asset);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Make shure that the right module is set for World.GetCurrentModle()&lt;br /&gt;
      // (see world.gs lines 939ff.) to start driver related initiations and&lt;br /&gt;
      // tell me, if my Init and SetProperties methods are finished.&lt;br /&gt;
      // Add handler for my tasks as dispatcher.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      AddHandler(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, &amp;quot;WorldInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;ObjectInitHandler&amp;quot;);&lt;br /&gt;
      AddHandler(me, &amp;quot;DISPATCHER&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;DispatcherHandler&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // It&#039;s nessecary to initalise the lib to force subscript preparing&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      //World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;dummylibrary&amp;quot;));&lt;br /&gt;
      dispobj = World.GetLibrary(GetAsset().LookupKUIDTable(&amp;quot;scriptinclude&amp;quot;));&lt;br /&gt;
      dispgoid = (cast&amp;lt;GameObject&amp;gt;dispobj).GetGameObjectID();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Load reacharea and other values from extension soup in my config.txt&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      Soup csp = me.GetAsset().GetConfigSoupCached();&lt;br /&gt;
      csp = csp.GetNamedSoup(&amp;quot;extensions&amp;quot;);&lt;br /&gt;
      csp = csp.GetNamedSoup(&amp;quot;reacharea-215489&amp;quot;);&lt;br /&gt;
      cranebase_reacharea_x    = csp.GetNamedTagAsInt(&amp;quot;cranebase_dimension_x&amp;quot;   );&lt;br /&gt;
      cranebase_reacharea_y    = csp.GetNamedTagAsInt(&amp;quot;cranebase_dimension_y&amp;quot;   );&lt;br /&gt;
      cranebase_reacharea_z    = csp.GetNamedTagAsInt(&amp;quot;cranebase_dimension_z&amp;quot;   );&lt;br /&gt;
      cranebase_origin_inset_x = csp.GetNamedTagAsInt(&amp;quot;cranebase_origin_inset_x&amp;quot;);&lt;br /&gt;
      cranebase_origin_inset_y = csp.GetNamedTagAsInt(&amp;quot;cranebase_origin_inset_y&amp;quot;);&lt;br /&gt;
      cranebase_origin_inset_z = csp.GetNamedTagAsInt(&amp;quot;cranebase_origin_inset_z&amp;quot;);&lt;br /&gt;
      max_container_count      = csp.GetNamedTagAsInt(&amp;quot;max_container_count&amp;quot;     );&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      moveCranePartsToZeroframe();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isInitMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;INIT_FINNISHED&amp;quot;,0);   // Init method finnished&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }    &lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrane_script.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_bridgecrane_reachable.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_script.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  // X acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  // X acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  //   acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  //   acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  //   acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_register isclass acts_bridgecrane_reachable&lt;br /&gt;
  {&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Outsource from acts_bridgecrane_script&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_script isclass acts_bridgecrane_register&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // public void SetProperties(Soup soup) ....................... ca. line  23&lt;br /&gt;
    // public Soup GetProperties(void) ............................ ca. line  85&lt;br /&gt;
    // public void ObjectInitHandler(Message msg) ................. ca. line 100&lt;br /&gt;
    // public void WorldInitHandler(Message msg) .................. ca. line 132&lt;br /&gt;
    // public void DispatcherHandler(Message msg) ................. ca. line 183&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void SetProperties(Soup soup)   // Callback method after Init method&lt;br /&gt;
    {&lt;br /&gt;
      inherited(soup);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      ObjectDataSoup.Copy(soup.GetNamedSoup(&amp;quot;ObjectData&amp;quot;));&lt;br /&gt;
      LocationSoup.Copy(soup.GetNamedSoup(&amp;quot;Location&amp;quot;));&lt;br /&gt;
      OrientationSoup.Copy(soup.GetNamedSoup(&amp;quot;Orientation&amp;quot;)) ;&lt;br /&gt;
      /*/-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot;CONTCRANE SETPROPERTIES SOUPS&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(ObjectDataSoup,&amp;quot;ObjDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(LocationSoup,&amp;quot;LocDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(OrientationSoup,&amp;quot;OriDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      isSetPropertiesMethodFinnished = true;&lt;br /&gt;
      PostMessage(me,&amp;quot;OBJECTINIT&amp;quot;,&amp;quot;SETPROPS_FINNISHED&amp;quot;,0.0);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public Soup GetProperties(void)   // Callback method before closing session&lt;br /&gt;
    {&lt;br /&gt;
      Soup soup = inherited();&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;ObjectData&amp;quot;,ObjectDataSoup);&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Location&amp;quot;,LocationSoup    );&lt;br /&gt;
      soup.SetNamedSoup(&amp;quot;Orientation&amp;quot;,OrientationSoup );&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot;CONTCRANE GETPROPERTIES SOUPS&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(ObjectDataSoup,&amp;quot;ObjDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(LocationSoup,&amp;quot;LocDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      if (acts_debug) actsTools.ShowSoup(OrientationSoup,&amp;quot;OriDS=&amp;gt;&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      return soup;&lt;br /&gt;
    } &lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void WorldInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTCRANE GOT WORLDINIT MESSAGE [&amp;quot;&lt;br /&gt;
              + msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      // If one of the two methods (Init or SetProperties) isn&#039;t finished yet, &lt;br /&gt;
      // post &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message a little bit later again.&lt;br /&gt;
      // So it is guaranteed that the Init and SetProperties methods are finished&lt;br /&gt;
      // as well as the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message tells to be save using the &lt;br /&gt;
      // World.GetCurrentModule method.&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (!(isSetPropertiesMethodFinnished and isInitMethodFinnished))&lt;br /&gt;
      {&lt;br /&gt;
        PostMessage(me, &amp;quot;World&amp;quot;, &amp;quot;ModuleInit&amp;quot;, 0.2);&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      isWorldInitFinnished = true;&lt;br /&gt;
      PostMessage(me, &amp;quot;OBJECTINIT&amp;quot;, &amp;quot;WORLD_INIT_FINNISHED&amp;quot;, 0.0);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void ObjectInitHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Until the Trainz core send the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; was send it is not&lt;br /&gt;
      // guarented to decide with the World.GetCurrentModule method to be in the &lt;br /&gt;
      // returned module! &lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
              + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;]&amp;quot;&lt;br /&gt;
              + &amp;quot; CONTCRANE GOT MESSAGE [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
      //-------------------------------------------------------------------------*/&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;OBJECTINIT&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        if (msg.minor==&amp;quot;INIT_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // Not used yet&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (msg.minor==&amp;quot;SETPROPS_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          if (ObjectDataSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadObjectDataInfos(ObjectDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;goid&amp;quot;,objectgoid);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;type&amp;quot;,objecttype);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;regID&amp;quot;,-1);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;active&amp;quot;,false);&lt;br /&gt;
            //ObjectDataSoup.SetNamedTag(&amp;quot;requested&amp;quot;,false);&lt;br /&gt;
            //ObjectDataSoup.SetNamedTag(&amp;quot;hooked&amp;quot;,false);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_reacharea_x&amp;quot;,cranebase_reacharea_x);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_reacharea_y&amp;quot;,cranebase_reacharea_y);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_reacharea_z&amp;quot;,cranebase_reacharea_z);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_origin_inset_x&amp;quot;,cranebase_origin_inset_x);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_origin_inset_y&amp;quot;,cranebase_origin_inset_y);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;cranebase_origin_inset_z&amp;quot;,cranebase_origin_inset_z);&lt;br /&gt;
            ObjectDataSoup.SetNamedTag(&amp;quot;max_container_count&amp;quot;,max_container_count);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                      + &amp;quot; =&amp;gt; SOUP &#039;ObjectDataSoup&#039;&amp;quot;);&lt;br /&gt;
          if (acts_debug) actsTools.ShowSoup(ObjectDataSoup,&amp;quot;=&amp;gt;&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
          if (LocationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadLocationDataInfos(LocationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            WorldCoordinate WC = me.GetMapObjectPosition();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bbx&amp;quot;,WC.baseboardX);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;bby&amp;quot;,WC.baseboardY);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;px&amp;quot;,WC.x);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;py&amp;quot;,WC.y);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;pz&amp;quot;,WC.z);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (OrientationSoup.CountTags()==0)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // LoadOrientationDataInfos(OrientationDataSoup);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            Orientation OR = me.GetMapObjectOrientation();&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rx&amp;quot;,OR.rx);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;ry&amp;quot;,OR.ry);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;rz&amp;quot;,OR.rz);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gx&amp;quot;,OR.rx*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gy&amp;quot;,OR.ry*180.0/Math.PI);&lt;br /&gt;
            LocationSoup.SetNamedTag(&amp;quot;gz&amp;quot;,OR.rz*180.0/Math.PI);&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // TBD: Adjust position and rotation to rounded values and handle&lt;br /&gt;
          //      the different pssibilities.&lt;br /&gt;
          //      (some methods see acts_tools_script.gs)&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Soup sp = actsTools.AutoAdjustMapObject(cast&amp;lt;MapObject&amp;gt;(me));&lt;br /&gt;
          // LocationSoup    = sp.GetNamedSoup(&amp;quot;AdjustedLocationSoup&amp;quot;);&lt;br /&gt;
          // OrientationSoup = sp.GetNamedSoup(&amp;quot;AdjustedOrientationSoup&amp;quot;);&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
        }&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (msg.minor==&amp;quot;WORLD_INIT_FINNISHED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Do no module only, driver module only or surveyor module only&lt;br /&gt;
          // related initiations&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (World.GetCurrentModule() == World.DRIVER_MODULE)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            PostMessage(cast&amp;lt;GameObject&amp;gt;dispobj,&lt;br /&gt;
                                 &amp;quot;REGISTER&amp;quot;, &amp;quot;REGISTER_ME&amp;quot;, ObjectDataSoup, 0.0);&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (World.GetCurrentModule() == World.SURVEYOR_MODULE)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // Not used yet&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
          }&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          if (World.GetCurrentModule() == World.NO_MODULE)&lt;br /&gt;
          {&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
            // Not used yet&lt;br /&gt;
            //-------------------------------------------------------------------&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public void DispatcherHandler(Message msg)&lt;br /&gt;
    {&lt;br /&gt;
      if (msg.dst==me and msg.major==&amp;quot;DISPATCHER&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        //-----------------------------------------------------------------------&lt;br /&gt;
        if (acts_debug) Interface.Log(Interface.GetTimeStamp()&lt;br /&gt;
                + &amp;quot; [&amp;quot; + objectgoid.SerialiseToString() + &amp;quot;] [&amp;quot;&lt;br /&gt;
                + &amp;quot; CONTCRANE GOT MESSAGE FROM DISPATCHER&amp;quot;&lt;br /&gt;
                + (cast&amp;lt;GameObject&amp;gt;msg.src).GetGameObjectID().SerialiseToString()&lt;br /&gt;
                + &amp;quot;] [&amp;quot;+msg.major+&amp;quot;] [&amp;quot;+msg.minor+&amp;quot;]&amp;quot;);&lt;br /&gt;
        //-----------------------------------------------------------------------*/&lt;br /&gt;
        if (msg.minor==&amp;quot;OBJECTSOUP_UPDATED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;OBJECTSOUP_INSERTED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
        if (msg.minor==&amp;quot;OBJECTSOUP_APPENDED&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          // Update the own ObjectDataSoup&lt;br /&gt;
          //---------------------------------------------------------------------&lt;br /&gt;
          ObjectDataSoup.Copy(cast&amp;lt;Soup&amp;gt;msg.paramSoup);&lt;br /&gt;
          //---------------------------------------------------------------------*/&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrane_reachable.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_bridgecrane_globals.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_reachable.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  //   acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  //   acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  // X acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  // X acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  //   acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_moving isclass acts_bridgecrane_globals&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // Set zeroframe translations for the asset parts&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int bridge_zeroframe  = cranebase_origin_inset_y;&lt;br /&gt;
    int trolley_zeroframe = cranebase_origin_inset_x;&lt;br /&gt;
    int lift_zeroframe  = 0;     // Scale 1.000..25.000 (cranebase_reacharea_z)&lt;br /&gt;
    int rotor_zeroframe = 900;   // Decimal degree -90.0..+90.0 (precision 0.1°)&lt;br /&gt;
    int gear_zeroframe  = 2991;  // Scale 1.000-2.991-6.058-12.192-13.716-16.154&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    void moveCranePartsToZeroframe(void)&lt;br /&gt;
    {&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;bridge-lod0&amp;quot;,  bridge_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;trolley-lod0&amp;quot;, trolley_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;lift-lod0&amp;quot;,    lift_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;rotor-lod0&amp;quot;,   rotor_zeroframe);&lt;br /&gt;
      me.SetMeshAnimationFrame(&amp;quot;gear-lod0&amp;quot;,    gear_zeroframe);&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: Where and when setting the fitting containers skin?&lt;br /&gt;
    //      Asset skins = GetAsset().FindAsset(&amp;quot;skinskuid&amp;quot;);&lt;br /&gt;
    //      SetFXTextureReplacement(&amp;quot;skincolor40ftsc&amp;quot;,skins,8);&lt;br /&gt;
    //      SetMeshVisible(&amp;quot;cont40ftsc-lod0&amp;quot;, true);&lt;br /&gt;
    //      me.SetMeshAnimationFrame(&amp;quot;gear-lod0&amp;quot;, 12191.0, 3.0);&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  /******************************************************************************&lt;br /&gt;
    -----------------------------------------------------------------------------&lt;br /&gt;
    In conjunction with the rotation of the cranearea there ar four cases to&lt;br /&gt;
    know about if a point lies within the reacharea, bounding edges are assumed&lt;br /&gt;
    to be outside.&lt;br /&gt;
    &lt;br /&gt;
     A B    B    &lt;br /&gt;
     D C   A C     0° ≤ w &amp;lt; 90°   CD &amp;lt; py &amp;lt; AB and AD &amp;lt; px &amp;lt; BC&lt;br /&gt;
            D&lt;br /&gt;
    &lt;br /&gt;
     B C    C&lt;br /&gt;
     A D   B D   90° ≤ w &amp;lt; 180°   AD &amp;lt; py &amp;lt; BC and AB &amp;lt; px &amp;lt; CD&lt;br /&gt;
            A&lt;br /&gt;
    &lt;br /&gt;
     C D    D &lt;br /&gt;
     B A   C A  180° ≤ w &amp;lt; 270°   AB &amp;lt; py &amp;lt; CD and BC &amp;lt; px &amp;lt; AD   &lt;br /&gt;
            B&lt;br /&gt;
  &lt;br /&gt;
     D A    A    &lt;br /&gt;
     C B   D B  270° ≤ w &amp;lt; 360°   BC &amp;lt; py &amp;lt; AD and CD &amp;lt; px &amp;lt; AB&lt;br /&gt;
            C&lt;br /&gt;
    -----------------------------------------------------------------------------&lt;br /&gt;
  *******************************************************************************/&lt;br /&gt;
  class acts_bridgecrane_reachable isclass acts_bridgecrane_moving&lt;br /&gt;
  {&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Loading values from config.txt extensions-219486 cranedata soup&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    void LoadCraneDataInfos(Soup sp)&lt;br /&gt;
    {&lt;br /&gt;
      cranebase_reacharea_x          &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_reacharea_x&amp;quot;,0);&lt;br /&gt;
      cranebase_reacharea_y          &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_reacharea_y&amp;quot;,0);&lt;br /&gt;
      cranebase_reacharea_z          &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_reacharea_z&amp;quot;,0);&lt;br /&gt;
      cranebase_origin_inset_x              &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_inset_x&amp;quot;,0);&lt;br /&gt;
      cranebase_origin_inset_y              &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_inset_y&amp;quot;,0);&lt;br /&gt;
      cranebase_origin_inset_z              &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;cranebase_inset_z&amp;quot;,0);&lt;br /&gt;
      trolley_bottom_height   &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;trolley_bottom_height&amp;quot;,0);&lt;br /&gt;
      lift_bottom_height &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;lift_bottom_height&amp;quot;,0);&lt;br /&gt;
      gear_bottom_height &lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;gear_bottom_height&amp;quot;,0);&lt;br /&gt;
      max_container_count&lt;br /&gt;
        = sp.GetNamedTagAsInt(&amp;quot;max_container_count&amp;quot;,0);&lt;br /&gt;
    }&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // Returns the vertices of the reacharea rectangle. The insets and dimensions&lt;br /&gt;
    // where deliverd over a objects config extension subsoup. Rotations x and y &lt;br /&gt;
    // are zero.&lt;br /&gt;
    //  A---+-----B&lt;br /&gt;
    //  |   ix    |   ix insetx, iy insety&lt;br /&gt;
    //  |iy-O-----+   dx=AD=BC dimensionx, dy=AB=CD dimensiony&lt;br /&gt;
    //  |   |     |   RC[0..3]&amp;lt;=&amp;gt;ABCD &lt;br /&gt;
    //  D---+-----C&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public WorldCoordinate[] GetReachareaCorners()&lt;br /&gt;
    {&lt;br /&gt;
      WorldCoordinate[] RC = new WorldCoordinate[4];    // Reacharea corners ABCD&lt;br /&gt;
      WorldCoordinate OR = me.GetMapObjectPosition();   // Origin of crane OR&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[0].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[0].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[0].x = OR.x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[0].y = OR.y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[0].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[1].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[1].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[1].x = OR.x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[1].y = OR.y + cranebase_reacharea_y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[1].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[2].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[2].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[2].x = OR.x + cranebase_reacharea_x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[2].y = OR.y + cranebase_reacharea_y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[2].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      RC[3].baseboardX = OR.baseboardX;&lt;br /&gt;
      RC[3].baseboardY = OR.baseboardY;&lt;br /&gt;
      RC[3].x = OR.x + cranebase_reacharea_x - cranebase_origin_inset_x;&lt;br /&gt;
      RC[3].y = OR.y - cranebase_origin_inset_y;&lt;br /&gt;
      RC[3].z = OR.z;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      return RC;&lt;br /&gt;
    }&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // The two point straight line formulas for x and y for the points A and B:&lt;br /&gt;
    //       (by-ay)                        (bx-ax)&lt;br /&gt;
    //   y = ------- * (x-ax) + by      x = ------- * (y-ay) + bx&lt;br /&gt;
    //       (bx-ax)                        (by-ay)&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public float ValueXStraightline(&lt;br /&gt;
                   WorldCoordinate P, WorldCoordinate A, WorldCoordinate B)&lt;br /&gt;
    { if (A.y==B.y) return A.y;&lt;br /&gt;
      else return cast&amp;lt;float&amp;gt;((B.x-A.x)*(P.y-A.y)/(B.y-A.y)); &lt;br /&gt;
      return 0.0;&lt;br /&gt;
    }&lt;br /&gt;
    public float ValueYStraightline(&lt;br /&gt;
                   WorldCoordinate P, WorldCoordinate A, WorldCoordinate B)&lt;br /&gt;
    { if (A.x==B.x) return A.x;&lt;br /&gt;
      else return cast&amp;lt;float&amp;gt;((B.y-A.y)*(P.x-A.x)/(B.x-A.x));&lt;br /&gt;
      return 0.0;&lt;br /&gt;
    }&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    // InsideReacharea returns true if the point is reachable, otherwise false.&lt;br /&gt;
    // Edges of the reacharea rectangle are assumed outside.&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    public bool InsideReacharea(WorldCoordinate P, WorldCoordinate[] W)&lt;br /&gt;
    {&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Adjust the point to the same baseboard as the container crane&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      WorldCoordinate SP = actsTools.WCoordAdjustBaseboard(P,me.GetMapObjectPosition());&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Calculate the case to proof&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      float rz = me.GetMapObjectOrientation().rz;&lt;br /&gt;
      int wi = cast&amp;lt;int&amp;gt;(rz*180*100/Math.PI);     // int rounded to 1/100&lt;br /&gt;
      int ri = wi/(90*100);&lt;br /&gt;
      while (ri&amp;lt;0) ri=ri+4;&lt;br /&gt;
      while (ri&amp;gt;3) ri=ri-4;&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Values of the edges (straight ölines) for the point coordinates&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      float xAB = ValueXStraightline(P, W[0], W[1]);&lt;br /&gt;
      float yAB = ValueYStraightline(P, W[0], W[1]);&lt;br /&gt;
      float xBC = ValueXStraightline(P, W[1], W[2]);&lt;br /&gt;
      float yBC = ValueYStraightline(P, W[1], W[2]);&lt;br /&gt;
      float xCD = ValueXStraightline(P, W[2], W[3]);&lt;br /&gt;
      float yCD = ValueYStraightline(P, W[2], W[3]);&lt;br /&gt;
      float xAD = ValueXStraightline(P, W[0], W[3]);&lt;br /&gt;
      float yAD = ValueYStraightline(P, W[0], W[3]);&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      // Calculating the resulting bool value&lt;br /&gt;
      //-------------------------------------------------------------------------&lt;br /&gt;
      switch(ri)&lt;br /&gt;
      {&lt;br /&gt;
        case 0:  //  0° &amp;lt;= rz° &amp;lt;  90°&lt;br /&gt;
          if(yCD &amp;lt; P.y and P.y &amp;lt; yAB and xAD &amp;lt; P.x and P.x &amp;lt; xBC) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        case 1:  //  90° &amp;lt;= rz° &amp;lt; 180°&lt;br /&gt;
          if(yAD &amp;lt; P.y and P.y &amp;lt; yBC and xAB &amp;lt; P.x and P.x &amp;lt; xCD) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        case 2:  // 180° &amp;lt;= rz° &amp;lt; 270°&lt;br /&gt;
          if(yAB &amp;lt; P.y and P.y &amp;lt; yCD and xBC &amp;lt; P.x and P.x &amp;lt; xAD) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        case 3:  // 270° &amp;lt;= rz° &amp;lt; 360°&lt;br /&gt;
          if(yBC &amp;lt; P.y and P.y &amp;lt; yAD and xCD &amp;lt; P.x and P.x &amp;lt; xAB) return true;&lt;br /&gt;
          return false;&lt;br /&gt;
        default:&lt;br /&gt;
          return false;&lt;br /&gt;
      }&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    &lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
===acts_bridgecrain_globals.gs===&lt;br /&gt;
&amp;lt;CODE&amp;gt;&lt;br /&gt;
  include &amp;quot;acts_global_values.gs&amp;quot;&lt;br /&gt;
  include &amp;quot;acts_tools_script.gs&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  //---------------------------------------------------------------------------&lt;br /&gt;
  // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_globals.gs&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  //   acts_bridgecrane           &amp;lt;-- acts_bridgecrane_script&lt;br /&gt;
  //   acts_bridgecrane_script    &amp;lt;-- acts_bridgecrane_register&lt;br /&gt;
  //   acts_bridgecrane_register  &amp;lt;-- acts_bridgecrane_reachable&lt;br /&gt;
  //   acts_bridgecrane_reachable &amp;lt;-- acts_bridgecrane_moving&lt;br /&gt;
  //   acts_bridgecrane_moving    &amp;lt;-- acts_bridgecrane_globals&lt;br /&gt;
  // X acts_bridgecrane_globals   &amp;lt;-- acts_global_values&lt;br /&gt;
  //   acts_global_values         &amp;lt;-- MapObject&lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  class acts_bridgecrane_globals isclass acts_global_values&lt;br /&gt;
  {&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // AssetInstanceSoup {&lt;br /&gt;
    // X ObjectDataSoup { ... },    Only container, contstack, contcrane&lt;br /&gt;
    // X LocationSoup { ... },      Only container, contstack, contcrane&lt;br /&gt;
    // X OrientationSoup { ... },   Only container, contstack, contcrane&lt;br /&gt;
    //   SkinDataSoup { ... },      Only container&lt;br /&gt;
    //   ContentDataSoup { ... },   Only container&lt;br /&gt;
    //   DispatcherDataSoup { ... } Only dispatcher&lt;br /&gt;
    //   ContainerSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContstackSoups  { ... }    Only dispatcher&lt;br /&gt;
    //   ContcraneSoups  { ... }    Only dispatcher&lt;br /&gt;
    // }&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // ObjectDataSoup { goid GameObjectID, type string,&lt;br /&gt;
    //                  length string, height string,  &lt;br /&gt;
    //                  stack goid, place int,           Only container&lt;br /&gt;
    //                  active bool, action string },&lt;br /&gt;
    // activ: true means the object sended a register message while session run&lt;br /&gt;
    //        All objects were set false while initialising dispatcher and if&lt;br /&gt;
    //        they stay false their entries will be deleted next initialising.&lt;br /&gt;
    // actions: [&amp;quot;APPENDED&amp;quot;, &amp;quot;INSERTED&amp;quot;, &amp;quot;UPDATED&amp;quot;];&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    Soup ObjectDataSoup = Constructors.NewSoup();&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // LocationSoup { bbx int, bby int,               // WorlCoordinate parameter&lt;br /&gt;
    //                px float, py float, pz float }&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    Soup LocationSoup = Constructors.NewSoup();&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    // OrientationSoup { rx float, ry float, rz float,    // in rad &lt;br /&gt;
    //                   gx float, gy float, gz float }   // in 1/10°&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    Soup OrientationSoup = Constructors.NewSoup();&lt;br /&gt;
    //-------------------------------------------------------------------------&lt;br /&gt;
    GameObjectID objectgoid = me.GetGameObjectID();&lt;br /&gt;
    string       objecttype = &amp;quot;CONTCRANE&amp;quot;;&lt;br /&gt;
    Library      dispobj;&lt;br /&gt;
    GameObjectID dispgoid;&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // Reach area values of the bridge crane will be loaded from this assets&lt;br /&gt;
    // config.txt file &lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int cranebase_reacharea_x;      //  30000 in [mm]&lt;br /&gt;
    int cranebase_reacharea_y;      // 100000 in [mm]&lt;br /&gt;
    int cranebase_reacharea_z;      //  26000 in [mm]&lt;br /&gt;
    int cranebase_origin_inset_x;   //  15000 in [mm]&lt;br /&gt;
    int cranebase_origin_inset_y;   //  50000 in [mm]&lt;br /&gt;
    int cranebase_origin_inset_z;   //   5000 in [mm]&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int lift_zero_length = 1000;   // 1000 in [mm] mandatory length for animation&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    int trolley_bottom_height;   // in [mm]&lt;br /&gt;
    int lift_bottom_height;      // in [mm] with lift z width as 1,000 [mm]&lt;br /&gt;
    int rotor_bottom_height;     // in [mm] with rotor z width as 500 [mm]&lt;br /&gt;
    int gear_bottom_height;      // in [mm] with gear z width as 500 [mm]&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // TBD: And not proofed yet. Differntiate between maximum container count&lt;br /&gt;
    //      for high cube and standard cube containers.&lt;br /&gt;
    //---------------------------------------------------------------------------&lt;br /&gt;
    // For now the maximum count is calculated from reacharea z dimension minus&lt;br /&gt;
    // one hc height to ensure the movement of containers by the crane. Because&lt;br /&gt;
    // of possibly different base heights of the stacks inside the crane&#039;s&lt;br /&gt;
    // reacharea, there are some more different (possibly smaller) maximum&lt;br /&gt;
    // stackheights.&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
    int max_container_count;     // Construction based max stackable containers&lt;br /&gt;
    // --------------------------------------------------------------------------&lt;br /&gt;
  };&lt;br /&gt;
  &lt;br /&gt;
  //-----------------------------------------------------------------------------&lt;br /&gt;
  /* ****************************************************************************&lt;br /&gt;
     This is the scripted bridge crane object for an active container terminal&lt;br /&gt;
     system (aCTS). It is a kind of prototype of a bridge crane to let&lt;br /&gt;
     constructors know how the things are fitting and working for aCTS.&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Some hints here too (see config description too):&lt;br /&gt;
     * The script logs dependin on the acts_debug variable (See&lt;br /&gt;
       acts.global_values.gs). So the script contains some overhead for testing&lt;br /&gt;
       informations. &lt;br /&gt;
     * Animations from Blender fbx runs from frame 1 ... n in Blender and fbx&lt;br /&gt;
       file. The import to Trainz will change this to frame 0 ... n-1, what is&lt;br /&gt;
       essential to know for precise transformations (moving and rotating) per&lt;br /&gt;
       animation frame.&lt;br /&gt;
     * The logical mesh hierarchy is as follows: cranebase--&amp;gt;&lt;br /&gt;
       --&amp;gt;cranebridge(py)--&amp;gt;trolley(px)--&amp;gt;lift(sz,pz)--&amp;gt;rotor(rz)--&amp;gt;gear(sx)&lt;br /&gt;
     * The cranes parts are imported to Trainz as own (animated) mesh objects&lt;br /&gt;
       with its respective origins at zero and its parented attachment points.&lt;br /&gt;
       All script calculations are based on this origin and the gaps to the&lt;br /&gt;
       attachment points for attaching the child meshes. The assets orientation&lt;br /&gt;
       is zero for x and y orientation.&lt;br /&gt;
     * The parent child hierarchy is realised within the mesh-table container.&lt;br /&gt;
     * The extensions values are in mm and define the reachable area of the&lt;br /&gt;
       cranes container gear. The dimensions x, y, z describe the cuboid&lt;br /&gt;
       length&#039;s, the gear may move and the insets x, y, z describes the location&lt;br /&gt;
       of the cranes origin within there.&lt;br /&gt;
     * The animations minimum frame 0 (resp. 1 in Blender) represents the locale&lt;br /&gt;
       relative minimal position (p = -inset) and the maximum frame (n = &lt;br /&gt;
       dimension) the maximal position p=dimension-inset. Example: &lt;br /&gt;
         dimension 80&lt;br /&gt;
         inset     30&lt;br /&gt;
         Trainz frames    0  10  20 30  40  50  60  70  80&lt;br /&gt;
         Blender frames   1  11  21 31  41  51  61  71  81&lt;br /&gt;
         Position       -30 -20 -10  0  10  20  30  40  50&lt;br /&gt;
     * The crane object (as well as the other object types) adjusts location to&lt;br /&gt;
       even mm and the orientation to 0.1 decimal degrees.&lt;br /&gt;
     * The movements of the cranes sub meshes will be realised with animation&lt;br /&gt;
       frame methods *MeshAnimation* from the MeshObject class in mashobject.gs&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Technical parameters for calculating script values 1 [mm] and 0.1 [°]&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Bridge  [BPY: 100,001F:    140m] BF[1 .. 100001] [0mm(1)100,000mm]&lt;br /&gt;
     Trolley [TPX:  30,001F:     30m] BF[1 ..  30001] [-15,000mm(1)+15,000mm]&lt;br /&gt;
     Lift    [LSZ:  25,001F:    1-26] BF[1 ..  25001] [1.000(0.001)26.000]&lt;br /&gt;
             [LPZ:  25,001F:     25m] BF[1 ..  25001] [+21,000mm(1)-5,000mm]&lt;br /&gt;
     Rotor   [ROZ:   1,801F:    180°] BF[1 ..   1801] [-90.0°(0.1)+90.0°]&lt;br /&gt;
     Gear    [GSY:  15,155F: 16.192m] BF[1 ..  16155] [1.000(0.001)16.154]&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     Containertype                      10ft    20ft     40ft     45ft     53ft&lt;br /&gt;
     Gear scale scale/length  1.000m  2.991m  6.058m  12.192m  13.716m  16.154m&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     More informations are documented within the config.txt and script comments.&lt;br /&gt;
     ----------------------------------------------------------------------------&lt;br /&gt;
     **************************************************************************** */&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
File is located in dispatcher library.&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ACTS:ContainerStack&amp;diff=40971</id>
		<title>ACTS:ContainerStack</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ACTS:ContainerStack&amp;diff=40971"/>
		<updated>2024-04-27T17:21:28Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Redirected page to ContainerStack&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[ContainerStack]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ACTS:ContainerCrane&amp;diff=40970</id>
		<title>ACTS:ContainerCrane</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ACTS:ContainerCrane&amp;diff=40970"/>
		<updated>2024-04-27T17:20:11Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Redirected page to ContainerCrane&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[ContainerCrane]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ACTS:Container&amp;diff=40969</id>
		<title>ACTS:Container</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ACTS:Container&amp;diff=40969"/>
		<updated>2024-04-27T17:19:36Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Redirected page to Container&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Container]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40844</id>
		<title>Category:ACTS</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40844"/>
		<updated>2024-04-24T17:51:22Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===License===&lt;br /&gt;
This page category shows informations about the Active Container Terminal System by ek.skirl. All information&#039;s are licensed [[TrainzOnline:Copyrights]] and for free use in noncommercial projects.&lt;br /&gt;
----&lt;br /&gt;
===Disclaimer===&lt;br /&gt;
This category is non official by N3V and Trainz. The N3V wiki is used to document the thoughts and technics used for the active container terminal system (aCTS) in a private manor. All informations came with no warranty under any circumstances. Use this on your own risks.&lt;br /&gt;
----&lt;br /&gt;
===Page hierarchy===&lt;br /&gt;
# [[Introduction]]&lt;br /&gt;
# [[AssumptionsPreliminaries]]&lt;br /&gt;
# [[MessagingSystem]]&lt;br /&gt;
# [[Versions]] (with links to Blender and Asset Source files)&lt;br /&gt;
# aCTS Assets&lt;br /&gt;
## [[Container]] (with config.txt and gs-scripts)&lt;br /&gt;
## [[ContainerStack]] (with config.txt and gs-scripts)&lt;br /&gt;
## [[ContainerCrane]] &lt;br /&gt;
### [[ContainerBridgeCrane]] (with config.txt and gs-scripts)&lt;br /&gt;
### [[ContainerBoomCrane]]&lt;br /&gt;
## [[Dispatcher]] (with config.txt and gs-scripts)&lt;br /&gt;
# [[MovingProcedure]]&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40843</id>
		<title>Category:ACTS</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40843"/>
		<updated>2024-04-24T17:49:17Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===License===&lt;br /&gt;
This page category shows informations about the Active Container Terminal System by ek.skirl. All information&#039;s are licensed [[TrainzOnline:Copyrights]] and for free use in noncommercial projects.&lt;br /&gt;
&lt;br /&gt;
===Disclaimer===&lt;br /&gt;
This category is non official by N3V and Trainz. The N3V wiki is used to document the thoughts and technics used for the active container terminal system (aCTS) in a private manor. All informations came with no warranty under any circumstances. Use this on your own risks.&lt;br /&gt;
&lt;br /&gt;
===Page hierarchy===&lt;br /&gt;
# [[Introduction]]&lt;br /&gt;
# [[AssumptionsPreliminaries]]&lt;br /&gt;
# [[MessagingSystem]]&lt;br /&gt;
# [[Versions]] (with links to Blender and Asset Source files)&lt;br /&gt;
# aCTS Assets&lt;br /&gt;
## [[Container]] (with config.txt and gs-scripts)&lt;br /&gt;
## [[ContainerStack]] (with config.txt and gs-scripts)&lt;br /&gt;
## [[ContainerCrane]] &lt;br /&gt;
### [[ContainerBridgeCrane]] (with config.txt and gs-scripts)&lt;br /&gt;
### [[ContainerBoomCrane]]&lt;br /&gt;
## [[Dispatcher]] (with config.txt and gs-scripts)&lt;br /&gt;
# [[MovingProcedure]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40842</id>
		<title>Versions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40842"/>
		<updated>2024-04-24T17:47:28Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Versions as milestones&lt;br /&gt;
&lt;br /&gt;
===Version 1.0===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Not yet in work. First self running version with no vehicled stacks. Moving containers randomly.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Collision control of cranes with stacks reachable by other cranes to. The idea is to pause the colliding container tasks until one task is ready.&lt;br /&gt;
&lt;br /&gt;
===Version 0.2===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For a crane object the dispatcher calculates if yet registered stacks are reachable and retours a list of reachable stacks with a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;EXISTING_REACHABLE_STACKS&#039;&#039;,StackGOIDListSoup message. If a not yet registered stack will be appended or updated a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;APPEND_REACHABLE_STACK&#039;&#039;,StackGOIDSoup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For stack objects the dispatcher calculates if yet registered cranes may reach it and posts the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;REACHABLE_STACK&amp;quot; to fitting cranes with appended goid as an one tag soup and reposts the list of crane goid&#039;s with the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;CRANES_REACHABLE&amp;quot; with the appended goid list as soup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For registered container objects the dispatcher reproofs the stack. Unregistered containers will be appended randomly to a stack and if there is yet no stack it will be informed to re register sometimes later again.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Messaging while moving containers from stack to stack.&lt;br /&gt;
&lt;br /&gt;
===Version 0.1===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Moving of animated parts.&lt;br /&gt;
&lt;br /&gt;
The asset instances of containers, stacks and cranes load their config parameters and their soups.&lt;br /&gt;
&lt;br /&gt;
After finishing their Init and SetProperties methods and if the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message was sent they post their &amp;quot;REGISTER&amp;quot;,&amp;quot;REGISTER_ME&amp;quot;,ObjectDataSoup message to the dispatcher.&lt;br /&gt;
&lt;br /&gt;
The dispatcher reposts after processing the registering a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;UPDATED&amp;quot;/&amp;quot;INSERTED&amp;quot;/&amp;quot;APPENDED&amp;quot;,ObjectDataSoup message. The registering process updates registered object&#039;s data or inserts/appends yet not registered object&#039;s data.&lt;br /&gt;
&lt;br /&gt;
* The used Blender files as zip archive: [[File:ACTS 215489 Blender Files V0.1.zip]]&lt;br /&gt;
&lt;br /&gt;
* The used Asset Source files as zip archive: [[File:ACTS_215489_Asset_Files_V0.1.zip]]&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=File:ACTS_215489_Asset_Files_V0.1.zip&amp;diff=40841</id>
		<title>File:ACTS 215489 Asset Files V0.1.zip</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=File:ACTS_215489_Asset_Files_V0.1.zip&amp;diff=40841"/>
		<updated>2024-04-24T17:46:05Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: The assets folders with the files to import content folders.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The assets folders with the files to import content folders.&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40840</id>
		<title>Versions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40840"/>
		<updated>2024-04-24T16:58:37Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Versions as milestones&lt;br /&gt;
&lt;br /&gt;
===Version 1.0===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Not yet in work. First self running version with no vehicled stacks. Moving containers randomly.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Collision control of cranes with stacks reachable by other cranes to. The idea is to pause the colliding container tasks until one task is ready.&lt;br /&gt;
&lt;br /&gt;
===Version 0.2===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For a crane object the dispatcher calculates if yet registered stacks are reachable and retours a list of reachable stacks with a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;EXISTING_REACHABLE_STACKS&#039;&#039;,StackGOIDListSoup message. If a not yet registered stack will be appended or updated a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;APPEND_REACHABLE_STACK&#039;&#039;,StackGOIDSoup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For stack objects the dispatcher calculates if yet registered cranes may reach it and posts the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;REACHABLE_STACK&amp;quot; to fitting cranes with appended goid as an one tag soup and reposts the list of crane goid&#039;s with the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;CRANES_REACHABLE&amp;quot; with the appended goid list as soup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For registered container objects the dispatcher reproofs the stack. Unregistered containers will be appended randomly to a stack and if there is yet no stack it will be informed to re register sometimes later again.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Messaging while moving containers from stack to stack.&lt;br /&gt;
&lt;br /&gt;
===Version 0.1===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Moving of animated parts.&lt;br /&gt;
&lt;br /&gt;
The asset instances of containers, stacks and cranes load their config parameters and their soups.&lt;br /&gt;
&lt;br /&gt;
After finishing their Init and SetProperties methods and if the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message was sent they post their &amp;quot;REGISTER&amp;quot;,&amp;quot;REGISTER_ME&amp;quot;,ObjectDataSoup message to the dispatcher.&lt;br /&gt;
&lt;br /&gt;
The dispatcher reposts after processing the registering a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;UPDATED&amp;quot;/&amp;quot;INSERTED&amp;quot;/&amp;quot;APPENDED&amp;quot;,ObjectDataSoup message. The registering process updates registered object&#039;s data or inserts/appends yet not registered object&#039;s data.&lt;br /&gt;
&lt;br /&gt;
The used Blender files as zip archive: [[File:ACTS 215489 Blender Files V0.1.zip]]&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40839</id>
		<title>Versions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40839"/>
		<updated>2024-04-24T16:58:18Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Versions as milestones&lt;br /&gt;
&lt;br /&gt;
===Version 1.0===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Not yet in work. First self running version with no vehicled stacks. Moving containers randomly.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Collision control of cranes with stacks reachable by other cranes to. The idea is to pause the colliding container tasks until one task is ready.&lt;br /&gt;
&lt;br /&gt;
===Version 0.02===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For a crane object the dispatcher calculates if yet registered stacks are reachable and retours a list of reachable stacks with a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;EXISTING_REACHABLE_STACKS&#039;&#039;,StackGOIDListSoup message. If a not yet registered stack will be appended or updated a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;APPEND_REACHABLE_STACK&#039;&#039;,StackGOIDSoup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For stack objects the dispatcher calculates if yet registered cranes may reach it and posts the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;REACHABLE_STACK&amp;quot; to fitting cranes with appended goid as an one tag soup and reposts the list of crane goid&#039;s with the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;CRANES_REACHABLE&amp;quot; with the appended goid list as soup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For registered container objects the dispatcher reproofs the stack. Unregistered containers will be appended randomly to a stack and if there is yet no stack it will be informed to re register sometimes later again.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Messaging while moving containers from stack to stack.&lt;br /&gt;
&lt;br /&gt;
===Version 0.01===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Moving of animated parts.&lt;br /&gt;
&lt;br /&gt;
The asset instances of containers, stacks and cranes load their config parameters and their soups.&lt;br /&gt;
&lt;br /&gt;
After finishing their Init and SetProperties methods and if the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message was sent they post their &amp;quot;REGISTER&amp;quot;,&amp;quot;REGISTER_ME&amp;quot;,ObjectDataSoup message to the dispatcher.&lt;br /&gt;
&lt;br /&gt;
The dispatcher reposts after processing the registering a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;UPDATED&amp;quot;/&amp;quot;INSERTED&amp;quot;/&amp;quot;APPENDED&amp;quot;,ObjectDataSoup message. The registering process updates registered object&#039;s data or inserts/appends yet not registered object&#039;s data.&lt;br /&gt;
&lt;br /&gt;
The used Blender files as zip archive: [[File:ACTS 215489 Blender Files V0.1.zip]]&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40838</id>
		<title>Category:ACTS</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40838"/>
		<updated>2024-04-24T16:52:36Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===License===&lt;br /&gt;
This page category shows informations about the Active Container Terminal System by ek.skirl. All information&#039;s are licensed [[TrainzOnline:Copyrights]] and for free use in noncommercial projects.&lt;br /&gt;
&lt;br /&gt;
===Disclaimer===&lt;br /&gt;
This category is non official by N3V and Trainz. The N3V wiki is used to document the thoughts and technics used for the active container terminal system (aCTS) in a private manor. All informations came with no warranty under any circumstances. Use this on your own risks.&lt;br /&gt;
&lt;br /&gt;
===Page hierarchy===&lt;br /&gt;
# [[Introduction]]&lt;br /&gt;
# [[AssumptionsPreliminaries]]&lt;br /&gt;
# [[MessagingSystem]]&lt;br /&gt;
# [[Versions]] (with link to Blender files)&lt;br /&gt;
# aCTS Assets&lt;br /&gt;
## [[Container]] (with config.txt and gs-scripts)&lt;br /&gt;
## [[ContainerStack]] (with config.txt and gs-scripts)&lt;br /&gt;
## [[ContainerCrane]] &lt;br /&gt;
### [[ContainerBridgeCrane]] (with config.txt and gs-scripts)&lt;br /&gt;
### [[ContainerBoomCrane]]&lt;br /&gt;
## [[Dispatcher]] (with config.txt and gs-scripts)&lt;br /&gt;
# [[MovingProcedure]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40837</id>
		<title>Category:ACTS</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40837"/>
		<updated>2024-04-24T16:46:17Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===License===&lt;br /&gt;
This page category shows informations about the Active Container Terminal System by ek.skirl. All information&#039;s are licensed [[TrainzOnline:Copyrights]] and for free use in noncommercial projects.&lt;br /&gt;
&lt;br /&gt;
===Disclaimer===&lt;br /&gt;
This category is non official by N3V and Trainz. The N3V wiki is used to document the thoughts and technics used for the active container terminal system (aCTS) in a private manor. All informations came with no warranty under any circumstances. Use this on your own risks.&lt;br /&gt;
&lt;br /&gt;
===Page hierarchy===&lt;br /&gt;
# [[Introduction]]&lt;br /&gt;
# [[AssumptionsPreliminaries]]&lt;br /&gt;
# [[MessagingSystem]]&lt;br /&gt;
# [[Versions]]&lt;br /&gt;
## [[Container]]&lt;br /&gt;
## [[ContainerStack]]&lt;br /&gt;
## [[ContainerCrane]]&lt;br /&gt;
### [[ContainerBridgeCrane]]&lt;br /&gt;
### [[ContainerBoomCrane]]&lt;br /&gt;
## [[Dispatcher]]&lt;br /&gt;
# [[MovingProcedure]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40836</id>
		<title>Category:ACTS</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Category:ACTS&amp;diff=40836"/>
		<updated>2024-04-24T16:45:31Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: /* Disclaimer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===License===&lt;br /&gt;
This page category shows informations about the Active Container Terminal System by ek.skirl. All information&#039;s are licensed [[TrainzOnline:Copyrights]] and for free use in noncommercial projects.&lt;br /&gt;
&lt;br /&gt;
===Disclaimer===&lt;br /&gt;
This category is non official by N3V and Trainz. The N3V wiki is used to document the thoughts and technics used for the active container terminal system (aCTS) in a private manor. All informations came with no warranty under any circumstances. Use this on your own risks.&lt;br /&gt;
&lt;br /&gt;
===Page hirarchy===&lt;br /&gt;
# [[Introduction]]&lt;br /&gt;
# [[AssumptionsPreliminaries]]&lt;br /&gt;
# [[MessagingSystem]]&lt;br /&gt;
# [[Versions]]&lt;br /&gt;
## [[Container]]&lt;br /&gt;
## [[ContainerStack]]&lt;br /&gt;
## [[ContainerCrane]]&lt;br /&gt;
### [[ContainerBridgeCrane]]&lt;br /&gt;
### [[ContainerBoomCrane]]&lt;br /&gt;
## [[Dispatcher]]&lt;br /&gt;
# [[MovingProcedure]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40835</id>
		<title>Versions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40835"/>
		<updated>2024-04-24T15:46:47Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Versions as milestones&lt;br /&gt;
&lt;br /&gt;
===Version 1.0===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Not yet in work. First self running version with no vehicled stacks. Moving containers randomly.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Collision control of cranes with stacks reachable by other cranes to. The idea is to pause the colliding container tasks until one task is ready.&lt;br /&gt;
&lt;br /&gt;
===Version 0.2===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For a crane object the dispatcher calculates if yet registered stacks are reachable and retours a list of reachable stacks with a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;EXISTING_REACHABLE_STACKS&#039;&#039;,StackGOIDListSoup message. If a not yet registered stack will be appended or updated a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;APPEND_REACHABLE_STACK&#039;&#039;,StackGOIDSoup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For stack objects the dispatcher calculates if yet registered cranes may reach it and posts the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;REACHABLE_STACK&amp;quot; to fitting cranes with appended goid as an one tag soup and reposts the list of crane goid&#039;s with the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;CRANES_REACHABLE&amp;quot; with the appended goid list as soup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For registered container objects the dispatcher reproofs the stack. Unregistered containers will be appended randomly to a stack and if there is yet no stack it will be informed to re register sometimes later again.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Messaging while moving containers from stack to stack.&lt;br /&gt;
&lt;br /&gt;
===Version 0.1===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Moving of animated parts.&lt;br /&gt;
&lt;br /&gt;
The asset instances of containers, stacks and cranes load their config parameters and their soups.&lt;br /&gt;
&lt;br /&gt;
After finishing their Init and SetProperties methods and if the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message was sent they post their &amp;quot;REGISTER&amp;quot;,&amp;quot;REGISTER_ME&amp;quot;,ObjectDataSoup message to the dispatcher.&lt;br /&gt;
&lt;br /&gt;
The dispatcher reposts after processing the registering a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;UPDATED&amp;quot;/&amp;quot;INSERTED&amp;quot;/&amp;quot;APPENDED&amp;quot;,ObjectDataSoup message. The registering process updates registered object&#039;s data or inserts/appends yet not registered object&#039;s data.&lt;br /&gt;
&lt;br /&gt;
The used Blender files as zip archive: [[File:ACTS 215489 Blender Files V0.1.zip]]&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40834</id>
		<title>Versions</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Versions&amp;diff=40834"/>
		<updated>2024-04-24T15:46:21Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Versions as milestones&lt;br /&gt;
&lt;br /&gt;
===Version 1.0===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Not yet in work. First self running version with no vehicled stacks. Moving containers randomly.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Collision control of cranes with stacks reachable by other cranes to. The idea is to pause the colliding container tasks until one task is ready.&lt;br /&gt;
&lt;br /&gt;
===Version 0.02===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For a crane object the dispatcher calculates if yet registered stacks are reachable and retours a list of reachable stacks with a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;EXISTING_REACHABLE_STACKS&#039;&#039;,StackGOIDListSoup message. If a not yet registered stack will be appended or updated a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;APPEND_REACHABLE_STACK&#039;&#039;,StackGOIDSoup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For stack objects the dispatcher calculates if yet registered cranes may reach it and posts the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;REACHABLE_STACK&amp;quot; to fitting cranes with appended goid as an one tag soup and reposts the list of crane goid&#039;s with the message &amp;quot;DISPATCHER&amp;quot;,&amp;quot;CRANES_REACHABLE&amp;quot; with the appended goid list as soup.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: For registered container objects the dispatcher reproofs the stack. Unregistered containers will be appended randomly to a stack and if there is yet no stack it will be informed to re register sometimes later again.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Messaging while moving containers from stack to stack.&lt;br /&gt;
&lt;br /&gt;
===Version 0.01===&lt;br /&gt;
&#039;&#039;TBD&#039;&#039;: Moving of animated parts.&lt;br /&gt;
&lt;br /&gt;
The asset instances of containers, stacks and cranes load their config parameters and their soups.&lt;br /&gt;
&lt;br /&gt;
After finishing their Init and SetProperties methods and if the &amp;quot;World&amp;quot;,&amp;quot;ModuleInit&amp;quot; message was sent they post their &amp;quot;REGISTER&amp;quot;,&amp;quot;REGISTER_ME&amp;quot;,ObjectDataSoup message to the dispatcher.&lt;br /&gt;
&lt;br /&gt;
The dispatcher reposts after processing the registering a &amp;quot;DISPATCHER&amp;quot;,&amp;quot;UPDATED&amp;quot;/&amp;quot;INSERTED&amp;quot;/&amp;quot;APPENDED&amp;quot;,ObjectDataSoup message. The registering process updates registered object&#039;s data or inserts/appends yet not registered object&#039;s data.&lt;br /&gt;
&lt;br /&gt;
The used Blender files as zip archive: [[File:ACTS 215489 Blender Files V0.1.zip]]&lt;br /&gt;
&lt;br /&gt;
[[Category:ACTS]]&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=ScriptsConfigs&amp;diff=40833</id>
		<title>ScriptsConfigs</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=ScriptsConfigs&amp;diff=40833"/>
		<updated>2024-04-24T15:44:04Z</updated>

		<summary type="html">&lt;p&gt;Ek.skirl: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ek.skirl</name></author>
	</entry>
</feed>