GWR Crane 16 Details: Difference between revisions
From TrainzOnline
Jump to navigationJump to search
First draft |
spelling |
||
| (2 intermediate revisions by the same 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 01:13, 23 August 2012
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
