Merge branch 'restrict_game_map'

This commit is contained in:
Chris Beck 2014-06-02 01:19:53 -04:00
commit dd1f1cc748
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;