resources::game_map is const *, move functionality to game_board

This commit changes the resources::game_map pointer to a const *,
so that changes to the game_map coming from lua or wml apis must
go through the game_board. Three functions were moved into the
game_board -- although substantively they did not change, there
were minor changes, in terms of the kind of error reporting done,
and also in how gui refresh orders are issued afterwards. In
testing the differences due to this refactor don't seem to be
noticeable.
This commit is contained in:
Chris Beck 2014-06-02 01:04:40 -04:00
parent a706e059fa
commit ac59b0d0e7
16 changed files with 148 additions and 109 deletions

View file

@ -230,7 +230,7 @@ bool shroud_clearer::clear_loc(team &tm, const map_location &loc,
size_t &enemy_count, size_t &friend_count,
move_unit_spectator * spectator)
{
gamemap &map = *resources::game_map;
const gamemap &map = resources::gameboard->map();
// This counts as clearing a tile for the return value if it is on the
// board and currently fogged under shared vision. (No need to explicitly
// check for shrouded since shrouded implies fogged.)

View file

@ -242,7 +242,7 @@ readonly_context_impl::readonly_context_impl(side_context &context, const config
add_known_aspect("support_villages",support_villages_);
add_known_aspect("village_value",village_value_);
add_known_aspect("villages_per_scout",villages_per_scout_);
keeps_.init(*resources::game_map);
keeps_.init(resources::gameboard->map());
}
@ -1002,7 +1002,7 @@ void keeps_cache::clear()
}
void keeps_cache::init(gamemap &map)
void keeps_cache::init(const gamemap &map)
{
map_ = ↦
}
@ -1095,7 +1095,7 @@ double readonly_context_impl::power_projection(const map_location& loc, const mo
map_location locs[6];
get_adjacent_tiles(loc,locs);
gamemap& map_ = *resources::game_map;
const gamemap& map_ = resources::gameboard->map();
unit_map& units_ = *resources::units;
int res = 0;

View file

@ -115,9 +115,9 @@ public:
void handle_generic_event(const std::string& event_name);
void clear();
const std::set<map_location>& get();
void init(gamemap &map);
void init(const gamemap &map);
private:
gamemap *map_;
const gamemap *map_;
std::set<map_location> keeps_;
};

View file

