Help with coding: Double headed and articulated vehicles

Discuss, get help with, or post new graphics for TTDPatch and OpenTTD, using the NewGRF system, here. Graphics for plain TTD also acceptable here.

Moderator: Graphics Moderators

Post Reply
User avatar
Zephyris
Tycoon
Tycoon
Posts: 2897
Joined: 16 May 2007 16:59

Help with coding: Double headed and articulated vehicles

Post by Zephyris »

I'm struggling to get into nfo coding, and im getting stuck with 2 main things, double headed trains and articulated road/rail vehicles. I would be immensely grateful if someone could provide me with basic (working!) examples of a double headed train, an articulated train (2 parts) and an articulated road vehicle (3 parts). Following me disecting and fully understanding these then I plan to make a basic tutorial on "mid level" nfo coding...

In return I can provide you with 8bpp, 32bpp or even 3d graphics :).
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5631
Joined: 13 Sep 2004 13:21
Location: The Moon

Post by PikkaBird »

Double-headed is easy: Set prop 13 to 01, make sure bit 4 of prop 1E is not set. :P
User avatar
Zephyris
Tycoon
Tycoon
Posts: 2897
Joined: 16 May 2007 16:59

Post by Zephyris »

Re: PikkaBird
Have done, but it doesnt draw the graphics for the rear head, instead uses the default for that vehicleID. Have you come across this before?
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5631
Joined: 13 Sep 2004 13:21
Location: The Moon

Post by PikkaBird »

Zephyris wrote:Re: PikkaBird
Have done, but it doesnt draw the graphics for the rear head, instead uses the default for that vehicleID. Have you come across this before?
If you want different graphics for the rear head, you will have to use var action 2s to pick graphics based on various variables (perhaps the position in the train, or whether the vehicle is facing forwards or backwards...)
User avatar
Zephyris
Tycoon
Tycoon
Posts: 2897
Joined: 16 May 2007 16:59

Post by Zephyris »

This is the problem, I'm simply trying to make a normal double headed train...

Code: Select all

// Automatically generated by GRFCODEC. Do not modify!
// (Info version 7)
// Format: spritenum pcxfile xpos ypos compression ysize xsize xrel yrel
    0 * 4	 0E 03 00 00
    1 * 77	 08 06 "RW" 04 03 "Train Demo Double Head" 00 "By "
	 "Richard Wheeler (Zephyris) 2007. "
	 "Version 0.1" 00
    2 * 22	 04 00 7F 01 0B "Manley-Morel DMU" 00
    3 * 49	 00 00 13 01 0B 00 CA 34 02 20 03 0C 04 18 06 01 05 00 08 01 09 70 00 0B 58 02 0D 3E 0E 36 4C 00 00 12 FF 13 01 14 4C 15 00 16 20 17 08 18 01 19 08
    4 * 4	 01 00 01 08
    5 c:\games\openttd\sprites/vehicledemotrain2.pcx 98 8 01 18 8 -3 -10
    6 c:\games\openttd\sprites/vehicledemotrain2.pcx 114 8 09 16 20 -14 -7
    7 c:\games\openttd\sprites/vehicledemotrain2.pcx 146 8 01 12 28 -14 -6
    8 c:\games\openttd\sprites/vehicledemotrain2.pcx 194 8 09 16 20 -6 -7
    9 c:\games\openttd\sprites/vehicledemotrain2.pcx 226 8 01 18 8 -3 -10
   10 c:\games\openttd\sprites/vehicledemotrain2.pcx 242 8 09 16 20 -14 -7
   11 c:\games\openttd\sprites/vehicledemotrain2.pcx 274 8 01 12 28 -14 -6
   12 c:\games\openttd\sprites/vehicledemotrain2.pcx 322 8 09 16 20 -6 -7
   13 * 9	 02 00 00 01 01 00 00 00 00
   14 * 7	 03 00 01 0B 00 00 00
Attachments
Plentfingbourne Bridge Transport, 14th Jan 1965.png
Plentfingbourne Bridge Transport, 14th Jan 1965.png (107.52 KiB) Viewed 453 times
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5631
Joined: 13 Sep 2004 13:21
Location: The Moon

Post by PikkaBird »

