Skip to content

Commit

Permalink
Support for multiple weighted field sprite variants
Browse files Browse the repository at this point in the history
The JSON required for terrain-aware sprites for fields in layering.json
previously demanded the use of a sprite array with weights, despite
our only supporting one sprite at a time and ignoring the weights. This
change makes the field syntax make sense, by introducing support for
supporting multiple field sprites, and respecting the weights by
introducing randomness seeded by map position.
  • Loading branch information
p4nc4k3z committed Aug 12, 2024
1 parent 12bb7da commit 03f494c
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 12 deletions.
4 changes: 2 additions & 2 deletions doc/TILESET.md
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ This entry sets it so that the f_desk furniture if it contains either a pen or a

`"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. For items multiple sprites can be provided with specific weights and will be selected at random.
`"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.

`"offset_x": 16`, `"offset_y": -48` optional sprite offset.

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

`"field": "fd_fire"` the field id. (only supported in field_variants)

`"sprite": [{"id": "desk_fd_fire", "weight": 1}]` A field can have at most one sprite.
`"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.

Expand Down
21 changes: 11 additions & 10 deletions src/cata_tiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ pixel_minimap_mode pixel_minimap_mode_from_string( const std::string &mode )
return pixel_minimap_mode::solid;
}

auto simple_point_hash = []( const auto &p )
{
return p.x + p.y * 65536;
};

} // namespace

static int msgtype_to_tilecolor( const game_message_type type, const bool bOldMsg )
Expand Down Expand Up @@ -2773,10 +2778,6 @@ bool cata_tiles::draw_from_id_string_internal( const std::string &id, TILE_CATEG
}
}

auto simple_point_hash = []( const auto & p ) {
return p.x + p.y * 65536;
};

// seed the PRNG to get a reproducible random int
// TODO: faster solution here
unsigned int seed = 0;
Expand Down Expand Up @@ -3649,8 +3650,8 @@ bool cata_tiles::draw_field_or_item( const tripoint &p, const lit_level ll, int
if( fld.id().str() == layer_var.id ) {

// get the sprite to draw
// roll should be based on the maptile seed to keep visuals consistent
int roll = 1;
// roll is based on the maptile seed to keep visuals consistent
int roll = simple_point_hash( p ) % layer_var.total_weight;
std::string sprite_to_draw;
for( const auto &sprite_list : layer_var.sprite ) {
roll = roll - sprite_list.second;
Expand All @@ -3677,8 +3678,8 @@ bool cata_tiles::draw_field_or_item( const tripoint &p, const lit_level ll, int
if( fld.id().str() == layer_var.id ) {

// get the sprite to draw
// roll should be based on the maptile seed to keep visuals consistent
int roll = 1;
// roll is based on the maptile seed to keep visuals consistent
int roll = simple_point_hash( p ) % layer_var.total_weight;
std::string sprite_to_draw;
for( const auto &sprite_list : layer_var.sprite ) {
roll = roll - sprite_list.second;
Expand Down Expand Up @@ -3766,7 +3767,7 @@ bool cata_tiles::draw_field_or_item( const tripoint &p, const lit_level ll, int
const bool layer_nv = nv_goggles_activated;

// get the sprite to draw
// roll should be based on the maptile seed to keep visuals consistent
// roll is based on the item seed to keep visuals consistent
int roll = i.seed % layer_var.total_weight;
std::string sprite_to_draw;
for( const auto &sprite_list : layer_var.sprite ) {
Expand Down Expand Up @@ -3811,7 +3812,7 @@ bool cata_tiles::draw_field_or_item( const tripoint &p, const lit_level ll, int
const bool layer_nv = nv_goggles_activated;

// get the sprite to draw
// roll should be based on the maptile seed to keep visuals consistent
// roll is based on the item seed to keep visuals consistent
int roll = i.seed % layer_var.total_weight;
std::string sprite_to_draw;
for( const auto &sprite_list : layer_var.sprite ) {
Expand Down

0 comments on commit 03f494c

Please sign in to comment.