This is a complete class - save to the filename and use as-is by copying all the text between the dotted lines
------------------------------------------------------- // sceneryloco.gs // // Turns a locomotive into a scenery train // ©Wulf_9, Sept '04 include "locomotive.gs" class SceneryLoco isclass Locomotive { Train myTrain; public void Disable(void) { Sleep(10.0); myTrain = me.GetMyTrain(); if (myTrain != null) myTrain.EnablePhysics(false); } public void Init(void) { inherited(); Disable(); } }; -------------------------------------------------------
Config.txt entries:-
script "sceneryloco" class "SceneryLoco"
Note, the extension is NOT used in these declarations, unlike 'include' statements in scripts.
______________________________________________________________________________________________________________________
This is a complete class - save to the filename and use as-is by copying all the text between the dotted lines
Tender version
------------------------------------------------------- // steamtender.gs // prevents unloading of coal at industries // ©Wulf_9, Sept '04 include "vehicle.gs" class Steam_Tender isclass Vehicle { bool UnloadProduct(LoadingReport report) { bool UnloadFlag = false; return UnloadFlag; } }; -------------------------------------------------------
Config.txt entries:-
script "steamtender" class "Steam_Tender"
______________________________________________________________________________________________________________________
Tank engine version
------------------------------------------------------- // steamtank.gs // prevents unloading of coal at industries // ©Wulf_9, Sept '04 include "vehicle.gs" class Steam_Tank isclass Locomotive { bool UnloadProduct(LoadingReport report) { bool UnloadFlag = false; return UnloadFlag; } }; -------------------------------------------------------
Config.txt entries:-
script "steamtank" class "Steam_Tank"
______________________________________________________________________________________________________________________
This is a complete class - save to the filename and use as-is by copying all the text between the dotted lines.
It is suggested to change myVehicleClass to your own custom class name, but make sure to edit every instance of it.
------------------------------------------------------- // Random Unique Number Script // ©Wulf_9, October 2004 // rrn_wagon.gs include "vehicle.gs" class myVehicleClass isclass Vehicle { Soup mySoup = GetAsset().GetConfigSoup(); string[] carNumbers = new string[0]; string myNumber = " "; void InitNumbers(void) { int low = mySoup.GetNamedTagAsInt("number_low"); int high = mySoup.GetNamedTagAsInt("number_high"); int n; for (n = 0; n < (high - low); n++) { carNumbers[n] = (string)(low + n); } } void SetNumber(void) { InitNumbers(); Vehicle[] allWagons = World.GetVehicleList(); string[] tNums = new string[0]; int idx = Math.Rand(0, carNumbers.size()); myNumber = carNumbers[idx]; myVehicleClass aWagon; int w, n, c; for (w = 0; w < allWagons.size(); w++) { if (allWagons[w].isclass(myVehicleClass) and allWagons[w] != me) { aWagon = cast<myVehicleClass> (allWagons[w]); tNums[tNums.size()] = aWagon.myNumber; } } for (n = 0; n < tNums.size(); n++) { for (c = 0; c < carNumbers.size(); c++) { if (carNumbers[c] == tNums[n]) { carNumbers[c, c + 1] = null; } } } if (tNums.size() > 0) { idx = Math.Rand(0, carNumbers.size()); myNumber = carNumbers[idx]; } SetFXNameText("number_left", myNumber); SetFXNameText("number_right", myNumber); } public void Init(void) { inherited(); SetNumber(); } }; -------------------------------------------------------
Add the following info to your config file - the extra mesh-table part is between the ; ### marks (but don't include them) :-
------------------------------------------------------- ; script and class declarations script "rrn_wagon" class "MyVehicleClass" ; Running number range examples number_low "58200" number_high "65750" mesh-table { default { mesh "my_vehicle_body/my_mesh.im" auto-create 1 ; ### effects { number_left { kind name att "a.numleft" fontsize 0.1 fontcolor 140,140,130 name } number_right { kind name att "a.numright" fontsize 0.1 fontcolor 140,140,130 name } } ; end 'effects' ; ### } ; end 'default' } ; end mesh-table -------------------------------------------------------
The 'name' tags must be left blank or they won't be editable.
The attachment points for the number text should be positioned at the relevant location on the car body, you can find the precise surface position by jockeying the point in or out in gmax, shift it sideways in + or - X until it just disappears, then bring it back a bit at a time until the green cross reappears on the outside surface - all this done in the appropriate side view. This will ensure that your numbers seem to be actually written on the body side rather than floating a few mm free in space, which, IMO, sucks a bit. Also bear in mind that text effects proceed outwards in both X directions from the origin, i.e. it is centre-justified. The attachment will need to be rotated in Z and Y to make the text show along the proper axis. If you want to include a space, use the underscore character instead of a whitespace :)
______________________________________________________________________________________________________________________
This is a complete class - save to the filename and use as-is by copying all the text between the dotted lines.
------------------------------------------------------- // slw_auxtender.gs // // Auxiliary tender (or water gin) distributor and feeder script // // Will run automatically when directly coupled, in single or multiple, // to an active steam loco and tender combination. Not for tank locos. // // GetVehicleProductQueue() is a specially-customised adaptation of // GetVehicleQueue() by Mike Carter, (c)TrainzProRoutes.com, 2004 // // This code is (c)Wulf_9, Saxon Locomotive Works, March 2005. // NOT to be used in payware without prior written agreement. // // Freeware creators are encouraged to use and share this script, // provided the code is distributed in UNMODIFIED form. Any and // all support obligations and other liabilities shall reside // with the author of the asset to which this script belongs. include "vehicle.gs" class SLW_ATWG isclass Vehicle { Asset waterAsset; Train thisTrain; float rsd; bool active = 0, update = 0; float EndLoad(LoadingReport report) { if (active) PostMessage(me, "SLW_ATWG", "ReBalance", 5.0); return 1.0; } bool UnloadProduct(LoadingReport report) { if (active) return false; return true; } ProductQueue GetVehicleProductQueue(Vehicle v, Asset prodAsset) { string vQ, prodKuid, catKuid; bool found = 0; int s, l, p; vQ = ""; Soup vSoup = v.GetAsset().GetConfigSoup(); Soup pSoup = prodAsset.GetConfigSoup(); Soup vqSoup = vSoup.GetNamedSoup("queues"); prodKuid = pSoup.GetNamedTag("kuid"); catKuid = pSoup.GetNamedTag("product-category"); for (s = 0; s < vqSoup.CountTags(); s++ ) { Soup load = vqSoup.GetNamedSoup(vqSoup.GetIndexedTagName(s)); if (load.GetNamedTag("product-kuid") == prodKuid) { found = 1; vQ = vqSoup.GetIndexedTagName(s); break; } for (l = 0; l < load.CountTags(); l++ ) { if (load.GetIndexedTagName(l) == "allowed-categories") { Soup prod = load.GetNamedSoup("allowed-categories"); for (p = 0; p < prod.CountTags(); p++) { if (prod.GetNamedTag(prod.GetIndexedTagName(p)) == catKuid) { found = 1; vQ = vqSoup.GetIndexedTagName(s); break; } } } if (found) break; } if (found) break; Soup prod = load.GetNamedSoup("allowed-products"); for (p = 0; p < prod.CountTags(); p++) { if (prod.GetNamedTag(prod.GetIndexedTagName(p)) == prodKuid) { found = 1; vQ = vqSoup.GetIndexedTagName(s); break; } } if (found) break; } return (v.GetQueue(vQ)); } void UpdateTrain(Message msg) { if (((msg.src == me) or TrainUtil.IsInTrain(thisTrain, msg.src)) and !update) { update = 1; ClearMessages("SLW_ATWG", "ReBalance"); thisTrain = me.GetMyTrain(); Vehicle[] cars = thisTrain.GetVehicles(); float avlf = 0.0; int i = 0, inc = 0, tvp = 0, avp = 0, atc = 1; active = 0; for (i = 0; i < cars.size(); i++) { ProductQueue pQ = GetVehicleProductQueue(cars[i], waterAsset); bool isST = (cars[i].GetVehicleTypeFlags() == Vehicle.TYPE_TENDER); bool facing = cars[i].GetDirectionRelativeToTrain(); bool isAT = cars[i].isclass(SLW_ATWG); if (facing) inc = i - 1; else inc = i + 1; bool count = 0; if (pQ and isST and !isAT) { if ((i > 0 and facing) or (i < cars.size() - 1 and !facing)) { if (cars[inc].GetEngineType() != Vehicle.ENGINE_STEAM) continue; } active = 1; count = 1; tvp = i; avp = tvp; ++atc; } if (pQ and isAT and (i == avp + 1)) { count = 1; avp = i; if (cars[i] != me) ++atc; } if (count) avlf = avlf + ((float)pQ.GetQueueCount() / (float)pQ.GetQueueSize()); } avlf = avlf / (float)atc; if (active) { for (i = tvp; i < (tvp + atc); i++) { ProductQueue pQ = GetVehicleProductQueue(cars[i], waterAsset); bool isAT = cars[i].isclass(SLW_ATWG); if (pQ and ((i == tvp) or isAT)) { int vQc = (int)(avlf * (float)pQ.GetQueueSize()); cars[i].SetQueueInitialCount(pQ, waterAsset, vQc); } } PostMessage(me, "SLW_ATWG", "ReBalance", rsd); } } update = 0; } void InitStart(Message msg) { thisTrain = me.GetMyTrain(); } public void Init(void) { inherited(); if (GetAsset().LookupKUIDTable("water")) waterAsset = GetAsset().FindAsset("water"); rsd = (float)GetAsset().GetConfigSoup().GetNamedTagAsInt("update_delay", 300); AddHandler(me, "Vehicle", "Coupled", "UpdateTrain"); AddHandler(me, "Vehicle", "BadCouple", "UpdateTrain"); AddHandler(me, "Vehicle", "Decoupled", "UpdateTrain"); AddHandler(me, "SLW_ATWG", "ReBalance", "UpdateTrain"); AddHandler(me, "World", "ModuleInit", "InitStart"); } }; -------------------------------------------------------
Config.txt entries:-
script "slw_auxtender" class "SLW_ATWG" ; this value is in seconds update_delay "180" kuid-table { water <kuid:-3:10004> }
______________________________________________________________________________________________________________________