Prop 12 is wrong, it should be FD for new graphics, not FF.

Also, here's a thing that I tell everyone: don't decode your own grfs. Format the NFO nicely, fill it with comments, it makes life a lot easier especially when you get into convoluted action 2 chains!
User avatar
George
Tycoon
Tycoon
Posts: 4364
Joined: 16 Apr 2003 16:09
Skype: george-vb
Location: Varna, Bulgaria
Contact:

Post by George »

PikkaBird wrote:Prop 12 is wrong, it should be FD for new graphics, not FF.
Also, here's a thing that I tell everyone: don't decode your own grfs. Format the NFO nicely, fill it with comments, it makes life a lot easier especially when you get into convoluted action 2 chains!
Or use action 0C. It is invented for it ;) See my late GRFs ;) as example
Image Image Image Image
User avatar
Zephyris
Tycoon
Tycoon
Posts: 2897
Joined: 16 May 2007 16:59

Post by Zephyris »

I've dived into articulated vehicles....
This is an articulated train, two parts. It works BUT draws the graphics for the second vehicle for both vehicles (ie. you get two tenders :s). Are there any obvious mistakes?
I would also greatly appreciate any description of what exactly the unlabled bits of the action 2s are for...

Code: Select all

// Automatically generated by GRFCODEC. Do not modify!
// (Info version 7)
// Format: spritenum pcxfile xpos ypos compression ysize xsize xrel yrel
//
//               Number of sprites (DWord)
//               |
    0 * 4	 0E 00 00 00
    1 * 45	 08 06 "RW" 04 04 "Simple Vehicle Demo: Articulated Train" 00
//
//  Vehicle Name
//
//                  Vehicle type (00 = rail, 01 = road, etc.)
//                  |  Language (7F = all languages)
//                  |  |  Number of names to Change
//                  |  |  |  Vehicle ID
//                  |  |  |  |  Name string
//                  |  |  |  |  |                 String termination
//                  |  |  |  |  |                 |
    2 * 21	 04 00 7F 01 00 "Kirby Paul Tank" 00
//
//  Vehicle Properties
//
//                  Rail vehicle type
//                  |  13 properties altered
//                  |  |  On one vehicle
//                  |  |  |  Date of introduction ( (date-1920)*365.25 )
//                  |  |  |  |           Reliability decay rate (20 = default)
//                  |  |  |  |           |     Vehicle lifetime (years)
//                  |  |  |  |           |     |     Model availability (years)
//                  |  |  |  |           |     |     |     Climate availability
//                  |  |  |  |           |     |     |     |     Track type (00 = railroad, 01 = monorail, 02 = maglev)
//                  |  |  |  |           |     |     |     |     |     Passenger only flag (for AI, 00 = all cargo, 01 = passenger only)
//                  |  |  |  |           |     |     |     |     |     |     Speed (speedmph*1.6)
//                  |  |  |  |           |     |     |     |     |     |     |        
    3 * 51	 00 00 14 01 00 00 22 07 02 20 03 0F 04 1E 06 01 05 00 08 00 09 40 00 
//	Power (hp, wagons = 00 00)
//	|        Running cost factor (steam = £cost/21.875, deisel = £cost/20.3125, electric = £cost/18.75)
//	|        |     Running cost base (30 4C 00 00 = steam, 36 4C 00 00 = deisel, 3C 4C 00 00 = electric)
//	|        |     |              Sprite ID (FD = new graphics)
//	|        |     |              |     Dual headed (00 = no, 01 = yes)
//	|        |     |              |     |     Cargo capacity
//	|        |     |              |     |     |     Cargo type
//	|        |     |              |     |     |     |     Weight (tons)
//	|        |     |              |     |     |     |     |     Price factor (£price/1562.5)
//	|        |     |              |     |     |     |     |     |     Engine Rank (for AI)
//	|        |     |              |     |     |     |     |     |     |     Traction type (00=steam, 08=deisel, 28=electric, 32=monorail, 38=maglev)
//	|        |     |              |     |     |     |     |     |     |     |     Callback (10=articulated)
//      |        |     |              |     |     |     |     |     |     |     |     |
  	0B 2C 01 0D 25 0E 30 4C 00 00 12 FD 13 00 14 00 15 00 16 2F 17 05 18 00 19 00 1E 10
