CCG/Modelling: Tenders

From TrainzOnline
< CCG
Jump to: navigation, search

Contents

Tenders

Locomotives with tenders normally operate as a unit.

However, if you use the runaround command in Driver the locomotive leaves the tender behind. For steam tender config.txt files, add the following line:

tender 1

This ensures the tender stays with the locomotive.

Tenders Dump Coal

To prevent steam tenders or the coal bunker of a steamer being robbed at the Power station or any Multi industry track that is coal unload enabled, you should use the "No Dump" Script by Wulf_9, reproduced with permission.


You may find the scripts useful.

Stop steam locos and tenders dumping coal.

This is a complete class - save to the filename and use as-is by copying all the text in the code box below

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;
   }
};


Include the script with the asset and add these lines to a tender config.txt file and it stops the tender dumping coal incorrectly.

Config.txt entries:-

script     "steamtender"
class      "Steam_Tender"

A second script is available for tank engines.

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;
   }
};


The following lines should be included in the config.txt file for the engine:

Config.txt entries:-

script "steamtank"
class "Steam_Tank"

Auxiliary Tender or Water Gin for Steam Locos

Script by Wulf_9


This is a complete class - save to the filename and use as-is by copying all the text in the code box.

// 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"
  
update_delay "180"
  
kuid-table
{
   water         <kuid:-3:10004>
}           

update_delay is a value is in seconds



Previous Page . . . . Next Page

Return to CCG Index

Content Creator's Guide

Personal tools