Trains Of Europe - Help with coding

Discussions about the technical aspects of graphics development, including NewGRF tools and utilities.

Moderator: Graphics Moderators

Post Reply
User avatar
Emperor Jake
Tycoon
Tycoon
Posts: 3441
Joined: 24 Apr 2007 09:37
Skype: Discord: Emperor Jake #4106
Location: Not Actually Japan
Contact:

Trains Of Europe - Help with coding

Post by Emperor Jake »

Hi
I'm currently working on a massive new set, which builds on my old Generic European Set. I have coded four new railtypes, each representing a different voltage system used in Europe:
1500V DC (DC15)
3000V DC (DC30)
15KV AC (ELAC)
25KV AC (ELRL) - regular electric rail; default electrics run on this

This is working fine so far - until I tried to code a multi-system locomotive.

Code: Select all

		track_type:         bitmask(ELRL, ELAC, DC15, DC30);
doesn't seem to work; the engine stubbornly keeps going on unelectrified tracks.

I then tried several other things, the one that seemed to work best out of them was creating another railtype that was compatible with all four electrified tracktypes. However, it clutters up the railtypes menu, and it doesn't appear to be possible for a locomotive to run on only ELAC and ELRL, but not the DC ones, for example.


Here is the code for the railtypes:

Code: Select all

item(FEAT_RAILTYPES) {
    property {
        label:                      "ELAC";
        name:                       string(STR_AC15);
        menu_text:                  string(STR_AC15);
        build_window_caption:       string(STR_AC15_BUILD);
        autoreplace_text:           string(STR_AC15_AUTOREPLACE);
        new_engine_text:            string(STR_AC15_NEW_ENGINE);
//	introduction_date:  date(1950,1,1);
        compatible_railtype_list:   ["RAIL","ELRL","ELAC","DC15","DC30"];          
	powered_railtype_list:      ["ELAC"];                 
        railtype_flags:             bitmask(RAILTYPE_FLAG_CATENARY);
        curve_speed_multiplier:     1;
//      station_graphics:           RAILTYPE_STATION_RAIL;          
        construction_cost:          2;                               
//        speed_limit:                230 km/h;
        acceleration_model:         ACC_MODEL_RAIL;  
	sort_order: 18;                 
    }
    graphics {             
	CATENARY_PYLONS: elac_pylons_group;             
    }
}

item(FEAT_RAILTYPES) {
    property {
        label:                      "DC15";
        name:                       string(STR_DC15);
        menu_text:                  string(STR_DC15);
        build_window_caption:       string(STR_DC15_BUILD);
        autoreplace_text:           string(STR_DC15_AUTOREPLACE);
        new_engine_text:            string(STR_DC15_NEW_ENGINE);
//	introduction_date:  date(1950,1,1);
        compatible_railtype_list:   ["RAIL","ELRL","ELAC","DC15","DC30"];          
	powered_railtype_list:      ["DC15"];                 
        railtype_flags:             bitmask(RAILTYPE_FLAG_CATENARY);
        curve_speed_multiplier:     1;
//      station_graphics:           RAILTYPE_STATION_RAIL;          
        construction_cost:          2;                               
//       speed_limit:                160 km/h;
        acceleration_model:         ACC_MODEL_RAIL;
	sort_order: 16;                    
    }
    graphics {             
	CATENARY_PYLONS: dc15_pylons_group;   
	CATENARY_WIRE:   dc_wire_group;          
    }
}

item(FEAT_RAILTYPES) {
    property {
        label:                      "DC30";
        name:                       string(STR_DC30);
        menu_text:                  string(STR_DC30);
        build_window_caption:       string(STR_DC30_BUILD);
        autoreplace_text:           string(STR_DC30_AUTOREPLACE);
        new_engine_text:            string(STR_DC30_NEW_ENGINE);
//	introduction_date:  date(1950,1,1);
        compatible_railtype_list:   ["RAIL","ELRL","ELAC","DC15","DC30"];          
	powered_railtype_list:      ["DC30"];                 
        railtype_flags:             bitmask(RAILTYPE_FLAG_CATENARY);
        curve_speed_multiplier:     1;
//      station_graphics:           RAILTYPE_STATION_RAIL;          
        construction_cost:          2;                               
//        speed_limit:                160 km/h;
        acceleration_model:         ACC_MODEL_RAIL;
	sort_order: 17;                    
    }
    graphics {             
	CATENARY_PYLONS: dc30_pylons_group;   
	CATENARY_WIRE:   dc_wire_group;          
    }
}