@ -530,8 +530,8 @@ ai_default_recruitment_stage::~ai_default_recruitment_stage()
void ai_default_recruitment_stage::analyze_potential_recruit_movements()
{
unit_map &units_ = *resources::units;
gamemap &map_ = *resources::game_map;
const unit_map &units_ = *resources::units;
const gamemap &map_ = *resources::game_map;
if(unit_movement_scores_.empty() == false ||
get_recruitment_ignore_bad_movement()) {

View file

@ -97,7 +97,7 @@ default_ai_context& default_ai_context_impl::get_default_ai_context(){
int default_ai_context_impl::rate_terrain(const unit& u, const map_location& loc) const
{
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
const t_translation::t_terrain terrain = map_.get_terrain(loc);
const int defense = u.defense_modifier(terrain);
int rating = 100 - defense;
@ -132,7 +132,7 @@ std::vector<target> default_ai_context_impl::find_targets(const move_map& enemy_
log_scope2(log_ai, "finding targets...");
unit_map &units_ = *resources::units;
unit_map::iterator leader = units_.find_leader(get_side());
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
std::vector<team> teams_ = *resources::teams;
const bool has_leader = leader != units_.end();

View file

@ -136,7 +136,7 @@ void aspect_attacks::do_attack_analysis(
//std::cerr << "ANALYSIS " << cur_analysis.movements.size() << " >= " << get_attack_depth() << "\n";
return;
}
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
unit_map &units_ = *resources::units;
std::vector<team> &teams_ = *resources::teams;
@ -359,7 +359,7 @@ void aspect_attacks::do_attack_analysis(
int aspect_attacks::rate_terrain(const unit& u, const map_location& loc)
{
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
const t_translation::t_terrain terrain = map_.get_terrain(loc);
const int defense = u.defense_modifier(terrain);
int rating = 100 - defense;

View file

@ -64,7 +64,7 @@ double goto_phase::evaluate()
// Execute goto-movements - first collect gotos in a list
std::vector<map_location> gotos;
unit_map &units_ = *resources::units;
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
for(unit_map::iterator ui = units_.begin(); ui != units_.end(); ++ui) {
if (ui->get_goto() == ui->get_location()) {
@ -222,9 +222,9 @@ void recruitment_phase::execute()
unit_combat_scores_.clear();
unit_movement_scores_.clear();
unit_map &units_ = *resources::units;
gamemap &map_ = *resources::game_map;
std::vector<team> &teams_ = *resources::teams;
const unit_map &units_ = *resources::units;
const gamemap &map_ = *resources::game_map;
const std::vector<team> &teams_ = *resources::teams;
map_location start_pos = units_.find_leader(get_side())->get_location();
@ -1046,7 +1046,7 @@ void get_villages_phase::find_villages(
const bool passive_leader = get_passive_leader();
size_t min_distance = 100000;
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
std::vector<team> &teams_ = *resources::teams;
// When a unit is dispatched we need to make sure we don't

View file

@ -273,7 +273,7 @@ std::pair<map_location,map_location> testing_move_to_targets_phase::choose_move(
raise_user_interact();
unit_map &units_ = *resources::units;
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
unit_map::iterator u;
@ -620,7 +620,7 @@ std::pair<map_location,map_location> testing_move_to_targets_phase::choose_move(
void testing_move_to_targets_phase::access_points(const move_map& srcdst, const map_location& u, const map_location& dst, std::vector<map_location>& out)
{
unit_map &units_ = *resources::units;
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
const unit_map::const_iterator u_it = units_.find(u);
if(u_it == units_.end()) {
return;
@ -711,7 +711,7 @@ map_location testing_move_to_targets_phase::form_group(const std::vector<map_loc
bool testing_move_to_targets_phase::move_group(const map_location& dst, const std::vector<map_location>& route, const std::set<map_location>& units)
{
unit_map &units_ = *resources::units;
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
const std::vector<map_location>::const_iterator itor = std::find(route.begin(),route.end(),dst);
if(itor == route.end()) {
@ -813,7 +813,7 @@ bool testing_move_to_targets_phase::move_group(const map_location& dst, const st
double testing_move_to_targets_phase::rate_group(const std::set<map_location>& group, const std::vector<map_location>& battlefield) const
{
unit_map &units_ = *resources::units;
gamemap &map_ = *resources::game_map;
const gamemap &map_ = *resources::game_map;
double strength = 0.0;
for(std::set<map_location>::const_iterator i = group.begin(); i != group.end(); ++i) {

View file

@ -14,10 +14,20 @@
#include "config.hpp"
#include "game_board.hpp"
#include "game_preferences.hpp"
#include "log.hpp"
#include "unit.hpp"
#include "utils/foreach.tpp"
#include <boost/foreach.hpp>
static lg::log_domain log_engine("enginerefac");
#define DBG_RG LOG_STREAM(debug, log_engine)
#define LOG_RG LOG_STREAM(info, log_engine)
#define WRN_RG LOG_STREAM(warn, log_engine)
#define ERR_RG LOG_STREAM(err, log_engine)
void game_board::new_turn(int player_num) {
BOOST_FOREACH (unit & i, units_) {
@ -87,6 +97,91 @@ void game_board::side_change_controller(int side_num, team::CONTROLLER ctrl, con
}
}
bool game_board::try_add_unit_to_recall_list(const map_location& loc, const unit& u)
{
if(teams_[u.side()-1].persistent()) {
teams_[u.side()-1].recall_list().push_back(u);
return true;
} else {
ERR_RG << "unit with id " << u.id() << ": location (" << loc.x << "," << loc.y <<") is not on the map, and player "
<< u.side() << " has no recall list.\n";
return false;
}
}
boost::optional<std::string> game_board::replace_map(const gamemap & newmap) {
boost::optional<std::string> ret = boost::optional<std::string> ();
/* Remember the locations where a village is owned by a side. */
std::map<map_location, int> villages;
FOREACH(const AUTO& village, map_.villages()) {
const int owner = village_owner(village);
if(owner != -1) {
villages[village] = owner;
}
}
for (unit_map::iterator itor = units_.begin(); itor != units_.end(); ) {
if (!newmap.on_board(itor->get_location())) {
if (!try_add_unit_to_recall_list(itor->get_location(), *itor)) {
*ret = std::string("replace_map: Cannot add a unit that would become off-map to the recall list\n");
}
units_.erase(itor++);
} else {
++itor;
}
}
/* Disown villages that are no longer villages. */
FOREACH(const AUTO& village, villages) {
if(!newmap.is_village(village.first)) {
teams_[village.second].lose_village(village.first);
}
}
map_ = newmap;
return ret;
}
void game_board::overlay_map(const gamemap & mask_map, const config & cfg, map_location loc, bool border) {
map_.overlay(mask_map, cfg, loc.x, loc.y, border);
}
bool game_board::change_terrain(const map_location &loc, const t_translation::t_terrain &t,
gamemap::tmerge_mode mode, bool replace_if_failed)
{
/*
* When a hex changes from a village terrain to a non-village terrain, and
* a team owned that village it loses that village. When a hex changes from
* a non-village terrain to a village terrain and there is a unit on that
* hex it does not automatically capture the village. The reason for not
* capturing villages it that there are too many choices to make; should a
* unit loose its movement points, should capture events be fired. It is
* easier to do this as wanted by the author in WML.
*/
t_translation::t_terrain
old_t = map_.get_terrain(loc),
new_t = map_.merge_terrains(old_t, t, mode, replace_if_failed);
if (new_t == t_translation::NONE_TERRAIN) return false;
preferences::encountered_terrains().insert(new_t);
if (map_.is_village(old_t) && !map_.is_village(new_t)) {
int owner = village_owner(loc);
if (owner != -1)
teams_[owner].lose_village(loc);
}
map_.set_terrain(loc, new_t);
BOOST_FOREACH(const t_translation::t_terrain &ut, map_.underlying_union_terrain(loc)) {
preferences::encountered_terrains().insert(ut);
}
return true;
}
void game_board::write_config(config & cfg) const {
for(std::vector<team>::const_iterator t = teams_.begin(); t != teams_.end(); ++t) {

View file

@ -21,6 +21,7 @@
#include "team.hpp"
#include "unit_map.hpp"
#include <boost/optional.hpp>
#include <vector>
class config;
@ -29,6 +30,7 @@ namespace events {
class mouse_handler;
}
class game_board {
std::vector<team> teams_;
@ -68,6 +70,15 @@ class game_board {
void side_drop_to (int side_num, team::CONTROLLER ctrl);
void side_change_controller (int side_num, team::CONTROLLER ctrl, const std::string pname = "");
// Manipulator from actionwml
bool try_add_unit_to_recall_list(const map_location& loc, const unit& u);
boost::optional<std::string> replace_map (const gamemap & r);
void overlay_map (const gamemap & o, const config & cfg, map_location loc, bool border);
bool change_terrain(const map_location &loc, const t_translation::t_terrain &t,
gamemap::tmerge_mode mode, bool replace_if_failed); //used only by lua
// Global accessor from unit.hpp
unit_map::iterator find_visible_unit(const map_location &loc, const team& current_team, bool see_all = false);

View file

@ -288,7 +288,7 @@ namespace { // Support functions
std::vector<map_location> fake_unit_path(const unit& fake_unit, const std::vector<std::string>& xvals, const std::vector<std::string>& yvals)
{
gamemap *game_map = resources::game_map;
const gamemap *game_map = resources::game_map;
std::vector<map_location> path;
map_location src;
map_location dst;
@ -532,56 +532,8 @@ namespace { // Support functions
resources::screen->invalidate_all();
}
bool try_add_unit_to_recall_list(const map_location& loc, const unit& u)
{
if((*resources::teams)[u.side()-1].persistent()) {
(*resources::teams)[u.side()-1].recall_list().push_back(u);
return true;
} else {
ERR_NG << "unit with id " << u.id() << ": location (" << loc.x << "," << loc.y <<") is not on the map, and player "
<< u.side() << " has no recall list.\n";
return false;
}
}
} // end anonymous namespace (support functions)
void change_terrain(const map_location &loc, const t_translation::t_terrain &t,
gamemap::tmerge_mode mode, bool replace_if_failed)
{
/*
* When a hex changes from a village terrain to a non-village terrain, and
* a team owned that village it loses that village. When a hex changes from
* a non-village terrain to a village terrain and there is a unit on that
* hex it does not automatically capture the village. The reason for not
* capturing villages it that there are too many choices to make; should a
* unit loose its movement points, should capture events be fired. It is
* easier to do this as wanted by the author in WML.
*/
gamemap *game_map = resources::game_map;
t_translation::t_terrain
old_t = game_map->get_terrain(loc),
new_t = game_map->merge_terrains(old_t, t, mode, replace_if_failed);
if (new_t == t_translation::NONE_TERRAIN) return;
preferences::encountered_terrains().insert(new_t);
if (game_map->is_village(old_t) && !game_map->is_village(new_t)) {
int owner = village_owner(loc);
if (owner != -1)
(*resources::teams)[owner].lose_village(loc);
}
game_map->set_terrain(loc, new_t);
context::screen_needs_rebuild(true);
BOOST_FOREACH(const t_translation::t_terrain &ut, game_map->underlying_union_terrain(loc)) {
preferences::encountered_terrains().insert(ut);
}
}
void handle_deprecated_message(const config& cfg)
{
// Note: no need to translate the string, since only used for deprecated things.
@ -1728,19 +1680,9 @@ WML_HANDLER_FUNCTION(replace_map, /*event_info*/, cfg)
* easier to do this as wanted by the author in WML.
*/
gamemap *game_map = resources::game_map;
const gamemap * game_map = resources::game_map;
gamemap map(*game_map);
/* Remember the locations where a village is owned by a side. */
std::map<map_location, int> villages;
FOREACH(const AUTO& village, map.villages()) {
const int owner = village_owner(village);
if(owner != -1) {
villages[village] = owner;
}
}
try {
if (cfg["map"].empty()) {
const vconfig& map_cfg = cfg.child("map");
@ -1748,7 +1690,7 @@ WML_HANDLER_FUNCTION(replace_map, /*event_info*/, cfg)
}
else map.read(cfg["map"], false);
} catch(incorrect_map_format_error&) {
lg::wml_error << "replace_map: Unable to load map " << cfg["map"] << "\n";
lg::wml_error << "replace_map: Unable to load map " << cfg["map"] << std::endl;
return;
} catch(twml_exception& e) {
e.show(*resources::screen);
@ -1757,38 +1699,24 @@ WML_HANDLER_FUNCTION(replace_map, /*event_info*/, cfg)
if (map.total_width() > game_map->total_width()
|| map.total_height() > game_map->total_height()) {
if (!cfg["expand"].to_bool()) {
lg::wml_error << "replace_map: Map dimension(s) increase but expand is not set\n";
lg::wml_error << "replace_map: Map dimension(s) increase but expand is not set" << std::endl;
return;
}
}
if (map.total_width() < game_map->total_width()
|| map.total_height() < game_map->total_height()) {
if (!cfg["shrink"].to_bool()) {
lg::wml_error << "replace_map: Map dimension(s) decrease but shrink is not set\n";
lg::wml_error << "replace_map: Map dimension(s) decrease but shrink is not set" << std::endl;
return;
}
unit_map *units = resources::units;
unit_map::iterator itor;
for (itor = units->begin(); itor != units->end(); ) {
if (!map.on_board(itor->get_location())) {
if (!try_add_unit_to_recall_list(itor->get_location(), *itor)) {
lg::wml_error << "replace_map: Cannot add a unit that would become off-map to the recall list\n";
}
units->erase(itor++);
} else {
++itor;
}
}
}
/* Disown villages that are no longer villages. */
FOREACH(const AUTO& village, villages) {
if(!map.is_village(village.first)) {
(*resources::teams)[village.second].lose_village(village.first);
}
boost::optional<std::string> errmsg = resources::gameboard->replace_map(map);
if (errmsg) {
lg::wml_error << *errmsg << std::endl;
}
*game_map = map;
resources::screen->reload_map();
context::screen_needs_rebuild(true);
ai::manager::raise_map_changed();
@ -2475,7 +2403,7 @@ WML_HANDLER_FUNCTION(terrain_mask, /*event_info*/, cfg)
return;
}
bool border = cfg["border"].to_bool();
resources::game_map->overlay(mask_map, cfg.get_parsed_config(), loc.x, loc.y, border);
resources::gameboard->overlay_map(mask_map, cfg.get_parsed_config(), loc, border);
context::screen_needs_rebuild(true);
}

View file

@ -295,7 +295,7 @@ std::vector<map_location> parse_location_range(const std::string &x, const std::
std::vector<map_location> res;
const std::vector<std::string> xvals = utils::split(x);
const std::vector<std::string> yvals = utils::split(y);
gamemap *map = resources::game_map;
const gamemap *map = resources::game_map;
assert(map);
int xmin = 1, xmax = map->w(), ymin = 1, ymax = map->h();
if (with_border) {

View file

@ -281,7 +281,7 @@ int movetype::terrain_info::data::calc_value(
return params_.default_value;
}
assert(resources::game_map);
gamemap & map = *resources::game_map;
const gamemap & map = *resources::game_map;
// Get a list of underlying terrains.
const t_translation::t_list & underlying = params_.use_move ?

View file

@ -21,7 +21,7 @@ namespace resources
game_config_manager *config_manager = NULL;
play_controller *controller = NULL;
game_data *gamedata = NULL;
gamemap *game_map = NULL;
const gamemap *game_map = NULL;
LuaKernel *lua_kernel = NULL;
persist_manager *persist = NULL;
game_display *screen = NULL;

View file

@ -45,7 +45,7 @@ namespace resources
extern play_controller *controller;
extern game_board *gameboard;
extern game_data *gamedata;
extern gamemap *game_map;
extern const gamemap *game_map;
extern LuaKernel *lua_kernel; // Set by game_events::manager.
extern persist_manager *persist;
extern game_classification *classification;

View file

@ -1288,7 +1288,12 @@ static int intf_set_terrain(lua_State *L)
}
}
game_events::change_terrain(map_location(x - 1, y - 1), terrain, mode, replace_if_failed);
bool result = resources::gameboard->change_terrain(map_location(x - 1, y - 1), terrain, mode, replace_if_failed);
if (result) {
resources::screen->recalculate_minimap();
resources::screen->invalidate_all();
resources::screen->rebuild_all();
}
return 0;
}
@ -1776,7 +1781,7 @@ static int intf_find_path(lua_State *L)
return luaL_argerror(L, arg - 2, "invalid location");
std::vector<team> &teams = *resources::teams;
gamemap &map = *resources::game_map;
const gamemap &map = *resources::game_map;
int viewing_side = 0;
bool ignore_units = false, see_all = false, ignore_teleport = false;
double stop_at = 10000;