GWR Crane 16 Details
From TrainzOnline
(Difference between revisions)
(First draft) |
(spelling) |
||
(2 intermediate revisions by one user not shown) | |||
Line 89: | Line 89: | ||
5 <kuid2:126323:53050:1> | 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: | ||
+ | |||
+ | [[File:GMax_Skin_Modifier_Crane_Controls1.jpg]] | ||
+ | |||
+ | |||
+ | ;Return to [[HowTo/Use_the_Skin_Modifier_in_GMax]] |
Latest revision as of 11:13, 23 August 2012
[edit] 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> }
[edit] 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; } };
[edit] 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