1 /* Copyright (C) 2013-2014 Michal Brzozowski (rusolis@poczta.fm)
2 
3    This file is part of KeeperRL.
4 
5    KeeperRL is free software; you can redistribute it and/or modify it under the terms of the
6    GNU General Public License as published by the Free Software Foundation; either version 2
7    of the License, or (at your option) any later version.
8 
9    KeeperRL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10    even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License along with this program.
14    If not, see http://www.gnu.org/licenses/ . */
15 
16 #include "stdafx.h"
17 #include "tile.h"
18 #include "gui_elem.h"
19 #include "view_id.h"
20 #include "view_object.h"
21 
Tile()22 Tile::Tile() {
23 }
24 
fromString(const string & ch,Color color,bool symbol)25 Tile Tile::fromString(const string& ch, Color color, bool symbol) {
26   Tile ret;
27   ret.color = color;
28   ret.text = ch;
29   ret.symFont = symbol;
30   return ret;
31 }
32 
Tile(TileCoord c)33 Tile::Tile(TileCoord c) : color{255, 255, 255}, tileCoord(c) {
34 }
35 
setRoundShadow()36 Tile Tile::setRoundShadow() {
37   roundShadow = true;
38   return *this;
39 }
40 
setWallShadow()41 Tile Tile::setWallShadow() {
42   wallShadow = true;
43   return *this;
44 }
45 
byCoord(TileCoord c)46 Tile Tile::byCoord(TileCoord c) {
47   return Tile(c);
48 }
49 
setFloorBorders()50 Tile Tile::setFloorBorders() {
51   floorBorders = true;
52   return *this;
53 }
54 
addConnection(DirSet dirs,TileCoord coord)55 Tile Tile::addConnection(DirSet dirs, TileCoord coord) {
56   connections[dirs] = coord;
57   if (dirs & (~connectionsMask))
58     connectionsMask = DirSet::fullSet();
59   anyConnections = true;
60   return *this;
61 }
62 
addOption(Dir d,TileCoord coord)63 Tile Tile::addOption(Dir d, TileCoord coord) {
64   connectionOption = make_pair(d, coord);
65   anyConnections = true;
66   return *this;
67 }
68 
addBackground(TileCoord coord)69 Tile Tile::addBackground(TileCoord coord) {
70   backgroundCoord = coord;
71   return *this;
72 }
73 
setColor(Color col)74 Tile Tile::setColor(Color col) {
75   color = col;
76   return *this;
77 }
78 
addExtraBorder(DirSet dir,TileCoord coord)79 Tile Tile::addExtraBorder(DirSet dir, TileCoord coord) {
80   extraBorders[dir] = coord;
81   return *this;
82 }
83 
addExtraBorderId(ViewId id)84 Tile Tile::addExtraBorderId(ViewId id) {
85   extraBorderIds.push_back(id);
86   anyExtraBorders = true;
87   return *this;
88 }
89 
addHighlight(TileCoord coord)90 Tile Tile::addHighlight(TileCoord coord) {
91   highlightCoord = coord;
92   return *this;
93 }
94 
getHighlightCoord() const95 optional<Tile::TileCoord> Tile::getHighlightCoord() const {
96   return highlightCoord;
97 }
98 
getExtraBorderIds() const99 const vector<ViewId>& Tile::getExtraBorderIds() const {
100   return extraBorderIds;
101 }
102 
hasExtraBorders() const103 bool Tile::hasExtraBorders() const {
104   return anyExtraBorders;
105 }
106 
getExtraBorderCoord(DirSet c) const107 optional<Tile::TileCoord> Tile::getExtraBorderCoord(DirSet c) const {
108   return extraBorders[c];
109 }
110 
setTranslucent(double v)111 Tile Tile::setTranslucent(double v) {
112   translucent = v;
113   return *this;
114 }
115 
hasSpriteCoord() const116 bool Tile::hasSpriteCoord() const {
117   return !!tileCoord;
118 }
119 
getSpriteCoord() const120 Tile::TileCoord Tile::getSpriteCoord() const {
121   CHECK(tileCoord);
122   return *tileCoord;
123 }
124 
getBackgroundCoord() const125 optional<Tile::TileCoord> Tile::getBackgroundCoord() const {
126   return backgroundCoord;
127 }
128 
hasAnyConnections() const129 bool Tile::hasAnyConnections() const {
130   return anyConnections;
131 }
132 
getSpriteCoord(DirSet c) const133 Tile::TileCoord Tile::getSpriteCoord(DirSet c) const {
134   if (connectionOption) {
135     if (c.has(connectionOption->first))
136       return connectionOption->second;
137     else {
138       CHECK(tileCoord);
139       return *tileCoord;
140     }
141   }
142   c = c & connectionsMask;
143   if (connections[c])
144     return *connections[c];
145   else {
146     CHECK(tileCoord);
147     return *tileCoord;
148   }
149 }
150 
151 static EnumMap<ViewId, optional<Tile>> tiles;
152 static EnumMap<ViewId, optional<Tile>> symbols;
153 
addTile(ViewId id,Tile tile)154 void Tile::addTile(ViewId id, Tile tile) {
155   tiles[id] = tile;
156 }
157 
addSymbol(ViewId id,Tile tile)158 void Tile::addSymbol(ViewId id, Tile tile) {
159   symbols[id] = tile;
160 }
161 
162 
163 class TileCoordLookup {
164   public:
TileCoordLookup(Renderer & r)165   TileCoordLookup(Renderer& r) : renderer(r) {}
166 
loadTiles()167   void loadTiles() {
168     genTiles();
169     bool bad = false;
170     for (ViewId id : ENUM_ALL(ViewId))
171       if (!tiles[id]) {
172         INFO << "ViewId not found: " << EnumInfo<ViewId>::getString(id);
173         bad = true;
174       }
175     CHECK(!bad);
176   }
177 
loadUnicode()178   void loadUnicode() {
179     genSymbols();
180     bool bad = false;
181     for (ViewId id : ENUM_ALL(ViewId))
182       if (!symbols[id]) {
183         INFO << "ViewId not found: " << EnumInfo<ViewId>::getString(id);
184         bad = true;
185       }
186     CHECK(!bad);
187   }
188 
byName(const string & s)189   Tile::TileCoord byName(const string& s) {
190     return renderer.getTileCoord(s);
191   }
192 
sprite(const string & s)193   Tile sprite(const string& s) {
194     return Tile::byCoord(byName(s));
195   }
196 
empty()197   Tile empty() {
198     return sprite("empty");
199   }
200 
getRoadTile(const string & prefix)201   Tile getRoadTile(const string& prefix) {
202     return sprite(prefix)
203       .addConnection({Dir::E, Dir::W}, byName(prefix + "ew"))
204       .addConnection({Dir::W}, byName(prefix + "w"))
205       .addConnection({Dir::E}, byName(prefix + "e"))
206       .addConnection({Dir::S}, byName(prefix + "s"))
207       .addConnection({Dir::N, Dir::S}, byName(prefix + "ns"))
208       .addConnection({Dir::N}, byName(prefix + "n"))
209       .addConnection({Dir::S, Dir::E}, byName(prefix + "se"))
210       .addConnection({Dir::S, Dir::W}, byName(prefix + "sw"))
211       .addConnection({Dir::N, Dir::E}, byName(prefix + "ne"))
212       .addConnection({Dir::N, Dir::W}, byName(prefix + "nw"))
213       .addConnection({Dir::N, Dir::E, Dir::S, Dir::W}, byName(prefix + "nesw"))
214       .addConnection({Dir::E, Dir::S, Dir::W}, byName(prefix + "esw"))
215       .addConnection({Dir::N, Dir::S, Dir::W}, byName(prefix + "nsw"))
216       .addConnection({Dir::N, Dir::E, Dir::S}, byName(prefix + "nes"))
217       .addConnection({Dir::N, Dir::E, Dir::W}, byName(prefix + "new"));
218   }
219 
getWallTile(const string & prefix)220   Tile getWallTile(const string& prefix) {
221     int tex = 1;
222     return sprite(prefix)
223       .addConnection({Dir::E}, byName(prefix + "e"))
224       .addConnection({Dir::E, Dir::W}, byName(prefix + "ew"))
225       .addConnection({Dir::W}, byName(prefix + "w"))
226       .addConnection({Dir::S}, byName(prefix + "s"))
227       .addConnection({Dir::N, Dir::S}, byName(prefix + "ns"))
228       .addConnection({Dir::N}, byName(prefix + "n"))
229       .addConnection({Dir::E, Dir::S}, byName(prefix + "es"))
230       .addConnection({Dir::S, Dir::W}, byName(prefix + "sw"))
231       .addConnection({Dir::N, Dir::E}, byName(prefix + "ne"))
232       .addConnection({Dir::N, Dir::W}, byName(prefix + "nw"))
233       .addConnection({Dir::N, Dir::E, Dir::S, Dir::W}, byName(prefix + "nesw"))
234       .addConnection({Dir::E, Dir::S, Dir::W}, byName(prefix + "esw"))
235       .addConnection({Dir::N, Dir::S, Dir::W}, byName(prefix + "nsw"))
236       .addConnection({Dir::N, Dir::E, Dir::S}, byName(prefix + "nes"))
237       .addConnection({Dir::N, Dir::E, Dir::W}, byName(prefix + "new"));
238   }
239 
getMountainTile(Tile background,const string & prefix)240   Tile getMountainTile(Tile background, const string& prefix) {
241     return background
242       .addCorner({Dir::S, Dir::W}, {Dir::W}, byName(prefix + "sw_w"))
243       .addCorner({Dir::N, Dir::W}, {Dir::W}, byName(prefix + "nw_w"))
244       .addCorner({Dir::S, Dir::E}, {Dir::E}, byName(prefix + "se_e"))
245       .addCorner({Dir::N, Dir::E}, {Dir::E}, byName(prefix + "ne_e"))
246       .addCorner({Dir::N, Dir::W}, {Dir::N}, byName(prefix + "nw_n"))
247       .addCorner({Dir::N, Dir::E}, {Dir::N}, byName(prefix + "ne_n"))
248       .addCorner({Dir::S, Dir::W}, {Dir::S}, byName(prefix + "sw_s"))
249       .addCorner({Dir::S, Dir::E}, {Dir::S}, byName(prefix + "se_s"))
250       .addCorner({Dir::N, Dir::W}, {}, byName(prefix + "nw"))
251       .addCorner({Dir::N, Dir::E}, {}, byName(prefix + "ne"))
252       .addCorner({Dir::S, Dir::W}, {}, byName(prefix + "sw"))
253       .addCorner({Dir::S, Dir::E}, {}, byName(prefix + "se"))
254       .addCorner({Dir::S, Dir::E, Dir::SE}, {Dir::S, Dir::E}, byName(prefix + "sese_se"))
255       .addCorner({Dir::S, Dir::W, Dir::SW}, {Dir::S, Dir::W}, byName(prefix + "swsw_sw"))
256       .addCorner({Dir::N, Dir::E, Dir::NE}, {Dir::N, Dir::E}, byName(prefix + "nene_ne"))
257       .addCorner({Dir::N, Dir::W, Dir::NW}, {Dir::N, Dir::W}, byName(prefix + "nwnw_nw"));
258   }
259 
getWaterTile(const string & background,const string & prefix)260   Tile getWaterTile(const string& background, const string& prefix) {
261     return empty().addBackground(byName(background))
262       .addConnection({Dir::N, Dir::E, Dir::S, Dir::W}, byName("empty"))
263       .addConnection({Dir::E, Dir::S, Dir::W}, byName(prefix + "esw"))
264       .addConnection({Dir::N, Dir::E, Dir::W}, byName(prefix + "new"))
265       .addConnection({Dir::N, Dir::S, Dir::W}, byName(prefix + "nsw"))
266       .addConnection({Dir::N, Dir::E, Dir::S}, byName(prefix + "nes"))
267       .addConnection({Dir::N, Dir::E}, byName(prefix + "ne"))
268       .addConnection({Dir::E, Dir::S}, byName(prefix + "es"))
269       .addConnection({Dir::S, Dir::W}, byName(prefix + "sw"))
270       .addConnection({Dir::N, Dir::W}, byName(prefix + "nw"))
271       .addConnection({Dir::S}, byName(prefix + "s"))
272       .addConnection({Dir::N}, byName(prefix + "n"))
273       .addConnection({Dir::W}, byName(prefix + "w"))
274       .addConnection({Dir::E}, byName(prefix + "e"))
275       .addConnection({Dir::N, Dir::S}, byName(prefix + "ns"))
276       .addConnection({Dir::E, Dir::W}, byName(prefix + "ew"));
277   }
278 
getExtraBorderTile(const string & prefix)279   Tile getExtraBorderTile(const string& prefix) {
280     return sprite(prefix)
281       .addExtraBorder({Dir::W, Dir::N}, byName(prefix + "wn"))
282       .addExtraBorder({Dir::E, Dir::N}, byName(prefix + "en"))
283       .addExtraBorder({Dir::E, Dir::S}, byName(prefix + "es"))
284       .addExtraBorder({Dir::W, Dir::S}, byName(prefix + "ws"))
285       .addExtraBorder({Dir::W, Dir::N, Dir::E}, byName(prefix + "wne"))
286       .addExtraBorder({Dir::S, Dir::N, Dir::E}, byName(prefix + "sne"))
287       .addExtraBorder({Dir::S, Dir::W, Dir::E}, byName(prefix + "swe"))
288       .addExtraBorder({Dir::S, Dir::W, Dir::N}, byName(prefix + "swn"))
289       .addExtraBorder({Dir::S, Dir::W, Dir::N, Dir::E}, byName(prefix + "swne"))
290       .addExtraBorder({Dir::N}, byName(prefix + "n"))
291       .addExtraBorder({Dir::E}, byName(prefix + "e"))
292       .addExtraBorder({Dir::S}, byName(prefix + "s"))
293       .addExtraBorder({Dir::W}, byName(prefix + "w"));
294   }
295 
genTiles()296   void genTiles() {
297     Tile::addTile(ViewId::UNKNOWN_MONSTER, sprite("unknown"));
298     Tile::addTile(ViewId::DIG_MARK, sprite("dig_mark"));
299     Tile::addTile(ViewId::FORBID_ZONE, sprite("dig_mark").setColor(Color::RED));
300     Tile::addTile(ViewId::DESTROY_BUTTON, sprite("remove"));
301     Tile::addTile(ViewId::EMPTY, empty());
302     Tile::addTile(ViewId::BORDER_GUARD, empty());
303     Tile::addTile(ViewId::DEMON_DWELLER, sprite("special_hmgw"));
304     Tile::addTile(ViewId::DEMON_LORD, sprite("special_hmgn"));
305     Tile::addTile(ViewId::VAMPIRE, sprite("vampire"));
306     Tile::addTile(ViewId::FALLEN_TREE, sprite("treecut"));
307     Tile::addTile(ViewId::DECID_TREE, sprite("tree2").addHighlight(byName("tree2_mark"))
308         .setRoundShadow());
309     Tile::addTile(ViewId::CANIF_TREE, sprite("tree1").addHighlight(byName("tree1_mark"))
310         .setRoundShadow());
311     Tile::addTile(ViewId::TREE_TRUNK, sprite("treecut"));
312     Tile::addTile(ViewId::UNICORN, sprite("unicorn"));
313     Tile::addTile(ViewId::BURNT_TREE, sprite("treeburnt")
314         .setRoundShadow());
315     Tile::addTile(ViewId::PLAYER, sprite("adventurer"));
316     Tile::addTile(ViewId::PLAYER_F, sprite("adventurer_female"));
317     Tile::addTile(ViewId::KEEPER, sprite("keeper"));
318     Tile::addTile(ViewId::KEEPER_F, sprite("keeper_female"));
319     Tile::addTile(ViewId::RETIRED_KEEPER, sprite("retired_keeper"));
320     Tile::addTile(ViewId::RETIRED_KEEPER_F, sprite("retired_keeper_female"));
321     Tile::addTile(ViewId::ELF, sprite("elf male"));
322     Tile::addTile(ViewId::ELF_WOMAN, sprite("elf female"));
323     Tile::addTile(ViewId::ELF_ARCHER, sprite("elf archer"));
324     Tile::addTile(ViewId::ELF_CHILD, sprite("elf kid"));
325     Tile::addTile(ViewId::ELF_LORD, sprite("elf lord"));
326     Tile::addTile(ViewId::DARK_ELF, sprite("dark_elf"));
327     Tile::addTile(ViewId::DARK_ELF_WOMAN, sprite("dark_elf_female"));
328     Tile::addTile(ViewId::DARK_ELF_WARRIOR, sprite("dark_elf_warrior"));
329     Tile::addTile(ViewId::DARK_ELF_CHILD, sprite("dark_elf_kid"));
330     Tile::addTile(ViewId::DARK_ELF_LORD, sprite("dark_elf_lord"));
331     Tile::addTile(ViewId::DRIAD, sprite("driad"));
332     Tile::addTile(ViewId::KOBOLD, sprite("kobold"));
333     Tile::addTile(ViewId::LIZARDMAN, sprite("lizardman"));
334     Tile::addTile(ViewId::LIZARDLORD, sprite("lizardlord"));
335     Tile::addTile(ViewId::IMP, sprite("imp"));
336     Tile::addTile(ViewId::PRISONER, sprite("prisoner"));
337     Tile::addTile(ViewId::OGRE, sprite("troll"));
338     Tile::addTile(ViewId::CHICKEN, sprite("hen"));
339     Tile::addTile(ViewId::GNOME, sprite("gnome"));
340     Tile::addTile(ViewId::GNOME_BOSS, sprite("gnomeboss"));
341     Tile::addTile(ViewId::DWARF, sprite("dwarf"));
342     Tile::addTile(ViewId::DWARF_BARON, sprite("dwarfboss"));
343     Tile::addTile(ViewId::DWARF_FEMALE, sprite("dwarf_f"));
344     Tile::addTile(ViewId::SHOPKEEPER, sprite("salesman"));
345     Tile::addTile(ViewId::BRIDGE, sprite("bridge").addOption(Dir::S, byName("bridge2")));
346     Tile::addTile(ViewId::ROAD, getRoadTile("road"));
347     Tile::addTile(ViewId::FLOOR, sprite("floor"));
348     Tile::addTile(ViewId::KEEPER_FLOOR, sprite("floor_keeper"));
349     Tile::addTile(ViewId::WOOD_FLOOR1, sprite("floor_wood1"));
350     Tile::addTile(ViewId::WOOD_FLOOR2, sprite("floor_wood2"));
351     Tile::addTile(ViewId::WOOD_FLOOR3, sprite("floor_wood3"));
352     Tile::addTile(ViewId::WOOD_FLOOR4, sprite("floor_wood4"));
353     Tile::addTile(ViewId::WOOD_FLOOR5, sprite("floor_wood5"));
354     Tile::addTile(ViewId::STONE_FLOOR1, sprite("floor_stone1"));
355     Tile::addTile(ViewId::STONE_FLOOR2, sprite("floor_stone2"));
356     Tile::addTile(ViewId::STONE_FLOOR3, sprite("floor_stone3"));
357     Tile::addTile(ViewId::STONE_FLOOR4, sprite("floor_stone4"));
358     Tile::addTile(ViewId::STONE_FLOOR5, sprite("floor_stone5"));
359     Tile::addTile(ViewId::CARPET_FLOOR1, sprite("floor_carpet1"));
360     Tile::addTile(ViewId::CARPET_FLOOR2, sprite("floor_carpet2"));
361     Tile::addTile(ViewId::CARPET_FLOOR3, sprite("floor_carpet3"));
362     Tile::addTile(ViewId::CARPET_FLOOR4, sprite("floor_carpet4"));
363     Tile::addTile(ViewId::CARPET_FLOOR5, sprite("floor_carpet5"));
364     Tile::addTile(ViewId::BUFF_FLOOR1, sprite("floor_buff1"));
365     Tile::addTile(ViewId::BUFF_FLOOR2, sprite("floor_buff2"));
366     Tile::addTile(ViewId::BUFF_FLOOR3, sprite("floor_buff3"));
367     Tile::addTile(ViewId::SAND, getExtraBorderTile("sand")
368         .addExtraBorderId(ViewId::WATER));
369     Tile::addTile(ViewId::MUD, getExtraBorderTile("mud")
370         .addExtraBorderId(ViewId::WATER)
371         .addExtraBorderId(ViewId::HILL)
372         .addExtraBorderId(ViewId::SAND));
373     Tile::addTile(ViewId::GRASS, getExtraBorderTile("grass")
374         .addExtraBorderId(ViewId::SAND)
375         .addExtraBorderId(ViewId::HILL)
376         .addExtraBorderId(ViewId::MUD)
377         .addExtraBorderId(ViewId::WATER));
378     Tile::addTile(ViewId::CROPS, sprite("wheatfield1"));
379     Tile::addTile(ViewId::CROPS2, sprite("wheatfield2"));
380     Tile::addTile(ViewId::MOUNTAIN, getMountainTile(sprite("mountain_ted"), "mountain").setWallShadow());
381     Tile::addTile(ViewId::DUNGEON_WALL, getMountainTile(sprite("mountain_ted"), "dungeonwall").setWallShadow());
382     Tile::addTile(ViewId::WALL, getWallTile("wall"));
383     Tile::addTile(ViewId::MAP_MOUNTAIN1, sprite("map_mountain1"));
384     Tile::addTile(ViewId::MAP_MOUNTAIN2, sprite("map_mountain2"));
385     Tile::addTile(ViewId::MAP_MOUNTAIN3, sprite("map_mountain3"));
386     Tile::addTile(ViewId::GOLD_ORE, getMountainTile(sprite("gold_ore")
387           .addBackground(byName("mountain_ted")).setWallShadow(), "mountain"));
388     Tile::addTile(ViewId::IRON_ORE, getMountainTile(sprite("iron_ore")
389           .addBackground(byName("mountain_ted")).setWallShadow(), "mountain"));
390     Tile::addTile(ViewId::STONE, getMountainTile(sprite("stone_ore")
391           .addBackground(byName("mountain_ted")).setWallShadow(), "mountain"));
392     Tile::addTile(ViewId::HILL, getExtraBorderTile("hill")
393         .addExtraBorderId(ViewId::SAND)
394         .addExtraBorderId(ViewId::WATER));
395     Tile::addTile(ViewId::WOOD_WALL, getWallTile("wood_wall").setWallShadow());
396     Tile::addTile(ViewId::BLACK_WALL, getWallTile("wall").setWallShadow());
397     Tile::addTile(ViewId::CASTLE_WALL, getWallTile("castle_wall").setWallShadow());
398     Tile::addTile(ViewId::MUD_WALL, getWallTile("mud_wall").setWallShadow());
399     Tile::addTile(ViewId::DOWN_STAIRCASE, sprite("down_stairs"));
400     Tile::addTile(ViewId::UP_STAIRCASE, sprite("up_stairs"));
401     Tile::addTile(ViewId::WELL, sprite("well")
402         .setRoundShadow());
403     Tile::addTile(ViewId::MINION_STATUE, sprite("statue")
404         .setRoundShadow());
405     Tile::addTile(ViewId::THRONE, sprite("throne").setRoundShadow());
406     Tile::addTile(ViewId::ORC, sprite("orc"));
407     Tile::addTile(ViewId::ORC_CAPTAIN, sprite("orc_captain"));
408     Tile::addTile(ViewId::ORC_SHAMAN, sprite("orcshaman"));
409     Tile::addTile(ViewId::HARPY, sprite("harpy"));
410     Tile::addTile(ViewId::DOPPLEGANGER, sprite("dopple"));
411     Tile::addTile(ViewId::SUCCUBUS, sprite("succubussmall"));
412     Tile::addTile(ViewId::BANDIT, sprite("bandit"));
413     Tile::addTile(ViewId::GHOST, sprite("ghost4"));
414     Tile::addTile(ViewId::SPIRIT, sprite("spirit"));
415     Tile::addTile(ViewId::GREEN_DRAGON, sprite("greendragon"));
416     Tile::addTile(ViewId::RED_DRAGON, sprite("reddragon"));
417     Tile::addTile(ViewId::CYCLOPS, sprite("cyclops"));
418     Tile::addTile(ViewId::MINOTAUR, sprite("mino"));
419     Tile::addTile(ViewId::SOFT_MONSTER, sprite("softmonster"));
420     Tile::addTile(ViewId::HYDRA, sprite("hydra"));
421     Tile::addTile(ViewId::SHELOB, sprite("szelob"));
422     Tile::addTile(ViewId::WITCH, sprite("witch"));
423     Tile::addTile(ViewId::WITCHMAN, sprite("witchman"));
424     Tile::addTile(ViewId::KNIGHT, sprite("knight"));
425     Tile::addTile(ViewId::WARRIOR, sprite("warrior"));
426     Tile::addTile(ViewId::SHAMAN, sprite("shaman"));
427     Tile::addTile(ViewId::DUKE, sprite("knightboss"));
428     Tile::addTile(ViewId::ARCHER, sprite("archer"));
429     Tile::addTile(ViewId::PESEANT, sprite("peasant"));
430     Tile::addTile(ViewId::PESEANT_WOMAN, sprite("peasantgirl"));
431     Tile::addTile(ViewId::CHILD, sprite("peasantkid"));
432     Tile::addTile(ViewId::CLAY_GOLEM, sprite("clay_golem"));
433     Tile::addTile(ViewId::STONE_GOLEM, sprite("stone_golem"));
434     Tile::addTile(ViewId::IRON_GOLEM, sprite("iron_golem"));
435     Tile::addTile(ViewId::LAVA_GOLEM, sprite("lava_golem"));
436     Tile::addTile(ViewId::AUTOMATON, sprite("automaton"));
437     Tile::addTile(ViewId::ELEMENTALIST, sprite("elementalist"));
438     Tile::addTile(ViewId::AIR_ELEMENTAL, sprite("airelement"));
439     Tile::addTile(ViewId::FIRE_ELEMENTAL, sprite("fireelement"));
440     Tile::addTile(ViewId::WATER_ELEMENTAL, sprite("waterelement"));
441     Tile::addTile(ViewId::EARTH_ELEMENTAL, sprite("earthelement"));
442     Tile::addTile(ViewId::ENT, sprite("ent"));
443     Tile::addTile(ViewId::ANGEL, sprite("ent"));
444     Tile::addTile(ViewId::ZOMBIE, sprite("zombie"));
445     Tile::addTile(ViewId::SKELETON, sprite("skeleton"));
446     Tile::addTile(ViewId::VAMPIRE_LORD, sprite("vampirelord"));
447     Tile::addTile(ViewId::MUMMY, sprite("mummy"));
448     Tile::addTile(ViewId::JACKAL, sprite("jackal"));
449     Tile::addTile(ViewId::DEER, sprite("deer"));
450     Tile::addTile(ViewId::HORSE, sprite("horse"));
451     Tile::addTile(ViewId::COW, sprite("cow"));
452     Tile::addTile(ViewId::PIG, sprite("pig"));
453     Tile::addTile(ViewId::DONKEY, sprite("donkey"));
454     Tile::addTile(ViewId::GOAT, sprite("goat"));
455     Tile::addTile(ViewId::BOAR, sprite("boar"));
456     Tile::addTile(ViewId::FOX, sprite("fox"));
457     Tile::addTile(ViewId::WOLF, sprite("wolf"));
458     Tile::addTile(ViewId::WEREWOLF, sprite("werewolf2"));
459     Tile::addTile(ViewId::DOG, sprite("dog"));
460     Tile::addTile(ViewId::KRAKEN_HEAD, sprite("krakenhead"));
461     Tile::addTile(ViewId::KRAKEN_LAND, sprite("krakenland1"));
462     Tile::addTile(ViewId::KRAKEN_WATER, sprite("krakenwater2"));
463     Tile::addTile(ViewId::DEATH, sprite("death"));
464     Tile::addTile(ViewId::FIRE_SPHERE, sprite("fire_sphere"));
465     Tile::addTile(ViewId::BEAR, sprite("bear"));
466     Tile::addTile(ViewId::BAT, sprite("bat"));
467     Tile::addTile(ViewId::GOBLIN, sprite("goblin"));
468     Tile::addTile(ViewId::RAT, sprite("rat"));
469     Tile::addTile(ViewId::SPIDER, sprite("spider"));
470     Tile::addTile(ViewId::FLY, sprite("fly"));
471     Tile::addTile(ViewId::ANT_WORKER, sprite("antwork"));
472     Tile::addTile(ViewId::ANT_SOLDIER, sprite("antw"));
473     Tile::addTile(ViewId::ANT_QUEEN, sprite("antq"));
474     Tile::addTile(ViewId::SNAKE, sprite("snake"));
475     Tile::addTile(ViewId::VULTURE, sprite("vulture"));
476     Tile::addTile(ViewId::RAVEN, sprite("raven"));
477     Tile::addTile(ViewId::BODY_PART, sprite("corpse4"));
478     Tile::addTile(ViewId::BONE, sprite("bone"));
479     Tile::addTile(ViewId::BUSH, sprite("bush").addHighlight(byName("bush_mark")));
480     Tile::addTile(ViewId::WATER, getWaterTile("waternesw", "water"));
481     Tile::addTile(ViewId::MAGMA, getWaterTile("magmanesw", "magma"));
482     Tile::addTile(ViewId::DOOR, sprite("door").setWallShadow());
483     Tile::addTile(ViewId::LOCKED_DOOR, sprite("locked_door").setWallShadow());
484     Tile::addTile(ViewId::BARRICADE, sprite("barricade").setRoundShadow());
485     Tile::addTile(ViewId::DIG_ICON, sprite("dig_icon"));
486     Tile::addTile(ViewId::SWORD, sprite("sword"));
487     Tile::addTile(ViewId::STEEL_SWORD, sprite("steel_sword"));
488     Tile::addTile(ViewId::SPEAR, sprite("spear"));
489     Tile::addTile(ViewId::SPECIAL_SWORD, sprite("special_sword"));
490     Tile::addTile(ViewId::ELVEN_SWORD, sprite("elven_sword"));
491     Tile::addTile(ViewId::KNIFE, sprite("knife"));
492     Tile::addTile(ViewId::WAR_HAMMER, sprite("warhammer"));
493     Tile::addTile(ViewId::SPECIAL_WAR_HAMMER, sprite("special_warhammer"));
494     Tile::addTile(ViewId::BATTLE_AXE, sprite("battle_axe"));
495     Tile::addTile(ViewId::STEEL_BATTLE_AXE, sprite("steel_battle_axe"));
496     Tile::addTile(ViewId::SPECIAL_BATTLE_AXE, sprite("special_battle_axe"));
497     Tile::addTile(ViewId::BOW, sprite("bow"));
498     Tile::addTile(ViewId::ELVEN_BOW, sprite("bow")); //For now
499     Tile::addTile(ViewId::ARROW, sprite("arrow_e"));
500     Tile::addTile(ViewId::WOODEN_STAFF, sprite("staff_wooden"));
501     Tile::addTile(ViewId::IRON_STAFF, sprite("staff_iron"));
502     Tile::addTile(ViewId::FORCE_BOLT, sprite("force_bolt"));
503     Tile::addTile(ViewId::AIR_BLAST, sprite("air_blast"));
504     Tile::addTile(ViewId::STUN_RAY, sprite("stun_ray"));
505     Tile::addTile(ViewId::CLUB, sprite("club"));
506     Tile::addTile(ViewId::HEAVY_CLUB, sprite("heavy club"));
507     Tile::addTile(ViewId::SCROLL, sprite("scroll"));
508     Tile::addTile(ViewId::AMULET1, sprite("amulet1"));
509     Tile::addTile(ViewId::AMULET2, sprite("amulet2"));
510     Tile::addTile(ViewId::AMULET3, sprite("amulet3"));
511     Tile::addTile(ViewId::AMULET4, sprite("amulet4"));
512     Tile::addTile(ViewId::AMULET5, sprite("amulet5"));
513     Tile::addTile(ViewId::FIRE_RESIST_RING, sprite("ring_red"));
514     Tile::addTile(ViewId::POISON_RESIST_RING, sprite("ring_green"));
515     Tile::addTile(ViewId::BOOK, sprite("book"));
516     Tile::addTile(ViewId::FIRST_AID, sprite("medkit"));
517     Tile::addTile(ViewId::TRAP_ITEM, sprite("trapbox"));
518     Tile::addTile(ViewId::POTION1, sprite("potion1"));
519     Tile::addTile(ViewId::POTION2, sprite("potion2"));
520     Tile::addTile(ViewId::POTION3, sprite("potion3"));
521     Tile::addTile(ViewId::POTION4, sprite("potion4"));
522     Tile::addTile(ViewId::POTION5, sprite("potion5"));
523     Tile::addTile(ViewId::POTION6, sprite("potion6"));
524     Tile::addTile(ViewId::MUSHROOM1, sprite("mushroom1").setRoundShadow());
525     Tile::addTile(ViewId::MUSHROOM2, sprite("mushroom2").setRoundShadow());
526     Tile::addTile(ViewId::MUSHROOM3, sprite("mushroom3").setRoundShadow());
527     Tile::addTile(ViewId::MUSHROOM4, sprite("mushroom4").setRoundShadow());
528     Tile::addTile(ViewId::MUSHROOM5, sprite("mushroom5").setRoundShadow());
529     Tile::addTile(ViewId::MUSHROOM6, sprite("mushroom6").setRoundShadow());
530     Tile::addTile(ViewId::KEY, sprite("key"));
531     Tile::addTile(ViewId::FOUNTAIN, sprite("fountain").setRoundShadow());
532     Tile::addTile(ViewId::GOLD, sprite("gold"));
533     Tile::addTile(ViewId::TREASURE_CHEST, sprite("treasurydeco"));
534     Tile::addTile(ViewId::CHEST, sprite("chest").setRoundShadow());
535     Tile::addTile(ViewId::OPENED_CHEST, sprite("chest_opened").setRoundShadow());
536     Tile::addTile(ViewId::COFFIN, sprite("coffin").setRoundShadow());
537     Tile::addTile(ViewId::OPENED_COFFIN, sprite("coffin_opened").setRoundShadow());
538     Tile::addTile(ViewId::BOULDER, sprite("boulder").setRoundShadow());
539     Tile::addTile(ViewId::PORTAL, sprite("surprise"));
540     Tile::addTile(ViewId::GAS_TRAP, sprite("gas_trap"));
541     Tile::addTile(ViewId::ALARM_TRAP, sprite("alarm_trap"));
542     Tile::addTile(ViewId::WEB_TRAP, sprite("web_trap"));
543     Tile::addTile(ViewId::SURPRISE_TRAP, sprite("surprisetrap"));
544     Tile::addTile(ViewId::TERROR_TRAP, sprite("terror_trap"));
545     Tile::addTile(ViewId::ROCK, sprite("stonepile"));
546     Tile::addTile(ViewId::IRON_ROCK, sprite("ironpile"));
547     Tile::addTile(ViewId::STEEL_INGOT, sprite("steelpile"));
548     Tile::addTile(ViewId::WOOD_PLANK, sprite("wood2"));
549     Tile::addTile(ViewId::STORAGE_EQUIPMENT, sprite("dig_mark").setColor(Color::BLUE.transparency(120)));
550     Tile::addTile(ViewId::STORAGE_RESOURCES, sprite("dig_mark").setColor(Color::GREEN.transparency(120)));
551     Tile::addTile(ViewId::PRISON, sprite("prison"));
552     Tile::addTile(ViewId::BED, sprite("sleepdeco").setRoundShadow());
553     Tile::addTile(ViewId::DORM, sprite("sleep").setFloorBorders());
554     Tile::addTile(ViewId::TORCH, sprite("torch").setTranslucent(0.35));
555     Tile::addTile(ViewId::ALTAR, sprite("altar").setRoundShadow());
556     Tile::addTile(ViewId::CREATURE_ALTAR, sprite("altar2").setRoundShadow());
557     Tile::addTile(ViewId::TORTURE_TABLE, sprite("torturedeco").setRoundShadow());
558     Tile::addTile(ViewId::IMPALED_HEAD, sprite("impaledhead").setRoundShadow());
559     Tile::addTile(ViewId::WHIPPING_POST, sprite("whipping_post").setRoundShadow());
560     Tile::addTile(ViewId::GALLOWS, sprite("gallows").setRoundShadow());
561     Tile::addTile(ViewId::NOTICE_BOARD, sprite("board").setRoundShadow());
562     Tile::addTile(ViewId::SOKOBAN_HOLE, sprite("hole"));
563     Tile::addTile(ViewId::TRAINING_WOOD, sprite("train_wood").setRoundShadow());
564     Tile::addTile(ViewId::TRAINING_IRON, sprite("train_iron").setRoundShadow());
565     Tile::addTile(ViewId::TRAINING_STEEL, sprite("train_steel").setRoundShadow());
566     Tile::addTile(ViewId::ARCHERY_RANGE, sprite("archery_range").setRoundShadow());
567     Tile::addTile(ViewId::DEMON_SHRINE, sprite("demon_shrine").setRoundShadow());
568     Tile::addTile(ViewId::BOOKCASE_WOOD, sprite("library_wood").setRoundShadow());
569     Tile::addTile(ViewId::BOOKCASE_IRON, sprite("library_iron").setRoundShadow());
570     Tile::addTile(ViewId::BOOKCASE_GOLD, sprite("library_gold").setRoundShadow());
571     Tile::addTile(ViewId::LABORATORY, sprite("labdeco").setRoundShadow());
572     Tile::addTile(ViewId::CAULDRON, sprite("labdeco"));
573     Tile::addTile(ViewId::BEAST_LAIR, sprite("lair").setFloorBorders());
574     Tile::addTile(ViewId::BEAST_CAGE, sprite("lairdeco").setRoundShadow());
575     Tile::addTile(ViewId::FORGE, sprite("forgedeco").setRoundShadow());
576     Tile::addTile(ViewId::WORKSHOP, sprite("workshopdeco").setRoundShadow());
577     Tile::addTile(ViewId::JEWELER, sprite("jewelerdeco").setRoundShadow());
578     Tile::addTile(ViewId::STEEL_FURNACE, sprite("steel_furnace").setRoundShadow());
579     Tile::addTile(ViewId::CEMETERY, sprite("graveyard").setFloorBorders());
580     Tile::addTile(ViewId::GRAVE, sprite("RIP").setRoundShadow());
581     Tile::addTile(ViewId::ROBE, sprite("robe"));
582     Tile::addTile(ViewId::LEATHER_GLOVES, sprite("leather_gloves"));
583     Tile::addTile(ViewId::DEXTERITY_GLOVES, sprite("blue_gloves"));
584     Tile::addTile(ViewId::STRENGTH_GLOVES, sprite("red_gloves"));
585     Tile::addTile(ViewId::LEATHER_ARMOR, sprite("leather_armor"));
586     Tile::addTile(ViewId::LEATHER_HELM, sprite("leather_helm"));
587     Tile::addTile(ViewId::TELEPATHY_HELM, sprite("blue_helm"));
588     Tile::addTile(ViewId::CHAIN_ARMOR, sprite("chain_armor"));
589     Tile::addTile(ViewId::STEEL_ARMOR, sprite("steel_armor"));
590     Tile::addTile(ViewId::IRON_HELM, sprite("iron_helm"));
591     Tile::addTile(ViewId::LEATHER_BOOTS, sprite("leather_boots"));
592     Tile::addTile(ViewId::IRON_BOOTS, sprite("iron_boots"));
593     Tile::addTile(ViewId::SPEED_BOOTS, sprite("blue_boots"));
594     Tile::addTile(ViewId::LEVITATION_BOOTS, sprite("green_boots"));
595     Tile::addTile(ViewId::GUARD_POST, sprite("guardroom").setRoundShadow());
596     Tile::addTile(ViewId::MANA, sprite("mana"));
597     Tile::addTile(ViewId::FETCH_ICON, sprite("leather_gloves"));
598     Tile::addTile(ViewId::EYEBALL, sprite("eyeball2").setRoundShadow());
599     Tile::addTile(ViewId::FOG_OF_WAR, getWaterTile("empty", "fogofwar"));
600     Tile::addTile(ViewId::CREATURE_HIGHLIGHT, sprite("creature_highlight"));
601     Tile::addTile(ViewId::SQUARE_HIGHLIGHT, sprite("square_highlight"));
602     Tile::addTile(ViewId::ROUND_SHADOW, sprite("round_shadow"));
603     Tile::addTile(ViewId::CAMPAIGN_DEFEATED, sprite("campaign_defeated"));
604     Tile::addTile(ViewId::ACCEPT_IMMIGRANT, symbol(u8"✓", Color::GREEN, true));
605     Tile::addTile(ViewId::REJECT_IMMIGRANT, symbol(u8"✘", Color::RED, true));
606     Tile::addTile(ViewId::FOG_OF_WAR_CORNER, sprite("fogofwar")
607         .addConnection({Dir::NE}, byName("fogofwarcornne"))
608         .addConnection({Dir::NW}, byName("fogofwarcornnw"))
609         .addConnection({Dir::SE}, byName("fogofwarcornse"))
610         .addConnection({Dir::SW}, byName("fogofwarcornsw")));
611     Tile::addTile(ViewId::SPECIAL_BLBN, sprite("special_blbn"));
612     Tile::addTile(ViewId::SPECIAL_BLBW, sprite("special_blbw"));
613     Tile::addTile(ViewId::SPECIAL_BLGN, sprite("special_blgn"));
614     Tile::addTile(ViewId::SPECIAL_BLGW, sprite("special_blgw"));
615     Tile::addTile(ViewId::SPECIAL_BMBN, sprite("special_bmbn"));
616     Tile::addTile(ViewId::SPECIAL_BMBW, sprite("special_bmbw"));
617     Tile::addTile(ViewId::SPECIAL_BMGN, sprite("special_bmgn"));
618     Tile::addTile(ViewId::SPECIAL_BMGW, sprite("special_bmgw"));
619     Tile::addTile(ViewId::SPECIAL_HLBN, sprite("special_hlbn"));
620     Tile::addTile(ViewId::SPECIAL_HLBW, sprite("special_hlbw"));
621     Tile::addTile(ViewId::SPECIAL_HLGN, sprite("special_hlgn"));
622     Tile::addTile(ViewId::SPECIAL_HLGW, sprite("special_hlgw"));
623     Tile::addTile(ViewId::SPECIAL_HMBN, sprite("special_hmbn"));
624     Tile::addTile(ViewId::SPECIAL_HMBW, sprite("special_hmbw"));
625     Tile::addTile(ViewId::SPECIAL_HMGN, sprite("special_hmgn"));
626     Tile::addTile(ViewId::SPECIAL_HMGW, sprite("special_hmgw"));
627 #ifndef RELEASE
628     Tile::addTile(ViewId::TUTORIAL_ENTRANCE, symbol(u8"?", Color::YELLOW));
629 #else
630     Tile::addTile(ViewId::TUTORIAL_ENTRANCE, sprite("empty"));
631 #endif
632 
633   }
634 
symbol(const string & s,Color id,bool symbol=false)635   Tile symbol(const string& s, Color id, bool symbol = false) {
636     return Tile::fromString(s, id, symbol);
637   }
638 
genSymbols()639   void genSymbols() {
640     Tile::addSymbol(ViewId::DEMON_DWELLER, symbol(u8"U", Color::PURPLE));
641     Tile::addSymbol(ViewId::DEMON_LORD, symbol(u8"U", Color::YELLOW));
642     Tile::addSymbol(ViewId::EMPTY, symbol(u8" ", Color::BLACK));
643     Tile::addSymbol(ViewId::DIG_MARK, symbol(u8" ", Color::BLACK));
644     Tile::addSymbol(ViewId::PLAYER, symbol(u8"@", Color::WHITE));
645     Tile::addSymbol(ViewId::PLAYER_F, symbol(u8"@", Color::YELLOW));
646     Tile::addSymbol(ViewId::KEEPER, symbol(u8"@", Color::PURPLE));
647     Tile::addSymbol(ViewId::KEEPER_F, symbol(u8"@", Color::PINK));
648     Tile::addSymbol(ViewId::RETIRED_KEEPER, symbol(u8"@", Color::BLUE));
649     Tile::addSymbol(ViewId::RETIRED_KEEPER_F, symbol(u8"@", Color::LIGHT_BLUE));
650     Tile::addSymbol(ViewId::UNKNOWN_MONSTER, symbol(u8"?", Color::LIGHT_GREEN));
651     Tile::addSymbol(ViewId::ELF, symbol(u8"@", Color::LIGHT_GREEN));
652     Tile::addSymbol(ViewId::ELF_WOMAN, symbol(u8"@", Color::LIGHT_GREEN));
653     Tile::addSymbol(ViewId::ELF_ARCHER, symbol(u8"@", Color::GREEN));
654     Tile::addSymbol(ViewId::ELF_CHILD, symbol(u8"@", Color::LIGHT_GREEN));
655     Tile::addSymbol(ViewId::ELF_LORD, symbol(u8"@", Color::DARK_GREEN));
656     Tile::addSymbol(ViewId::DARK_ELF, symbol(u8"@", Color::ALMOST_DARK_GRAY));
657     Tile::addSymbol(ViewId::DARK_ELF_WOMAN, symbol(u8"@", Color::ALMOST_DARK_GRAY));
658     Tile::addSymbol(ViewId::DARK_ELF_WARRIOR, symbol(u8"@", Color::GRAY));
659     Tile::addSymbol(ViewId::DARK_ELF_CHILD, symbol(u8"@", Color::ALMOST_GRAY));
660     Tile::addSymbol(ViewId::DARK_ELF_LORD, symbol(u8"@", Color::LIGHT_GRAY));
661     Tile::addSymbol(ViewId::DRIAD, symbol(u8"@", Color::LIGHT_BROWN));
662     Tile::addSymbol(ViewId::UNICORN, symbol(u8"h", Color::WHITE));
663     Tile::addSymbol(ViewId::KOBOLD, symbol(u8"k", Color::LIGHT_BROWN));
664     Tile::addSymbol(ViewId::SHOPKEEPER, symbol(u8"@", Color::LIGHT_BLUE));
665     Tile::addSymbol(ViewId::LIZARDMAN, symbol(u8"@", Color::LIGHT_BROWN));
666     Tile::addSymbol(ViewId::LIZARDLORD, symbol(u8"@", Color::BROWN));
667     Tile::addSymbol(ViewId::IMP, symbol(u8"i", Color::LIGHT_BROWN));
668     Tile::addSymbol(ViewId::PRISONER, symbol(u8"@", Color::LIGHT_BROWN));
669     Tile::addSymbol(ViewId::OGRE, symbol(u8"O", Color::GREEN));
670     Tile::addSymbol(ViewId::CHICKEN, symbol(u8"c", Color::YELLOW));
671     Tile::addSymbol(ViewId::GNOME, symbol(u8"g", Color::GREEN));
672     Tile::addSymbol(ViewId::GNOME_BOSS, symbol(u8"g", Color::DARK_BLUE));
673     Tile::addSymbol(ViewId::DWARF, symbol(u8"h", Color::BLUE));
674     Tile::addSymbol(ViewId::DWARF_BARON, symbol(u8"h", Color::DARK_BLUE));
675     Tile::addSymbol(ViewId::DWARF_FEMALE, symbol(u8"h", Color::LIGHT_BLUE));
676     Tile::addSymbol(ViewId::FLOOR, symbol(u8".", Color::LIGHT_GRAY));
677     Tile::addSymbol(ViewId::KEEPER_FLOOR, symbol(u8".", Color::WHITE));
678     Tile::addSymbol(ViewId::WOOD_FLOOR1, symbol(u8".", Color::LIGHT_BROWN));
679     Tile::addSymbol(ViewId::WOOD_FLOOR2, symbol(u8".", Color::BROWN));
680     Tile::addSymbol(ViewId::WOOD_FLOOR3, symbol(u8".", Color::LIGHT_BROWN));
681     Tile::addSymbol(ViewId::WOOD_FLOOR4, symbol(u8".", Color::BROWN));
682     Tile::addSymbol(ViewId::WOOD_FLOOR5, symbol(u8".", Color::BROWN));
683     Tile::addSymbol(ViewId::STONE_FLOOR1, symbol(u8".", Color::LIGHT_GRAY));
684     Tile::addSymbol(ViewId::STONE_FLOOR2, symbol(u8".", Color::GRAY));
685     Tile::addSymbol(ViewId::STONE_FLOOR3, symbol(u8".", Color::LIGHT_GRAY));
686     Tile::addSymbol(ViewId::STONE_FLOOR4, symbol(u8".", Color::GRAY));
687     Tile::addSymbol(ViewId::STONE_FLOOR5, symbol(u8".", Color::GRAY));
688     Tile::addSymbol(ViewId::CARPET_FLOOR1, symbol(u8".", Color::PURPLE));
689     Tile::addSymbol(ViewId::CARPET_FLOOR2, symbol(u8".", Color::PINK));
690     Tile::addSymbol(ViewId::CARPET_FLOOR3, symbol(u8".", Color::PURPLE));
691     Tile::addSymbol(ViewId::CARPET_FLOOR4, symbol(u8".", Color::PINK));
692     Tile::addSymbol(ViewId::CARPET_FLOOR5, symbol(u8".", Color::PINK));
693     Tile::addSymbol(ViewId::BUFF_FLOOR1, symbol(u8".", Color::PURPLE));
694     Tile::addSymbol(ViewId::BUFF_FLOOR2, symbol(u8".", Color::PINK));
695     Tile::addSymbol(ViewId::BUFF_FLOOR3, symbol(u8".", Color::PURPLE));
696     Tile::addSymbol(ViewId::BRIDGE, symbol(u8"_", Color::BROWN));
697     Tile::addSymbol(ViewId::ROAD, symbol(u8".", Color::LIGHT_GRAY));
698     Tile::addSymbol(ViewId::SAND, symbol(u8".", Color::YELLOW));
699     Tile::addSymbol(ViewId::MUD, symbol(u8"��", Color::BROWN, true));
700     Tile::addSymbol(ViewId::GRASS, symbol(u8"��", Color::GREEN, true));
701     Tile::addSymbol(ViewId::CROPS, symbol(u8"��", Color::YELLOW, true));
702     Tile::addSymbol(ViewId::CROPS2, symbol(u8"��", Color::YELLOW, true));
703     Tile::addSymbol(ViewId::CASTLE_WALL, symbol(u8"#", Color::LIGHT_GRAY));
704     Tile::addSymbol(ViewId::MUD_WALL, symbol(u8"#", Color::LIGHT_BROWN));
705     Tile::addSymbol(ViewId::WALL, symbol(u8"#", Color::LIGHT_GRAY));
706     Tile::addSymbol(ViewId::MOUNTAIN, symbol(u8"#", Color::DARK_GRAY));
707     Tile::addSymbol(ViewId::DUNGEON_WALL, symbol(u8"#", Color::LIGHT_GRAY));
708     Tile::addSymbol(ViewId::MAP_MOUNTAIN1, symbol(u8"^", Color::DARK_GRAY));
709     Tile::addSymbol(ViewId::MAP_MOUNTAIN2, symbol(u8"^", Color::GRAY));
710     Tile::addSymbol(ViewId::MAP_MOUNTAIN3, symbol(u8"^", Color::LIGHT_GRAY));
711     Tile::addSymbol(ViewId::GOLD_ORE, symbol(u8"⁂", Color::YELLOW, true));
712     Tile::addSymbol(ViewId::IRON_ORE, symbol(u8"⁂", Color::DARK_BROWN, true));
713     Tile::addSymbol(ViewId::STONE, symbol(u8"⁂", Color::LIGHT_GRAY, true));
714     Tile::addSymbol(ViewId::HILL, symbol(u8"��", Color::DARK_GREEN, true));
715     Tile::addSymbol(ViewId::WOOD_WALL, symbol(u8"#", Color::DARK_BROWN));
716     Tile::addSymbol(ViewId::BLACK_WALL, symbol(u8"#", Color::LIGHT_GRAY));
717     Tile::addSymbol(ViewId::DOWN_STAIRCASE, symbol(u8"➘", Color::ALMOST_WHITE, true));
718     Tile::addSymbol(ViewId::UP_STAIRCASE, symbol(u8"➚", Color::ALMOST_WHITE, true));
719     Tile::addSymbol(ViewId::WELL, symbol(u8"0", Color::BLUE));
720     Tile::addSymbol(ViewId::MINION_STATUE, symbol(u8"&", Color::LIGHT_GRAY));
721     Tile::addSymbol(ViewId::THRONE, symbol(u8"Ω", Color::YELLOW, true));
722     Tile::addSymbol(ViewId::ORC, symbol(u8"o", Color::DARK_BLUE));
723     Tile::addSymbol(ViewId::ORC_CAPTAIN, symbol(u8"o", Color::PURPLE));
724     Tile::addSymbol(ViewId::ORC_SHAMAN, symbol(u8"o", Color::YELLOW));
725     Tile::addSymbol(ViewId::HARPY, symbol(u8"R", Color::YELLOW));
726     Tile::addSymbol(ViewId::DOPPLEGANGER, symbol(u8"&", Color::YELLOW));
727     Tile::addSymbol(ViewId::SUCCUBUS, symbol(u8"&", Color::RED));
728     Tile::addSymbol(ViewId::BANDIT, symbol(u8"@", Color::DARK_BLUE));
729     Tile::addSymbol(ViewId::GREEN_DRAGON, symbol(u8"D", Color::GREEN));
730     Tile::addSymbol(ViewId::RED_DRAGON, symbol(u8"D", Color::RED));
731     Tile::addSymbol(ViewId::CYCLOPS, symbol(u8"C", Color::GREEN));
732     Tile::addSymbol(ViewId::MINOTAUR, symbol(u8"M", Color::PURPLE));
733     Tile::addSymbol(ViewId::SOFT_MONSTER, symbol(u8"M", Color::PINK));
734     Tile::addSymbol(ViewId::HYDRA, symbol(u8"H", Color::PURPLE));
735     Tile::addSymbol(ViewId::SHELOB, symbol(u8"S", Color::PURPLE));
736     Tile::addSymbol(ViewId::WITCH, symbol(u8"@", Color::BROWN));
737     Tile::addSymbol(ViewId::WITCHMAN, symbol(u8"@", Color::WHITE));
738     Tile::addSymbol(ViewId::GHOST, symbol(u8"&", Color::WHITE));
739     Tile::addSymbol(ViewId::SPIRIT, symbol(u8"&", Color::LIGHT_BLUE));
740     Tile::addSymbol(ViewId::KNIGHT, symbol(u8"@", Color::LIGHT_GRAY));
741     Tile::addSymbol(ViewId::WARRIOR, symbol(u8"@", Color::DARK_GRAY));
742     Tile::addSymbol(ViewId::SHAMAN, symbol(u8"@", Color::YELLOW));
743     Tile::addSymbol(ViewId::DUKE, symbol(u8"@", Color::BLUE));
744     Tile::addSymbol(ViewId::ARCHER, symbol(u8"@", Color::BROWN));
745     Tile::addSymbol(ViewId::PESEANT, symbol(u8"@", Color::GREEN));
746     Tile::addSymbol(ViewId::PESEANT_WOMAN, symbol(u8"@", Color::GREEN));
747     Tile::addSymbol(ViewId::CHILD, symbol(u8"@", Color::LIGHT_GREEN));
748     Tile::addSymbol(ViewId::CLAY_GOLEM, symbol(u8"Y", Color::YELLOW));
749     Tile::addSymbol(ViewId::STONE_GOLEM, symbol(u8"Y", Color::LIGHT_GRAY));
750     Tile::addSymbol(ViewId::IRON_GOLEM, symbol(u8"Y", Color::ORANGE));
751     Tile::addSymbol(ViewId::LAVA_GOLEM, symbol(u8"Y", Color::PURPLE));
752     Tile::addSymbol(ViewId::AUTOMATON, symbol(u8"A", Color::LIGHT_GRAY));
753     Tile::addSymbol(ViewId::ELEMENTALIST, symbol(u8"@", Color::YELLOW));
754     Tile::addSymbol(ViewId::AIR_ELEMENTAL, symbol(u8"E", Color::LIGHT_BLUE));
755     Tile::addSymbol(ViewId::FIRE_ELEMENTAL, symbol(u8"E", Color::RED));
756     Tile::addSymbol(ViewId::WATER_ELEMENTAL, symbol(u8"E", Color::BLUE));
757     Tile::addSymbol(ViewId::EARTH_ELEMENTAL, symbol(u8"E", Color::GRAY));
758     Tile::addSymbol(ViewId::ENT, symbol(u8"E", Color::LIGHT_BROWN));
759     Tile::addSymbol(ViewId::ANGEL, symbol(u8"A", Color::LIGHT_BLUE));
760     Tile::addSymbol(ViewId::ZOMBIE, symbol(u8"Z", Color::GREEN));
761     Tile::addSymbol(ViewId::SKELETON, symbol(u8"Z", Color::WHITE));
762     Tile::addSymbol(ViewId::VAMPIRE, symbol(u8"V", Color::DARK_GRAY));
763     Tile::addSymbol(ViewId::VAMPIRE_LORD, symbol(u8"V", Color::PURPLE));
764     Tile::addSymbol(ViewId::MUMMY, symbol(u8"Z", Color::YELLOW));
765     Tile::addSymbol(ViewId::JACKAL, symbol(u8"d", Color::LIGHT_BROWN));
766     Tile::addSymbol(ViewId::DEER, symbol(u8"R", Color::DARK_BROWN));
767     Tile::addSymbol(ViewId::HORSE, symbol(u8"H", Color::LIGHT_BROWN));
768     Tile::addSymbol(ViewId::COW, symbol(u8"C", Color::WHITE));
769     Tile::addSymbol(ViewId::PIG, symbol(u8"p", Color::YELLOW));
770     Tile::addSymbol(ViewId::DONKEY, symbol(u8"D", Color::GRAY));
771     Tile::addSymbol(ViewId::GOAT, symbol(u8"g", Color::GRAY));
772     Tile::addSymbol(ViewId::BOAR, symbol(u8"b", Color::LIGHT_BROWN));
773     Tile::addSymbol(ViewId::FOX, symbol(u8"d", Color::ORANGE_BROWN));
774     Tile::addSymbol(ViewId::WOLF, symbol(u8"d", Color::DARK_BLUE));
775     Tile::addSymbol(ViewId::WEREWOLF, symbol(u8"d", Color::WHITE));
776     Tile::addSymbol(ViewId::DOG, symbol(u8"d", Color::BROWN));
777     Tile::addSymbol(ViewId::KRAKEN_HEAD, symbol(u8"S", Color::GREEN));
778     Tile::addSymbol(ViewId::KRAKEN_WATER, symbol(u8"S", Color::DARK_GREEN));
779     Tile::addSymbol(ViewId::KRAKEN_LAND, symbol(u8"S", Color::DARK_GREEN));
780     Tile::addSymbol(ViewId::DEATH, symbol(u8"D", Color::DARK_GRAY));
781     Tile::addSymbol(ViewId::FIRE_SPHERE, symbol(u8"e", Color::RED));
782     Tile::addSymbol(ViewId::BEAR, symbol(u8"N", Color::BROWN));
783     Tile::addSymbol(ViewId::BAT, symbol(u8"b", Color::DARK_GRAY));
784     Tile::addSymbol(ViewId::GOBLIN, symbol(u8"o", Color::GREEN));
785     Tile::addSymbol(ViewId::RAT, symbol(u8"r", Color::BROWN));
786     Tile::addSymbol(ViewId::SPIDER, symbol(u8"s", Color::BROWN));
787     Tile::addSymbol(ViewId::ANT_WORKER, symbol(u8"a", Color::BROWN));
788     Tile::addSymbol(ViewId::ANT_SOLDIER, symbol(u8"a", Color::YELLOW));
789     Tile::addSymbol(ViewId::ANT_QUEEN, symbol(u8"a", Color::PURPLE));
790     Tile::addSymbol(ViewId::FLY, symbol(u8"b", Color::GRAY));
791     Tile::addSymbol(ViewId::SNAKE, symbol(u8"S", Color::YELLOW));
792     Tile::addSymbol(ViewId::VULTURE, symbol(u8"v", Color::DARK_GRAY));
793     Tile::addSymbol(ViewId::RAVEN, symbol(u8"v", Color::DARK_GRAY));
794     Tile::addSymbol(ViewId::BODY_PART, symbol(u8"%", Color::RED));
795     Tile::addSymbol(ViewId::BONE, symbol(u8"%", Color::WHITE));
796     Tile::addSymbol(ViewId::BUSH, symbol(u8"&", Color::DARK_GREEN));
797     Tile::addSymbol(ViewId::DECID_TREE, symbol(u8"��", Color::DARK_GREEN, true));
798     Tile::addSymbol(ViewId::CANIF_TREE, symbol(u8"♣", Color::DARK_GREEN, true));
799     Tile::addSymbol(ViewId::TREE_TRUNK, symbol(u8".", Color::BROWN));
800     Tile::addSymbol(ViewId::BURNT_TREE, symbol(u8".", Color::DARK_GRAY));
801     Tile::addSymbol(ViewId::WATER, symbol(u8"~", Color::LIGHT_BLUE));
802     Tile::addSymbol(ViewId::MAGMA, symbol(u8"~", Color::RED));
803     Tile::addSymbol(ViewId::DOOR, symbol(u8"|", Color::BROWN));
804     Tile::addSymbol(ViewId::LOCKED_DOOR, symbol(u8"|", Color::YELLOW));
805     Tile::addSymbol(ViewId::BARRICADE, symbol(u8"X", Color::BROWN));
806     Tile::addSymbol(ViewId::DIG_ICON, symbol(u8"⛏", Color::LIGHT_GRAY, true));
807     Tile::addSymbol(ViewId::STEEL_SWORD, symbol(u8")", Color::LIGHT_BLUE));
808     Tile::addSymbol(ViewId::SWORD, symbol(u8")", Color::LIGHT_GRAY));
809     Tile::addSymbol(ViewId::SPEAR, symbol(u8"/", Color::LIGHT_GRAY));
810     Tile::addSymbol(ViewId::SPECIAL_SWORD, symbol(u8")", Color::YELLOW));
811     Tile::addSymbol(ViewId::ELVEN_SWORD, symbol(u8")", Color::GRAY));
812     Tile::addSymbol(ViewId::KNIFE, symbol(u8")", Color::WHITE));
813     Tile::addSymbol(ViewId::WAR_HAMMER, symbol(u8")", Color::BLUE));
814     Tile::addSymbol(ViewId::SPECIAL_WAR_HAMMER, symbol(u8")", Color::LIGHT_BLUE));
815     Tile::addSymbol(ViewId::BATTLE_AXE, symbol(u8")", Color::GREEN));
816     Tile::addSymbol(ViewId::STEEL_BATTLE_AXE, symbol(u8")", Color::LIGHT_BLUE));
817     Tile::addSymbol(ViewId::SPECIAL_BATTLE_AXE, symbol(u8")", Color::LIGHT_GREEN));
818     Tile::addSymbol(ViewId::ELVEN_BOW, symbol(u8")", Color::YELLOW));
819     Tile::addSymbol(ViewId::BOW, symbol(u8")", Color::BROWN));
820     Tile::addSymbol(ViewId::WOODEN_STAFF, symbol(u8")", Color::YELLOW));
821     Tile::addSymbol(ViewId::IRON_STAFF, symbol(u8")", Color::ORANGE));
822     Tile::addSymbol(ViewId::CLUB, symbol(u8")", Color::BROWN));
823     Tile::addSymbol(ViewId::HEAVY_CLUB, symbol(u8")", Color::BROWN));
824     Tile::addSymbol(ViewId::ARROW, symbol(u8"/", Color::BROWN));
825     Tile::addSymbol(ViewId::FORCE_BOLT, symbol(u8"*", Color::LIGHT_BLUE));
826     Tile::addSymbol(ViewId::AIR_BLAST, symbol(u8"*", Color::WHITE));
827     Tile::addSymbol(ViewId::STUN_RAY, symbol(u8"*", Color::LIGHT_GREEN));
828     Tile::addSymbol(ViewId::SCROLL, symbol(u8"?", Color::WHITE));
829     Tile::addSymbol(ViewId::AMULET1, symbol(u8"\"", Color::YELLOW));
830     Tile::addSymbol(ViewId::AMULET2, symbol(u8"\"", Color::YELLOW));
831     Tile::addSymbol(ViewId::AMULET3, symbol(u8"\"", Color::YELLOW));
832     Tile::addSymbol(ViewId::AMULET4, symbol(u8"\"", Color::YELLOW));
833     Tile::addSymbol(ViewId::AMULET5, symbol(u8"\"", Color::YELLOW));
834     Tile::addSymbol(ViewId::FIRE_RESIST_RING, symbol(u8"=", Color::RED));
835     Tile::addSymbol(ViewId::POISON_RESIST_RING, symbol(u8"=", Color::GREEN));
836     Tile::addSymbol(ViewId::BOOK, symbol(u8"+", Color::YELLOW));
837     Tile::addSymbol(ViewId::FIRST_AID, symbol(u8"+", Color::RED));
838     Tile::addSymbol(ViewId::TRAP_ITEM, symbol(u8"+", Color::YELLOW));
839     Tile::addSymbol(ViewId::POTION1, symbol(u8"!", Color::LIGHT_RED));
840     Tile::addSymbol(ViewId::POTION2, symbol(u8"!", Color::BLUE));
841     Tile::addSymbol(ViewId::POTION3, symbol(u8"!", Color::YELLOW));
842     Tile::addSymbol(ViewId::POTION4, symbol(u8"!", Color::VIOLET));
843     Tile::addSymbol(ViewId::POTION5, symbol(u8"!", Color::DARK_BROWN));
844     Tile::addSymbol(ViewId::POTION6, symbol(u8"!", Color::LIGHT_GRAY));
845     Tile::addSymbol(ViewId::MUSHROOM1, symbol(u8"⋆", Color::PINK, true));
846     Tile::addSymbol(ViewId::MUSHROOM2, symbol(u8"⋆", Color::YELLOW, true));
847     Tile::addSymbol(ViewId::MUSHROOM3, symbol(u8"⋆", Color::PURPLE, true));
848     Tile::addSymbol(ViewId::MUSHROOM4, symbol(u8"⋆", Color::BROWN, true));
849     Tile::addSymbol(ViewId::MUSHROOM5, symbol(u8"⋆", Color::LIGHT_GRAY, true));
850     Tile::addSymbol(ViewId::MUSHROOM6, symbol(u8"⋆", Color::ORANGE, true));
851     Tile::addSymbol(ViewId::KEY, symbol(u8"*", Color::YELLOW));
852     Tile::addSymbol(ViewId::FOUNTAIN, symbol(u8"0", Color::LIGHT_BLUE));
853     Tile::addSymbol(ViewId::GOLD, symbol(u8"$", Color::YELLOW));
854     Tile::addSymbol(ViewId::TREASURE_CHEST, symbol(u8"=", Color::BROWN));
855     Tile::addSymbol(ViewId::OPENED_CHEST, symbol(u8"=", Color::BROWN));
856     Tile::addSymbol(ViewId::CHEST, symbol(u8"=", Color::BROWN));
857     Tile::addSymbol(ViewId::OPENED_COFFIN, symbol(u8"⚰", Color::DARK_GRAY, true));
858     Tile::addSymbol(ViewId::COFFIN, symbol(u8"⚰", Color::DARK_GRAY, true));
859     Tile::addSymbol(ViewId::BOULDER, symbol(u8"●", Color::LIGHT_GRAY, true));
860     Tile::addSymbol(ViewId::PORTAL, symbol(u8"��", Color::LIGHT_GREEN, true));
861     Tile::addSymbol(ViewId::GAS_TRAP, symbol(u8"☠", Color::GREEN, true));
862     Tile::addSymbol(ViewId::ALARM_TRAP, symbol(u8"^", Color::RED, true));
863     Tile::addSymbol(ViewId::WEB_TRAP, symbol(u8"#", Color::WHITE, true));
864     Tile::addSymbol(ViewId::SURPRISE_TRAP, symbol(u8"^", Color::BLUE, true));
865     Tile::addSymbol(ViewId::TERROR_TRAP, symbol(u8"^", Color::WHITE, true));
866     Tile::addSymbol(ViewId::ROCK, symbol(u8"✱", Color::LIGHT_GRAY, true));
867     Tile::addSymbol(ViewId::IRON_ROCK, symbol(u8"✱", Color::ORANGE, true));
868     Tile::addSymbol(ViewId::STEEL_INGOT, symbol(u8"✱", Color::LIGHT_BLUE, true));
869     Tile::addSymbol(ViewId::WOOD_PLANK, symbol(u8"\\", Color::BROWN));
870     Tile::addSymbol(ViewId::STORAGE_EQUIPMENT, symbol(u8".", Color::GREEN));
871     Tile::addSymbol(ViewId::STORAGE_RESOURCES, symbol(u8".", Color::BLUE));
872     Tile::addSymbol(ViewId::PRISON, symbol(u8".", Color::BLUE));
873     Tile::addSymbol(ViewId::DORM, symbol(u8".", Color::BROWN));
874     Tile::addSymbol(ViewId::BED, symbol(u8"=", Color::WHITE));
875     Tile::addSymbol(ViewId::TORCH, symbol(u8"*", Color::YELLOW));
876     Tile::addSymbol(ViewId::ALTAR, symbol(u8"Ω", Color::WHITE, true));
877     Tile::addSymbol(ViewId::CREATURE_ALTAR, symbol(u8"Ω", Color::YELLOW, true));
878     Tile::addSymbol(ViewId::TORTURE_TABLE, symbol(u8"=", Color::GRAY));
879     Tile::addSymbol(ViewId::IMPALED_HEAD, symbol(u8"⚲", Color::BROWN, true));
880     Tile::addSymbol(ViewId::WHIPPING_POST, symbol(u8"}", Color::BROWN, true));
881     Tile::addSymbol(ViewId::GALLOWS, symbol(u8"}", Color::ORANGE, true));
882     Tile::addSymbol(ViewId::NOTICE_BOARD, symbol(u8"|", Color::BROWN));
883     Tile::addSymbol(ViewId::SOKOBAN_HOLE, symbol(u8"0", Color::DARK_BLUE));
884     Tile::addSymbol(ViewId::TRAINING_WOOD, symbol(u8"‡", Color::BROWN, true));
885     Tile::addSymbol(ViewId::TRAINING_IRON, symbol(u8"‡", Color::LIGHT_GRAY, true));
886     Tile::addSymbol(ViewId::TRAINING_STEEL, symbol(u8"‡", Color::LIGHT_BLUE, true));
887     Tile::addSymbol(ViewId::ARCHERY_RANGE, symbol(u8"⌾", Color::LIGHT_BLUE, true));
888     Tile::addSymbol(ViewId::DEMON_SHRINE, symbol(u8"Ω", Color::PURPLE, true));
889     Tile::addSymbol(ViewId::BOOKCASE_WOOD, symbol(u8"▤", Color::BROWN, true));
890     Tile::addSymbol(ViewId::BOOKCASE_IRON, symbol(u8"▤", Color::LIGHT_GRAY, true));
891     Tile::addSymbol(ViewId::BOOKCASE_GOLD, symbol(u8"▤", Color::YELLOW, true));
892     Tile::addSymbol(ViewId::LABORATORY, symbol(u8"ω", Color::PURPLE, true));
893     Tile::addSymbol(ViewId::CAULDRON, symbol(u8"ω", Color::PURPLE, true));
894     Tile::addSymbol(ViewId::BEAST_LAIR, symbol(u8".", Color::YELLOW));
895     Tile::addSymbol(ViewId::BEAST_CAGE, symbol(u8"▥", Color::LIGHT_GRAY, true));
896     Tile::addSymbol(ViewId::WORKSHOP, symbol(u8"&", Color::LIGHT_BROWN));
897     Tile::addSymbol(ViewId::FORGE, symbol(u8"&", Color::LIGHT_BLUE));
898     Tile::addSymbol(ViewId::JEWELER, symbol(u8"&", Color::YELLOW));
899     Tile::addSymbol(ViewId::STEEL_FURNACE, symbol(u8"&", Color::PINK));
900     Tile::addSymbol(ViewId::CEMETERY, symbol(u8".", Color::DARK_BLUE));
901     Tile::addSymbol(ViewId::GRAVE, symbol(u8"☗", Color::GRAY, true));
902     Tile::addSymbol(ViewId::BORDER_GUARD, symbol(u8" ", Color::BLACK));
903     Tile::addSymbol(ViewId::ROBE, symbol(u8"[", Color::LIGHT_BROWN));
904     Tile::addSymbol(ViewId::LEATHER_GLOVES, symbol(u8"[", Color::BROWN));
905     Tile::addSymbol(ViewId::STRENGTH_GLOVES, symbol(u8"[", Color::RED));
906     Tile::addSymbol(ViewId::DEXTERITY_GLOVES, symbol(u8"[", Color::LIGHT_BLUE));
907     Tile::addSymbol(ViewId::LEATHER_ARMOR, symbol(u8"[", Color::BROWN));
908     Tile::addSymbol(ViewId::LEATHER_HELM, symbol(u8"[", Color::BROWN));
909     Tile::addSymbol(ViewId::TELEPATHY_HELM, symbol(u8"[", Color::LIGHT_GREEN));
910     Tile::addSymbol(ViewId::CHAIN_ARMOR, symbol(u8"[", Color::LIGHT_GRAY));
911     Tile::addSymbol(ViewId::STEEL_ARMOR, symbol(u8"[", Color::LIGHT_BLUE));
912     Tile::addSymbol(ViewId::IRON_HELM, symbol(u8"[", Color::LIGHT_GRAY));
913     Tile::addSymbol(ViewId::LEATHER_BOOTS, symbol(u8"[", Color::BROWN));
914     Tile::addSymbol(ViewId::IRON_BOOTS, symbol(u8"[", Color::LIGHT_GRAY));
915     Tile::addSymbol(ViewId::SPEED_BOOTS, symbol(u8"[", Color::LIGHT_BLUE));
916     Tile::addSymbol(ViewId::LEVITATION_BOOTS, symbol(u8"[", Color::LIGHT_GREEN));
917     Tile::addSymbol(ViewId::FALLEN_TREE, symbol(u8"*", Color::GREEN));
918     Tile::addSymbol(ViewId::GUARD_POST, symbol(u8"⚐", Color::YELLOW, true));
919     Tile::addSymbol(ViewId::DESTROY_BUTTON, symbol(u8"X", Color::RED));
920     Tile::addSymbol(ViewId::FORBID_ZONE, symbol(u8"#", Color::RED));
921     Tile::addSymbol(ViewId::MANA, symbol(u8"✱", Color::BLUE, true));
922     Tile::addSymbol(ViewId::EYEBALL, symbol(u8"e", Color::BLUE));
923     Tile::addSymbol(ViewId::FETCH_ICON, symbol(u8"��", Color::LIGHT_BROWN, true));
924     Tile::addSymbol(ViewId::FOG_OF_WAR, symbol(u8" ", Color::WHITE));
925     Tile::addSymbol(ViewId::CREATURE_HIGHLIGHT, symbol(u8" ", Color::WHITE));
926     Tile::addSymbol(ViewId::SQUARE_HIGHLIGHT, symbol(u8"⛶", Color::WHITE, true));
927     Tile::addSymbol(ViewId::ROUND_SHADOW, symbol(u8" ", Color::WHITE));
928     Tile::addSymbol(ViewId::CAMPAIGN_DEFEATED, symbol(u8"X", Color::RED));
929     Tile::addSymbol(ViewId::FOG_OF_WAR_CORNER, symbol(u8" ", Color::WHITE));
930     Tile::addSymbol(ViewId::ACCEPT_IMMIGRANT, symbol(u8"✓", Color::GREEN, true));
931     Tile::addSymbol(ViewId::REJECT_IMMIGRANT, symbol(u8"✘", Color::RED, true));
932     Tile::addSymbol(ViewId::SPECIAL_BLBN, symbol(u8"B", Color::PURPLE));
933     Tile::addSymbol(ViewId::SPECIAL_BLBW, symbol(u8"B", Color::LIGHT_RED));
934     Tile::addSymbol(ViewId::SPECIAL_BLGN, symbol(u8"B", Color::LIGHT_GRAY));
935     Tile::addSymbol(ViewId::SPECIAL_BLGW, symbol(u8"B", Color::WHITE));
936     Tile::addSymbol(ViewId::SPECIAL_BMBN, symbol(u8"B", Color::YELLOW));
937     Tile::addSymbol(ViewId::SPECIAL_BMBW, symbol(u8"B", Color::ORANGE));
938     Tile::addSymbol(ViewId::SPECIAL_BMGN, symbol(u8"B", Color::GREEN));
939     Tile::addSymbol(ViewId::SPECIAL_BMGW, symbol(u8"B", Color::LIGHT_GREEN));
940     Tile::addSymbol(ViewId::SPECIAL_HLBN, symbol(u8"H", Color::PURPLE));
941     Tile::addSymbol(ViewId::SPECIAL_HLBW, symbol(u8"H", Color::LIGHT_RED));
942     Tile::addSymbol(ViewId::SPECIAL_HLGN, symbol(u8"H", Color::LIGHT_GRAY));
943     Tile::addSymbol(ViewId::SPECIAL_HLGW, symbol(u8"H", Color::WHITE));
944     Tile::addSymbol(ViewId::SPECIAL_HMBN, symbol(u8"H", Color::YELLOW));
945     Tile::addSymbol(ViewId::SPECIAL_HMBW, symbol(u8"H", Color::ORANGE));
946     Tile::addSymbol(ViewId::SPECIAL_HMGN, symbol(u8"H", Color::GREEN));
947     Tile::addSymbol(ViewId::SPECIAL_HMGW, symbol(u8"H", Color::LIGHT_GREEN));
948     Tile::addSymbol(ViewId::TUTORIAL_ENTRANCE, symbol(u8" ", Color::LIGHT_GREEN));
949   }
950 
951   private:
952   Renderer& renderer;
953 };
954 
initialize(Renderer & renderer,bool useTiles)955 void Tile::initialize(Renderer& renderer, bool useTiles) {
956   TileCoordLookup lookup(renderer);
957   lookup.loadUnicode();
958   if (useTiles)
959     lookup.loadTiles();
960 }
961 
getTile(ViewId id,bool sprite)962 const Tile& Tile::getTile(ViewId id, bool sprite) {
963   if (sprite && tiles[id]) {
964     return *tiles[id];
965   }
966   else {
967     CHECK(symbols[id]);
968     return *symbols[id];
969   }
970 }
971 
getTile(ViewId id)972 const Tile& Tile::getTile(ViewId id) {
973   if (tiles[id])
974     return *tiles[id];
975   else {
976     CHECK(symbols[id]);
977     return *symbols[id];
978   }
979 }
980 
getColor(const ViewObject & object)981 Color Tile::getColor(const ViewObject& object) {
982   if (object.hasModifier(ViewObject::Modifier::INVISIBLE))
983     return Color::DARK_GRAY;
984   if (object.hasModifier(ViewObject::Modifier::HIDDEN))
985     return Color::LIGHT_GRAY;
986   Color color = symbols[object.id()]->color;
987   if (object.hasModifier(ViewObject::Modifier::PLANNED)) {
988     return Color(color.r / 2, color.g / 2, color.b / 2);
989   }
990   if (auto bleeding = object.getAttribute(ViewObject::Attribute::WOUNDED))
991     if (*bleeding > 0) {
992       *bleeding = 0.5 + *bleeding / 2;
993       *bleeding = min(1.0f, *bleeding);
994       return Color(
995           (1 - *bleeding) * color.r + *bleeding * 255,
996           (1 - *bleeding) * color.g,
997           (1 - *bleeding) * color.b);
998   }
999   return color;
1000 }
1001 
addCorner(DirSet corner,DirSet borders,TileCoord coord)1002 Tile Tile::addCorner(DirSet corner, DirSet borders, TileCoord coord) {
1003   anyCorners = true;
1004   for (DirSet dirs : Range(0, 255))
1005     if ((dirs & corner) == borders)
1006       corners[dirs].push_back(coord);
1007   return *this;
1008 }
1009 
hasAnyCorners() const1010 bool Tile::hasAnyCorners() const {
1011   return anyCorners;
1012 }
1013 
getCornerCoords(DirSet c) const1014 const vector<Tile::TileCoord>& Tile::getCornerCoords(DirSet c) const {
1015   return corners[c];
1016 }
1017 
1018