Skip to content

Commit

Permalink
Merge pull request #78199 from ShnitzelX2/tile-layering-convenience
Browse files Browse the repository at this point in the history
Less verbose reading of layering.json
  • Loading branch information
Night-Pryanik authored Nov 30, 2024
2 parents 62dc950 + b00ed3a commit 9b7b74c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 25 deletions.
30 changes: 23 additions & 7 deletions doc/TILESET.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ A tilesheet can be an expansion from a mod. Each expansion tilesheet is a singl
### layering.json
An optional file called layering.json can be provided. this file defines layering data for specific furniture and terrain. A default layering.json is provided with the repository. an example would be:
An optional file called `layering.json` can be provided. This file defines "layer contexts" (referred to in JSON as "layer variants"), or entries for drawing items/fields differently based on furniture/terrain they're placed on. A default `layering.json` is provided with the repository.
```c++
{
Expand Down Expand Up @@ -502,21 +502,37 @@ An optional file called layering.json can be provided. this file defines layerin
}
```

This entry sets it so that the f_desk furniture if it contains either a pen or a laptop will draw a custom sprite for them in addition to a normal top item sprite.
In this example, we provide the context tile `f_desk` and multiple items that will display differently while placed on it -- a pen using `desk_pen_1` or `desk_pen_2`, and a laptop using `desk_laptop`. `fd_fire`, a field, will use the sprite `desk_fd_fire` on `f_desk`.

`"context": "f_desk"` the furniture or terrain that this should apply to.
`"context": "f_desk"` the furniture or terrain that this should apply to. `"context"` can also be exactly one JSON flag placed in an array, which will display the given sprite for any furniture/terrain that has that flag.

`"append_variants"`: an additional suffix automatically appended to sprite names from the item name, e.g. "_postup" for sprites of items posted on walls. The suffix must begin with an underscore '\_'. The expected sprite name format (see Hardcoded IDs above for sprite name formats) for using `"append_variants"` is:

"item name" + "append_variants"

Example: `american_flag_hoisted` or `national_flag_var_indian_flag_postup`

Example usage of flag `context` and `append_variants`:
```JSON
{
"variants": [
{
"context": [ "WALL" ],
"append_variants": "_postup",
"item_variants": [
{ "item": "american_flag", "layer": 90,
```
##### Items

`"item_variants":` the definitions for what items will have a variant sprite.
`"item_variants":` the definitions for what items will have contextual sprites. Note: has nothing to do with item variants, this is really item_(layer)_variants.

`"item": "laptop"` the item id. (only supported in item_variants)

`"layer": 100` this defines the order the sprites will draw in. 1 drawing first 100 drawing last (so 100 ends up on top). This only works for items, Fields are instead drawn in the order they are stacked on the tile.

`"sprite": [{"id": "desk_pen_1", "weight": 2}, {"id": "desk_pen_2", "weight": 2}]` an array of the possible sprites that can display. Multiple sprites can be provided with specific weights and will be selected at random for each item.
`"sprite": [{"id": "desk_pen_1", "weight": 2}, {"id": "desk_pen_2", "weight": 2}]` an array of the possible sprites that can display. Multiple sprites can be provided with specific weights and will be selected at random for each item. If not provided, defaults to item name.

`"offset_x": 16`, `"offset_y": -48` optional sprite offset.
`"offset_x": 16`, `"offset_y": -48` optional sprite offset. Defaults to 0 if not provided.

##### Fields

Expand All @@ -526,7 +542,7 @@ This entry sets it so that the f_desk furniture if it contains either a pen or a

`"sprite": [{"id": "desk_fd_fire", "weight": 1}]` an array of the possible sprites that can display. Multiple sprites can be provided with specific weights and will be selected at random based on map position.

`"offset_x": 16`, `"offset_y": -48` optional sprite offset.
`"offset_x": 16`, `"offset_y": -48` optional sprite offset. Defaults to 0 if not provided.

## `compose.py`

Expand Down
45 changes: 29 additions & 16 deletions src/cata_tiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ void tileset_cache::loader::load_layers( const JsonObject &config )

