Merge pull request #760 from jyrkive/editor-crashes
Fix crash on placing a unit with the scenario editor
This commit is contained in:
commit
bda24b3f93
31 changed files with 81 additions and 69 deletions
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]) == ¤t_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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>},
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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!
|
||||
|
|
Loading…
Add table
Reference in a new issue