<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.trainzsimulator.com/index.php?action=history&amp;feed=atom&amp;title=Texture_Replacement.</id>
	<title>Texture Replacement. - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.trainzsimulator.com/index.php?action=history&amp;feed=atom&amp;title=Texture_Replacement."/>
	<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Texture_Replacement.&amp;action=history"/>
	<updated>2026-11-05T09:07:30Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Texture_Replacement.&amp;diff=11453&amp;oldid=prev</id>
		<title>Tonyhilliam at 02:07, 17 January 2018</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Texture_Replacement.&amp;diff=11453&amp;oldid=prev"/>
		<updated>2018-01-17T02:07:53Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw-interface=&quot;&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:07, 17 January 2018&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l222&quot;&gt;Line 222:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 222:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Str.Tokens(&amp;quot;Brick, Dark Stock.texture&amp;quot;,&amp;quot;.&amp;quot;)[0];&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;Str.Tokens()&amp;#039;&amp;#039; is a method which splits a string up into separate &amp;#039;words&amp;#039; based on the value of the second parameter, in this case a full stop. The method returns an array of strings. In our case the first element of this array would be &amp;#039;&amp;#039;&amp;quot;Brick, Dark Stock&amp;quot;&amp;#039;&amp;#039; and the second would be &amp;#039;&amp;#039;&amp;quot;texture&amp;quot;&amp;#039;&amp;#039;. The &amp;#039;&amp;#039;[0]&amp;#039;&amp;#039; at the end of the statement is an array index notation which signifies that we are interested in the first element of the array. So the whole expression serves to return the phrase &amp;#039;&amp;#039;&amp;quot;Brick, Dark Stock&amp;quot;&amp;#039;&amp;#039;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Str.Tokens(&amp;quot;Brick, Dark Stock.texture&amp;quot;,&amp;quot;.&amp;quot;)[0];&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;Str.Tokens()&amp;#039;&amp;#039; is a method which splits a string up into separate &amp;#039;words&amp;#039; based on the value of the second parameter, in this case a full stop. The method returns an array of strings. In our case the first element of this array would be &amp;#039;&amp;#039;&amp;quot;Brick, Dark Stock&amp;quot;&amp;#039;&amp;#039; and the second would be &amp;#039;&amp;#039;&amp;quot;texture&amp;quot;&amp;#039;&amp;#039;. The &amp;#039;&amp;#039;[0]&amp;#039;&amp;#039; at the end of the statement is an array index notation which signifies that we are interested in the first element of the array. So the whole expression serves to return the phrase &amp;#039;&amp;#039;&amp;quot;Brick, Dark Stock&amp;quot;&amp;#039;&amp;#039;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Back to [[Getting Started in TrainzScript]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Back to [[Getting Started in TrainzScript]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Tonyhilliam</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Texture_Replacement.&amp;diff=814&amp;oldid=prev</id>
		<title>Windwalkr: 1 revision</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Texture_Replacement.&amp;diff=814&amp;oldid=prev"/>
		<updated>2010-02-03T13:59:59Z</updated>

		<summary type="html">&lt;p&gt;1 revision&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw-interface=&quot;&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 13:59, 3 February 2010&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Windwalkr</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Texture_Replacement.&amp;diff=813&amp;oldid=prev</id>
		<title>Andi06 at 22:29, 13 July 2008</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Texture_Replacement.&amp;diff=813&amp;oldid=prev"/>
		<updated>2008-07-13T22:29:31Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Since this tutorial is concerned with script and not with the creation of texture-group assets we will be using a ready made texture library. If you are using my gmax source the mapping is already suitable for use with this library, otherwise you may need to make some adjustments. There are one or two things you will need to do in any event to set up the Engine Shed for texture replacement. &lt;br /&gt;
* If you don&amp;#039;t already have it you will need to download a copy of [http://www.auran.com/TRS2004/DLS_viewasset.php?AssetID=85023# &amp;#039;&amp;#039;AJS Masonry Textures &amp;lt;kuid:122285:3599&amp;gt;&amp;#039;&amp;#039;] from the DLS, this is about 1Mb.&lt;br /&gt;
* You will need to open the Engine Shed config.txt file and add a kuid-table including a reference to this asset:&lt;br /&gt;
 &amp;lt;font color=blue&amp;gt;kuid-table {&lt;br /&gt;
    skins   &amp;lt;kuid:122285:3599&amp;gt;&lt;br /&gt;
 }&amp;lt;/font&amp;gt;&lt;br /&gt;