//
//  Definition of Graphics
//
//                  Vehicle type (00 = rail, 01 = road, etc.)
//                  |  Number of vehicles
//                  |  |  Number of views (4 = symmetric, 8 = non-symmetric)
//                  |  |  |
    4 * 4	 01 00 02 08
    5 c:\games\openttd\sprites/vehicledemoartrain.pcx 98 8 01 18 8 -3 -10
    6 c:\games\openttd\sprites/vehicledemoartrain.pcx 114 8 09 16 20 -14 -7
    7 c:\games\openttd\sprites/vehicledemoartrain.pcx 146 8 01 12 28 -14 -6
    8 c:\games\openttd\sprites/vehicledemoartrain.pcx 194 8 09 16 20 -6 -7
    9 c:\games\openttd\sprites/vehicledemoartrain.pcx 226 8 01 18 8 -3 -10
   10 c:\games\openttd\sprites/vehicledemoartrain.pcx 242 8 09 16 20 -14 -7
   11 c:\games\openttd\sprites/vehicledemoartrain.pcx 274 8 01 12 28 -14 -6
   12 c:\games\openttd\sprites/vehicledemoartrain.pcx 322 8 09 16 20 -6 -7
   13 c:\games\openttd\sprites/vehicledemoartrain.pcx 354 8 01 18 8 -3 -10
   14 c:\games\openttd\sprites/vehicledemoartrain.pcx 370 8 09 16 20 -14 -7
   15 c:\games\openttd\sprites/vehicledemoartrain.pcx 402 8 01 12 28 -14 -6
   16 c:\games\openttd\sprites/vehicledemoartrain.pcx 450 8 09 16 20 -6 -7
   17 c:\games\openttd\sprites/vehicledemoartrain.pcx 482 8 01 18 8 -3 -10
   18 c:\games\openttd\sprites/vehicledemoartrain.pcx 498 8 09 16 20 -14 -7
   19 c:\games\openttd\sprites/vehicledemoartrain.pcx 530 8 01 12 28 -14 -6
   20 c:\games\openttd\sprites/vehicledemoartrain.pcx 578 8 09 16 20 -6 -7
//
//  Definition of use of graphics
//
//                  Vehicle type (00 = rail, 01 = road, etc.)
//                  |  Cargo ID
//                  |  |  Number loaded types
//                  |  |  |  Number of loading types
//                  |  |  |  |  Sprite set (action 00 number)
//                  |  |  |  |  |     Sprite set (action 00 number)
// First vehicle    |  |  |  |  |     |
   21 * 9 	 02 00 00 01 01 00 00 00 00
// Second vehicle
   22 * 9 	 02 00 01 01 01 01 00 01 00
//
// When to use the graphics
//
//                     Action 2 ID
//                     |                 Cargo ID for first vehicle
//                     |                 |           Cargo ID for every other vehicle
//                     |                 |           |
   23 * 14 	 02 00 00 81 40 10 FF 01 00 00 00 00 01 00
//
// Vehicle to be articulated
//
//                     Action 2 ID
//                     |                 Vehicle ID
//                     |                 |           Termination
//                     |                 |           |
   24 * 14 	 02 00 01 81 10 00 FF 01 00 80 01 01 FF FF
//
// Call back check
//
//                     Action 2 ID
//                     |                 Call back 16 (articulated)
//                     |                 |           Graphics
//                     |                 |           |
   25 * 14 	 02 00 02 81 0C 00 FF 01 01 00 16 16 00 00
//
//  Associates defined graphics to vehicles
//
//                  Vehicle type (00 = rail, 01 = road, etc.)
//                  |  Number of vehicles modified
//                  |  |  Vehicle IDs
//                  |  |  |  No cargo specific graphics
//                  |  |  |  |  Action 2 ID
//                  |  |  |  |  |
   26 * 7 	 03 00 01 00 00 02 00
edit: code commebts are not quite perfect (tabs :S) but i hope you can get the idea.
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5631
Joined: 13 Sep 2004 13:21
Location: The Moon

Post by PikkaBird »

I think the wiki's explanation of var action 2 is fairly straightforward?