item(FEAT_RAILTYPES) {
    property {
        label:                      "RAIL";
        compatible_railtype_list:   ["TRIF","RAIL","ELRL","ELAC","DC15","DC30"];          
	powered_railtype_list:      ["TRIF","ELRL","ELAC","DC15","DC30"];                 
    }
}

item(FEAT_RAILTYPES) {
    property {
        label:                      "ELRL";
        name:                       string(STR_AC25);
        menu_text:                  string(STR_AC25);
        build_window_caption:       string(STR_AC25_BUILD);
        autoreplace_text:           string(STR_AC25_AUTOREPLACE);
        new_engine_text:            string(STR_AC25_NEW_ENGINE);
        compatible_railtype_list:   ["RAIL","ELRL","ELAC","DC15","DC30"];          
	powered_railtype_list:      ["ELRL"];                 
    }
}

/*
item(FEAT_RAILTYPES) {
    property {
        label:                      "MULT";
        name:                       string(N_A);
        menu_text:                  string(N_A);
        build_window_caption:       string(N_A);
        autoreplace_text:           string(N_A);
        new_engine_text:            string(N_A);
        compatible_railtype_list:   ["ELRL","ELAC","DC15","DC30"];          
	powered_railtype_list:      ["ELRL","ELAC","DC15","DC30"];
	introduction_date:  date(9999,1,1); 
	speed_limit: 1;
        construction_cost:          65525;                   
    }
}
*/

And the multi system locomotive:

Code: Select all

switch (FEAT_TRAINS, SELF, ms_train_power_switch, current_railtype) {
	ELRL: return 2000;
	ELAC: return 2000;
	DC30: return 1500;
	DC15: return 1500;
//	RAIL: return 0;  //train just coasts to a halt on unpowered track
    CB_FAILED;
}

switch (FEAT_TRAINS, SELF, ms_train_speed_switch, current_railtype) {
	ELRL: return 230;
	ELAC: return 200;
	DC30: return 160;
	DC15: return 160;
//	RAIL: return 1;  //makes game crash when engine enters RAIL
//	RAIL: return 0;  //game says max speed is 65,535 km/h
    CB_FAILED;
}

switch (FEAT_TRAINS, SELF, ms_railtype_switch, extra_callback_info1) {
	PROP_TRAINS_POWER: ms_train_power_switch;
	PROP_TRAINS_SPEED: ms_train_speed_switch;
    CB_FAILED;
}

switch (FEAT_TRAINS, SELF, ms_train_switch, current_callback) {
	VEH_CB_VEHICLE_PROPERTIES: ms_railtype_switch;
    test_train_group;
}

//Testing Multi-System Train
item(FEAT_TRAINS, ms_train) {
	property {
		sprite_id:          SPRITE_ID_NEW_TRAIN;
		misc_flags:         bitmask(TRAIN_FLAG_2CC);
		name:               string(STR_NAME_TEST_TRAIN_4);
		climates_available: ALL_CLIMATES;
		track_type:         bitmask(ELRL, ELAC, DC15, DC30);
		introduction_date:  date(1950,1,1);
		speed:              230 km/h;
		tractive_effort_coefficient:    0.5;
		power:              2000 hp;
		weight: 100;
		dual_headed:        0;
		engine_class:       ENGINE_CLASS_ELECTRIC;
		}
		graphics {                          
		ms_train_switch;
		}
		
}
Does anyone have any advice on this? I would appreciate some help. If it's not possible at all, then consider it a feature request :wink:

Thanks,
Jake
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5631
Joined: 13 Sep 2004 13:21
Location: The Moon

Re: Trains Of Europe - Help with coding

Post by PikkaBird »

And this is what happens when we write NML without understanding the grf spec. :)
Yexo
Tycoon
Tycoon
Posts: 3663
Joined: 20 Dec 2007 12:49

Re: Trains Of Europe - Help with coding

Post by Yexo »

Or without understanding the nml documentation.
http://hg.openttdcoop.org/nml/raw-file/tip/docs/vehicles.html#trains-property wrote: track_type
item from railtypetable
Default railtype table: RAIL, MONO, MGLV. If you install a railtypetable yourself you'll always get the railtype you specified. If you want a vehicle to run on electric rail and you don't have a railtypetable, set track_type to RAIL and make sure that you set engine_class to ENGINE_CLASS_ELECTRIC.
You can't suddenly use a bitmask of multiple values when the documentation says you need "(one) item from railtypetable". If you were able to use a bitmask there the documentation would have said so.