The texture group contains a library of masonry textures which you can use to change the appearance of the shed walls. As before this will be controlled by the Property Editor, but this time we want to be able to select the texture required from a list rather than having to type its name. This will require modifications to the code and some additional Property Handler methods.&lt;br /&gt;
&lt;br /&gt;
 include &amp;quot;Buildable.gs&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 class Tutorial isclass Buildable {&lt;br /&gt;
 &lt;br /&gt;
    bool doorsOpen = false;&lt;br /&gt;
    bool roofVisible;&lt;br /&gt;
    string nameText = &amp;quot;None&amp;quot;;&lt;br /&gt;
 &amp;lt;font color=#808080&amp;gt;// Global variables to hold the texture library, skin index and description.&amp;lt;/font&amp;gt;&lt;br /&gt;
    &amp;lt;font color=blue&amp;gt;Asset skins;&lt;br /&gt;
    int skin;&lt;br /&gt;
    string skinDescription = &amp;quot;None&amp;quot;;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    void SetNameText(void);&lt;br /&gt;
 &lt;br /&gt;
    public void Init(void) {&lt;br /&gt;
       inherited();&lt;br /&gt;
       SetFXCoronaTexture(&amp;quot;corona&amp;quot;,null);&lt;br /&gt;
       SetNameText();&lt;br /&gt;
       AddHandler(me,&amp;quot;Object&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;ObjectHandler&amp;quot;);&lt;br /&gt;
 &amp;lt;font color=#808080&amp;gt;// This call sets &amp;#039;&amp;#039;skins&amp;#039;&amp;#039;, to refer to the texture-group defined in our kuid-table.&amp;lt;/font&amp;gt;&lt;br /&gt;
       &amp;lt;font color=blue&amp;gt;skins = GetAsset().FindAsset(&amp;quot;skins&amp;quot;);&amp;lt;/font&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    Asset GetCorona(string mesh, string effect) {&lt;br /&gt;
       Soup meshtable = GetAsset().GetConfigSoup().GetNamedSoup(&amp;quot;mesh-table&amp;quot;);&lt;br /&gt;
       Soup effects = meshtable.GetNamedSoup(mesh).GetNamedSoup(&amp;quot;effects&amp;quot;);&lt;br /&gt;
       KUID kuid = effects.GetNamedSoup(effect).GetNamedTagAsKUID(&amp;quot;texture-kuid&amp;quot;);&lt;br /&gt;
       return World.FindAsset(kuid);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    thread void RingTheBell(void) {&lt;br /&gt;
       while (doorsOpen) {&lt;br /&gt;
          Sleep(0.35 + World.Play2DSound(GetAsset(),&amp;quot;bell.wav&amp;quot;));&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    void SetNameText(void) {&lt;br /&gt;
       if (nameText == &amp;quot;None&amp;quot; or nameText == &amp;quot;&amp;quot;) {&lt;br /&gt;
          SetFXNameText(&amp;quot;name&amp;quot;,&amp;quot; &amp;quot;);&lt;br /&gt;
       } else {&lt;br /&gt;
          SetFXNameText(&amp;quot;name&amp;quot;,nameText);&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=#808080&amp;gt;/* &amp;#039;&amp;#039;SetSkin()&amp;#039;&amp;#039; is a new method to deal with executing the texture-replacement &lt;br /&gt;
    calls. If the value of the &amp;#039;&amp;#039;skin&amp;#039;&amp;#039; parameter is zero then texture replacement &lt;br /&gt;
    will be turned off and the model will revert to the texture initially defined &lt;br /&gt;
    in the mesh.  Any other value will result in the corresponding texture from &lt;br /&gt;
    the texture-group being assigned to the mesh. */&amp;lt;/font&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;font color=blue&amp;gt;void SetSkin(int skin) {&lt;br /&gt;
       if (skin == 0) SetFXTextureReplacement(&amp;quot;masonry&amp;quot;,null,0);&lt;br /&gt;
       else SetFXTextureReplacement(&amp;quot;masonry&amp;quot;,skins,skin);&lt;br /&gt;
    }&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    void ObjectHandler(Message msg) {&lt;br /&gt;
       Vehicle vehicle = cast&amp;lt;Vehicle&amp;gt;msg.src;&lt;br /&gt;
       if (!vehicle) return;&lt;br /&gt;
       if (msg.minor == &amp;quot;InnerEnter&amp;quot;) {&lt;br /&gt;
          doorsOpen = true;&lt;br /&gt;
          SetMeshAnimationState(&amp;quot;default&amp;quot;, true);&lt;br /&gt;
          SetFXCoronaTexture(&amp;quot;corona&amp;quot;,GetCorona(&amp;quot;default&amp;quot;,&amp;quot;corona&amp;quot;));&lt;br /&gt;
          RingTheBell();&lt;br /&gt;
       }&lt;br /&gt;
       else if (msg.minor == &amp;quot;InnerLeave&amp;quot;) {&lt;br /&gt;
          doorsOpen = false;&lt;br /&gt;
          SetMeshAnimationState(&amp;quot;default&amp;quot;, false);&lt;br /&gt;
          SetFXCoronaTexture(&amp;quot;corona&amp;quot;,null);&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=#808080&amp;gt;/* &amp;#039;&amp;#039;GetNamedTagAsInt()&amp;#039;&amp;#039; allows us to initialise &amp;#039;&amp;#039;skin&amp;#039;&amp;#039; with a default value&lt;br /&gt;
    if the tag doesn&amp;#039;t already exist.  &amp;#039;&amp;#039;GetNamedTag()&amp;#039;&amp;#039; retrieves a string value&lt;br /&gt;
    and doesn&amp;#039;t have the same capability, so we have to do a little additional&lt;br /&gt;
    work to ensure that &amp;#039;&amp;#039;skinDescription&amp;#039;&amp;#039; is always initialised. If you look&lt;br /&gt;
    back at the top of the file you will see that we assigned the value of &lt;br /&gt;
    &amp;quot;None&amp;quot; to &amp;#039;&amp;#039;skinDescription&amp;#039;&amp;#039; when it was originally declared.  We leave &lt;br /&gt;
    that value alone unless &amp;#039;&amp;#039;soup&amp;#039;&amp;#039; has anything more interesting to tell us. */&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    public void SetProperties(Soup soup) {&lt;br /&gt;
       inherited(soup);&lt;br /&gt;
       roofVisible = soup.GetNamedTagAsBool (&amp;quot;roof&amp;quot;,true);&lt;br /&gt;
       SetMeshVisible(&amp;quot;roof&amp;quot;,roofVisible,1.0);&lt;br /&gt;
       nameText = soup.GetNamedTag(&amp;quot;name&amp;quot;);&lt;br /&gt;
       SetNameText();&lt;br /&gt;
       &amp;lt;font color=blue&amp;gt;skin = soup.GetNamedTagAsInt(&amp;quot;skin&amp;quot;,0);&lt;br /&gt;
       string temp = soup.GetNamedTag(&amp;quot;skinDescription&amp;quot;);&lt;br /&gt;
       if (temp != &amp;quot;&amp;quot;) skinDescription = temp;&lt;br /&gt;
       SetSkin(skin);&amp;lt;/font&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    public Soup GetProperties(void) {&lt;br /&gt;
       Soup soup = inherited();&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;roof&amp;quot;,roofVisible);&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;name&amp;quot;,nameText);&lt;br /&gt;
       &amp;lt;font color=blue&amp;gt;soup.SetNamedTag(&amp;quot;skin&amp;quot;,skin);&lt;br /&gt;
       soup.SetNamedTag(&amp;quot;skinDescription&amp;quot;,skinDescription);&amp;lt;/font&amp;gt;&lt;br /&gt;
       return soup;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=#808080&amp;gt;/* Additional code to present &amp;#039;&amp;#039;skinDescription&amp;#039;&amp;#039; in the Property Editor. */&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     public string GetDescriptionHTML(void) {&lt;br /&gt;
       string roofStatus = &amp;quot;Show&amp;quot;;&lt;br /&gt;
       if (roofVisible) roofStatus = &amp;quot;Hide&amp;quot;;&lt;br /&gt;
       string html = inherited()&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;         + &amp;quot;&amp;lt;font size=5&amp;gt;&amp;lt;br&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;         + &amp;quot;Roof: &amp;lt;a href=live://property/roof&amp;gt;&amp;quot; + roofStatus + &amp;quot;&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;         + &amp;quot;Name: &amp;lt;a href=live://property/name&amp;gt;&amp;quot; + nameText + &amp;quot;&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
          &amp;lt;font color=blue&amp;gt;&amp;lt;nowiki&amp;gt;+ &amp;quot;Name: &amp;lt;a href=live://property/skin&amp;gt;&amp;quot; + skinDescription + &amp;quot;&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
          + &amp;quot;&amp;lt;/font&amp;gt;&amp;quot;;&lt;br /&gt;
       return html;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    public string GetPropertyName(string pID) {&lt;br /&gt;
       string result = inherited(pID);&lt;br /&gt;
       if (pID == &amp;quot;name&amp;quot;) result = &amp;quot;Enter Name Text&amp;quot;;&lt;br /&gt;
       &amp;lt;font color=blue&amp;gt;else if (pID == &amp;quot;skin&amp;quot;) result = &amp;quot;Select Masonry Texture&amp;quot;;&amp;lt;/font&amp;gt;&lt;br /&gt;
       return result;&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
 &amp;lt;font color=#808080&amp;gt;/* Advise Trainz that the &amp;#039;&amp;#039;skin&amp;#039;&amp;#039; property is of type &amp;quot;list&amp;quot;. */&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    public string GetPropertyType(string pID) {&lt;br /&gt;
       string result = inherited(pID);&lt;br /&gt;
       if (pID == &amp;quot;roof&amp;quot;) result = &amp;quot;link&amp;quot;;&lt;br /&gt;
       else if (pID == &amp;quot;name&amp;quot;) result = &amp;quot;string&amp;quot;;&lt;br /&gt;
       &amp;lt;font color=blue&amp;gt;else if (pID == &amp;quot;skin&amp;quot;) result = &amp;quot;list&amp;quot;;&amp;lt;/font&amp;gt;&lt;br /&gt;
       return result;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=#808080&amp;gt;/* &amp;#039;&amp;#039;GetPropertyElementList()&amp;#039;&amp;#039; builds the list that we will be presenting to the &lt;br /&gt;
    users to allow them to select a texture. The method returns an array, or &lt;br /&gt;
    indexed list, of strings.  It does this by loading the names of the skins &lt;br /&gt;
    from the textures table in &amp;#039;&amp;#039;config.txt&amp;#039;&amp;#039; of the texture group. This table &lt;br /&gt;
    lists all of the &amp;#039;&amp;#039;*.texture&amp;#039;&amp;#039; files which the asset contains. The method &lt;br /&gt;
    then parses through the soup using a &amp;#039;&amp;#039;for&amp;#039;&amp;#039; loop and chops the &amp;#039;&amp;#039;&amp;quot;.texture&amp;quot;&amp;#039;&amp;#039; &lt;br /&gt;
    off the end of the filename before adding it to our &amp;#039;&amp;#039;result&amp;#039;&amp;#039; array. */&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=blue&amp;gt;public string[] GetPropertyElementList(string pID) {&lt;br /&gt;
       string[] result = inherited(pID);&lt;br /&gt;
       if (pID == &amp;quot;skin&amp;quot;) {&lt;br /&gt;
          result[result.size()] = &amp;quot;None&amp;quot;;&lt;br /&gt;
          Soup soup = skins.GetConfigSoup().GetNamedSoup(&amp;quot;textures&amp;quot;);&lt;br /&gt;
          int n;&lt;br /&gt;
          for (n = 1; n &amp;lt; soup.CountTags(); n++) {&lt;br /&gt;
             result[result.size()] = Str.Tokens(soup.GetNamedTag(n),&amp;quot;.&amp;quot;)[0];&lt;br /&gt;
          }&lt;br /&gt;
       }&lt;br /&gt;
       return result;&lt;br /&gt;
    }&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    public string GetPropertyValue(string pID) {&lt;br /&gt;
       string result = inherited(pID);&lt;br /&gt;
       if (pID == &amp;quot;name&amp;quot;) result = nameText;&lt;br /&gt;
       return result;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=#808080&amp;gt;/* You may have become used to simply adding new statements to the standard property&lt;br /&gt;
    methods, but this is a bit of a special case. &amp;#039;&amp;#039;SetPropertyValue()&amp;#039;&amp;#039; is a new&lt;br /&gt;
    function with the same name as a method which already exists but with a different&lt;br /&gt;
    set of parameters. TrainzScript allows this duplication and it can be very useful,&lt;br /&gt;
    it can also be a little confusing, so you need to watch out for it.&lt;br /&gt;
 &lt;br /&gt;
    In this particular case we want the same method to deal with two values:&lt;br /&gt;
    the skin index and the skin description. The first is a number representing the&lt;br /&gt;
    position of the selection within the list, and the second is the string value of&lt;br /&gt;
    the list item itself. Both are set in the same method before calling &amp;#039;&amp;#039;SetSkin()&amp;#039;&amp;#039;&lt;br /&gt;
    which actually does the skin swapping. */&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=blue&amp;gt;public void SetPropertyValue(string pID, string value, int index) {&lt;br /&gt;
       if (pID == &amp;quot;skin&amp;quot;) {&lt;br /&gt;
          skin = index;&lt;br /&gt;
          skinDescription = value;&lt;br /&gt;
          SetSkin(skin);&lt;br /&gt;
       }&lt;br /&gt;
       else inherited(pID,value,index);&lt;br /&gt;
    }&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    public void SetPropertyValue(string pID, string value) {&lt;br /&gt;
       if (pID == &amp;quot;name&amp;quot;) {&lt;br /&gt;
          if (value == &amp;quot;&amp;quot;) nameText = &amp;quot;None&amp;quot;;&lt;br /&gt;
          else nameText = value;&lt;br /&gt;
          SetNameText();&lt;br /&gt;
       }&lt;br /&gt;
       else inherited(pID, value);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    public void LinkPropertyValue(string pID) {&lt;br /&gt;
       if (pID == &amp;quot;roof&amp;quot;) {&lt;br /&gt;
          roofVisible = !roofVisible;&lt;br /&gt;
          SetMeshVisible(&amp;quot;roof&amp;quot;,roofVisible,1.0);&lt;br /&gt;
       }&lt;br /&gt;
       else inherited(pID);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
You may have found these statements in &amp;#039;&amp;#039;GetPropertyElementList()&amp;#039;&amp;#039; a little bewildering:&lt;br /&gt;
&lt;br /&gt;
 for(n = 1; n &amp;lt; soup.CountTags(); n++) {&lt;br /&gt;
    result[result.size()] = Str.Tokens(soup.GetNamedTag(n),&amp;quot;.&amp;quot;)[0];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;for()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; defines a loop which is executed a set number of times and requires three statements as parameters. Since these are statements and not formal parameters they are terminated with &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; rather than &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;,&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;#039;&amp;#039;n&amp;#039;&amp;#039; is an integer counter variable, and &amp;#039;&amp;#039;n = 1&amp;#039;&amp;#039; is a statement defining the initial value of the counter&lt;br /&gt;
* The second statement sets out a conditional test. While this test is true the loop will continue to run. In our case the test is the number of tag values in the soup.&lt;br /&gt;
* The third statement &amp;#039;&amp;#039;n++&amp;#039;&amp;#039; defines what happens to &amp;#039;&amp;#039;n&amp;#039;&amp;#039; at the end of each loop, &amp;#039;&amp;#039;n++&amp;#039;&amp;#039; means add 1 to the value of &amp;#039;&amp;#039;n&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;result[result.size()] =&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; instructs the script to add a new value to the end of an array.&lt;br /&gt;
* Array indices start at zero, so on the first run with an empty array this would evaluate to &amp;#039;&amp;#039;result[0] =&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;soup.GetNamedTag(n)&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; returns the value of the &amp;#039;&amp;#039;n&amp;#039;&amp;#039;th tag in the database. Although &amp;#039;&amp;#039;n&amp;#039;&amp;#039; is a number TrainzScript is usually quite accommodating at converting it to a string where this makes sense.  Let&amp;#039;s assume that this has returned &amp;#039;&amp;#039;&amp;quot;Brick, Dark Stock.texture&amp;quot;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Str.Tokens(&amp;quot;Brick, Dark Stock.texture&amp;quot;,&amp;quot;.&amp;quot;)[0];&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;Str.Tokens()&amp;#039;&amp;#039; is a method which splits a string up into separate &amp;#039;words&amp;#039; based on the value of the second parameter, in this case a full stop. The method returns an array of strings. In our case the first element of this array would be &amp;#039;&amp;#039;&amp;quot;Brick, Dark Stock&amp;quot;&amp;#039;&amp;#039; and the second would be &amp;#039;&amp;#039;&amp;quot;texture&amp;quot;&amp;#039;&amp;#039;. The &amp;#039;&amp;#039;[0]&amp;#039;&amp;#039; at the end of the statement is an array index notation which signifies that we are interested in the first element of the array. So the whole expression serves to return the phrase &amp;#039;&amp;#039;&amp;quot;Brick, Dark Stock&amp;quot;&amp;#039;&amp;#039;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Back to [[Getting Started in TrainzScript]]&lt;/div&gt;</summary>
		<author><name>Andi06</name></author>
	</entry>
</feed>