GWR Crane 16 Details
From TrainzOnline
Config.txt
Here is the Config.txt for the GWR Crane 16 Asset.
kuid <kuid:329364:1613> username "GWR Crane 16" kind "traincar" trainz-build 3.3 engine 1 enginespec <kuid:329364:1563> enginesound <kuid2:126323:53050:1> hornsound <kuid:30992:54000> script "crane" class "crane" mesh-table { default { mesh "body.im" auto-create 1 anim "slewing.kin" } jib { mesh "jib.im" auto-create 1 att-parent "default" att "a.cranepivot" anim "jib.kin" } crane { mesh "crane.im" auto-create 1 att-parent "default" att "a.cranepivot" anim "donkey.kin" } hook { mesh "hook.im" auto-create 1 att-parent "jib" att "a.rope" anim "hook.kin" } } bogeys { 0 { bogey <kuid:-10:149> } 1 { bogey <kuid:-10:149> } 2 { bogey <kuid:329364:1610> } 3 { bogey <kuid:329364:1612> sideplay-permitted 1 } } mass 60000 category-class "AT" category-era "1890s;1900s;1910s" category-region "00" description "Reproduction of Crane 16 from GWR plan website." kuid-table { 0 <kuid:-10:149> 1 <kuid:30992:54000> 2 <kuid:329364:1563> 3 <kuid:329364:1610> 4 <kuid:329364:1612> 5 <kuid2:126323:53050:1> }
Crane.gs Script
The script to control the crane and to provide a user interface is as follows:
// crane.gs // Author: Peter Villaume 2011 // A script for loco mounted crane. By pressing the pantograph button, a control panel // for the crane is presented. The user can raise and lower the hook and jib, and can // slew the crane. // Product objects may be attached to the hook by altering the config.txt. NOT YET!!! include "locomotive.gs" include "world.gs" include "train.gs" class crane isclass Locomotive { bool DeRailed = false; bool FirstTime; thread void VehicleMonitor(void); thread void ScanBrowser(void); // Private methods void ConstructBrowser(); void CraneHome(); void sniffMyTrain(void); // Private attributes Browser browser; Train myTrain; public void Init(void) { inherited(); if(me.GetMyTrain()) { sniffMyTrain(); // resets myTrain myTrain.SetPantographState(0); // start with panto down. Any value for pantograph // greater than 0 will cause the crane control browser // to be opened. FirstTime = true; VehicleMonitor(); } else Interface.Log("No Crane Loco detected - script stopped"); } thread void VehicleMonitor() { // runs continuously bool donkey = false; bool AI_on = false; int panto; sniffMyTrain(); // resets myTrain.. panto = myTrain.GetPantographState(); if (panto>0) myTrain.SetPantographState(0); while (! DeRailed) { sniffMyTrain(); // pantographs are automatically raised whenever the train is set to run in AI. // We need to ignore this so check if AI is on. (or manual control is off) // The crane is a steam loco so pantograph should be down when in manual control. if (AI_on and (myTrain.GetAutopilotMode() == Train.CONTROL_MANUAL)) { AI_on = false; myTrain.SetPantographState(0); } if (myTrain.GetTrainVelocity() != 0.0) browser = null; // close browser if train is moving panto = myTrain.GetPantographState(); if ((myTrain.GetAutopilotMode() == Train.CONTROL_MANUAL) and (panto>0) and (myTrain.GetVelocity() == 0.0)) { myTrain.SetPantographState(0); ConstructBrowser(); Sleep(0.5); if (FirstTime) { FirstTime = false; ScanBrowser(); } } if (myTrain.GetAutopilotMode() != Train.CONTROL_MANUAL) AI_on = true; Sleep(0.5); } } thread void ScanBrowser() { bool jibbing = false; bool hoisting = false; bool slewing = false; Message msg; wait() { on "Vehicle", "Derailed", msg: { if(msg.src == me) { //Interface.Log("VehicleMonitor: I am derailed"); DeRailed = true; } } on "Browser-URL", "live://crane-raisehook", msg: // if browser link Raise Hook is clicked if ( browser and msg.src == browser ) { hoisting = !hoisting; // toggle hoisting. SetMeshAnimationSpeed("crane",-1); // run both animations in reverse SetMeshAnimationSpeed("hook",-0.25); if (hoisting) { StartMeshAnimationLoop("crane"); StartMeshAnimationLoop("hook"); } else { if (!slewing and !jibbing) StopMeshAnimation("crane"); StopMeshAnimation("hook"); } } msg.src = null; // clear message source to avoid confusion continue; on "Browser-URL", "live://crane-lowerhook", msg: // if browser link Lower Jib is clicked if ( browser and msg.src == browser ) { hoisting = !hoisting; // toggle hoisting. SetMeshAnimationSpeed("crane",1); SetMeshAnimationSpeed("hook",0.25); if (hoisting) { StartMeshAnimationLoop("crane"); StartMeshAnimationLoop("hook"); } else { if (!slewing and !jibbing) StopMeshAnimation("crane"); StopMeshAnimation("hook"); } } msg.src = null; // clear message source to avoid confusion continue; on "Browser-URL", "live://crane-raisejib", msg: // if browser link Raise Jib is clicked if ( browser and msg.src == browser ) { jibbing = !jibbing; // toggle jibbing. SetMeshAnimationSpeed("crane",1); SetMeshAnimationSpeed("jib",0.25); if (jibbing) { StartMeshAnimationLoop("crane"); StartMeshAnimationLoop("jib"); } else { if (!slewing and !hoisting) StopMeshAnimation("crane"); StopMeshAnimation("jib"); } } msg.src = null; // clear message source to avoid confusion continue; on "Browser-URL", "live://crane-lowerjib", msg: // if browser link Lower Jib is clicked if ( browser and msg.src == browser ) { jibbing = !jibbing; // toggle jibbing. SetMeshAnimationSpeed("crane",-1); SetMeshAnimationSpeed("jib",-0.25); if (jibbing) { StartMeshAnimationLoop("crane"); StartMeshAnimationLoop("jib"); } else { if (!slewing and !hoisting) StopMeshAnimation("crane"); StopMeshAnimation("jib"); } } msg.src = null; // clear message source to avoid confusion continue; on "Browser-URL", "live://crane-slewleft", msg: // if browser link Slew Left is clicked if ( browser and msg.src == browser ) { slewing = !slewing; // toggle slewing. SetMeshAnimationSpeed("default",0.125); SetMeshAnimationSpeed("crane",1); if (slewing) { StartMeshAnimationLoop("crane"); StartMeshAnimationLoop("default"); } else { if (!jibbing and !hoisting) StopMeshAnimation("crane"); StopMeshAnimation("default"); } } msg.src = null; // clear message source to avoid confusion continue; on "Browser-URL", "live://crane-slewright", msg: // if browser link Slew Right is clicked if ( browser and msg.src == browser ) { slewing = !slewing; // toggle slewing. SetMeshAnimationSpeed("default",-0.125); // set animation to run in reverse SetMeshAnimationSpeed("crane",-1); if (slewing) { StartMeshAnimationLoop("crane"); StartMeshAnimationLoop("default"); } else { if (!jibbing and !hoisting) StopMeshAnimation("crane"); StopMeshAnimation("default"); } } msg.src = null; // clear message source to avoid confusion continue; on "Browser-URL", "live://crane-home", msg: // if browser link crane home is clicked if ( browser and msg.src == browser ) CraneHome(); msg.src = null; // clear message source to avoid confusion continue; on "Browser-Closed", "", msg: // if browser is Closed if ( browser and msg.src == browser ) browser = null; msg.src = null; // clear message source to avoid confusion // CraneHome(); continue; Sleep(0.5); } } // listen to messages from my train only - also handles clearing up sniffs on old train // The variable myTrain changes whenever there is a coupling or decoupling event. void sniffMyTrain() { Train oldTrain = myTrain; myTrain = me.GetMyTrain(); if (oldTrain) { if (oldTrain != myTrain) { Sniff(oldTrain, "Train", "", false); Sniff(myTrain, "Train", "", true); } } else { Sniff(myTrain, "Train", "", true); } } void CraneHome() { if ((GetMeshAnimationFrame("hook")!=0) or (GetMeshAnimationFrame("jib")!=0) or (GetMeshAnimationFrame("body")!=0)) { StartMeshAnimationLoop("crane"); // firstly raise hook float frame = GetMeshAnimationFrame("hook"); // check no of frames to travel float ttime = frame * 8.0 / 60.0; // calculate travel time SetMeshAnimationFrame("hook",0, ttime); // now raise hook. ttime = ttime + 1; Sleep(ttime); // wait for hook to reach top frame = GetMeshAnimationFrame("jib")- 30; // secondly, lower jib to frame 30 if (frame<0) frame = -frame; ttime = frame * 8.0 / 60.0; // calculate travel time SetMeshAnimationFrame("jib",30, ttime); // move the jib to frame 30. ttime = ttime + 1; Sleep(ttime); // wait for jib to travel frame = GetMeshAnimationFrame("default"); // get slewing position. if (frame>90) // if greater than halfway around { // set to travel shortest way back frame = 179 - frame; ttime = frame * 8.0 / 30.0; SetMeshAnimationSpeed("default",0.125); // set slew animation to rotate forward StartMeshAnimationLoop("default"); // start slew animation Sleep(1); while (GetMeshAnimationFrame("default") > 20) Sleep(1); // check if passed rest position StopMeshAnimation("default"); // stop slew animation Sleep(1); } frame = GetMeshAnimationFrame("default"); // get slew position..jib should be on left side if loco ttime = frame * 8.0 / 30.0; // calculate slewing travel time SetMeshAnimationFrame("default",0, ttime); // slew to rest position (frame 0) ttime = ttime + 1; Sleep(ttime); // wait for slewing travel SetMeshAnimationFrame("jib",0,4); // lower jib to rest position Sleep(5); StopMeshAnimation("crane"); // turn off donkey engine animation } } void ConstructBrowser() { browser = null; if ( !browser ) browser = Constructors. NewBrowser(); browser.SetCloseEnabled(true); browser.SetWindowPosition(Interface.GetDisplayWidth()-240, Interface.GetDisplayHeight() - 300); browser.SetWindowSize(200, 140); // browser.SetWindowTitle("Crane"); // browser.SetWindowStyle(Browser.STYLE_NO_FRAME); browser.SetWindowVisible(true); browser.LoadHTMLFile(GetAsset(), "ui.html"); } public string GetDescriptionHTML(void) { string html = inherited(); html = html + "<table><tr><td><img src='PEV.tga' width=350 height=50>"; html = html + "</td></tr><tr><td>" + "<font color=#FFFFFF size=1>" + "<b>OPERATION</b><br></font>" + "<font color=#000000 size=1>" + "The crane controls are enabled by pressing the Pantographs " + "button when the Crane Loco is selected when stationary. " + "The slewing, jib raise-lower and hook raise-lower are " + "controlled by clicking on the appropriate the arrow buttons.<br>" + "To move the loco on the track again, close the " + "crane controls display." + "<br><br>" + "<font color=#FFFFFF size=1>" + "<b>CONFIGURATION</b><br></font>" + "<font color=#000000 size=1>" + "None required."; html = html + "</font></td></tr></table></body></html>"; return html; } };
UI.html
This is the html file that creates the user interface:
<!-- Crane Controls in mini browser --> <html> <body> <table> <tr> <td width> <font>Crane Controls</font> </td> </tr> <tr> <td width=80> <font>Hoist</font> </td> <td width=40> <a href='live://crane-raisehook' tooltip='Raise Hook'><img src='grey_arrow_up.tga' width=24 height=24></a> </td> <td> <a href='live://crane-lowerhook' tooltip='Lower Hook'><img src='grey_arrow_down.tga' width=24 height=24></a> </td> </tr> <tr> <td width=80> <font>Jib<br><br></font> </td> <td width=40> <a href='live://crane-raisejib' tooltip='Raise Jib'><img src='blue_arrow_up.tga' width=24 height=24></a> </td> <td> <a href='live://crane-lowerjib' tooltip='Lower Jib'><img src='blue_arrow_down.tga' width=24 height=24></a> </td> </tr> <tr> <td width=80> <font>Slew</font> </td> <td width=40> <a href='live://crane-slewleft' tooltip='Slew Left'><img src='green_arrow_left.tga' width=24 height=24></a> </td> <td> <a href='live://crane-slewright' tooltip='Slew Right'><img src='green_arrow_right.tga' width=24 height=24></a> </td> </tr> <tr> <td width=80><a href='live://crane-home' tooltip='return crane to home position'><font>Crane Home</font></a></td> <td width=40></td> <td></td> </tr> </table> </body> </html>
The above UI.html file produces the following minibrowser in Trainz:
- Return to HowTo/Use_the_Skin_Modifier_in_GMax