CCG/Example: Industry(Coal Mine)
Contents |
Industry (Coal Mine)
Directory Structure
A typical asset of this kind has the following File\Directory Structure:
Required Files
config.txt - The config file for the asset.
thumb.jpg - The thumbnail image for this asset. A 240x180 jpeg.
various.tga - The texture graphic files for the various textures used in the industry asset. various.texture.txt - The texture.txt files for the various textures used in the industry asset, usually generated when the model is exported. See the section on Texture.txt files on Page 96 for more information.
various.wav - The various sound files used in the industry asset.
icon_coalmine.tga - The image files used as an icon for the industry model asset.
coalmine.im - The indexed mesh used for the asset.
coalmine.kin - The animation file used for the asset.
coalmine.gs - The script file used to outline the behavior of the industry.
load.im, load.im, globe.im - The model mesh files for the main model, the animated coal load (coal pile) and lights.
coalmine.kin, load.kin, anim.kin - The animation files for the mine, coal load (coal pile) and lights.
Config.txt File Listing
username "Test Coal Mine"
kind "industry"
light 1
nightmode "lamp"
script "coalmine"
class "CoalMine"
icon0 <kuid:-3:10164>
kuid <kuid:171456:100012>
trainz-build 2.9
category-class "AA"
category-region "AU"
category-era "1980s;1990s;2000s"
kuid-table
{
pipe <kuid:-3:10051>
coal <kuid:44179:60013>
diesel <kuid:-3:10011>
}
soundscript
{
daysingle
{
repeat-delay 0,0
distance 10,300
sound
{
0 "coal_mine_ambient.wav"
}
}
truck_run0
{
trigger "truck_run0"
attachment "a.sound"
repeat-delay 0,0
distance 5,200
sound
{
0 "truck_run.wav"
}
}
truck_idle
{
trigger "truck_idle"
attachment "a.sound"
repeat-delay 0,0
distance 5,200
sound
{
0 "truck_idle.wav"
}
}
coal_dump
{
trigger "coal_dump"
attachment "a.sound"
nostartdelay 1
repeat-delay 1,0
distance 5,200
sound
{
0 "coal_dump.wav"
}
}
clunk
{
attachment "a.sound"
trigger "clunk0"
nostartdelay 1
repeat-delay 1,0
distance 10,300
sound
{
0 "clunk.wav"
}
}
backup
{
attachment "a.sound"
trigger "reverse"
repeat-delay 0,0
distance 5,100
sound
{
0 "warning.wav"
}
}
}
mesh-table
{
default
{
mesh "coalmine.im"
auto-create 1
anim "coalmine.kin"
animation-loop-speed 1
critical-animation 1
effects
{
0
{
kind "name"
fontsize 0.3
fontcolor 220,220,220
att "a.name0"
name "name"
}
1
{
kind "name"
fontsize 0.3
fontcolor 220,220,220
att "a.name1"
name "name"
}
2
{
kind "name"
fontsize 0.3
fontcolor 220,220,220
att "a.name2"
name "name"
}
3
{
kind "name"
fontsize 0.16
fontcolor 220,220,220
att "a.name3"
name "name"
}
}
load
{
mesh "load/load.im"
anim "load/load.kin"
auto-create 1
}
load_diesel
{
mesh "diesel_load.im"
anim "diesel_load.kin"
auto-create 1
att "a.diesel_load"
att-parent "default"
}
warning-light-0
{
mesh "warninglight/warninglight.im"
att "a.warnlight_0"
att-parent "default"
anim "warninglight/anim.kin"
auto-create 1
animation-loop-speed 1
effects
{
0
{
kind "corona"
att "a.lightcorona0"
}
1
{
kind "corona"
att "a.lightcorona1"
}
}
}
warning-light-1
{
mesh "warninglight/warninglight.im"
att "a.warnlight_1"
att-parent "default"
anim "warninglight/anim.kin"
auto-create 1
animation-loop-speed 1
effects
{
0
{
kind "corona"
att "a.lightcorona0"
}
1
{
kind "corona"
att "a.lightcorona1"
}
}
}
warning-light-2
{
mesh "warninglight/warninglight.im"
att "a.warnlight_2"
att-parent "default"
anim "warninglight/anim.kin"
auto-create 1
animation-loop-speed 1
effects
{
0
{
kind "corona"
att "a.lightcorona0"
}
1
{
kind "corona"
att "a.lightcorona1"
}
}
}
dumpsterwarning-light-1
{
mesh "warninglight/warninglight.im"
att "a.warnlight_3"
att-parent "default"
anim "warninglight/anim.kin"
auto-create 1
animation-loop-speed 1
effects
{
0
{
kind "corona"
att "a.lightcorona0"
}
1
{
kind "corona"
att "a.lightcorona1"
}
}
}
dumpsterwarning-light-2
{
mesh "warninglight/warninglight.im"
att "a.warnlight_4"
att-parent "default"
anim "warninglight/anim.kin"
auto-create 1
animation-loop-speed 1
effects
{
0
{
kind "corona"
att "a.lightcorona0"
}
1
{
kind "corona"
att "a.lightcorona1"
}
}
}
}
attached-track
{
out_track0
{
track <kuid:-1:15>
vertices
{
0 "a.track0a"
1 "a.track0b"
2 "a.track0c"
3 "a.track0d"
}
}
out_track1
{
track <kuid:-1:15>
vertices
{
0 "a.track1a"
1 "a.track1b"
2 "a.track1c"
3 "a.track1d"
}
}
out_track2
{
track <kuid:-1:15>
vertices
{
0 "a.track2a"
1 "a.track2b"
2 "a.track2c"
3 "a.track2d"
}
}
out_track3
{
track <kuid:-1:15>
vertices
{
0 "a.track3a"
1 "a.track3b"
2 "a.track3c"
3 "a.track3d"
}
}
in_track0
{
track <kuid:-1:15>
vertices
{
0 "a.track4a"
1 "a.track4b"
2 "a.track4c"
3 "a.track4d"
}
}
}
attached-trigger
{
out_load0
{
att "a.trig0"
radius 2
}
out_load1
{
att "a.trig1"
radius 2
}
out_load2
{
att "a.trig2"
radius 2
}
out_load3
{
att "a.trig3"
radius 2
}
in_load0
{
att "a.trig4"
radius 10
}
in_load1
{
att "a.trig5"
radius 10
}
in_load2
{
att "a.trig6"
radius 10
}
in_load3
{
att "a.trig7"
radius 10
}
}
queues
{
coal_out
{
size 1357500
animated-mesh "load"
product-kuid <kuid:44179:60013>
initial-count 543000
allowed-products
{
0 <kuid:44179:60013>
}
}
diesel_in
{
size 310400
animated-mesh "load_diesel"
product-kuid <kuid:-3:10011>
initial-count 155200
allowed-products
{
0 <kuid:-3:10011>
}
}
}
processes
{
coal_consumer
{
start-enabled 1
duration 30
}
}
inputs
{
0
{
amount 6465
queue "diesel_in"
}
}
outputs
{
0
{
amount 22620
queue "coal_out"
}
}
smoke0
{
attachment "a.stack0"
mode "time"
color 46,46,39,150
accel 0.5,0.3,0
rate 8
velocity 3
lifetime 10
minsize 2
maxsize 10
enabled 1
}
smoke1
{
attachment "a.stack1"
mode "time"
color 176,176,176,100
accel 0.5,0.3,0
rate 8
velocity 3
lifetime 8
minsize 2
maxsize 5
enabled 1
}
smoke2
{
attachment "a.load_top0"
mode "time"
color 25,25,25,220
accel 0.5,0.3,0
rate 8
velocity 3
lifetime 10
minsize 2
maxsize 10
enabled 0
}
smoke3
{
attachment "a.load_top1"
mode "time"
color 25,25,25,220
accel 0.5,0.3,0
rate 8
velocity 3
lifetime 10
minsize 2
maxsize 10
enabled 0
}
smoke4
{
attachment "a.load_top2"
mode "time"
color 25,25,25,220
accel 0.5,0.3,0
rate 8
velocity 3
lifetime 10
minsize 2
maxsize 10
enabled 0
}
smoke5
{
attachment "a.load_top3"
mode "time"
color 25,25,25,220
accel 0.5,0.3,0
rate 8
velocity 3
lifetime 10
minsize 2
maxsize 10
enabled 0
}
string-table
{
coalmine_loadbay1 "Coal load bay #1"
coalmine_loadbay2 "Coal load bay #2"
coalmine_loadbay3 "Coal load bay #3"
coalmine_loadbay4 "Coal load bay #4"
coalmine_dieselunload "Diesel unload bay"
}
thumbnails
{
0
{
image "icon_coalmine.tga"
width 64
height 64
}
1
{
image "diesel_icon.tga"
width 64
height 64
}
2
{
image "thumb.jpg"
width 240
height 180
}
}
Script Listing
coalmine.gs
include "BaseIndustry.gs"
//
class CoalMine isclass BaseIndustry
{
ProductQueue coalOutQueue, dieselInQueue;
bool scriptletEnabled = true;
//bool nodiesel = false;
bool animating = false;
bool processing = false;
// Track if they only supply some of the logs that were requested in the waybill.
int dieselWBRemain = 0;
//
bool TriggerSupportsMovingLoad(Vehicle vehicle, string triggerName)
{
if (itc.IsTrainCommand(vehicle.GetMyTrain(), Industry.LOAD_COMMAND))
if (triggerName == "out_load0" or triggerName == "out_load" or triggerName == "out_load2" or triggerName =="out_load3")
return true;
return false;
}
void PerformMovingLoad(Vehicle vehicle, string triggerName)
{
// OUTPUT trigger - load
float speed = vehicle.GetVelocity();
if (speed > -.0f and speed < .0f)
{
int coalAvailable = coalOutQueue.GetQueueCount();
if (triggerName == "out_load0")
{
SendMessage(me, "pfx", "+2");
//World.PlaySound("coal_load.wav");
LoadingReport report = CreateLoadingReport(coalOutQueue, coalAvailable);
vehicle.LoadProduct(report);
SendMessage(me, "pfx", "-2");
}
if (triggerName == "out_load")
{
SendMessage(me, "pfx", "+3");
//World.PlaySound("coal_load.wav");
LoadingReport report = CreateLoadingReport(coalOutQueue, coalAvailable);
vehicle.LoadProduct(report);
SendMessage(me, "pfx", "-3");
}
if (triggerName == "out_load2")
{
SendMessage(me, "pfx", "+");
//World.PlaySound("coal_load.wav");
LoadingReport report = CreateLoadingReport(coalOutQueue, coalAvailable);
vehicle.LoadProduct(report);
SendMessage(me, "pfx", "-");
}
if (triggerName == "out_load3")
{
SendMessage(me, "pfx", "+");
//World.PlaySound("coal_load.wav");
LoadingReport report = CreateLoadingReport(coalOutQueue, coalAvailable);
vehicle.LoadProduct(report);
SendMessage(me, "pfx", "-");
}
}
}
//
bool TriggerSupportsStoppedLoad(Vehicle vehicle, string triggerName)
{
if (itc.IsTrainCommand(vehicle.GetMyTrain(), Industry.UNLOAD_COMMAND))
{
bool vehicleToTrain = vehicle.
GetFacingRelativeToTrain();
int direction = vehicle.GetRelationToTrack(me, "in_track0");
if (!vehicleToTrain)
direction = -direction;
// Are we up to the furthest trigger away from the side we entered for diesel?
if (direction == Vehicle.DIRECTION_BACKWARD and triggerName == "in_load0")
return true;
if (direction == Vehicle.DIRECTION_FORWARD and triggerName == "in_load3")
return true;
// If the train has already stopped, then fall thru and allow this load as well
if (triggerName == "in_load0" or triggerName == "in_load" or triggerName == "in_load2" or triggerName =="in_load3")
{
if (vehicle.GetMyTrain().IsStopped())
return true;
}
}
return false;
}
void PerformStoppedLoad(Vehicle vehicle, string triggerName)
{
int spaceAvailable = dieselInQueue.GetQueueSpace();
LoadingReport report = CreateUnloadingReport(dieselInQueue, spaceAvailable);
int direction = vehicle.GetRelationToTrack(me, "in_track0");
if (direction == Vehicle.DIRECTION_FORWARD)
report.sideFlags = LoadingReport.LEFT_SIDE;
else if (direction == Vehicle.DIRECTION_BACKWARD)
report.sideFlags = LoadingReport.RIGHT_SIDE;
vehicle.UnloadProduct(report);
// Ensure we are tracking this if we are waiting for a way bill to complete in its entirety
if (dieselWBRemain > 0)
dieselWBRemain = dieselWBRemain - report.amount;
/*if (report.amount > 0)
{
nodiesel = false;
SetMeshAnimationFrame("default", 2);
StartMeshAnimationLoop("default");
}*/
}
//
thread void CoalMain(void)
{
Message msg;
wait()
{
on "Scriptlet-Enabled", "":
{
if (!scriptletEnabled)
{
scriptletEnabled = true;
SetProcessEnabled("coal_consumer", true);
}
continue;
}
// ? Power station is providing electricity, if not already running. start the
on "Scriptlet-Enabled", "0":
{
if (scriptletEnabled)
{
scriptletEnabled = false;
SetProcessEnabled("coal_consumer", false);
}
continue;
}
// logs_consumer process in lumber mill has started, so active smoke stack particles and
// start the animation (forklift & conveyor)
on "Process-Start", "coal_consumer":
//Interface.Print("CoalMine.LumberMain():
Process-Start:coal_consumer message received, starting default animation amd smoke stack particles");
SendMessage(me, "pfx", "+0+");
if (animating) // only start animating if animation isn't already running
StartMeshAnimationLoop("default");
continue;
// logs_consumer process has stopped, disable particle effect and stop animation
on "Process-Stop", "coal_consumer":
//Interface.Print("CoalMine.LumberMain():
Process-Stop:coal_consumer message received, stopping default animation and smoke stack particles");
SendMessage(me, "pfx", "-0-");
StopMeshAnimation("default");
continue;
//
on "Animation-Event", "animstop":
{
//if (!(GetProcessStarted("logs_consumer") and
GetProcessEnabled("logs_consumer")))
//Interface.Print("Animation-Event: animstop message received, stopping default animation!");
StopMeshAnimation("default");
// make sure we didn't overshoot the end of the animation
SetMeshAnimationFrame("default", 2);
// it's actually possible to receive the Animation-Event message multiple times, even
// though we tell the game engine to stop the animation.this can occur if the frame-rate
// is low and the animation repeats multiple times inside one frame. it's important that we
// check for this situation, otherwise a script exception will result.
if (animating)
{
animating = false;
if (!processing)
{
// we are making the assumption that there is only one process, "coal_consumer"
// if there were more, we would have to be careful to finish the correct process here
PerformProcessOutput("coal_consumer");
PerformProcessFinished("coal_consumer");
}
}
continue;
}
}
}
// Called by the game once when a process is ready to start (see Industry.gs)
void NotifyProcessStarted(string processName)
{
//Interface.Print("CoalMine.NotifyProcessFinished: Process Started");
if (scriptletEnabled) // only when power is running
{
if (PerformProcessInput(processName))
{
//Interface.Print("NotifyProcessStarted: Starting the default animation!");
// we are making the assumption that there is only one process, "logs_consumer"
SetMeshAnimationFrame("default", 2);
StartMeshAnimationLoop("default");
animating = true;
processing = true;
PerformProcessStarted(processName);
}
else
PerformProcessCancelled(processName);
}
}
// called by the game once when a process is ready to stop see Industry.gs)
void NotifyProcessFinished(string processName)
{
//Interface.Print("CoalMine.NotifyProcessFinished: Process Finished");
if (scriptletEnabled)
{
processing = false;
if (!animating)
{
PerformProcessOutput(processName);
PerformProcessFinished(processName);
PostMessage(me, "GenericIndustry", "ProcessComplete",0.0f);
}
}
//if (GetProcessInput(processName, dieselInQueue,GetAsset().FindAsset("diesel")) <= 0)
//{
//nodiesel = true;
//StopMeshAnimation("default");
//SetMeshAnimationFrame("default", 0);
//}
}
//
public void Init(void)
{
inherited();
usePipeAnimation = true;
useGenericViewDetails = true;
coalOutQueue = GetQueue("coal_out");
dieselInQueue = GetQueue("diesel_in");
AddAssetToIndustryProductInfo("diesel", "diesel_in","coal_consumer", true);
AddAssetToIndustryProductInfo("coal", "coal_out", "coal_consumer", false);
// Enabled or disabled on startup? (Depends on if we have fuel! :D)
/*if (dieselInQueue.GetQueueCount() > 0)
{
nodiesel = false;
SetMeshAnimationFrame("default", 2);
StartMeshAnimationLoop("default");
}
else
{
nodiesel = true;
StopMeshAnimation("default");
SetMeshAnimationFrame("default", 0);
}*/
CoalMain();
}
public Requirement[] GetRequirements(void)
{
Requirement[] ret = new Requirement[0];
if (dieselInQueue.GetQueueCount() < 7700 or dieselWBRemain > 0) // Approx 2% of full
{
ResourceRequirement req = new ResourceRequirement();
req.resource = dieselInQueue.GetProductFilter().GetProducts()[0];
// This is how many we have asked for. Wait till it is fullfilled,
// if we are not already waiting for a waybill to be completed.
req.amount = 23200; // tank cars
if (dieselInQueue.GetQueueCount() < 7700 and dieselWBRemain == 0)
dieselWBRemain = 23200;
req.dst = me;
req.dstQueue = dieselInQueue;
ret[ret.size()] = req;
}
return ret;
}
public void AppendDriverDestinations(string[] destNames,string[] destTracks)
{
StringTable stringTable = GetAsset().GetStringTable();
destNames[destNames.size()] = stringTable.GetString("coalmine_loadBay");
destTracks[destTracks.size()] = "out_track0";
destNames[destNames.size()] = stringTable.GetString("coalmine_loadBay2");
destTracks[destTracks.size()] = "out_track";
destNames[destNames.size()] = stringTable.GetString("coalmine_loadBay3");
destTracks[destTracks.size()] = "out_track2";
destNames[destNames.size()] = stringTable.GetString("coalmine_loadBay");
destTracks[destTracks.size()] = "out_track3";
destNames[destNames.size()] = stringTable.GetString("coalmine_dieselUnload");
destTracks[destTracks.size()] = "in_track0";
}
};
Download this asset
This asset is available for download from the TRS2006 website at:
http://files.auran.com/TRS2006/Downloads/Example_Download.zip.