One engine can only ever support one track type. If you want an engine to run on multiple track types you have to make those track types compatible. Just like the default "Rail" and "Electric rail" are compatible. It looks like you've already set the compatible_railtype_list property correctly. However the way you coded it now (with powered_railtype_list only containing the railtype itself) your trains can run on the other track types but won't be able to function as engine there.
User avatar
Emperor Jake
Tycoon
Tycoon
Posts: 3441
Joined: 24 Apr 2007 09:37
Skype: Discord: Emperor Jake #4106
Location: Not Actually Japan
Contact:

Re: Trains Of Europe - Help with coding

Post by Emperor Jake »

Yexo wrote: One engine can only ever support one track type. If you want an engine to run on multiple track types you have to make those track types compatible. Just like the default "Rail" and "Electric rail" are compatible. It looks like you've already set the compatible_railtype_list property correctly. However the way you coded it now (with powered_railtype_list only containing the railtype itself) your trains can run on the other track types but won't be able to function as engine there.
So is what I'm trying to do even possible?

If I make the different railtypes compatible, then they would become pointless because then a 1500V DC only locomotive would simply be able to go on all electric tracks. :?
Yexo wrote: You can't suddenly use a bitmask of multiple values when the documentation says you need "(one) item from railtypetable". If you were able to use a bitmask there the documentation would have said so.
Then maybe nmlc should complain when trying to compile it?
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: Trains Of Europe - Help with coding

Post by planetmaker »

Emperor Jake wrote:

Code: Select all

		track_type:         bitmask(ELRL, ELAC, DC15, DC30);
An engine can only have one track type associated. It's not a bitmask, I'm afraid.

The compatibility is defined by the track properties of the railtypes.
VEH_CB_VEHICLE_PROPERTIES wrote: Most properties will only change when the vehicle is bought, serviced (enters a depot), visits a station or on loading of a saved game. Other ones such as TE are called every time a TE calculation is run.
On of those properties which can change is power, when the railtype changes.

Thus you could give it a try to adjust power via this callback accordingly - and IIRC you'd have to declare the track types as (unpowered? powered?) compatible.

I might be wrong though ;-)
User avatar
Emperor Jake
Tycoon
Tycoon
Posts: 3441
Joined: 24 Apr 2007 09:37
Skype: Discord: Emperor Jake #4106
Location: Not Actually Japan
Contact:

Re: Trains Of Europe - Help with coding

Post by Emperor Jake »

planetmaker wrote:On of those properties which can change is power, when the railtype changes.

Thus you could give it a try to adjust power via this callback accordingly - and IIRC you'd have to declare the track types as (unpowered? powered?) compatible.

I might be wrong though ;-)
I've already tried this - if I make the tracktypes like this:

Code: Select all

item(FEAT_RAILTYPES) {
    property {
        label:                      "DC30";
        name:                       string(STR_DC30);
        menu_text:                  string(STR_DC30);
        build_window_caption:       string(STR_DC30_BUILD);
        autoreplace_text:           string(STR_DC30_AUTOREPLACE);
        new_engine_text:            string(STR_DC30_NEW_ENGINE);
//	introduction_date:  date(1950,1,1);
        compatible_railtype_list:   ["RAIL","ELRL","ELAC","DC15","DC30"];          
	powered_railtype_list:      ["ELRL","ELAC","DC15","DC30"];                 
        railtype_flags:             bitmask(RAILTYPE_FLAG_CATENARY);
        curve_speed_multiplier:     1;
//      station_graphics:           RAILTYPE_STATION_RAIL;          
        construction_cost:          2;                               
//        speed_limit:                160 km/h;
        acceleration_model:         ACC_MODEL_RAIL;
	sort_order: 17;                    
    }
    graphics {             
	CATENARY_PYLONS: dc30_pylons_group;   
	CATENARY_WIRE:   dc_wire_group;          
    }
}
then EVERY electric locomotive runs on that track regardless of railtype. I want some trains to be only powered under a single railtype.
If I use the callback to set the power to zero, then the train simply coasts to a halt and becomes stuck because it's on a compatible, but unpowered, railtype.
Yexo
Tycoon
Tycoon
Posts: 3663
Joined: 20 Dec 2007 12:49

Re: Trains Of Europe - Help with coding

Post by Yexo »