std::string context;
std::set<std::string> flags;
std::string append_suffix;
furn_str_id furn_exists;
ter_str_id ter_exists;
if( item.has_string( "context" ) ) {
Expand All @@ -893,11 +894,18 @@ void tileset_cache::loader::load_layers( const JsonObject &config )
else if( item.has_array( "context" ) ) {
context = item.get_array( "context" ).next_value().get_string();
}

if( item.has_string( "append_variants" ) ) {
append_suffix = item.get_string( "append_variants" );
if( append_suffix.empty() ) {
config.throw_error( "append_variants cannot be empty string" );
}
}
std::vector<layer_context_sprites> item_layers;
std::vector<layer_context_sprites> field_layers;
if( item.has_array( "item_variants" ) ) {
for( const JsonObject vars : item.get_array( "item_variants" ) ) {
if( vars.has_member( "item" ) && vars.has_array( "sprite" ) && vars.has_member( "layer" ) ) {
if( vars.has_member( "item" ) && vars.has_member( "layer" ) ) {
layer_context_sprites lcs;
lcs.id = vars.get_string( "item" );

Expand All @@ -910,20 +918,20 @@ void tileset_cache::loader::load_layers( const JsonObject &config )
offset.y = vars.get_int( "offset_y" );
}
lcs.offset = offset;
lcs.append_suffix = append_suffix;

int total_weight = 0;
for( const JsonObject sprites : vars.get_array( "sprite" ) ) {
std::string id = sprites.get_string( "id" );
int weight = sprites.get_int( "weight", 1 );
lcs.sprite.emplace( id, weight );
if( sprites.has_string( "append_variants" ) ) {
lcs.append_variant = sprites.get_string( "append_variants" );
if( lcs.append_variant.empty() ) {
config.throw_error( "append_variants cannot be empty string" );
}
if( vars.has_array( "sprite" ) ) {
for( const JsonObject sprites : vars.get_array( "sprite" ) ) {
std::string id = sprites.get_string( "id" );
int weight = sprites.get_int( "weight", 1 );
lcs.sprite.emplace( id, weight );
total_weight += weight;
}

total_weight += weight;
} else {
//default if unprovided = item name
lcs.sprite.emplace( lcs.id, 1 );
total_weight = 1;
}
lcs.total_weight = total_weight;
item_layers.push_back( lcs );
Expand Down Expand Up @@ -2335,7 +2343,12 @@ cata_tiles::find_tile_looks_like( const std::string &id, TILE_CATEGORY category,
// Try the variant first
if( !variant.empty() ) {
if( category != TILE_CATEGORY::VEHICLE_PART ) {
if( auto ret = find_tile_with_season( id + "_var_" + variant ) ) {
//indicates a sprite suffix
if( variant[0] == '_' ) {
if( auto ret = find_tile_with_season( id + variant ) ) {
return ret; // with variant
}
} else if( auto ret = find_tile_with_season( id + "_var_" + variant ) ) {
return ret; // with variant
}
} else {
Expand Down Expand Up @@ -3701,9 +3714,9 @@ bool cata_tiles::draw_field_or_item( const tripoint &p, const lit_level ll, int

if( i.has_itype_variant() ) {
variant = i.itype_variant().id;
if( !layer_var.append_variant.empty() ) {
variant += layer_var.append_variant;
}
}
if( !layer_var.append_suffix.empty() ) {
variant += layer_var.append_suffix;
}
// if we have found info on the item go through and draw its stuff
draw_from_id_string( sprite_to_draw, TILE_CATEGORY::ITEM, layer_it_category, p, 0,
Expand Down
4 changes: 2 additions & 2 deletions src/cata_tiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ class layer_context_sprites
int layer;
point offset;
int total_weight;
//if set, appends to the "item+variant" name for item variant handling
std::string append_variant;
//if set, appends to the sprite name for handling contexts
std::string append_suffix;
};

class tileset
Expand Down

0 comments on commit 9b7b74c

Please sign in to comment.