Freeciv21
Develop your civilization from humble roots to a global empire
layer_special.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 2021-2023 Freeciv21 contributors.
3 \_ \ / __/ This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 #include "layer_special.h"
15 
16 #include "extras.h"
17 #include "game.h" // For extra_type_iterate
18 #include "tilespec.h"
19 
20 namespace freeciv {
21 
22 layer_special::layer_special(struct tileset *ts, mapview_layer layer)
23  : freeciv::layer(ts, layer), m_sprites{nullptr}
24 {
25  fc_assert(layer == LAYER_SPECIAL1 || layer == LAYER_SPECIAL2
26  || layer == LAYER_SPECIAL3);
27 }
28 
33  const QString &tag, extrastyle_id style)
34 {
35  // SINGLE1 extras have a sprite on special layer 1 only
36  // SINGLE2 extras have a sprite on special layer 2 only
37  // 3LAYER extras have a sprite on all 3 layers
38  if (style == ESTYLE_SINGLE1 && type() == LAYER_SPECIAL1) {
39  set_sprite(extra, tag);
40  } else if (style == ESTYLE_SINGLE2 && type() == LAYER_SPECIAL2) {
41  set_sprite(extra, tag);
42  } else if (style == ESTYLE_3LAYER) {
43  auto full_tag_name = QStringLiteral("%1_bg").arg(tag);
44  if (type() == LAYER_SPECIAL2) {
45  full_tag_name = QStringLiteral("%1_mg").arg(tag);
46  } else if (type() == LAYER_SPECIAL3) {
47  full_tag_name = QStringLiteral("%1_fg").arg(tag);
48  }
49 
50  set_sprite(extra, full_tag_name, tileset_full_tile_offset(tileset()));
51  }
52 }
53 
54 void layer_special::set_sprite(const extra_type *extra, const QString &tag,
55  const QPoint &offset)
56 {
57  fc_assert_ret(extra != nullptr);
58 
59  if (auto sprite = load_sprite({tag})) {
60  m_sprites.at(extra->id) =
61  std::make_unique<drawn_sprite>(tileset(), sprite, true, offset);
62  }
63 }
64 
65 std::vector<drawn_sprite>
66 layer_special::fill_sprite_array(const tile *ptile, const tile_edge *pedge,
67  const tile_corner *pcorner,
68  const unit *punit) const
69 {
70  Q_UNUSED(pedge);
71  Q_UNUSED(pcorner);
72  Q_UNUSED(punit);
73 
74  if (ptile == nullptr) {
75  return {};
76  }
77 
78  auto sprites = std::vector<drawn_sprite>();
79 
80  extra_type_iterate(pextra)
81  {
82  if (tile_has_extra(ptile, pextra) && is_extra_drawing_enabled(pextra)
83  && m_sprites[extra_index(pextra)]) {
84  // Check whether the extra is hidden by some other extra.
85  bool hidden = false;
86  extra_type_list_iterate(pextra->hiders, phider)
87  {
88  if (BV_ISSET(ptile->extras, extra_index(phider))) {
89  hidden = true;
90  break;
91  }
92  }
94 
95  if (!hidden) {
96  sprites.push_back(*m_sprites[extra_index(pextra)]);
97  }
98  }
99  }
101 
102  return sprites;
103 }
104 
106 {
107  // The array is indexed by the extra id, which depends on the ruleset.
108  // Clear it.
109  for (auto &sprite : m_sprites) {
110  sprite = nullptr;
111  }
112 }
113 
114 } // namespace freeciv
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
void initialize_extra(const extra_type *extra, const QString &tag, extrastyle_id style) override
Loads sprites for the extra if it has ESTYLE_SINGLE1/2 or ESTYLE_3LAYER.
void set_sprite(const extra_type *extra, const QString &tag, const QPoint &offset=QPoint())
std::vector< drawn_sprite > fill_sprite_array(const tile *ptile, const tile_edge *pedge, const tile_corner *pcorner, const unit *punit) const override
Returns the list of sprites drawn by this layer somewhere on the map.
void reset_ruleset() override
Resets cached data that depends on the ruleset.
layer_special(struct tileset *ts, mapview_layer layer)
std::array< std::unique_ptr< drawn_sprite >, MAX_EXTRA_TYPES > m_sprites
Definition: layer_special.h:44
A layer when drawing the map.
Definition: layer.h:153
mapview_layer type() const
Definition: layer.h:238
QPixmap * load_sprite(const QStringList &possible_names, bool required=false, bool verbose=true) const
Shortcut to load a sprite from the tileset.
Definition: layer.cpp:79
struct tileset * tileset() const
Definition: layer.h:241
#define extra_type_iterate(_p)
Definition: extras.h:279
#define extra_type_list_iterate(extralist, pextra)
Definition: extras.h:145
#define extra_type_iterate_end
Definition: extras.h:285
#define extra_index(_e_)
Definition: extras.h:163
#define extra_type_list_iterate_end
Definition: extras.h:147
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert(condition)
Definition: log.h:89
Definition: path.cpp:10
int id
Definition: extras.h:75
Definition: tile.h:42
bv_extras extras
Definition: tile.h:47
Definition: unit.h:134
#define tile_has_extra(ptile, pextra)
Definition: tile.h:130
QPoint tileset_full_tile_offset(const struct tileset *t)
Return the x and y offsets of full tiles in the tileset.
Definition: tilespec.cpp:416
bool is_extra_drawing_enabled(const extra_type *pextra)
Should the given extra be drawn FIXME: Some extras can not be switched.
Definition: tilespec.cpp:3133