The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
translation.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Routines for terrain-conversion.
18  */
19 
20 #define GETTEXT_DOMAIN "wesnoth-lib"
21 
22 #include "global.hpp"
23 #include "gettext.hpp"
24 #include "log.hpp"
25 #include "terrain/translation.hpp"
27 #include "util.hpp"
28 #include "wml_exception.hpp"
29 
30 
31 #define ERR_G LOG_STREAM(err, lg::general())
32 #define WRN_G LOG_STREAM(warn, lg::general())
33 
34 namespace t_translation {
35 
36  size_t max_map_size() {
37  return 1000; //TODO make this overridable by the user without having to rebuild
38  }
39 
40 /***************************************************************************************/
41 // forward declaration of internal functions
42 
43  // The low level convertors,
44  // These function are the ones which know about the internal format.
45  // All other functions are unaware of the internal format.
46 
47  /**
48  * Get the mask for a single layer.
49  *
50  * @param terrain 1 layer of a terrain, might have a wildcard.
51  *
52  * @return Mask for that layer.
53  */
54  static t_layer get_layer_mask_(t_layer terrain); //inlined
55 
56  /**
57  * Gets a mask for a terrain, this mask is used for wildcard matching.
58  *
59  * @param terrain The terrain which might have a wildcard.
60  *
61  * @return The mask for this terrain.
62  */
63  static t_terrain get_mask_(const t_terrain& terrain);
64 
65  /**
66  * Converts a string to a layer.
67  *
68  * @param str The terrain string to convert, but needs to be
69  * sanitized so no spaces and only the terrain to convert.
70  *
71  * @return The converted layer.
72  */
73  static t_layer string_to_layer_(const char* begin, const char* end);
75  {
76  return string_to_layer_(str.c_str(), str.c_str() + str.size());
77  }
78 
79  /**
80  * Converts a terrain string to a number.
81  * @param str The terrain string with an optional number.
82  * @param start_position Returns the start_position, the caller should
83  * set it on -1 and it's only changed it there is
84  * a starting position found.
85  * @param filler If the terrain has only 1 layer then the filler
86  * will be used as the second layer.
87  *
88  * @return The terrain code found in the string if no
89  * valid terrain is found VOID will be returned.
90  */
91  static t_terrain string_to_number_(std::string str, std::string& start_position, const t_layer filler);
92  static t_terrain string_to_number_(const std::string& str, const t_layer filler = NO_LAYER);
93 
94  /**
95  * Converts a terrain number to a string
96  *
97  * @param terrain The terrain number to convert.
98  * @param start_position The starting position, if smaller than 0
99  * it's ignored else it's written.
100  *
101  * @return The converted string, if no starting
102  * position given it's padded to 4 chars else
103  * padded to 7 chars.
104  */
105  static std::string number_to_string_(t_terrain terrain, const std::string& start_position = "");
106 
107  /**
108  * Converts a terrain string to a number for the builder.
109  * The translation rules differ from the normal conversion rules
110  *
111  * @param str The terrain string.
112  *
113  * @return Number for the builder map.
114  */
115  static t_terrain string_to_builder_number_(std::string str);
116 
117 /***************************************************************************************/
118 
120 
123 
132 
138 
144 
145 const t_match ALL_FORESTS("F*,*^F*");
146 const t_match ALL_HILLS("!,*^V*,!,H*");
147 const t_match ALL_MOUNTAINS("!,*^V*,!,M*"); //excluding impassable mountains
148 const t_match ALL_SWAMPS("!,*^V*,*^B*,!,S*"); //excluding swamp villages and bridges
149 
150 /***************************************************************************************/
151 
153  base(string_to_layer_(b)), overlay(o)
154 {}
155 
158 {}
159 
161  terrain(),
162  mask(),
163  masked_terrain(),
164  has_wildcard(false),
165  is_empty(true)
166 {}
167 
168 t_match::t_match(const std::string& str, const t_layer filler) :
169  terrain(t_translation::read_list(str, filler)),
170  mask(),
171  masked_terrain(),
173  is_empty(terrain.empty())
174 
175 {
176  mask.resize(terrain.size());
177  masked_terrain.resize(terrain.size());
178 
179  for(size_t i = 0; i < terrain.size(); i++) {
181  masked_terrain[i] = mask[i] & terrain[i];
182  }
183 }
184 
186  terrain(t_list(1, tcode)),
187  mask(),
188  masked_terrain(),
190  is_empty(terrain.empty())
191 {
192  mask.resize(terrain.size());
193  masked_terrain.resize(terrain.size());
194 
195  for(size_t i = 0; i < terrain.size(); i++) {
197  masked_terrain[i] = mask[i] & terrain[i];
198  }
199 }
200 
202  : x(0)
203  , y(0)
204 {
205 }
206 
207 coordinate::coordinate(const int x_, const int y_)
208  : x(x_)
209  , y(y_)
210 {
211 }
212 
214 {
215  return string_to_number_(str, filler);
216 }
217 
219 {
220  return number_to_string_(tcode);
221 }
222 
223 t_list read_list(const std::string& str, const t_layer filler)
224 {
225  // Handle an empty string
226  t_list result;
227 
228  if(str.empty()) {
229  return result;
230  }
231 
232  size_t offset = 0;
233  while(offset < str.length()) {
234 
235  // Get a terrain chunk
236  const std::string separators = ",";
237  const size_t pos_separator = str.find_first_of(separators, offset);
238  const std::string terrain = str.substr(offset, pos_separator - offset);
239 
240  // Process the chunk
241  const t_terrain tile = string_to_number_(terrain, filler);
242 
243  // Add the resulting terrain number
244  result.push_back(tile);
245 
246  // Evaluate the separator
247  if(pos_separator == std::string::npos) {
248  offset = str.length();
249  } else {
250  offset = pos_separator + 1;
251  }
252  }
253 
254  return result;
255 }
256 
258 {
259  std::stringstream result;
260 
261  t_list::const_iterator itor = list.begin();
262  for( ; itor != list.end(); ++itor) {
263  if(itor == list.begin()) {
264  result << number_to_string_(*itor);
265  } else {
266  result << ", " << number_to_string_(*itor);
267  }
268  }
269 
270  return result.str();
271 }
272 
273 t_map read_game_map(const std::string& str, tstarting_positions& starting_positions, coordinate border_offset)
274 {
275  t_map result;
276 
277  size_t offset = 0;
278  size_t x = 0, y = 0, width = 0;
279 
280  // Skip the leading newlines
281  while(offset < str.length() && utils::isnewline(str[offset])) {
282  ++offset;
283  }
284 
285  // Did we get an empty map?
286  if((offset + 1) >= str.length()) {
287  return result;
288  }
289 
290  while(offset < str.length()) {
291 
292  // Get a terrain chunk
293  const std::string separators = ",\n\r";
294  const size_t pos_separator = str.find_first_of(separators, offset);
295  const std::string terrain = str.substr(offset, pos_separator - offset);
296 
297  // Process the chunk
298  std::string starting_position;
299  // The gamemap never has a wildcard
300  const t_terrain tile = string_to_number_(terrain, starting_position, NO_LAYER);
301 
302  // Add to the resulting starting position
303  if(!starting_position.empty()) {
304  if (starting_positions.left.find(starting_position) != starting_positions.left.end()) {
305  WRN_G << "Starting position " << starting_position << " is redefined." << std::endl;
306  }
307  starting_positions.insert(tstarting_positions::value_type(starting_position, coordinate(x - border_offset.x, y - border_offset.y)));
308  }
309 
310  // Make space for the new item
311  // NOTE we increase the vector every loop for every x and y.
312  // Profiling with an increase of y with 256 items didn't show
313  // an significant speed increase.
314  // So didn't rework the system to allocate larger vectors at once.
315  if(result.size() <= x) {
316  result.resize(x + 1);
317  }
318  if(result[x].size() <= y) {
319  result[x].resize(y + 1);
320  }
321 
322  // Add the resulting terrain number
323  result[x][y] = tile;
324 
325  // Evaluate the separator
326  if(pos_separator == std::string::npos || utils::isnewline(str[pos_separator])) {
327  // the first line we set the with the other lines we check the width
328  if(y == 0) {
329  // x contains the offset in the map
330  width = x + 1;
331  } else {
332  if((x + 1) != width ) {
333  ERR_G << "Map not a rectangle error occurred at line offset " << y << " position offset " << x << std::endl;
334  throw error("Map not a rectangle.");
335  }
336  if (y > max_map_size()) {
337  ERR_G << "Map size exceeds limit (y > " << max_map_size() << ")" << std::endl;
338  throw error("Map height limit exceeded.");
339  }
340  }
341 
342  // Prepare next iteration
343  ++y;
344  x = 0;
345 
346  // Avoid in infinite loop if the last line ends without an EOL
347  if(pos_separator == std::string::npos) {
348  offset = str.length();
349 
350  } else {
351 
352  offset = pos_separator + 1;
353  // Skip the following newlines
354  while(offset < str.length() && utils::isnewline(str[offset])) {
355  ++offset;
356  }
357  }
358 
359  } else {
360  ++x;
361  offset = pos_separator + 1;
362  if (x > max_map_size()) {
363  ERR_G << "Map size exceeds limit (x > " << max_map_size() << ")" << std::endl;
364  throw error("Map width limit exceeded.");
365  }
366  }
367 
368  }
369 
370  if(x != 0 && (x + 1) != width) {
371  ERR_G << "Map not a rectangle error occurred at the end" << std::endl;
372  throw error("Map not a rectangle.");
373  }
374 
375  return result;
376 }
377 
378 std::string write_game_map(const t_map& map, const tstarting_positions& starting_positions, coordinate border_offset)
379 {
380  std::stringstream str;
381 
382  for(size_t y = 0; y < map[0].size(); ++y) {
383  for(size_t x = 0; x < map.size(); ++x) {
384 
385  // If the current location is a starting position,
386  // it needs to be added to the terrain.
387  // After it's found it can't be found again,
388  // so the location is removed from the map.
389  auto itor = starting_positions.right.find(coordinate(x - border_offset.x, y - border_offset.y));
390  std::string starting_position;
391  if (itor != starting_positions.right.end()) {
392  starting_position = itor->second;
393  }
394  // Add the separator
395  if(x != 0) {
396  str << ", ";
397  }
398  str << number_to_string_(map[x][y], starting_position);
399  }
400 
401  if (y < map[0].size() -1)
402  str << "\n";
403  }
404 
405  return str.str();
406 }
407 
408 bool terrain_matches(const t_terrain& src, const t_terrain& dest)
409 {
410  return terrain_matches(src, t_list(1, dest));
411 }
412 
413 bool terrain_matches(const t_terrain& src, const t_list& dest)
414 {
415  // NOTE we impose some code duplication.
416  // It could have been rewritten to get a match structure
417  // and then call the version with the match structure.
418  // IMO that's some extra overhead to this function
419  // which is not required. Hence the two versions
420  if(dest.empty()) {
421  return false;
422  }
423 
424 #if 0
425  std::cerr << std::hex << "src = " << src.base << "^" << src.overlay << "\t"
426  << src_mask.base << "^" << src_mask.overlay << "\t"
427  << masked_src.base << "^" << masked_src.overlay << "\t"
428  << src_has_wildcard << "\n";
429 #endif
430 
431  bool result = true;
432  t_list::const_iterator itor = dest.begin();
433 
434  // Try to match the terrains if matched jump out of the loop.
435  for(; itor != dest.end(); ++itor) {
436 
437  // Match wildcard
438  if(*itor == STAR) {
439  return result;
440  }
441 
442  // Match inverse symbol
443  if(*itor == NOT) {
444  result = !result;
445  continue;
446  }
447 
448  // Full match
449  if(src == *itor) {
450  return result;
451  }
452 
453  // Does the destination wildcard match
454  const t_terrain dest_mask = get_mask_(*itor);
455  const t_terrain masked_dest = (*itor & dest_mask);
456  const bool dest_has_wildcard = has_wildcard(*itor);
457 #if 0
458  std::cerr << std::hex << "dest= "
459  << itor->base << "^" << itor->overlay << "\t"
460  << dest_mask.base << "^" << dest_mask.overlay << "\t"
461  << masked_dest.base << "^" << masked_dest.overlay << "\t"
462  << dest_has_wildcard << "\n";
463 #endif
464  if(dest_has_wildcard &&
465  (src.base & dest_mask.base) == masked_dest.base &&
466  (src.overlay & dest_mask.overlay) == masked_dest.overlay) {
467  return result;
468  }
469 
470 /* Test code */ /*
471  if(src_has_wildcard && dest_has_wildcard && (
472  (
473  get_layer_mask_(itor->base) != NO_LAYER &&
474  get_layer_mask_(src.overlay) != NO_LAYER &&
475  (src.base & dest_mask.base) == masked_dest.base &&
476  (itor->overlay & src_mask.overlay) == masked_src.overlay
477  ) || (
478  get_layer_mask_(itor->overlay) != NO_LAYER &&
479  get_layer_mask_(src.base) != NO_LAYER &&
480  (src.overlay & dest_mask.overlay) == masked_dest.overlay &&
481  (itor->base & src_mask.base) == masked_src.base
482  ))) {
483 
484  return result;
485  }
486 */
487  }
488 
489  // No match, return the inverse of the result
490  return !result;
491 }
492 
493 // This routine is used for the terrain building,
494 // so it's one of the delays while loading a map.
495 // This routine is optimized a bit at the loss of readability.
496 bool terrain_matches(const t_terrain& src, const t_match& dest)
497 {
498  if(dest.is_empty) {
499  return false;
500  }
501 
502  bool result = true;
503 
504  // Try to match the terrains if matched jump out of the loop.
505  // We loop on the dest.terrain since the iterator is faster than operator[].
506  // The i holds the value for operator[].
507  // Since dest.mask and dest.masked_terrain need to be in sync,
508  // they are less often looked up, so no iterator for them.
509  size_t i = 0;
510  t_list::const_iterator end = dest.terrain.end();
511  for(t_list::const_iterator terrain_itor = dest.terrain.begin();
512  terrain_itor != end;
513  ++i, ++terrain_itor) {
514 
515  // Match wildcard
516  if(*terrain_itor == STAR) {
517  return result;
518  }
519 
520  // Match inverse symbol
521  if(*terrain_itor == NOT) {
522  result = !result;
523  continue;
524  }
525 
526  // Full match
527  if(*terrain_itor == src) {
528  return result;
529  }
530 
531  // Does the destination wildcard match
532  if(dest.has_wildcard &&
533  (src.base & dest.mask[i].base) == dest.masked_terrain[i].base &&
534  (src.overlay & dest.mask[i].overlay) == dest.masked_terrain[i].overlay) {
535  return result;
536  }
537 
538 /* Test code */ /*
539  if(src_has_wildcard && has_wildcard(*terrain_itor) && (
540  (
541  get_layer_mask_(terrain_itor->base) != NO_LAYER &&
542  get_layer_mask_(src.overlay) != NO_LAYER &&
543  (src.base & dest.mask[i].base) == dest.masked_terrain[i].base &&
544  (terrain_itor->overlay & src_mask.overlay) == masked_src.overlay
545  ) || (
546  get_layer_mask_(terrain_itor->overlay) != NO_LAYER &&
547  get_layer_mask_(src.base) != NO_LAYER &&
548  (src.overlay & dest.mask[i].overlay) == dest.masked_terrain[i].overlay &&
549  (terrain_itor->base & src_mask.base) == masked_src.base
550  ))) {
551 
552  return result;
553  }
554 */
555  }
556 
557  // No match, return the inverse of the result
558  return !result;
559 }
560 
561 bool has_wildcard(const t_terrain& tcode)
562 {
563  if(tcode.overlay == NO_LAYER) {
564  return get_layer_mask_(tcode.base) != NO_LAYER;
565  } else {
566  return get_layer_mask_(tcode.base) != NO_LAYER || get_layer_mask_(tcode.overlay) != NO_LAYER;
567  }
568 }
569 
570 bool has_wildcard(const t_list& list)
571 {
572  if(list.empty()) {
573  return false;
574  }
575 
576  // Test all items for a wildcard
577  t_list::const_iterator itor = list.begin();
578  for(; itor != list.end(); ++itor) {
579  if(has_wildcard(*itor)) {
580  return true;
581  }
582  }
583 
584  // No wildcard found
585  return false;
586 }
587 
589 {
590  size_t offset = 0;
591  t_map result;
592 
593  // Skip the leading newlines
594  while(offset < str.length() && utils::isnewline(str[offset])) {
595  ++offset;
596  }
597 
598  // Did we get an empty map?
599  if((offset + 1) >= str.length()) {
600  return result;
601  }
602 
603  size_t x = 0, y = 0;
604  while(offset < str.length()) {
605 
606  // Get a terrain chunk
607  const std::string separators = ",\n\r";
608  const size_t pos_separator = str.find_first_of(separators, offset);
609 
610  std::string terrain = "";
611  // Make sure we didn't hit an empty chunk
612  // which is allowed
613  if(pos_separator != offset) {
614  terrain = str.substr(offset, pos_separator - offset);
615  }
616 
617  // Process the chunk
618  const t_terrain tile = string_to_builder_number_(terrain);
619 
620  // Make space for the new item
621  if(result.size() <= y) {
622  result.resize(y + 1);
623  }
624  if(result[y].size() <= x) {
625  result[y].resize(x + 1);
626  }
627 
628  // Add the resulting terrain number,
629  result[y][x] = tile;
630 
631  // evaluate the separator
632  if(pos_separator == std::string::npos) {
633  // Probably not required to change the value,
634  // but be sure the case should be handled at least.
635  // I'm not sure how it is defined in the standard,
636  // but here it's defined at max u32 which with +1 gives 0
637  // and make a nice infinite loop.
638  offset = str.length();
639  } else if(utils::isnewline(str[pos_separator])) {
640  // Prepare next iteration
641  ++y;
642  x = 0;
643 
644  offset = pos_separator + 1;
645  // Skip the following newlines
646  while(offset < str.length() && utils::isnewline(str[offset])) {
647  ++offset;
648  }
649 
650  } else {
651  ++x;
652  offset = pos_separator + 1;
653  }
654 
655  }
656 
657  return result;
658 }
659 
660 /***************************************************************************************/
661 // Internal
662 
664 {
665  // Test for the star 0x2A in every position
666  // and return the appropriate mask
667 /*
668  * This is what the code intents to do, but in order to gain some more
669  * speed it's changed to the code below, which does the same but faster.
670  * This routine is used often in the builder and the speedup is noticeable. */
671  if((terrain & 0xFF000000) == 0x2A000000) return 0x00000000;
672  if((terrain & 0x00FF0000) == 0x002A0000) return 0xFF000000;
673  if((terrain & 0x0000FF00) == 0x00002A00) return 0xFFFF0000;
674  if((terrain & 0x000000FF) == 0x0000002A) return 0xFFFFFF00;
675 
676 /*
677  Uint8 *ptr = (Uint8 *) &terrain;
678 
679  if(ptr[3] == 0x2A) return 0x00000000;
680  if(ptr[2] == 0x2A) return 0xFF000000;
681  if(ptr[1] == 0x2A) return 0xFFFF0000;
682  if(ptr[0] == 0x2A) return 0xFFFFFF00;
683 */
684  // no star found return the default
685  return 0xFFFFFFFF;
686 }
687 
689 {
690  if(terrain.overlay == NO_LAYER) {
691  return t_terrain(get_layer_mask_(terrain.base), 0xFFFFFFFF);
692  } else {
693  return t_terrain(get_layer_mask_(terrain.base), get_layer_mask_(terrain.overlay));
694  }
695 }
696 
697 static t_layer string_to_layer_(const char* begin, const char* end)
698 {
699  size_t size = end - begin;
700  if (begin == end) {
701  return NO_LAYER;
702  }
703  t_layer result = 0;
704 
705  // Validate the string
706  VALIDATE(size <= 4, _("A terrain with a string with more "
707  "than 4 characters has been found, the affected terrain is :") + std::string(begin, end));
708 
709  // The conversion to int puts the first char
710  // in the highest part of the number.
711  // This will make the wildcard matching
712  // later on a bit easier.
713  for(size_t i = 0; i < 4; ++i) {
714  const unsigned char c = (i < size) ? begin[i] : 0;
715 
716  // Clearing the lower area is a nop on i == 0
717  // so no need for if statement
718  result <<= 8;
719 
720  // Add the result
721  result += c;
722  }
723 
724  return result;
725 }
726 
727 static t_terrain string_to_number_(const std::string& str, const t_layer filler) {
728  std::string dummy;
729  return string_to_number_(str, dummy, filler);
730 }
731 
732 static t_terrain string_to_number_(std::string str, std::string& start_position, const t_layer filler)
733 {
734  const char* c_str = str.c_str();
735  size_t begin = 0;
736  size_t end = str.size();
738 
739  // Strip the spaces around us
740  const std::string& whitespace = " \t";
741  begin = str.find_first_not_of(whitespace);
742  end = str.find_last_not_of(whitespace) + 1;
743  if(begin == std::string::npos) {
744  return result;
745  }
746 
747  // Split if we have 1 space inside
748  size_t offset = str.find(' ', begin);
749  if(offset < end) {
750  try {
751  start_position = str.substr(begin, offset - begin);
752  } catch(bad_lexical_cast&) {
753  return VOID_TERRAIN;
754  }
755  begin = offset + 1;
756  }
757 
758  offset = str.find('^', 0);
759  if(offset != std::string::npos) {
760  const std::string base_str(str, 0, offset);
761  const std::string overlay_str(str, offset + 1, str.size());
762  result = t_terrain { string_to_layer_(c_str + begin, c_str + offset), string_to_layer_(c_str + offset + 1, c_str + end) };
763  } else {
764  result = t_terrain { string_to_layer_(c_str + begin, c_str + end), filler };
765 
766  // Ugly hack
767  if(filler == WILDCARD && (result.base == NOT.base ||
768  result.base == STAR.base)) {
769 
770  result.overlay = NO_LAYER;
771  }
772  }
773 
774  return result;
775 }
776 
778 {
779  std::string result = "";
780 
781  // Insert the start position
782  if(!start_position.empty()) {
783  result = start_position + " ";
784  }
785 
786  /*
787  * The initialization of tcode is done to make gcc-4.7 happy. Otherwise it
788  * some uninitialized fields might be used. Its analysis are wrong, but
789  * Initialize to keep it happy.
790  */
791  unsigned char tcode[9] = {0};
792  // Insert the terrain tcode
793  tcode[0] = ((terrain.base & 0xFF000000) >> 24);
794  tcode[1] = ((terrain.base & 0x00FF0000) >> 16);
795  tcode[2] = ((terrain.base & 0x0000FF00) >> 8);
796  tcode[3] = (terrain.base & 0x000000FF);
797 
798  if(terrain.overlay != NO_LAYER) {
799  tcode[4] = '^'; //the layer separator
800  tcode[5] = ((terrain.overlay & 0xFF000000) >> 24);
801  tcode[6] = ((terrain.overlay & 0x00FF0000) >> 16);
802  tcode[7] = ((terrain.overlay & 0x0000FF00) >> 8);
803  tcode[8] = (terrain.overlay & 0x000000FF);
804  } else {
805  // If no second layer, the second layer won't be written,
806  // so no need to initialize that part of the array
807  tcode[4] = 0;
808  }
809 
810  for(int i = 0; i < 9; ++i) {
811  if(tcode[i] != 0 && tcode[i] != 0xFF) {
812  result += tcode[i];
813  }
814  if(i == 4 && tcode[i] == 0) {
815  // no layer, stop
816  break;
817  }
818  }
819 
820  return result;
821 }
822 
824 {
825  // Strip the spaces around us
826  const std::string& whitespace = " \t";
827  str.erase(0, str.find_first_not_of(whitespace));
828  if(! str.empty()) {
829  str.erase(str.find_last_not_of(whitespace) + 1);
830  }
831 
832  // Empty string is allowed here, so handle it
833  if(str.empty()) {
834  return t_terrain();
835  }
836 
837  const int number = lexical_cast_default(str, -1);
838  if(number == -1) {
839  // At this point we have a single char
840  // which should be interpreted by the
841  // map builder, so return this number
842  return t_terrain(str[0] << 24, 0);
843  } else {
844  return t_terrain(0, number);
845  }
846 }
847 
848 } // end namespace t_translation
849 
850 #if 0
851 // small helper rule to test the matching rules
852 // building rule
853 // make terrain_translation.o && g++ terrain_translation.o libwesnoth-core.a -lSDL -o terrain_translation
854 int main(int argc, char** argv)
855 {
856  if(argc > 1) {
857 
858  if(std::string(argv[1]) == "match" && argc == 4) {
860 
862 
863  if(t_translation::terrain_matches(src, dest)) {
864  std::cout << "Match\n" ;
865  } else {
866  std::cout << "No match\n";
867  }
868  }
869  }
870 }
871 
872 #endif
873 
static t_terrain string_to_builder_number_(std::string str)
Converts a terrain string to a number for the builder.
#define ERR_G
Definition: translation.cpp:31
Contains an x and y coordinate used for starting positions in maps.
Definition: translation.hpp:97
tformula< unsigned > x_
The x coordinate of the rectangle.
Definition: canvas.cpp:682
const t_terrain STAR
boost::bimaps::bimap< boost::bimaps::set_of< std::string >, boost::bimaps::multiset_of< coordinate >> tstarting_positions
const t_terrain NOT
const t_terrain UNDERGROUND_VILLAGE
t_list read_list(const std::string &str, const t_layer filler)
Reads a list of terrains from a string, when reading the.
std::string write_game_map(const t_map &map, const tstarting_positions &starting_positions, coordinate border_offset)
Write a gamemap in to a vector string.
const GLfloat * c
Definition: glew.h:12741
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
size_t max_map_size()
Return the maximum allowed map size (in either dimension), the maximum map area is, therefore, this value squared.
Definition: translation.cpp:36
const t_terrain HILL
const t_layer WILDCARD
Definition: translation.hpp:37
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:29
const t_terrain MOUNTAIN
static t_layer get_layer_mask_(t_layer terrain)
Get the mask for a single layer.
static t_terrain string_to_number_(std::string str, std::string &start_position, const t_layer filler)
Converts a terrain string to a number.
const t_terrain MINUS
t_map read_game_map(const std::string &str, tstarting_positions &starting_positions, coordinate border_offset)
Reads a gamemap string into a 2D vector.
bool has_wildcard(const t_terrain &tcode)
Tests whether a terrain code contains a wildcard.
const t_terrain DEEP_WATER
const t_terrain FOGGED
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
GLenum src
Definition: glew.h:2392
const std::string number
template to number regex
const t_terrain OFF_MAP_USER
t_terrain read_terrain_code(const std::string &str, const t_layer filler)
Reads a single terrain from a string.
const t_terrain HUMAN_KEEP
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
GLintptr offset
Definition: glew.h:1650
std::vector< std::vector< t_terrain > > t_map
Definition: translation.hpp:76
const t_terrain BASE
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
const t_terrain GRASS_LAND
const t_match ALL_FORESTS
const t_terrain PLUS
GLuint GLuint end
Definition: glew.h:1221
GLuint64EXT * result
Definition: glew.h:10727
std::string write_list(const t_list &list)
Writes a list of terrains to a string, only writes the new format.
#define VALIDATE(cond, message)
The macro to use for the validation of WML.
const t_terrain FOREST
This structure can be used for matching terrain strings.
Definition: translation.hpp:83
const t_terrain DWARVEN_CASTLE
GLenum GLint GLuint mask
Definition: glew.h:1813
#define WRN_G
Definition: translation.cpp:32
static const ::config * terrain
The terrain used to create the cache.
Definition: minimap.cpp:135
Templates and utility-routines for strings and numbers.
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:47
const t_terrain HUMAN_CASTLE
const t_terrain CAVE
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
const t_match ALL_MOUNTAINS("!,*^V*,!,M*")
static t_terrain get_mask_(const t_terrain &terrain)
Gets a mask for a terrain, this mask is used for wildcard matching.
const t_terrain CAVE_WALL
static std::string number_to_string_(t_terrain terrain, const std::string &start_position="")
Converts a terrain number to a string.
size_t i
Definition: function.cpp:1057
bool terrain_matches(const t_terrain &src, const t_terrain &dest)
Tests whether a specific terrain matches an expression, for matching rules see above.
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
tformula< unsigned > y_
The y coordinate of the rectangle.
Definition: canvas.cpp:682
const t_terrain DWARVEN_KEEP
int main(int argc, char **argv)
bool isnewline(const char c)
std::string write_terrain_code(const t_terrain &tcode)
Writes a single terrain code to a string.
const t_layer NO_LAYER
Definition: translation.hpp:38
const t_terrain VOID_TERRAIN
GLsizeiptr size
Definition: glew.h:1649
To lexical_cast_default(From a, To def=To())
Definition: util.hpp:103
Standard logging facilities (interface).
const t_match ALL_SWAMPS("!,*^V*,*^B*,!,S*")
#define c
Definition: glew.h:12743
uint32_t t_layer
Definition: translation.hpp:36
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1220
const t_terrain SHALLOW_WATER
Thrown when a lexical_cast fails.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
static t_layer string_to_layer_(const char *begin, const char *end)
Converts a string to a layer.
t_map read_builder_map(const std::string &str)
Reads a builder map.
const t_match ALL_HILLS("!,*^V*,!,H*")
std::vector< t_terrain > t_list
Definition: translation.hpp:75