Your problem, I reckon, is the 40 10 FF in sprite 23. 40 10 FF means "count the total number of vehicles in this train", which I don't think is what you meant to test...
User avatar
Zephyris
Tycoon
Tycoon
Posts: 2897
Joined: 16 May 2007 16:59

Post by Zephyris »

Code: Select all

23 * 14 02 // Action 2
        00 // Feature: Trains
        00 // Action 2 ID
        81 // Access lowest byte of variable
        40 // Variable: Position in/length of consist (format: 00nnbbff)
        // Variable adjustment:
        10 // Shift variable 16 to the right
        FF // And mask
        // Variable shift not equal to 6 of 7 so add/divide/modulo value not set
        01 // Number of ranges to check for
        // Range 1:
	00 00 // Cargo ID for range 1
        00 // Low range limit
        00 // High Range Limit
	// Default if no ranges match:
        01 00 // Cargo ID for default
As far as I understand this is accessing the "position in consist" part of variable 40 (ff) not the consist length (bb).
I don't understand the calculation (this was taken from an existing .grf) and I am confused by it, why is the bit shift there? Would the following make sense?

Code: Select all

23 * 14 02 // Action 2
        00 // Feature: Trains
        00 // Action 2 ID
        81 // Access lowest byte of variable
        40 // Variable: Position in/length of consist (format: 00nnbbff)
        // Variable adjustment:
        00 // Shift variable 16 to the right **no shift required**
        FF // And mask
        // Variable shift not equal to 6 of 7 so add/divide/modulo value not set
        01 // Number of ranges to check for
        // Range 1:
	00 00 // Cargo ID for range 1
        00 // Low range limit
        00 // High Range Limit
	// Default if no ranges match:
        01 00 // Cargo ID for default
So only vehicles with an ff value of 00 (ie. the first vehicle) would get cargo ID 00 00, and the rest would revert to the default of 01 00.
User avatar
minime
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 18 Jan 2004 10:02
Skype: dan.masek
Location: Prague, Czech Republic
Contact:

Post by minime »

... not the consist length (bb).
bb is not the consist length!
I don't understand the calculation (this was taken from an existing .grf) and I am confused by it, why is the bit shift there?
Since variable 40 contains a DWORD in format 00nnbbff and the calculation only works with a byte, you first shift the value 16 bits to the right. That leaves you with a DWORD in format 000000nn, of which the lowest byte is the desired nn part.
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. --Albert Einstein
Image Image Image
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5631
Joined: 13 Sep 2004 13:21
Location: The Moon

Post by PikkaBird »

Zephyris wrote:So only vehicles with an ff value of 00 (ie. the first vehicle) would get cargo ID 00 00, and the rest would revert to the default of 01 00.
That is correct.

However, have you considered what would happen if this locomotive is not the first vehicle in the train, eg it's doubleheaded?

In this situation, I personally would test 41 00 01 - that is, check the position in the chain of vehicles with the same ID only, and AND-mask out all but the lowest bit. This will give you the sequence {00, 01, 00, 01 ...} for any given chain of vehicles with this ID.

A final thought; making articulated locomotives from the same ID currently does funny things to some of the stats. You may be better off using a different ID for the tender anyway (which makes all this discussion of var 2s to pick graphics academic!).
User avatar
Zephyris
Tycoon
Tycoon
Posts: 2897
Joined: 16 May 2007 16:59

Post by Zephyris »

Do you know ehich vehicle statistics are affected? I assume if action 0 specified a capacity of 10 the articulated vehicle (2 parts) would have a capacity of 20, but only appear as 10 in the buy menu...

And its not purely academic, its going to be very useful for articulated road vehicles...
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5631
Joined: 13 Sep 2004 13:21
Location: The Moon

Post by PikkaBird »

Zephyris wrote:Do you know ehich vehicle statistics are affected? I assume if action 0 specified a capacity of 10 the articulated vehicle (2 parts) would have a capacity of 20, but only appear as 10 in the buy menu...
It also doubles the horsepower of the locomotive when it leaves the depot (this is a relatively recent change, and think counts as a bug). The workaround is to use callback 36 to set the HP of the second part to 0.
Post Reply

Return to “Graphics Development”

Who is online

Users browsing this forum: Google [Bot] and 17 guests