Feature #1348

Bridge support

Added by planetmaker over 2 years ago. Updated over 1 year ago.

Status:New Start date:2010-08-29
Priority:Normal Due date:
Assignee:- % Done:

0%

Category:-
Target version:-

Description

Support for feature 0x06, bridges.

Attached a patch which introduces most action0 properties. Missing: sprite layout

Done:
- nothing, most action0 properties in attached patch

Todo:
- Property 0x0D (Sprite layout)
- possibly 0x08 (introduction year). TTDP requires the short introduction year, setting long introduction year (0x0F) might not be enough
- Constants
- Varaction2
- Documentation
- Regression

bridges_action0.diff Magnifier (1.2 kB) planetmaker, 2010-08-29 15:40

bridge_1_properties.diff Magnifier (1.6 kB) foobar, 2012-01-21 17:58

bridge_2_example.diff Magnifier (2.8 kB) foobar, 2012-01-21 17:58

History

#1 Updated by yexo over 2 years ago

  • Target version changed from 0.1.0 to 0.2.0

#2 Updated by Hirundo almost 2 years ago

  • Target version deleted (0.2.0)

#3 Updated by foobar over 1 year ago

Obviously I should have looked here first, as now I've done the basically the same thing as this patch...

Anyhoe, I also looked into the sprite layout property. I think it's a good idea to discuss/agree an NML format that users will write first. These are lengthy as they are in NFO, so that will be even worse in NML if you want to keep it user-readable (other than have the user supply an array of sprite numbers).

For now I came up with the following. Basically for each bridge table entry it asks the user for a sprite number and a recolour constant. This has to be provided for each rail/road/maglev/monorail and x/y combination. And separate for each individual bridge piece.
This allows to: leave out certain bridge pieces (as is possible in NFO); defaulting to 0 for each missing rail/road/maglev/monorail and x/y.
Currently it's a bit of a tradeoff between limiting deep nesting and limiting the amount of different property label thingies. One can decrease the latter by further nesting or limit nesting by increasing the amount of labels.