Emperor Jake wrote:
Yexo wrote: You can't suddenly use a bitmask of multiple values when the documentation says you need "(one) item from railtypetable". If you were able to use a bitmask there the documentation would have said so.
Then maybe nmlc should complain when trying to compile it?
Yes, that would be good if that was possible. However it's not so easy, since nmlc first simplifies whatever you write in a single number, and after all a bitmask is just another number.

What you want (only some locomotives are able to run on multiple track types) is indeed impossible. That's not a limitation of NML but a limitation of the current nfo spec.
User avatar
Emperor Jake
Tycoon
Tycoon
Posts: 3441
Joined: 24 Apr 2007 09:37
Skype: Discord: Emperor Jake #4106
Location: Not Actually Japan
Contact:

Re: Trains Of Europe - Help with coding

Post by Emperor Jake »

Yexo wrote:
What you want (only some locomotives are able to run on multiple track types) is indeed impossible. That's not a limitation of NML but a limitation of the current nfo spec.
Dang. That's what I was dreading :(

If it were implemented, what would be the best way? I would think that making "track_type" a bitmask would make the most sense. This would be potentially useful for dual gauge tracks and other fancy new railtype things, such as weight limits (eg "Big Powerful Locomotive" is not compatible with "Cheap Railway Track" because it is too heavy)
I would like to request this feature (or something that will allow doing the same thing if there is a better idea) I have no idea how hard it would be to code though.

Thanks,
Jake
User avatar
DJ Nekkid
Tycoon
Tycoon
Posts: 2141
Joined: 30 Nov 2006 20:33

Re: Trains Of Europe - Help with coding

Post by DJ Nekkid »

VarAction2 variable 4A ? (but yes, a bitmask would be nice, but it would need a new property in the train action0)
Member of the
ImageImage
User avatar
Emperor Jake
Tycoon
Tycoon
Posts: 3441
Joined: 24 Apr 2007 09:37
Skype: Discord: Emperor Jake #4106
Location: Not Actually Japan
Contact:

Re: Trains Of Europe - Help with coding

Post by Emperor Jake »

Adding a callback would work - one that simply decides whether a tracktype is compatible or not.

For example:

Code: Select all


switch (FEAT_TRAINS, SELF, ms_train_power_switch, current_railtype) {
	ELRL: return 2000;
	ELAC: return 2000;
	DC30: return 1500;
	DC15: return 1500;
    CB_FAILED;
}

switch (FEAT_TRAINS, SELF, ms_train_speed_switch, current_railtype) {
	ELRL: return 230;
	ELAC: return 200;
	DC30: return 160;
	DC15: return 160;
    CB_FAILED;
}

switch (FEAT_TRAINS, SELF, ms_properties_switch, extra_callback_info1) {
	PROP_TRAINS_POWER: ms_train_power_switch;
	PROP_TRAINS_SPEED: ms_train_speed_switch;
    CB_FAILED;
}


//decides which railtypes are compatible - all of these are defined as being compatible to RAIL normally
switch (FEAT_TRAINS, SELF, ms_railtype_switch, current_railtype) {  
	ELRL: return 1;
	ELAC: return 1;
	DC30: return 1;
	DC15: return 1;
        TRIF: return 0;
        RAIL: return 0;
    CB_FAILED;
}

switch (FEAT_TRAINS, SELF, ms_train_switch, current_callback) {
	VEH_CB_VEHICLE_PROPERTIES: ms_properties_switch;
	VEH_CB_COMPATIBLE_RAILTYPES: ms_railtype_switch;  //new callback
    test_train_group;
}

//Testing Multi-System Train
item(FEAT_TRAINS, ms_train) {
	property {
		sprite_id:          SPRITE_ID_NEW_TRAIN;
		misc_flags:         bitmask(TRAIN_FLAG_2CC);
		name:               string(STR_NAME_TEST_TRAIN);
		climates_available: ALL_CLIMATES;
		track_type:         RAIL;
		introduction_date:  date(1950,1,1);
		speed:              200 km/h;
		tractive_effort_coefficient:    0.5;
		power:              2000 hp;
		weight:              100;
		dual_headed:        0;
		engine_class:       ENGINE_CLASS_ELECTRIC;
		}
		graphics {                          
		ms_train_switch;
		}
		
}
Yexo
Tycoon
Tycoon
Posts: 3663
Joined: 20 Dec 2007 12:49

Re: Trains Of Europe - Help with coding

Post by Yexo »

That would make all caching the pathfinder does impossible.
User avatar
Emperor Jake
Tycoon
Tycoon
Posts: 3441
Joined: 24 Apr 2007 09:37
Skype: Discord: Emperor Jake #4106
Location: Not Actually Japan
Contact:

