1 #pragma once
2 #ifndef CATA_SRC_MAPGENFORMAT_H
3 #define CATA_SRC_MAPGENFORMAT_H
4 
5 #include <cstddef>
6 #include <iosfwd>
7 #include <type_traits>
8 #include <vector>
9 
10 #include "type_id.h"
11 
12 class map;
13 struct point;
14 
15 namespace mapf
16 {
17 template<typename ID>
18 class format_effect;
19 
20 /**
21  * Set terrain and furniture on the supplied map.
22  * @param m The supplied map
23  * @param ter_b,furn_b The lookup table for placing terrain / furniture
24  *   (result of @ref ter_bind / @ref furn_bind).
25  * @param cstr Contains the ASCII representation of the map. Each character in it represents
26  *   one tile on the map. It will be looked up in \p ter_b and \p furn_b to get the terrain/
27  *   furniture to place there (if that lookup returns a null id, nothing is set on the map).
28  *   A newline character continues on the next line (resets `x` to \p startx and increments `y`).
29  * @param start Coordinates in the map where to start drawing \p cstr.
30  */
31 void formatted_set_simple( map *m, const point &start, const char *cstr,
32                            const format_effect<ter_id> &ter_b, const format_effect<furn_id> &furn_b );
33 
34 template<typename ID>
35 class format_effect
36 {
37     private:
38         std::string characters;
39         std::vector<ID> determiners;
40 
41     public:
42         format_effect( const std::string &chars,
43                        std::vector<ID> dets );
44 
45         ID translate( char c ) const;
46 };
47 
48 /**
49  * The functions create a mapping of characters to ids, usable with @ref formatted_set_simple.
50  * The first parameter must a string literal, containing the mapped characters.
51  * Only every second character of it is mapped:
52  * `"a b c"` maps `a` to the first id, `b` to the second and `c` to the third id.
53  * The further parameters form an array of suitable size with ids to map to.
54  *
55  * \code
56  * ter_bind( "a", t_dirt );
57  * ter_bind( "a b", t_dirt, t_wall );
58  * // This does not work (t_wall is not mapped to any character):
59  * ter_bind( "a", t_dirt, t_wall );
60  * // This does not work (character b is not mapped to any id):
61  * ter_bind( "a b", t_dirt );
62  * \endcode
63  */
64 /**@{*/
65 template<size_t N, typename ...Args>
ter_bind(const char (& characters)[N],Args...ids)66 inline format_effect<ter_id> ter_bind( const char ( &characters )[N], Args... ids )
67 {
68     // Note to self: N contains the 0-char at the end of a string literal!
69     static_assert( N % 2 == 0, "list of characters to bind to must be odd, e.g. \"a b c\"" );
70     static_assert( N / 2 == sizeof...( Args ),
71                    "list of characters to bind to must match the size of the remaining arguments" );
72     return format_effect<ter_id>( characters, { std::forward<Args>( ids )... } );
73 }
74 
75 template<size_t N, typename ...Args>
furn_bind(const char (& characters)[N],Args...ids)76 inline format_effect<furn_id> furn_bind( const char ( &characters )[N], Args... ids )
77 {
78     // Note to self: N contains the 0-char at the end of a string literal!
79     static_assert( N % 2 == 0, "list of characters to bind to must be odd, e.g. \"a b c\"" );
80     static_assert( N / 2 == sizeof...( Args ),
81                    "list of characters to bind to must match the size of the remaining arguments" );
82     return format_effect<furn_id>( characters, { std::forward<Args>( ids )... } );
83 }
84 /**@}*/
85 
86 } //END NAMESPACE mapf
87 
88 #endif // CATA_SRC_MAPGENFORMAT_H
89