item(FEAT_BRIDGES, item_bridge_concrete, 1) {
    property {
        bridge_layout:      {
                            bridgepiece_edge_north:     {
                                                        rail_x_back:        {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_x_front:       {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_x_pillars:     {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_y_back:        {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_y_front:       {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_y_pillars:     {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        road_x_back:        {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        road_x_front:       {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        road_x_pillars:     {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        road_y_back:        {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        road_y_front:       {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        road_y_pillars:     {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        monorail_x_back:    {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        monorail_x_front:   {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        monorail_x_pillars: {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        monorail_y_back:    {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        monorail_y_front:   {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        monorail_y_pillars: {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        maglev_x_back:      {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        maglev_x_front:     {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        maglev_x_pillars:   {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        maglev_y_back:      {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        maglev_y_front:     {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        maglev_y_pillars:   {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                            };
                            bridgepiece_edge_south: { <repeat> };
                            bridgepiece_intermediate_1: { <repeat> };
                            bridgepiece_intermediate_2: { <repeat> };
                            bridgepiece_middle_1: { <repeat> };
                            bridgepiece_middle_2: { <repeat> };
                            bridgepiece_heads: {        rail_flat_x_north:  {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_flat_y_north:  {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_flat_x_south:  {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_flat_y_south:  {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_slope_x_north:  {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_slope_y_north:  {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_slope_x_south:  {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        rail_slope_y_south:  {
                                                                            sprite:  0xA67;
                                                                            palette: PALETTE_STRUCT_CONCRETE;
                                                        };
                                                        <repeat 3x for road, monorail and maglev>
                            };
        };
    }
}

For the sake of completeness I also included my patches against NML r1791. I used slightly different names for the properties, but did add the one constant and included an example in a separate patch. How to name the properties can of course be discussed, but that's not the main concern right now.

#4 Updated by planetmaker over 1 year ago

From a language perspective I suggest to handle the layouts with the same syntax as it's handled for airports and industries: a separate layout property and the layout then as a separate block.
And the individual parts of a bridge layout again should then be handled similar or identical to the tile layout blocks.

#5 Updated by Hirundo over 1 year ago

If possible the sprite layout syntax / structure should be reused as planetmaker says. Essentially it's the same, except that bridge sprites use a fixed set of sprites / bounding boxes.

Currently I'm considering the following, but I'm not sure yet:
1. The sprite layout property is split into 7 properties, one for each bridge part ("table"). These can be set individually in NFO, so that's no problem.
2. Each property is an array of 8 sprite layouts (rail/road/mono/mglv both x and y). If we can come up with a nice way to handle spritelayouts that work in two directions (X and Y) we can use that here, as well as for stations. This would reduce the number of spritelayouts to 4. Spritelayouts may be parametrized as long as they are compile-time constants.
3. Each of these spritelayouts may contain a 'front', 'back' and 'pillar' sprite, undefined sprites are zeroed.

Bridge heads might need some additional care.

#6 Updated by foobar over 1 year ago

I have to agree that it's best to keep the syntax as similar as possible to existing syntax of other features.

Based on your suggestions I made some examples, to get some better feeling for how it will turn out. Personally I'm in favour of the last example. That I think is also something that can be used for stations, but then filled with ground/childsprite/building blocks rather than front/back/pillar blocks. So basically you first branch into x and y and then have the normal spritelayout contents.

For bridgeheads we may do the same, but these will only support a 'back' block and not front/pillar. For the property this could be split into two properties: one for flat bridgeheads and one for sloped bridgeheads. Then the array for the property value will be identical to the other bridge pieces. Only difference is that if you supply one bridgehead property, you must supply the other as well.

Something else I came up with last night is not defaulting to 0 for undefined sprites, but instead defaulting to the default TTD values for each bridge. That way the user can for instance replace only road bridges without having to recode the rail/mono/mlev bridges himself, as NML will do that for him then. For this some sort of pseudo-constant "BRIDGE_DEFAULT_LAYOUT" could be used instead of setting a spritelayout identifier.

item(FEAT_BRIDGES, item_bridge_concrete, 1) {
    /* bridges only support a properties block. Even new graphics are defined here */
    property {
        layout_edge_north:      [sl_en_rail_x, sl_en_rail_y, sl_en_road_x, sl_en_road_y, sl_en_mono_x, sl_en_mono_y, sl_en_mlev_x, sl_en_mlev_y]; 
        layout_edge_south:      [sl_es_rail_x, sl_es_rail_y, sl_es_road_x, sl_es_road_y, sl_es_mono_x, sl_es_mono_y, sl_es_mlev_x, sl_es_mlev_y];
        layout_intermediate_1:  [sl_i1_rail_x, sl_i1_rail_y, sl_i1_road_x, sl_i1_road_y, sl_i1_mono_x, sl_i1_mono_y, sl_i1_mlev_x, sl_i1_mlev_y];
        layout_intermediate_2:  [sl_i2_rail_x, sl_i2_rail_y, sl_i2_road_x, sl_i2_road_y, sl_i2_mono_x, sl_i2_mono_y, sl_i2_mlev_x, sl_i2_mlev_y];
        layout_middle_1:        [sl_m1_rail_x, sl_m1_rail_y, sl_m1_road_x, sl_m1_road_y, sl_m1_mono_x, sl_m1_mono_y, sl_m1_mlev_x, sl_m1_mlev_y];
        layout_middle_2:        [sl_m2_rail_x, sl_m2_rail_y, sl_m2_road_x, sl_m2_road_y, sl_m2_mono_x, sl_m2_mono_y, sl_m2_mlev_x, sl_m2_mlev_y];
        layout_heads:           <something to be decided>;
    }
}

spritelayout sl_en_rail_x {
    front { 
        sprite:  0xA67;
        palette: PALETTE_STRUCT_CONCRETE;
    }
    back {
        sprite:  0xA67;
        palette: PALETTE_STRUCT_CONCRETE;
    }
    pillar {
        sprite:  0xA67;
        palette: PALETTE_STRUCT_CONCRETE;
    }
}

//OR
//(with the added disadvantage of not being able to specify a separate recolour for each sprite)

spritelayout sl_en_rail_x {
    front: 0xA67;
    back:  0xA67;
    pillar:  0xA67;
    palette: PALETTE_STRUCT_CONCRETE;
}

//OR
//spritelayout in two directions, only four per brige part instead of the above 8

spritelayout sl_en_rail {
    direction_x {
        front { 
            sprite:  0xA67;
            palette: PALETTE_STRUCT_CONCRETE;
        }
        back {
            sprite:  0xA67;
            palette: PALETTE_STRUCT_CONCRETE;
        }
        pillar {
            sprite:  0xA67;
            palette: PALETTE_STRUCT_CONCRETE;
        }
    }
    direction_y {
        front { 
            sprite:  0xA67;
            palette: PALETTE_STRUCT_CONCRETE;
        }
        back {
            sprite:  0xA67;
            palette: PALETTE_STRUCT_CONCRETE;
        }
        pillar {
            sprite:  0xA67;
            palette: PALETTE_STRUCT_CONCRETE;
        }
    }
}

#7 Updated by Hirundo over 1 year ago

NML could indeed store the default bridge tables and use those if one of rail/road/mono/maglev is not defined. If a layout doesn't define e.g. a pillar sprite, that should still be set to 0.

Palette should be set per sprite, not per group of sprites. There are also some other properties (always_draw, recolour_mode, hide_sprite (comp. time constant)) that apply to bridges.

It might be best to use the graphics block for this purpose, instead of using the property block. Switch blocks would have to be disabled, so the spritelayouts can be evaluated at compile time. If we merge the X and Y directions, the number of spritelayouts remains manageable.

Spritelayouts would have to gain a pseudo-variable 'axis' that contains 0 for x and 1 for y. Then you can easily do 0xABCD + axis as sprite number, again to save typing.

Also available in: Atom PDF