Merge pull request #760 from jyrkive/editor-crashes

Fix crash on placing a unit with the scenario editor
This commit is contained in:
Jyrki Vesterinen 2016-09-06 23:27:03 +03:00 committed by GitHub
commit bda24b3f93
31 changed files with 81 additions and 69 deletions

View file

@ -86,7 +86,7 @@ const std::set<std::string> get_recruits(int side, const map_location &recruit_l
local_result.insert(find_it->recruits().begin(),
find_it->recruits().end());
}
else if ( find_it->is_visible_to_team(current_team, resources::gameboard->map(), false) )
else if ( find_it->is_visible_to_team(current_team, *resources::gameboard, false) )
{
// This hex is visibly occupied, so we cannot recruit here.
allow_local = false;
@ -187,7 +187,7 @@ std::vector<unit_const_ptr > get_recalls(int side, const map_location &recall_lo
add_leader_filtered_recalls(find_it.get_shared_ptr(), result);
return result;
}
else if ( find_it->is_visible_to_team(resources::gameboard->teams()[side-1], resources::gameboard->map(), false) )
else if ( find_it->is_visible_to_team(resources::gameboard->teams()[side-1], *resources::gameboard, false) )
{
// This hex is visibly occupied, so we cannot recall here.
allow_local = false;
@ -588,7 +588,7 @@ namespace { // Helpers for place_recruit()
for ( unit_itor = units.begin(); unit_itor != units.end(); ++unit_itor ) {
if (resources::gameboard->teams()[unit_itor->side()-1].is_enemy(new_unit.side()) &&
unit_itor->is_visible_to_team(resources::gameboard->teams()[new_unit.side()-1], *map, false)) {
unit_itor->is_visible_to_team(resources::gameboard->teams()[new_unit.side()-1], *resources::gameboard, false)) {
int dist = distance_between(unit_itor->get_location(),recruit_loc) - unit_itor->level();
if (dist < min_dist) {
min_dist = dist;

View file

@ -351,7 +351,7 @@ void calculate_healing(int side, bool update_display)
const team & viewing_team =
resources::gameboard->teams()[resources::screen->viewing_team()];
if (!resources::controller->is_skipping_replay() && update_display &&
patient.is_visible_to_team(viewing_team, resources::gameboard->map(), false) )
patient.is_visible_to_team(viewing_team, *resources::gameboard, false) )
{
unit_list.push_front(heal_unit(patient, healers, healing, curing == POISON_CURE));
}

View file

@ -427,7 +427,7 @@ namespace { // Private helpers for move_unit()
if ( neighbor_it != units.end() &&
current_team_->is_enemy(neighbor_it->side()) &&
neighbor_it->invisible(adjacent[i]) )
neighbor_it->invisible(adjacent[i], *resources::gameboard) )
{
// Ambushed!
ambushed_ = true;
@ -735,7 +735,7 @@ namespace { // Private helpers for move_unit()
if ( start != begin_ ) {
// Check for being unable to leave the current hex.
if ( !move_it_->get_ability_bool("skirmisher", *start) &&
if ( !move_it_->get_ability_bool("skirmisher", *start, *resources::gameboard) &&
pathfind::enemy_zoc(*current_team_, *start, *current_team_) )
zoc_stop_ = *start;
}
@ -758,7 +758,7 @@ namespace { // Private helpers for move_unit()
moves_left_.push_back(remaining_moves);
// Check for being unable to leave this hex.
if ( !move_it_->get_ability_bool("skirmisher", *end) &&
if ( !move_it_->get_ability_bool("skirmisher", *end, *resources::gameboard) &&
pathfind::enemy_zoc(*current_team_, *end, *current_team_) )
zoc_stop_ = *end;
}

View file

@ -600,7 +600,7 @@ std::vector<int> get_sides_not_seeing(const unit & target)
size_t team_size = teams.size();
for ( size_t i = 0; i != team_size; ++i)
if ( !target.is_visible_to_team(teams[i], resources::gameboard->map(), false) )
if ( !target.is_visible_to_team(teams[i], *resources::gameboard, false) )
// not_see contains side numbers; i is a team index, so add 1.
not_seeing.push_back(i+1);
@ -646,7 +646,7 @@ bool actor_sighted(const unit & target, const std::vector<int> * cache)
needs_event[target.side()-1] = false;
// Exclude those teams that cannot see the target.
for ( size_t i = 0; i != teams_size; ++i )
needs_event[i] = needs_event[i] && target.is_visible_to_team(teams[i], resources::gameboard->map(), false);
needs_event[i] = needs_event[i] && target.is_visible_to_team(teams[i], *resources::gameboard, false);
// Cache "jamming".
std::vector< std::map<map_location, int> > jamming_cache(teams_size);

View file

@ -302,7 +302,7 @@ void protect_goal::add_targets(std::back_insert_iterator< std::vector< target >
{
int distance = distance_between(u.get_location(), loc);
if (current_team().is_enemy(u.side()) && distance < radius_ &&
!u.invisible(u.get_location()))
!u.invisible(u.get_location(), *resources::gameboard))
{
DBG_AI_GOAL << "side " << get_side() << ": in " << goal_type << ": found threat target. " << u.get_location() << " is a threat to "<< loc << '\n';
*target_list = target(u.get_location(),

View file

@ -379,7 +379,7 @@ void readonly_context_impl::calculate_moves(const unit_map& units, std::map<map_
}
// We can't see where invisible enemy units might move.
if (enemy && un_it->invisible(un_it->get_location()) && !see_all) {
if (enemy && un_it->invisible(un_it->get_location(), *resources::gameboard) && !see_all) {
continue;
}
// If it's an enemy unit, reset its moves while we do the calculations.

View file

@ -104,7 +104,7 @@ std::shared_ptr<attacks_vector> aspect_attacks_base::analyze_targets() const
// Attack anyone who is on the enemy side,
// and who is not invisible or petrified.
if (current_team().is_enemy(j->side()) && !j->incapacitated() &&
!j->invisible(j->get_location()))
!j->invisible(j->get_location(), *resources::gameboard))
{
if (!is_allowed_enemy(*j)) {
continue;
@ -288,7 +288,7 @@ void aspect_attacks_base::do_attack_analysis(
}
// No surround bonus if target is skirmisher
if (!itor->get_ability_bool("skirmisher"))
if (!itor->get_ability_bool("skirmisher", *resources::gameboard))
surround_bonus = 1.2;
}
@ -360,7 +360,7 @@ int aspect_attacks_base::rate_terrain(const unit& u, const map_location& loc)
const int neutral_village_value = 10;
const int enemy_village_value = 15;
if(map_.gives_healing(terrain) && u.get_ability_bool("regenerate",loc) == false) {
if(map_.gives_healing(terrain) && u.get_ability_bool("regenerate", loc, *resources::gameboard) == false) {
rating += healing_value;
}

View file

@ -1342,7 +1342,7 @@ double get_healing_phase::evaluate()
if(u.side() == get_side() &&
(u.max_hitpoints() - u.hitpoints() >= game_config::poison_amount/2
|| u.get_state(unit::STATE_POISONED)) &&
!u.get_ability_bool("regenerate"))
!u.get_ability_bool("regenerate", *resources::gameboard))
{
// Look for the village which is the least vulnerable to enemy attack.
typedef std::multimap<map_location,map_location>::const_iterator Itor;

View file

@ -81,7 +81,7 @@ int default_ai_context_impl::count_free_hexes_in_castle(const map_location &loc,
ret += count_free_hexes_in_castle(adj[n], checked_hexes);
if (u == units_.end()
|| (current_team().is_enemy(u->side())
&& u->invisible(adj[n]))
&& u->invisible(adj[n], *resources::gameboard))
|| ((&resources::gameboard->teams()[u->side() - 1]) == &current_team()
&& u->movement_left() > 0)) {
ret += 1;
@ -109,7 +109,7 @@ int default_ai_context_impl::rate_terrain(const unit& u, const map_location& loc
const int neutral_village_value = 10;
const int enemy_village_value = 15;
if(map_.gives_healing(terrain) && u.get_ability_bool("regenerate",loc) == false) {
if(map_.gives_healing(terrain) && u.get_ability_bool("regenerate", loc, *resources::gameboard) == false) {
rating += healing_value;
}
@ -228,7 +228,7 @@ std::vector<target> default_ai_context_impl::find_targets(const move_map& enemy_
for(u = units_.begin(); u != units_.end(); ++u) {
//is a visible enemy leader
if (u->can_recruit() && current_team().is_enemy(u->side())
&& !u->invisible(u->get_location())) {
&& !u->invisible(u->get_location(), *resources::gameboard)) {
assert(map_.on_board(u->get_location()));
LOG_AI << "found enemy leader (side: " << u->side() << ") target... " << u->get_location() << " with value: " << get_leader_value() << "\n";
targets.push_back(target(u->get_location(), get_leader_value(), target::TYPE::LEADER));

View file

@ -210,7 +210,7 @@ void attack_map_callable::collect_possible_attacks(std::vector<variant>& vars, m
/* if tile is occupied by friendly or petrified/invisible unit */
if (!ai_.current_team().is_enemy(unit->side()) ||
unit->incapacitated() ||
unit->invisible(unit->get_location()))
unit->invisible(unit->get_location(), *resources::gameboard))
continue;
/* add attacks with default weapon */
attack_callable* item = new attack_callable(attacker_location, attack_position, adj[n], -1);

View file

@ -19,6 +19,7 @@
#include "ai/formula/ai.hpp"
#include "ai/formula/candidates.hpp"
#include "game_board.hpp"
#include "log.hpp"
#include "resources.hpp"
@ -164,7 +165,7 @@ void attack_candidate_action::evaluate(ai::formula_ai* ai, unit_map& units)
}
} else
{
if (ai->current_team().is_enemy(i->side()) && !i->incapacitated() && !i->invisible(i->get_location())) {
if (ai->current_team().is_enemy(i->side()) && !i->incapacitated() && !i->invisible(i->get_location(), *resources::gameboard)) {
enemy_res.push_back(variant(new unit_callable(*i)));
}
}

View file

@ -2102,7 +2102,9 @@ void display::draw_minimap()
draw_minimap_units();
#else
if(minimap_ == nullptr || minimap_->w > area.w || minimap_->h > area.h) {
minimap_ = image::getMinimap(area.w, area.h, get_map(), &dc_->teams()[currentTeam_], (selectedHex_.valid() && !is_blindfolded()) ? &reach_map_ : nullptr);
minimap_ = image::getMinimap(area.w, area.h, get_map(),
dc_->teams().empty() ? nullptr : &dc_->teams()[currentTeam_],
(selectedHex_.valid() && !is_blindfolded()) ? &reach_map_ : nullptr);
if(minimap_ == nullptr) {
return;
}
@ -2159,7 +2161,7 @@ void display::draw_minimap_units()
for(unit_map::const_iterator u = dc_->units().begin(); u != dc_->units().end(); ++u) {
if (fogged(u->get_location()) ||
(dc_->teams()[currentTeam_].is_enemy(u->side()) &&
u->invisible(u->get_location())) ||
u->invisible(u->get_location(), *dc_)) ||
u->get_hidden()) {
continue;
}
@ -2830,6 +2832,12 @@ void display::draw_invalidated() {
}
invalidated_hexes_ += invalidated_.size();
if (dc_->teams().empty())
{
// The unit drawer can't function without teams
return;
}
unit_drawer drawer = unit_drawer(*this, energy_bar_rects_);
for (const map_location& loc : invalidated_) {

View file

@ -46,7 +46,7 @@ bool display_context::would_be_discovered(const map_location & loc, int side_num
if(see_all) {
return true;
} else if (!teams()[side_num-1].fogged(u_loc)
&& !u.invisible(u_loc, true)) {
&& !u.invisible(u_loc, *this, true)) {
return true;
}
}
@ -58,7 +58,7 @@ const unit * display_context::get_visible_unit(const map_location & loc, const t
{
if (!map().on_board(loc)) return nullptr;
const unit_map::const_iterator u = units().find(loc);
if (!u.valid() || !u->is_visible_to_team(current_team, map(), see_all)) {
if (!u.valid() || !u->is_visible_to_team(current_team, *this, see_all)) {
return nullptr;
}
return &*u;

View file

@ -175,7 +175,7 @@ unit_map::iterator game_board::find_visible_unit(const map_location &loc,
{
if (!map_->on_board(loc)) return units_.end();
unit_map::iterator u = units_.find(loc);
if (!u.valid() || !u->is_visible_to_team(current_team, *map_, see_all))
if (!u.valid() || !u->is_visible_to_team(current_team, *this, see_all))
return units_.end();
return u;
}
@ -184,7 +184,7 @@ bool game_board::has_visible_unit(const map_location & loc, const team& current_
{
if (!map_->on_board(loc)) return false;
unit_map::const_iterator u = units_.find(loc);
if (!u.valid() || !u->is_visible_to_team(current_team, *map_, see_all))
if (!u.valid() || !u->is_visible_to_team(current_team, *this, see_all))
return false;
return true;
}

View file

@ -33,7 +33,9 @@
#include "gui/widgets/window.hpp"
#include "display.hpp"
#include "formatter.hpp"
#include "game_board.hpp"
#include "marked-up_text.hpp"
#include "resources.hpp"
#include "units/map.hpp"
#include "units/ptr.hpp"
#include "units/unit.hpp"
@ -149,7 +151,7 @@ void tunit_list::pre_show(twindow& window)
// NOTE: this needs to be done *after* the row is added
// TODO: show custom statuses
if(!unit->get_state(unit::STATE_PETRIFIED)) {
find_widget<timage>(row_grid, "unit_status_slowed", false).set_visible(twidget::tvisible::invisible);
find_widget<timage>(row_grid, "unit_status_petrified", false).set_visible(twidget::tvisible::invisible);
}
if(!unit->get_state(unit::STATE_POISONED)) {
@ -157,11 +159,11 @@ void tunit_list::pre_show(twindow& window)
}
if(!unit->get_state(unit::STATE_SLOWED)) {
find_widget<timage>(row_grid, "unit_status_invisible", false).set_visible(twidget::tvisible::invisible);
find_widget<timage>(row_grid, "unit_status_slowed", false).set_visible(twidget::tvisible::invisible);
}
if(!unit->invisible(unit->get_location(), false)) {
find_widget<timage>(row_grid, "unit_status_petrified", false).set_visible(twidget::tvisible::invisible);
if(!unit->invisible(unit->get_location(), *resources::gameboard, false)) {
find_widget<timage>(row_grid, "unit_status_invisible", false).set_visible(twidget::tvisible::invisible);
}
}

View file

@ -435,7 +435,7 @@ void menu_handler::show_enemy_moves(bool ignore_units, int side_num)
// Compute enemy movement positions
for(unit_map::iterator u = units().begin(); u != units().end(); ++u) {
bool invisible = u->invisible(u->get_location());
bool invisible = u->invisible(u->get_location(), gui_->get_disp_context());
if (teams()[side_num - 1].is_enemy(u->side()) &&
!gui_->fogged(u->get_location()) && !u->incapacitated() && !invisible)
@ -1293,7 +1293,7 @@ void menu_handler::do_search(const std::string& new_search)
last_search_.begin(), last_search_.end(),
chars_equal_insensitive) != name.end()) {
if (!teams()[gui_->viewing_team()].is_enemy(ui->side()) ||
!ui->invisible(ui->get_location())) {
!ui->invisible(ui->get_location(), gui_->get_disp_context())) {
found = true;
}
}

View file

@ -779,7 +779,7 @@ void mouse_handler::select_hex(const map_location& hex, const bool browse, const
clicked_location.destinations.insert(hex);
for(unit_map::iterator u = pc_.gamestate().board_.units_.begin(); u != pc_.gamestate().board_.units_.end(); ++u) {
bool invisible = u->invisible(u->get_location());
bool invisible = u->invisible(u->get_location(), gui_->get_disp_context());
if (!gui_->fogged(u->get_location()) && !u->incapacitated() && !invisible)
{
@ -1097,7 +1097,7 @@ void mouse_handler::show_attack_options(const unit_map::const_iterator &u)
// (Visible to current team, not necessarily the unit's team.)
if (!pc_.get_map_const().on_board(loc)) continue;
unit_map::const_iterator i = pc_.gamestate().board_.units().find(loc);
if ( !i || !i->is_visible_to_team(cur_team, pc_.gamestate().board_.map(), false) )
if ( !i || !i->is_visible_to_team(cur_team, gui_->get_disp_context(), false) )
continue;
const unit &target = *i;
// Can only attack non-petrified enemies.
@ -1119,7 +1119,7 @@ bool mouse_handler::unit_in_cycle(unit_map::const_iterator it)
return false;
if (current_team().is_enemy(int(gui().viewing_team()+1)) &&
it->invisible(it->get_location()))
it->invisible(it->get_location(), gui().get_disp_context()))
return false;
if (it->get_hidden())

View file

@ -401,7 +401,7 @@ static void find_routes(
if ( skirmisher && next.moves_left > 0 &&
enemy_zoc(*current_team, next_hex, *viewing_team, see_all) &&
!skirmisher->get_ability_bool("skirmisher", next_hex) ) {
!skirmisher->get_ability_bool("skirmisher", next_hex, *resources::gameboard) ) {
next.moves_left = 0;
}
}
@ -656,7 +656,7 @@ marked_route mark_route(const plain_route &rt)
++turns;
bool invisible = u.invisible(*i,false);
bool invisible = u.invisible(*i, *resources::gameboard, false);
res.marks[*i] = marked_route::mark(turns, zoc, capture, invisible);
@ -669,7 +669,7 @@ marked_route mark_route(const plain_route &rt)
}
zoc = enemy_zoc(unit_team, *(i + 1), viewing_team)
&& !u.get_ability_bool("skirmisher", *(i+1));
&& !u.get_ability_bool("skirmisher", *(i+1), *resources::gameboard);
if (zoc) {
movement = 0;
@ -752,7 +752,7 @@ double shortest_path_calculator::cost(const map_location& loc, const double so_f
// check ZoC
if (!ignore_unit_ && remaining_movement != terrain_cost
&& enemy_zoc(teams_[unit_.side()-1], loc, viewing_team_, see_all_)
&& !unit_.get_ability_bool("skirmisher", loc)) {
&& !unit_.get_ability_bool("skirmisher", loc, *resources::gameboard)) {
// entering ZoC cost all remaining MP
move_cost += remaining_movement;
} else {

View file

@ -236,7 +236,7 @@ const teleport_map get_teleport_locations(const unit &u,
{
std::vector<teleport_group> groups;
if (u.get_ability_bool("teleport")) {
if (u.get_ability_bool("teleport", *resources::gameboard)) {
for (const unit_ability & teleport : u.get_abilities("teleport")) {
const int tunnel_count = (teleport.first)->child_count("tunnel");
for(int i = 0; i < tunnel_count; ++i) {

View file

@ -623,7 +623,7 @@ void play_controller::tab()
for (const unit& u : gamestate().board_.units()){
const map_location& loc = u.get_location();
if(!gui_->fogged(loc) &&
!(gamestate().board_.teams()[gui_->viewing_team()].is_enemy(u.side()) && u.invisible(loc)))
!(gamestate().board_.teams()[gui_->viewing_team()].is_enemy(u.side()) && u.invisible(loc, gui_->get_disp_context())))
dictionary.insert(u.name());
}
//TODO List map labels

View file

@ -299,7 +299,7 @@ static config unit_status(reports::context & rc, const unit* u)
if (!u) return config();
config res;
map_location displayed_unit_hex = rc.screen().displayed_unit_hex();
if (rc.map().on_board(displayed_unit_hex) && u->invisible(displayed_unit_hex)) {
if (rc.map().on_board(displayed_unit_hex) && u->invisible(displayed_unit_hex, rc.dc())) {
add_status(res, "misc/invisible.png", N_("invisible: "),
N_("This unit is invisible. It cannot be seen or attacked by enemy units."));
}
@ -762,7 +762,7 @@ static int attack_info(reports::context & rc, const attack_type &at, config &res
continue;
const map_location &loc = enemy.get_location();
if (viewing_team.fogged(loc) ||
(viewing_team.is_enemy(enemy.side()) && enemy.invisible(loc)))
(viewing_team.is_enemy(enemy.side()) && enemy.invisible(loc, rc.dc())))
continue;
bool new_type = seen_types.insert(enemy.type_id()).second;
if (new_type) {

View file

@ -2300,11 +2300,11 @@ static int intf_unit_defense(lua_State *L)
* - Arg 2: string.
* - Ret 1: boolean.
*/
static int intf_unit_ability(lua_State *L)
int game_lua_kernel::intf_unit_ability(lua_State *L)
{
const unit& u = luaW_checkunit(L, 1);
char const *m = luaL_checkstring(L, 2);
lua_pushboolean(L, u.get_ability_bool(m));
lua_pushboolean(L, u.get_ability_bool(m, board()));
return 1;
}
@ -4087,7 +4087,6 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle
{ "remove_modifications", &intf_remove_modifications },
{ "set_music", &intf_set_music },
{ "transform_unit", &intf_transform_unit },
{ "unit_ability", &intf_unit_ability },
{ "unit_defense", &intf_unit_defense },
{ "unit_movement_cost", &intf_unit_movement_cost },
{ "unit_vision_cost", &intf_unit_vision_cost },
@ -4186,6 +4185,7 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle
{ "synchronize_choice", &intf_synchronize_choice },
{ "synchronize_choices", &intf_synchronize_choices },
{ "teleport", &dispatch<&game_lua_kernel::intf_teleport > },
{ "unit_ability", &dispatch<&game_lua_kernel::intf_unit_ability > },
{ "view_locked", &dispatch<&game_lua_kernel::intf_view_locked > },
{ "place_shroud", &dispatch2<&game_lua_kernel::intf_shroud_op, true > },
{ "remove_shroud", &dispatch2<&game_lua_kernel::intf_shroud_op, false > },
@ -4385,7 +4385,7 @@ int game_lua_kernel::return_unit_method(lua_State *L, char const *m) {
{"movement", intf_unit_movement_cost},
{"vision", intf_unit_vision_cost},
{"jamming", intf_unit_jamming_cost},
{"ability", intf_unit_ability},
{"ability", &dispatch<&game_lua_kernel::intf_unit_ability>},
{"transform", intf_transform_unit},
{"select", &dispatch<&game_lua_kernel::intf_select_unit>},
};

View file

@ -89,6 +89,7 @@ class game_lua_kernel : public lua_kernel_base
int intf_set_side_variable(lua_State *L);
int intf_highlight_hex(lua_State *L);
int intf_is_enemy(lua_State *L);
int intf_unit_ability(lua_State *L);
int intf_view_locked(lua_State *L);
int intf_lock_view(lua_State *L);
int intf_get_terrain(lua_State *L);

View file

@ -222,7 +222,7 @@ const time_of_day tod_manager::get_illuminated_time_of_day(const unit_map & unit
for ( size_t i = 0; i != 7; ++i ) {
const unit_map::const_iterator itor = units.find(locs[i]);
if (itor != units.end() &&
itor->get_ability_bool("illuminates") &&
itor->get_ability_bool("illuminates", *resources::gameboard) &&
!itor->incapacitated())
{
unit_ability_list illum = itor->get_abilities("illuminates");

View file

@ -17,6 +17,7 @@
* Manage unit-abilities, like heal, cure, and weapon_specials.
*/
#include "display_context.hpp"
#include "game_board.hpp"
#include "log.hpp"
#include "resources.hpp"
@ -126,10 +127,8 @@ bool affects_side(const config& cfg, const std::vector<team>& teams, size_t side
}
bool unit::get_ability_bool(const std::string& tag_name, const map_location& loc) const
bool unit::get_ability_bool(const std::string& tag_name, const map_location& loc, const display_context& dc) const
{
assert(resources::gameboard);
for (const config &i : this->abilities_.child_range(tag_name)) {
if (ability_active(tag_name, i, loc) &&
ability_affects_self(tag_name, i, loc))
@ -153,7 +152,7 @@ bool unit::get_ability_bool(const std::string& tag_name, const map_location& loc
if ( &*it == this )
continue;
for (const config &j : it->abilities_.child_range(tag_name)) {
if (affects_side(j, resources::gameboard->teams(), side(), it->side()) &&
if (affects_side(j, dc.teams(), side(), it->side()) &&
it->ability_active(tag_name, j, adjacent[i]) &&
ability_affects_adjacent(tag_name, j, i, loc, *it))
{

View file

@ -76,7 +76,7 @@ void unit_drawer::redraw_unit (const unit & u) const
std::string ellipse=u.image_ellipse();
if ( hidden || is_blindfolded || !u.is_visible_to_team(viewing_team_ref,map, show_everything) )
if ( hidden || is_blindfolded || !u.is_visible_to_team(viewing_team_ref, dc, show_everything) )
{
ac.clear_haloes();
if(ac.anim_) {
@ -102,7 +102,7 @@ void unit_drawer::redraw_unit (const unit & u) const
// instead use -1.0 (as in "negative depth", it will be ignored by rendering)
params.submerge= is_flying ? -1.0 : terrain_info.unit_submerge();
if (u.invisible(loc) &&
if (u.invisible(loc, dc) &&
params.highlight_ratio > 0.5) {
params.highlight_ratio = 0.5;
}

View file

@ -500,7 +500,7 @@ bool basic_unit_filter_impl::internal_matches_filter(const unit & u, const map_l
bool found = false;
for (const int viewer : viewers) {
bool fogged = fc_.get_disp_context().teams()[viewer - 1].fogged(loc);
bool hiding = u.invisible(loc/*, false(?) */);
bool hiding = u.invisible(loc, fc_.get_disp_context());
bool unit_hidden = fogged || hiding;
if (vision["visible"].to_bool(true) != unit_hidden) {
found = true;

View file

@ -267,7 +267,7 @@ void unit_mover::start(unit_ptr u)
disp_->invalidate(path_[0]);
// If the unit can be seen here by the viewing side:
if ( !is_enemy_ || !temp_unit_ptr_->invisible(path_[0]) ) {
if ( !is_enemy_ || !temp_unit_ptr_->invisible(path_[0], disp_->get_disp_context()) ) {
// Scroll to the path, but only if it fully fits on screen.
// If it does not fit we might be able to do a better scroll later.
disp_->scroll_to_tiles(path_, game_display::ONSCREEN, true, true, 0.0, false);
@ -336,8 +336,8 @@ void unit_mover::proceed_to(unit_ptr u, size_t path_index, bool update, bool wai
for ( ; current_ < path_index; ++current_ )
// If the unit can be seen by the viewing side while making this step:
if ( !is_enemy_ || !temp_unit_ptr_->invisible(path_[current_]) ||
!temp_unit_ptr_->invisible(path_[current_+1]) )
if ( !is_enemy_ || !temp_unit_ptr_->invisible(path_[current_], disp_->get_disp_context()) ||
!temp_unit_ptr_->invisible(path_[current_+1], disp_->get_disp_context()) )
{
// Wait for the previous step to complete before drawing the next one.
wait_for_anims();

View file

@ -2280,7 +2280,7 @@ void unit::apply_modifications()
max_experience_ = std::max<int>(1, (max_experience_ * exp_accel + 50)/100);
}
bool unit::invisible(const map_location& loc, bool see_all) const
bool unit::invisible(const map_location& loc, const display_context& dc, bool see_all) const
{
if (loc != get_location()) {
DBG_UT << "unit::invisible called: id = " << id() << " loc = " << loc << " get_loc = " << get_location() << std::endl;
@ -2305,7 +2305,7 @@ bool unit::invisible(const map_location& loc, bool see_all) const
// Test hidden status
static const std::string hides("hides");
bool is_inv = get_ability_bool(hides,loc);
bool is_inv = get_ability_bool(hides, loc, dc);
if(is_inv){
is_inv = (resources::gameboard ? !resources::gameboard->would_be_discovered(loc, side_,see_all) : true);
}
@ -2322,14 +2322,14 @@ bool unit::invisible(const map_location& loc, bool see_all) const
}
bool unit::is_visible_to_team(team const& team, gamemap const& map, bool const see_all) const
bool unit::is_visible_to_team(team const& team, display_context const& dc, bool const see_all) const
{
map_location const& loc = get_location();
if (!map.on_board(loc))
if (!dc.map().on_board(loc))
return false;
if (see_all)
return true;
if (team.is_enemy(side()) && invisible(loc))
if (team.is_enemy(side()) && invisible(loc, dc))
return false;
// allied planned moves are also visible under fog. (we assume that fake units on the map are always whiteboard markers)
if (!team.is_enemy(side()) && underlying_id_.is_fake())

View file

@ -25,6 +25,7 @@
#include "units/id.hpp"
class display;
class display_context;
class gamemap;
struct SDL_Color;
class team;
@ -366,13 +367,13 @@ public:
* Returns true if the unit is currently under effect by an ability with this given TAG NAME.
* This means that the ability could be owned by the unit itself, or by an adjacent unit.
*/
bool get_ability_bool(const std::string& tag_name, const map_location& loc) const;
bool get_ability_bool(const std::string& tag_name, const map_location& loc, const display_context& dc) const;
/**
* Returns true if the unit is currently under effect by an ability with this given TAG NAME.
* This means that the ability could be owned by the unit itself, or by an adjacent unit.
*/
bool get_ability_bool(const std::string &tag_name) const
{ return get_ability_bool(tag_name, loc_); }
bool get_ability_bool(const std::string &tag_name, const display_context& dc) const
{ return get_ability_bool(tag_name, loc_, dc); }
unit_ability_list get_abilities(const std::string &tag_name, const map_location& loc) const;
unit_ability_list get_abilities(const std::string &tag_name) const
{ return get_abilities(tag_name, loc_); }
@ -389,9 +390,9 @@ public:
void generate_name();
// Only see_all=true use caching
bool invisible(const map_location& loc, bool see_all=true) const;
bool invisible(const map_location& loc, const display_context& dc, bool see_all = true) const;
bool is_visible_to_team(team const& team, gamemap const & map , bool const see_all = true) const;
bool is_visible_to_team(team const& team, display_context const& dc, bool const see_all = true) const;
/** Mark this unit as clone so it can be inserted to unit_map
* @returns self (for convenience)

View file

@ -68,7 +68,7 @@ void mapbuilder::pre_build()
//Remove any unit the current side cannot see to avoid their detection by planning
//Units will be restored to the unit map by destruction of removers_
if(!on_current_side && !u.is_visible_to_team(resources::gameboard->teams()[viewer_team()], resources::gameboard->map(), false)) {
if(!on_current_side && !u.is_visible_to_team(resources::gameboard->teams()[viewer_team()], *resources::gameboard, false)) {
removers_.push_back(new temporary_unit_remover(*resources::units, u.get_location()));
//Don't do anything else to the removed unit!