The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
map_context.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2017 by Tomasz Sniatowski <kailoran@gmail.com>
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 #define GETTEXT_DOMAIN "wesnoth-editor"
15 
17 
18 #include "display.hpp"
19 #include "editor/action/action.hpp"
20 #include "filesystem.hpp"
21 #include "formula/string_utils.hpp"
22 #include "game_board.hpp"
23 #include "gettext.hpp"
24 #include "map/exception.hpp"
25 #include "map/label.hpp"
26 #include "preferences/editor.hpp"
28 #include "serialization/parser.hpp"
29 #include "team.hpp"
30 #include "terrain/type_data.hpp"
31 #include "units/unit.hpp"
32 #include "wml_exception.hpp"
33 
34 #include <boost/regex.hpp>
35 
36 namespace editor
37 {
39  : side(t.side())
40  , id(t.team_name())
41  , name(t.user_team_name())
42  , gold(t.gold())
43  , income(t.base_income())
46  , fog(t.uses_fog())
47  , shroud(t.uses_shroud())
48  , share_vision(t.share_vision())
49  , controller(t.controller())
50  , no_leader(t.no_leader())
51  , hidden(t.hidden())
52 {
53 }
54 
55 const size_t map_context::max_action_stack_size_ = 100;
56 
57 map_context::map_context(const editor_map& map, bool pure_map, const config& schedule)
58  : filename_()
59  , map_data_key_()
60  , embedded_(false)
61  , pure_map_(pure_map)
62  , map_(map)
63  , undo_stack_()
64  , redo_stack_()
65  , actions_since_save_(0)
66  , starting_position_label_locs_()
67  , needs_reload_(false)
68  , needs_terrain_rebuild_(false)
69  , needs_labels_reset_(false)
70  , changed_locations_()
71  , everything_changed_(false)
72  , scenario_id_()
73  , scenario_name_()
74  , scenario_description_()
75  , xp_mod_(70)
76  , victory_defeated_(true)
77  , random_time_(false)
78  , active_area_(-1)
79  , labels_(nullptr)
80  , units_()
81  , teams_()
82  , tod_manager_(new tod_manager(schedule))
83  , mp_settings_()
84  , game_classification_()
85  , music_tracks_()
86 {
87 }
88 
90  : filename_(filename)
91  , map_data_key_()
92  , embedded_(false)
93  , pure_map_(false)
94  , map_(game_config)
95  , undo_stack_()
96  , redo_stack_()
97  , actions_since_save_(0)
98  , starting_position_label_locs_()
99  , needs_reload_(false)
100  , needs_terrain_rebuild_(false)
101  , needs_labels_reset_(false)
102  , changed_locations_()
103  , everything_changed_(false)
104  , scenario_id_()
105  , scenario_name_()
106  , scenario_description_()
107  , xp_mod_(70)
108  , victory_defeated_(true)
109  , random_time_(false)
110  , active_area_(-1)
111  , labels_(nullptr)
112  , units_()
113  , teams_()
114  , tod_manager_(new tod_manager(game_config.find_child("editor_times", "id", "default")))
115  , mp_settings_()
116  , game_classification_()
117  , music_tracks_()
118 {
119  /*
120  * Overview of situations possibly found in the file:
121  *
122  * 0. Not a scenario or map file.
123  * 0.1 File not found
124  * 0.2 Map file empty
125  * 0.3 No valid data
126  * 1. It's a file containing only pure map data.
127  * * embedded_ = false
128  * * pure_map_ = true
129  * 2. A scenario embedding the map
130  * * embedded_ = true
131  * * pure_map_ = true
132  * The data/scenario-test.cfg for example.
133  * The map is written back to the file.
134  * 3. The map file is referenced by map_data={MACRO_ARGUEMENT}.
135  * * embedded_ = false
136  * * pure_map_ = true
137  * 4. The file contains an editor generated scenario file.
138  * * embedded_ = false
139  * * pure_map_ = false
140  */
141 
142  log_scope2(log_editor, "Loading file " + filename);
143 
144  // 0.1 File not found
145  if(!filesystem::file_exists(filename) || filesystem::is_directory(filename)) {
146  throw editor_map_load_exception(filename, _("File not found"));
147  }
148 
149  std::string file_string = filesystem::read_file(filename);
150 
151  // 0.2 Map file empty
152  if(file_string.empty()) {
153  std::string message = _("Empty file");
154  throw editor_map_load_exception(filename, message);
155  }
156 
157  // 1.0 Pure map data
158  boost::regex rexpression_map_data(R"""(map_data\s*=\s*"(.+?)")""");
159  boost::smatch matched_map_data;
160 
161  if(!boost::regex_search(
162  file_string, matched_map_data, rexpression_map_data, boost::regex_constants::match_not_dot_null)
163  ) {
164  map_ = editor_map::from_string(game_config, file_string); // throws on error
165  pure_map_ = true;
166 
168  return;
169  }
170 
171  // 2.0 Embedded map
172  const std::string& map_data = matched_map_data[1];
173 
174  boost::regex rexpression_macro(R"""(\{(.+?)\})""");
175  boost::smatch matched_macro;
176 
177  if(!boost::regex_search(map_data, matched_macro, rexpression_macro)) {
178  // We have a map_data string but no macro ---> embedded or scenario
179 
180  boost::regex rexpression_scenario(R"""(\[(scenario|test|multiplayer|tutorial)\])""");
181  if(!boost::regex_search(file_string, rexpression_scenario)) {
182  LOG_ED << "Loading generated scenario file" << std::endl;
183  // 4.0 editor generated scenario
184  try {
185  load_scenario(game_config);
186  } catch(config::error& e) {
187  // We already caught and rethrew this exception in load_scenario
188  throw editor_map_load_exception("load_scenario", e.message);
189  }
190  } else {
191  LOG_ED << "Loading embedded map file" << std::endl;
192  embedded_ = true;
193  pure_map_ = true;
194  map_ = editor_map::from_string(game_config, map_data);
195  }
196 
198  return;
199  }
200 
201  // 3.0 Macro referenced pure map
202  const std::string& macro_argument = matched_macro[1];
203  LOG_ED << "Map looks like a scenario, trying {" << macro_argument << "}" << std::endl;
204 
205  std::string new_filename = filesystem::get_wml_location(macro_argument,
207 
208  if(new_filename.empty()) {
209  std::string message = _("The map file looks like a scenario, "
210  "but the map_data value does not point to an existing file")
211  + std::string("\n") + macro_argument;
212  throw editor_map_load_exception(filename, message);
213  }
214 
215  LOG_ED << "New filename is: " << new_filename << std::endl;
216 
217  filename_ = new_filename;
218  file_string = filesystem::read_file(filename_);
219  map_ = editor_map::from_string(game_config, file_string);
220  pure_map_ = true;
221 
223 }
224 
226 {
227  undo_stack_.clear();
228  redo_stack_.clear();
229 }
230 
232 {
233  teams_.emplace_back();
234 
235  config cfg;
236  cfg["side"] = teams_.size(); // side is 1-indexed, so we can just use size()
237  cfg["hidden"] = false;
238 
239  // TODO: build might be slight overkill here just to set the side...
240  teams_.back().build(cfg, get_map());
241 
243 }
244 
246 {
247  assert(teams_.size() >= static_cast<unsigned int>(info.side));
248 
249  team& t = teams_[info.side - 1];
250  // t.set_save_id(id);
251  // t.set_name(name);
252  t.change_team(info.id, info.name);
253  t.have_leader(!info.no_leader);
255  t.set_gold(info.gold);
256  t.set_base_income(info.income);
257  t.set_hidden(info.hidden);
258  t.set_fog(info.fog);
259  t.set_shroud(info.shroud);
263 
265 }
266 
268  const std::string& name,
269  const std::string& description,
270  int turns,
271  int xp_mod,
272  bool victory_defeated,
273  bool random_time)
274 {
275  scenario_id_ = id;
277  scenario_description_ = description;
278  random_time_ = random_time;
280  tod_manager_->set_number_of_turns(turns);
281  xp_mod_ = xp_mod;
283 }
284 
286 {
287  tod_manager_->set_current_time(time);
288  if(!pure_map_) {
290  }
291 }
292 
294 {
295  tod_manager_->remove_time_area(index);
296  active_area_--;
298 }
299 
300 void map_context::replace_schedule(const std::vector<time_of_day>& schedule)
301 {
302  tod_manager_->replace_schedule(schedule);
303  if(!pure_map_) {
305  }
306 }
307 
308 void map_context::replace_local_schedule(const std::vector<time_of_day>& schedule)
309 {
310  tod_manager_->replace_local_schedule(schedule, active_area_);
311  if(!pure_map_) {
313  }
314 }
315 
317 {
318  config scenario;
319 
320  try {
321  read(scenario, *(preprocess_file(filename_)));
322  } catch(config::error& e) {
323  LOG_ED << "Caught a config error while parsing file: '" << filename_ << "'\n" << e.message << std::endl;
324  throw e;
325  }
326 
327  scenario_id_ = scenario["id"].str();
328  scenario_name_ = scenario["name"].str();
329  scenario_description_ = scenario["description"].str();
330 
331  xp_mod_ = scenario["experience_modifier"].to_int();
332 
333  victory_defeated_ = scenario["victory_when_enemies_defeated"].to_bool(true);
334  random_time_ = scenario["random_start_time"].to_bool(false);
335 
336  map_ = editor_map::from_string(game_config, scenario["map_data"]); // throws on error
337 
338  labels_.read(scenario);
339 
340  tod_manager_.reset(new tod_manager(scenario));
341  for(const config& time_area : scenario.child_range("time_area")) {
342  tod_manager_->add_time_area(map_, time_area);
343  }
344 
345  for(const config& item : scenario.child_range("item")) {
346  const map_location loc(item);
347  overlays_.emplace(loc, overlay(item));
348  }
349 
350  for(const config& music : scenario.child_range("music")) {
351  music_tracks_.emplace(music["name"], sound::music_track(music));
352  }
353 
354  int i = 1;
355  for(config& side : scenario.child_range("side")) {
356  teams_.emplace_back();
357 
358  side["side"] = i;
359  teams_.back().build(side, map_);
360 
361  for(config& a_unit : side.child_range("unit")) {
362  map_location loc(a_unit, nullptr);
363  a_unit["side"] = i;
364 
365  units_.add(loc, unit(a_unit, true));
366  }
367 
368  ++i;
369  }
370 }
371 
373 {
374  return map_.set_selection(tod_manager_->get_area_by_index(index));
375 }
376 
377 void map_context::draw_terrain(const t_translation::terrain_code& terrain, const map_location& loc, bool one_layer_only)
378 {
379  t_translation::terrain_code full_terrain = one_layer_only
380  ? terrain
382 
383  draw_terrain_actual(full_terrain, loc, one_layer_only);
384 }
385 
387  const t_translation::terrain_code& terrain, const map_location& loc, bool one_layer_only)
388 {
389  if(!map_.on_board_with_border(loc)) {
390  // requests for painting off the map are ignored in set_terrain anyway,
391  // but ideally we should not have any
392  LOG_ED << "Attempted to draw terrain off the map (" << loc << ")\n";
393  return;
394  }
395 
396  t_translation::terrain_code old_terrain = map_.get_terrain(loc);
397 
398  if(terrain != old_terrain) {
399  if(terrain.base == t_translation::NO_LAYER) {
401  } else if(one_layer_only) {
403  } else {
404  map_.set_terrain(loc, terrain);
405  }
406 
408  }
409 }
410 
412  const t_translation::terrain_code& terrain, const std::set<map_location>& locs, bool one_layer_only)
413 {
414  t_translation::terrain_code full_terrain = one_layer_only
415  ? terrain
417 
418  for(const map_location& loc : locs) {
419  draw_terrain_actual(full_terrain, loc, one_layer_only);
420  }
421 }
422 
424 {
425  everything_changed_ = false;
426  changed_locations_.clear();
427 }
428 
430 {
431  if(!everything_changed()) {
432  changed_locations_.insert(loc);
433  }
434 }
435 
436 void map_context::add_changed_location(const std::set<map_location>& locs)
437 {
438  if(!everything_changed()) {
439  changed_locations_.insert(locs.begin(), locs.end());
440  }
441 }
442 
444 {
445  everything_changed_ = true;
446 }
447 
449 {
450  return everything_changed_;
451 }
452 
454 {
455  disp.labels().clear_all();
457 }
458 
460 {
461  std::set<map_location> new_label_locs = map_.set_starting_position_labels(disp);
462  starting_position_label_locs_.insert(new_label_locs.begin(), new_label_locs.end());
463 }
464 
466 {
469  set_needs_labels_reset(false);
470 }
471 
473 {
474  config scenario;
475 
476  scenario["id"] = scenario_id_;
477  scenario["name"] = t_string(scenario_name_);
478  scenario["description"] = scenario_description_;
479 
480  scenario["experience_modifier"] = xp_mod_;
481  scenario["victory_when_enemies_defeated"] = victory_defeated_;
482  scenario["random_starting_time"] = random_time_;
483 
484  scenario.append(tod_manager_->to_config());
485  scenario.remove_attribute("turn_at");
486 
487  scenario["map_data"] = map_.write();
488 
489  labels_.write(scenario);
490 
491  overlay_map::const_iterator it;
492  for(it = overlays_.begin(); it != overlays_.end(); ++it) {
493  config& item = scenario.add_child("item");
494 
495  it->first.write(item);
496 
497  item["image"] = it->second.image;
498  item["id"] = it->second.id;
499  item["halo"] = it->second.halo;
500  item["visible_in_fog"] = it->second.visible_in_fog;
501  item["name"] = it->second.name;
502  item["team_name"] = it->second.team_name;
503  }
504 
505  for(const music_map::value_type& track : music_tracks_) {
506  track.second.write(scenario, true);
507  }
508 
509  for(std::vector<team>::const_iterator t = teams_.begin(); t != teams_.end(); ++t) {
510  int side_num = t - teams_.begin() + 1;
511 
512  config& side = scenario.add_child("side");
513 
514  side["side"] = side_num;
515  side["hidden"] = t->hidden();
516 
517  side["controller"] = t->controller();
518  side["no_leader"] = t->no_leader();
519 
520  side["team_name"] = t->team_name();
521  side["user_team_name"] = t->user_team_name();
522 
523  // TODO
524  // side["allow_player"] = "yes";
525 
526  side["fog"] = t->uses_fog();
527  side["shroud"] = t->uses_shroud();
528  side["share_vision"] = t->share_vision();
529 
530  side["gold"] = t->gold();
531  side["income"] = t->base_income();
532 
533  for(const map_location& village : t->villages()) {
534  village.write(side.add_child("village"));
535  }
536 
537  // current visible units
538  for(unit_map::const_iterator i = units_.begin(); i != units_.end(); ++i) {
539  if(i->side() == side_num) {
540  config& u = side.add_child("unit");
541 
542  i->get_location().write(u);
543 
544  u["type"] = i->type_id();
545  u["name"] = i->name();
546  u["facing"] = map_location::write_direction(i->facing());
547 
548  if(!boost::regex_match(i->id(), boost::regex(".*-[0-9]+"))) {
549  u["id"] = i->id();
550  }
551 
552  if(i->can_recruit()) {
553  u["canrecruit"] = i->can_recruit();
554  }
555 
556  if(i->unrenamable()) {
557  u["unrenamable"] = i->unrenamable();
558  }
559 
560  if(!i->recruits().empty()) {
561  u["extra_recruit"] = utils::join(i->recruits());
562  }
563  }
564  }
565  }
566 
567  return scenario;
568 }
569 
571 {
572  assert(!is_embedded());
573 
574  if(scenario_id_.empty()) {
576  }
577 
578  if(scenario_name_.empty()) {
580  }
581 
582  try {
583  std::stringstream wml_stream;
584  {
585  config_writer out(wml_stream, false);
586  out.write(to_config());
587  }
588 
589  if(!wml_stream.str().empty()) {
590  filesystem::write_file(get_filename(), wml_stream.str());
591  }
592 
593  clear_modified();
594  } catch(filesystem::io_exception& e) {
595  utils::string_map symbols;
596  symbols["msg"] = e.what();
597  const std::string msg = vgettext("Could not save the scenario: $msg", symbols);
598 
599  throw editor_map_save_exception(msg);
600  }
601 
602  // TODO the return value of this method does not need to be boolean.
603  // We either return true or there is an exception thrown.
604  return true;
605 }
606 
608 {
609  std::string map_data = map_.write();
610 
611  try {
612  if(!is_embedded()) {
614  } else {
616 
617  boost::regex rexpression_map_data(R"""((.*map_data\s*=\s*")(.+?)(".*))""");
618  boost::smatch matched_map_data;
619 
620  if(boost::regex_search(map_string, matched_map_data, rexpression_map_data,
621  boost::regex_constants::match_not_dot_null)) {
622  std::stringstream ss;
623  ss << matched_map_data[1];
624  ss << map_data;
625  ss << matched_map_data[3];
626 
628  } else {
629  throw editor_map_save_exception(_("Could not save into scenario"));
630  }
631  }
632 
634 
635  clear_modified();
636  } catch(filesystem::io_exception& e) {
637  utils::string_map symbols;
638  symbols["msg"] = e.what();
639  const std::string msg = vgettext("Could not save the map: $msg", symbols);
640 
641  throw editor_map_save_exception(msg);
642  }
643 
644  // TODO the return value of this method does not need to be boolean.
645  // We either return true or there is an exception thrown.
646  return true;
647 }
648 
650 {
651  if(map_.h() != map.h() || map_.w() != map.w()) {
653  } else {
655  }
656 
657  map_ = map;
658 }
659 
661 {
662  LOG_ED << "Performing action " << action.get_id() << ": " << action.get_name() << ", actions count is "
663  << action.get_instance_count() << std::endl;
664  editor_action* undo = action.perform(*this);
665  if(actions_since_save_ < 0) {
666  // set to a value that will make it impossible to get to zero, as at this point
667  // it is no longer possible to get back the original map state using undo/redo
668  actions_since_save_ = 1 + undo_stack_.size();
669  }
670 
672 
673  undo_stack_.emplace_back(undo);
674 
676 
677  redo_stack_.clear();
678 }
679 
681 {
682  LOG_ED << "Performing (partial) action " << action.get_id() << ": " << action.get_name() << ", actions count is "
683  << action.get_instance_count() << std::endl;
684  if(!can_undo()) {
685  throw editor_logic_exception("Empty undo stack in perform_partial_action()");
686  }
687 
688  editor_action_chain* undo_chain = dynamic_cast<editor_action_chain*>(last_undo_action());
689  if(undo_chain == nullptr) {
690  throw editor_logic_exception("Last undo action not a chain in perform_partial_action()");
691  }
692 
693  editor_action* undo = action.perform(*this);
694 
695  // actions_since_save_ += action.action_count();
696  undo_chain->prepend_action(undo);
697 
698  redo_stack_.clear();
699 }
700 
702 {
703  return actions_since_save_ != 0;
704 }
705 
707 {
709 }
710 
712 {
714 }
715 
717 {
718  return !undo_stack_.empty();
719 }
720 
722 {
723  return !redo_stack_.empty();
724 }
725 
727 {
728  return undo_stack_.empty() ? nullptr : undo_stack_.back().get();
729 }
730 
732 {
733  return redo_stack_.empty() ? nullptr : redo_stack_.back().get();
734 }
735 
737 {
738  return undo_stack_.empty() ? nullptr : undo_stack_.back().get();
739 }
740 
742 {
743  return redo_stack_.empty() ? nullptr : redo_stack_.back().get();
744 }
745 
747 {
748  LOG_ED << "undo() beg, undo stack is " << undo_stack_.size() << ", redo stack " << redo_stack_.size() << std::endl;
749 
750  if(can_undo()) {
753  } else {
754  WRN_ED << "undo() called with an empty undo stack" << std::endl;
755  }
756 
757  LOG_ED << "undo() end, undo stack is " << undo_stack_.size() << ", redo stack " << redo_stack_.size() << std::endl;
758 }
759 
761 {
762  LOG_ED << "redo() beg, undo stack is " << undo_stack_.size() << ", redo stack " << redo_stack_.size() << std::endl;
763 
764  if(can_redo()) {
767  } else {
768  WRN_ED << "redo() called with an empty redo stack" << std::endl;
769  }
770 
771  LOG_ED << "redo() end, undo stack is " << undo_stack_.size() << ", redo stack " << redo_stack_.size() << std::endl;
772 }
773 
775 {
776  // callers should check for these conditions
777  if(!can_undo()) {
778  throw editor_logic_exception("Empty undo stack in partial_undo()");
779  }
780 
781  editor_action_chain* undo_chain = dynamic_cast<editor_action_chain*>(last_undo_action());
782  if(undo_chain == nullptr) {
783  throw editor_logic_exception("Last undo action not a chain in partial undo");
784  }
785 
786  // a partial undo performs the first action form the current action's action_chain that would be normally performed
787  // i.e. the *first* one.
788  const editor_action_ptr first_action_in_chain(undo_chain->pop_first_action());
789  if(undo_chain->empty()) {
791  undo_stack_.pop_back();
792  }
793 
794  redo_stack_.emplace_back(first_action_in_chain->perform(*this));
795  // actions_since_save_ -= last_redo_action()->action_count();
796 }
797 
799 {
800  undo_stack_.clear();
801  redo_stack_.clear();
802 }
803 
805 {
806  if(stack.size() > max_action_stack_size_) {
807  stack.pop_front();
808  }
809 }
810 
812 {
813  assert(!from.empty());
814 
815  editor_action_ptr action(nullptr);
816  action.swap(from.back());
817 
818  from.pop_back();
819 
820  editor_action* reverse_action = action->perform(*this);
821  to.emplace_back(reverse_action);
822 
823  trim_stack(to);
824 }
825 
827 {
828  return is_pure_map() ? _("New Map") : _("New Scenario");
829 }
830 
831 } // end namespace editor
void add_changed_location(const map_location &loc)
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:374
void set_side_setup(editor_team_info &info)
TODO.
int actions_since_save_
Number of actions performed since the map was saved.
action_stack undo_stack_
The undo stack.
bool victory_defeated() const
editor_action * last_redo_action()
void undo()
Un-does the last action, and puts it in the redo stack for a possible redo.
virtual const gamemap & map() const
editor_map map_
The map object of this map_context.
::tod_manager * tod_manager
Definition: resources.cpp:30
void set_shroud(bool shroud)
Definition: team.hpp:320
unit_iterator end()
Definition: map.hpp:415
const char * what() const NOEXCEPT
Definition: exceptions.hpp:37
std::vector< char_t > string
std::set< map_location > starting_position_label_locs_
Cache of set starting position labels.
size_t index(const utf8::string &str, const size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
void write(const config &cfg)
std::map< std::string, t_string > string_map
void write(config &res) const
Definition: label.cpp:79
int village_support
Definition: game_config.cpp:72
This class represents a single unit of a specific type.
Definition: unit.hpp:101
std::unique_ptr< editor_action > editor_action_ptr
Action pointer typedef.
void append(const config &cfg)
Append data from another config object to this one.
Definition: config.cpp:250
void perform_action_between_stacks(action_stack &from, action_stack &to)
Perform an action at the back of one stack, and then move it to the back of the other stack...
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
team::SHARE_VISION share_vision
Definition: map_context.hpp:42
std::set< map_location > set_starting_position_labels(display &disp)
Set labels for staring positions in the given display object.
Definition: editor_map.cpp:139
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
void new_side()
Adds a new side to the map.
bool save_scenario()
Saves the scenario under the current filename.
logger & info()
Definition: log.cpp:91
virtual ~map_context()
Map context destructor.
child_itors child_range(config_key_type key)
Definition: config.cpp:295
bool modified() const
#define LOG_ED
void draw_terrain(const t_translation::terrain_code &terrain, const map_location &loc, bool one_layer_only=false)
Draw a terrain on a single location on the map.
virtual const std::string & get_name() const
Definition: action_base.hpp:74
unit_iterator begin()
Definition: map.hpp:405
bool everything_changed() const
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:55
static int get_instance_count()
Debugging aid.
const ter_layer NO_LAYER
Definition: translation.hpp:46
void redo()
Re-does a previously undid action, and puts it back in the undo stack.
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:110
lg::log_domain log_editor
Container action wrapping several actions into one.
Definition: action.hpp:90
const std::string & get_filename() const
-file sdl_utils.hpp
void change_controller(const std::string &new_controller)
Definition: team.hpp:272
void set_share_vision(const std::string &vision_status)
Definition: team.hpp:386
std::deque< editor_action_ptr > action_stack
Action stack typedef.
void set_hidden(bool value)
Definition: team.hpp:342
void remove_attribute(config_key_type key)
Definition: config.cpp:218
std::string scenario_description_
std::string scenario_name_
void set_needs_reload(bool value=true)
Setter for the reload flag.
void clear_modified()
Clear the modified state.
void partial_undo()
Un-does a single step from a undo action chain.
bool embedded_
Whether the map context refers to a map embedded in a scenario file.
void set_scenario_setup(const std::string &id, const std::string &name, const std::string &description, int turns, int xp_mod, bool victory_defeated, bool random_time)
TODO.
void remove_area(int index)
void set_terrain(const map_location &loc, const t_translation::terrain_code &terrain, const terrain_type_data::merge_mode mode=terrain_type_data::BOTH, bool replace_if_failed=false)
Clobbers over the terrain at location 'loc', with the given terrain.
Definition: map.cpp:381
void set_map(const editor_map &map)
std::string filename_
Definition: action_wml.cpp:546
t_translation::terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:301
#define WRN_ED
const t_string get_default_context_name() const
bool fog()
Definition: game.cpp:540
bool pure_map_
Whether the map context refers to a file containing only the pure map data.
static const size_t max_action_stack_size_
Action stack (i.e.
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:44
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:89
void have_leader(bool value=true)
Definition: team.hpp:340
bool is_pure_map() const
std::unique_ptr< tod_manager > tod_manager_
std::vector< team > teams_
editor_team_info(const team &t)
Definition: map_context.cpp:38
umap_retval_pair_t add(const map_location &l, const unit &u)
Adds a copy of unit u at location l of the map.
Definition: map.cpp:78
void read(config &cfg, std::istream &in, abstract_validator *validator)
Definition: parser.cpp:612
Class for writing a config out to a file in pieces.
void reset_starting_position_labels(display &disp)
void write_file(const std::string &fname, const std::string &data)
Throws io_exception if an error occurs.
editor_action * pop_first_action()
Remove the first added action and return it, transferring ownership to the caller.
Definition: action.cpp:151
int w() const
Effective map width.
Definition: map.hpp:90
editor_map & get_map()
Map accessor.
Definition: map_context.hpp:92
void replace_schedule(const std::vector< time_of_day > &schedule)
void add_to_recent_files()
Adds the map to the editor's recent files list.
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
Editor action classes.
void set_starting_time(int time)
TODO.
bool save_map()
Saves the map under the current filename.
void set_village_support(int support)
Definition: team.hpp:200
std::string get_short_wml_path(const std::string &filename)
Returns a short path to filename, skipping the (user) data directory.
#define log_scope2(domain, description)
Definition: log.hpp:187
map_display and display: classes which take care of displaying the map and game-data on the screen...
editor_action * last_undo_action()
int village_gold()
Definition: game.cpp:670
Manage the empty-palette in the editor.
Definition: action.cpp:29
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:98
void perform_action(const editor_action &action)
Performs an action (thus modifying the map).
bool can_undo() const
static const ::config * terrain
The terrain used to create the cache.
Definition: minimap.cpp:133
void set_fog(bool fog)
Definition: team.hpp:321
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
void set_needs_terrain_rebuild(bool value=true)
Setter for the terrain rebuild flag.
std::string scenario_id_
Encapsulates the map of the game.
Definition: location.hpp:40
void set_village_gold(int income)
Definition: team.hpp:193
void perform_partial_action(const editor_action &action)
Performs a partial action, assumes that the top undo action has been modified to maintain coherent st...
static editor_map from_string(const config &terrain_cfg, const std::string &data)
Wrapper around editor_map(cfg, data) that catches possible exceptions and wraps them in a editor_map_...
Definition: editor_map.cpp:56
std::string write() const
Definition: map.cpp:206
void clear_changed_locations()
bool shroud()
Definition: game.cpp:550
void set_starting_position_labels(display &disp)
t_translation::terrain_code terrain_with_default_base() const
Definition: terrain.cpp:282
bool can_redo() const
This class adds extra editor-specific functionality to a normal gamemap.
Definition: editor_map.hpp:69
void set_gold(int amount)
Definition: team.hpp:205
int h() const
Effective map height.
Definition: map.hpp:93
std::string get_wml_location(const std::string &filename, const std::string &current_dir=std::string())
Returns a complete path to the actual WML file or directory or an empty string if the file isn't pres...
Game configuration data as global variables.
Definition: build_info.cpp:53
map_context(const map_context &)=delete
int village_income
Definition: game_config.cpp:71
An exception object used when an IO error occurs.
Definition: filesystem.hpp:46
Base class for all editor actions.
Definition: action_base.hpp:40
Internal representation of music tracks.
void prepend_action(editor_action *a)
Add an action at the beginning of the chain.
Definition: action.cpp:130
#define i
void draw_terrain_actual(const t_translation::terrain_code &terrain, const map_location &loc, bool one_layer_only=false)
Actual drawing function used by both overloaded variants of draw_terrain.
void load_scenario(const config &game_config)
Declarations for File-IO.
overlay_map overlays_
config & add_child(config_key_type key)
Definition: config.cpp:408
action_stack redo_stack_
The redo stack.
std::string vgettext(const char *msgid, const utils::string_map &symbols)
std::string base_name(const std::string &file, const bool remove_extension=false)
Returns the base filename of a file, with directory name stripped.
void read(const config &cfg)
Definition: label.cpp:91
int turns()
Definition: game.cpp:560
int get_id() const
Debugging aid.
Definition: action_base.hpp:92
double t
Definition: astarsearch.cpp:64
team::CONTROLLER controller
Definition: map_context.hpp:43
void clear_undo_redo()
Clear the undo and redo stacks.
void set_needs_labels_reset(bool value=true)
Setter for the labels reset flag.
std::string message
Definition: exceptions.hpp:31
void replace_local_schedule(const std::vector< time_of_day > &schedule)
Replace the [time]s of the currently active area.
std::string filename_
The actual filename of this map.
static const char * name(const std::vector< SDL_Joystick * > &joysticks, const size_t index)
Definition: joystick.cpp:48
void change_team(const std::string &name, const t_string &user_name)
Definition: team.cpp:582
void trim_stack(action_stack &stack)
Checks if an action stack reached its capacity and removes the front element if so.
map_labels & labels()
Definition: display.cpp:2490
#define e
void set_base_income(int amount)
Definition: team.hpp:208
void add_recent_files_entry(const std::string &path)
Adds an entry to the recent files list.
Definition: editor.cpp:124
void clear_all()
Definition: label.cpp:239
std::set< map_location > changed_locations_
virtual editor_action * perform(map_context &) const
Perform the action, returning an undo action that, when performed, shall reverse any effects of this ...
Definition: action.cpp:63
void clear_starting_position_labels(display &disp)
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
filesystem::scoped_istream preprocess_file(const std::string &fname, preproc_map *defines)
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:139
bool is_embedded() const
bool set_selection(const std::set< map_location > &area)
Select the given area.
Definition: editor_map.cpp:171
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
bool select_area(int index)
Select the nth tod area.