Re: Trains Of Europe - Help with coding

Post by Emperor Jake »

Would it be possible to implement it in any way then? :?

How about a different approach:
Is it possible to keep a railtype from ever appearing to the player, even though it has a vehicle? Because the multi voltage locomotive works best if there is an extra railtype that is compatible with the others.
Yexo
Tycoon
Tycoon
Posts: 3663
Joined: 20 Dec 2007 12:49

Re: Trains Of Europe - Help with coding

Post by Yexo »

I don't see the point of such a railtype. What use would it have?
User avatar
DJ Nekkid
Tycoon
Tycoon
Posts: 2141
Joined: 30 Nov 2006 20:33

Re: Trains Of Europe - Help with coding

Post by DJ Nekkid »

I do see his point, but imho would a bitmask in the train action0 be better, as an engine can be 'dual voltage' or 'dual type' somehow. (example: 1500VDC, 25kVAC and 750v 3ra rail).
A 1500VDC train would not be powered on 25kVAC and 750v 3rd rails, and thus would the railtype not have thoose as a 'powered' type.
I have not tested the earlier mentioned var2, but that should probably do what im thinking of (4A), in NFO i suspect it would be something like:

Code: Select all

Translation table with:
RAIL // 0
ELRL // 1
15DC // 2
25AC // 3

-1 * 0  02 00 xx 85 4A 00 FF
     01 80 \wx0101 // Allow on 'standard' elrails
     01 80 \wx0102 // Allow on 1500VDC
     01 80 \wx 0103 // Allow on 25k VAC
     00 80 // Dissallow on everything else
Or is the usage for Var2 4A something completely different? As long as 15DC and 25AC is compatible railtypes it should work i think?
Member of the
ImageImage
User avatar
Emperor Jake
Tycoon
Tycoon
Posts: 3441
Joined: 24 Apr 2007 09:37
Skype: Discord: Emperor Jake #4106
Location: Not Actually Japan
Contact:

Re: Trains Of Europe - Help with coding

Post by Emperor Jake »

Yexo wrote:I don't see the point of such a railtype. What use would it have?
It allows the multivoltage locomotive to travel on all four electric tracktypes, exactly the way I intended, but it also clutters up the railtype list. The other main problem is that a locomotive which isn't compatible with a electrification type will still go on that track, but will become stuck because it has no power.

Here is a test GRF to give you a better idea :)
Attachments
toetracks.grf
(10.69 KiB) Downloaded 149 times
Eddi
Tycoon
Tycoon
Posts: 8289
Joined: 17 Jan 2007 00:14

Re: Trains Of Europe - Help with coding

Post by Eddi »

how about making an articulated engine.

e.g., for a dual-AC engine, first half is powered with 25kV AC, and second half is powered with 15kV AC. with some trickery with shortened and invisible vehicles, you can make it look like a normal single engine.
User avatar
Emperor Jake
Tycoon
Tycoon
Posts: 3441
Joined: 24 Apr 2007 09:37
Skype: Discord: Emperor Jake #4106
Location: Not Actually Japan
Contact:

Re: Trains Of Europe - Help with coding

Post by Emperor Jake »

I've tried that - it didn't work. The engine will only go on whatever tracktype the first part is compatible with, and it ignores the power of the articulated sections as well.
User avatar
DJ Nekkid
Tycoon
Tycoon
Posts: 2141
Joined: 30 Nov 2006 20:33

Re: Trains Of Europe - Help with coding

Post by DJ Nekkid »

What eddi talks about should work, did you set the tracktypes to be compatible with eachother?
Im not at home atm, but ill make a test in nfo when i get there...
Member of the
ImageImage
as
Transport Coordinator
Transport Coordinator
Posts: 281
Joined: 07 Mar 2007 20:13

Re: Trains Of Europe - Help with coding

Post by as »

It won't work, most action0 properties are not available to articulated parts and are ignored.
see http://wiki.ttdpatch.net/tiki-index.php ... ion0Trains (possibly this info is also somewhere in NML docs?)
Yexo
Tycoon
Tycoon
Posts: 3663
Joined: 20 Dec 2007 12:49

Re: Trains Of Europe - Help with coding

Post by Yexo »

as wrote:see http://wiki.ttdpatch.net/tiki-index.php ... ion0Trains (possibly this info is also somewhere in NML docs?)
Not yet.
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: Ahrefs [Bot] and 4 guests