Merge branch 'reference_count_units'
This commit is contained in:
commit
35180b82d1
76 changed files with 533 additions and 414 deletions
|
@ -21,9 +21,11 @@
|
|||
|
||||
#include "construct_dialog.hpp"
|
||||
#include "display.hpp"
|
||||
#include "formula_string_utils.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
#include "sdl/alpha.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "../synced_checkup.hpp"
|
||||
#include "../synced_context.hpp"
|
||||
#include "../team.hpp"
|
||||
#include "../unit.hpp"
|
||||
#include "../unit_display.hpp"
|
||||
#include "../variable.hpp"
|
||||
#include "../whiteboard/manager.hpp"
|
||||
|
@ -189,10 +190,11 @@ void unit_creator::add_unit(const config &cfg, const vconfig* vcfg)
|
|||
bool animate = temp_cfg["animate"].to_bool();
|
||||
temp_cfg.remove_attribute("animate");
|
||||
|
||||
std::vector<unit> &recall_list = team_.recall_list();
|
||||
std::vector<unit>::iterator recall_list_element = find_if_matches_id(recall_list, id);
|
||||
std::vector<UnitPtr > &recall_list = team_.recall_list();
|
||||
std::vector<UnitPtr >::iterator recall_list_it = find_if_matches_id(recall_list, id);
|
||||
UnitPtr & recall_list_element = *recall_list_it;
|
||||
|
||||
if ( recall_list_element == recall_list.end() ) {
|
||||
if ( recall_list_it == recall_list.end() ) {
|
||||
//make a temporary unit
|
||||
boost::scoped_ptr<unit> temp_unit(new unit(temp_cfg, true, vcfg));
|
||||
map_location loc = find_location(temp_cfg, temp_unit.get());
|
||||
|
@ -206,7 +208,8 @@ void unit_creator::add_unit(const config &cfg, const vconfig* vcfg)
|
|||
else if ( add_to_recall_ ) {
|
||||
//add to recall list
|
||||
unit *new_unit = temp_unit.get();
|
||||
recall_list.push_back(*new_unit);
|
||||
UnitPtr temp_ptr = UnitPtr(new unit(*new_unit));
|
||||
recall_list.push_back(temp_ptr);
|
||||
DBG_NG << "inserting unit with id=["<<id<<"] on recall list for side " << new_unit->side() << "\n";
|
||||
preferences::encountered_units().insert(new_unit->type_id());
|
||||
}
|
||||
|
@ -286,6 +289,12 @@ bool can_recruit_from(const map_location& leader_loc, int side)
|
|||
!= map_location::null_location();
|
||||
}
|
||||
|
||||
bool can_recruit_from(const unit& leader)
|
||||
{
|
||||
return can_recruit_from(leader.get_location(), leader.side());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks to see if a leader at @a leader_loc could recruit on @a recruit_loc.
|
||||
* This takes into account terrain, shroud (for side @a side), and whether or
|
||||
|
@ -328,6 +337,11 @@ bool can_recruit_on(const map_location& leader_loc, const map_location& recruit_
|
|||
return !rt.steps.empty();
|
||||
}
|
||||
|
||||
bool can_recruit_on(const unit& leader, const map_location& recruit_loc)
|
||||
{
|
||||
return can_recruit_on(leader.get_location(), recruit_loc, leader.side());
|
||||
}
|
||||
|
||||
|
||||
namespace actions {
|
||||
|
||||
|
@ -402,26 +416,29 @@ namespace { // Helpers for get_recalls()
|
|||
* that can be skipped (because they are already in @a result), and the
|
||||
* underlying ID of units added to @a result will be added to @a already_added.
|
||||
*/
|
||||
void add_leader_filtered_recalls(const unit & leader,
|
||||
std::vector<const unit*> & result,
|
||||
void add_leader_filtered_recalls(const UnitConstPtr leader,
|
||||
std::vector< UnitConstPtr > & result,
|
||||
std::set<size_t> * already_added = NULL)
|
||||
{
|
||||
const team& leader_team = (*resources::teams)[leader.side()-1];
|
||||
const std::vector<unit>& recall_list = leader_team.recall_list();
|
||||
const team& leader_team = (*resources::teams)[leader->side()-1];
|
||||
const std::vector<UnitPtr >& recall_list = leader_team.recall_list();
|
||||
const std::string& save_id = leader_team.save_id();
|
||||
|
||||
BOOST_FOREACH(const unit& recall_unit, recall_list)
|
||||
BOOST_FOREACH(const UnitConstPtr & recall_unit_ptr, recall_list)
|
||||
{
|
||||
const unit & recall_unit = *recall_unit_ptr;
|
||||
// Do not add a unit twice.
|
||||
size_t underlying_id = recall_unit.underlying_id();
|
||||
if ( !already_added || already_added->count(underlying_id) == 0 )
|
||||
{
|
||||
// Only units that match the leader's recall filter are valid.
|
||||
scoped_recall_unit this_unit("this_unit", save_id, &recall_unit - &recall_list[0]);
|
||||
const std::vector<UnitPtr >::const_iterator rit = find_if_matches_id(recall_list, recall_unit.id());
|
||||
|
||||
if ( recall_unit.matches_filter(vconfig(leader.recall_filter()), map_location::null_location()) )
|
||||
scoped_recall_unit this_unit("this_unit", save_id, rit - recall_list.begin());
|
||||
|
||||
if ( recall_unit.matches_filter(vconfig(leader->recall_filter()), map_location::null_location()) )
|
||||
{
|
||||
result.push_back(&recall_unit);
|
||||
result.push_back(recall_unit_ptr);
|
||||
if ( already_added != NULL )
|
||||
already_added->insert(underlying_id);
|
||||
}
|
||||
|
@ -430,11 +447,11 @@ namespace { // Helpers for get_recalls()
|
|||
}
|
||||
}// anonymous namespace
|
||||
|
||||
const std::vector<const unit*> get_recalls(int side, const map_location &recall_loc)
|
||||
std::vector<UnitConstPtr > get_recalls(int side, const map_location &recall_loc)
|
||||
{
|
||||
LOG_NG << "getting recall list for side " << side << " at location " << recall_loc << "\n";
|
||||
|
||||
std::vector<const unit*> result;
|
||||
std::vector<UnitConstPtr > result;
|
||||
|
||||
/*
|
||||
* We have three use cases:
|
||||
|
@ -449,14 +466,14 @@ const std::vector<const unit*> get_recalls(int side, const map_location &recall_
|
|||
|
||||
// Check for a leader at recall_loc (means we are recalling from there,
|
||||
// rather than to there).
|
||||
unit_map::const_iterator find_it = resources::units->find(recall_loc);
|
||||
const unit_map::const_iterator find_it = resources::units->find(recall_loc);
|
||||
if ( find_it != resources::units->end() ) {
|
||||
if ( find_it->can_recruit() && find_it->side() == side &&
|
||||
resources::gameboard->map().is_keep(recall_loc) )
|
||||
{
|
||||
// We have been requested to get the recalls for this
|
||||
// particular leader.
|
||||
add_leader_filtered_recalls(*find_it, result);
|
||||
add_leader_filtered_recalls(find_it.get_shared_ptr(), result);
|
||||
return result;
|
||||
}
|
||||
else if ( find_it->is_visible_to_team((*resources::teams)[side-1], resources::gameboard->map(), false) )
|
||||
|
@ -482,17 +499,17 @@ const std::vector<const unit*> get_recalls(int side, const map_location &recall_
|
|||
continue;
|
||||
leader_in_place= true;
|
||||
|
||||
add_leader_filtered_recalls(*u, result, &valid_local_recalls);
|
||||
add_leader_filtered_recalls(u.get_shared_ptr(), result, &valid_local_recalls);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !leader_in_place )
|
||||
{
|
||||
// Return the full recall list.
|
||||
const std::vector<unit>& recall_list = (*resources::teams)[side-1].recall_list();
|
||||
BOOST_FOREACH(const unit &recall, recall_list)
|
||||
const std::vector< UnitPtr >& recall_list = (*resources::teams)[side-1].recall_list();
|
||||
BOOST_FOREACH(const UnitConstPtr & recall, recall_list)
|
||||
{
|
||||
result.push_back(&recall);
|
||||
result.push_back(recall);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -515,9 +532,10 @@ namespace { // Helpers for check_recall_location()
|
|||
return RECRUIT_NO_LEADER;
|
||||
|
||||
// Make sure the recalling unit can recall this specific unit.
|
||||
const team& recall_team = (*resources::teams)[recaller.side()-1];
|
||||
team& recall_team = (*resources::teams)[recaller.side()-1];
|
||||
std::vector<UnitPtr >::iterator it = find_if_matches_id(recall_team.recall_list(), recall_unit.id());
|
||||
scoped_recall_unit this_unit("this_unit", recall_team.save_id(),
|
||||
&recall_unit - &recall_team.recall_list()[0]);
|
||||
it - recall_team.recall_list().begin());
|
||||
if ( !recall_unit.matches_filter(vconfig(recaller.recall_filter()),
|
||||
map_location::null_location()) )
|
||||
return RECRUIT_NO_ABLE_LEADER;
|
||||
|
@ -966,12 +984,12 @@ bool place_recruit(const unit &u, const map_location &recruit_location, const ma
|
|||
void recruit_unit(const unit_type & u_type, int side_num, const map_location & loc,
|
||||
const map_location & from, bool show, bool use_undo)
|
||||
{
|
||||
const unit new_unit(u_type, side_num, true);
|
||||
const UnitPtr new_unit = UnitPtr( new unit(u_type, side_num, true));
|
||||
|
||||
|
||||
// Place the recruit.
|
||||
bool mutated = place_recruit(new_unit, loc, from, u_type.cost(), false, show);
|
||||
statistics::recruit_unit(new_unit);
|
||||
bool mutated = place_recruit(*new_unit, loc, from, u_type.cost(), false, show);
|
||||
statistics::recruit_unit(*new_unit);
|
||||
|
||||
// To speed things a bit, don't bother with the undo stack during
|
||||
// an AI turn. The AI will not undo nor delay shroud updates.
|
||||
|
@ -999,16 +1017,16 @@ bool recall_unit(const std::string & id, team & current_team,
|
|||
const map_location & loc, const map_location & from,
|
||||
bool show, bool use_undo)
|
||||
{
|
||||
std::vector<unit> & recall_list = current_team.recall_list();
|
||||
std::vector<UnitPtr > & recall_list = current_team.recall_list();
|
||||
|
||||
// Find the unit to recall.
|
||||
std::vector<unit>::iterator recall_it = find_if_matches_id(recall_list, id);
|
||||
std::vector<UnitPtr >::iterator recall_it = find_if_matches_id(recall_list, id);
|
||||
if ( recall_it == recall_list.end() )
|
||||
return false;
|
||||
|
||||
|
||||
// Make a copy of the unit before erasing it from the list.
|
||||
unit recall(*recall_it);
|
||||
UnitPtr recall(*recall_it);
|
||||
recall_list.erase(recall_it);
|
||||
// ** IMPORTANT: id might become invalid at this point!
|
||||
// (Use recall.id() instead, if needed.)
|
||||
|
@ -1017,15 +1035,15 @@ bool recall_unit(const std::string & id, team & current_team,
|
|||
// We also check to see if a custom unit level recall has been set if not,
|
||||
// we use the team's recall cost otherwise the unit's.
|
||||
bool mutated;
|
||||
if (recall.recall_cost() < 0) {
|
||||
mutated = place_recruit(recall, loc, from, current_team.recall_cost(),
|
||||
if (recall->recall_cost() < 0) {
|
||||
mutated = place_recruit(*recall, loc, from, current_team.recall_cost(),
|
||||
true, show);
|
||||
}
|
||||
else {
|
||||
mutated = place_recruit(recall, loc, from, recall.recall_cost(),
|
||||
mutated = place_recruit(*recall, loc, from, recall->recall_cost(),
|
||||
true, show);
|
||||
}
|
||||
statistics::recall_unit(recall);
|
||||
statistics::recall_unit(*recall);
|
||||
|
||||
// To speed things a bit, don't bother with the undo stack during
|
||||
// an AI turn. The AI will not undo nor delay shroud updates.
|
||||
|
|
|
@ -21,12 +21,13 @@
|
|||
#ifndef ACTIONS_CREATE_H_INCLUDED
|
||||
#define ACTIONS_CREATE_H_INCLUDED
|
||||
|
||||
class config;
|
||||
class team;
|
||||
class vconfig;
|
||||
class config;
|
||||
class team;
|
||||
class unit_type;
|
||||
class vconfig;
|
||||
|
||||
#include "../map_location.hpp"
|
||||
#include "../unit.hpp"
|
||||
#include "../unit_ptr.hpp"
|
||||
|
||||
|
||||
class unit_creator {
|
||||
|
@ -71,16 +72,14 @@ private:
|
|||
bool can_recruit_from(const map_location& leader_loc, int side);
|
||||
/// Checks to see if @a leader (assumed a leader) can recruit somewhere.
|
||||
/// This takes into account terrain, shroud, and the presence of visible units.
|
||||
inline bool can_recruit_from(const unit& leader)
|
||||
{ return can_recruit_from(leader.get_location(), leader.side()); }
|
||||
bool can_recruit_from(const unit& leader);
|
||||
|
||||
/// Checks to see if a leader at @a leader_loc could recruit on @a recruit_loc.
|
||||
bool can_recruit_on(const map_location& leader_loc, const map_location& recruit_loc, int side);
|
||||
/// Checks to see if @a leader (assumed a leader) can recruit on @a recruit_loc.
|
||||
/// This takes into account terrain, shroud, and whether or not there is already
|
||||
/// a visible unit at recruit_loc.
|
||||
inline bool can_recruit_on(const unit& leader, const map_location& recruit_loc)
|
||||
{ return can_recruit_on(leader.get_location(), recruit_loc, leader.side()); }
|
||||
bool can_recruit_on(const unit& leader, const map_location& recruit_loc);
|
||||
|
||||
|
||||
namespace actions {
|
||||
|
@ -190,7 +189,7 @@ const std::set<std::string> get_recruits(int side, const map_location &recruit_l
|
|||
* @param recall_loc the hex field being part of the castle the player wants to recruit on or from.
|
||||
* @return a set of units that can be recalled by @a side on (or from) @a recall_loc or the full recall list of @a side.
|
||||
*/
|
||||
const std::vector<const unit*> get_recalls(int side, const map_location &recall_loc);
|
||||
std::vector<UnitConstPtr > get_recalls(int side, const map_location &recall_loc);
|
||||
|
||||
/**
|
||||
* Place a unit into the game.
|
||||
|
|
|
@ -1073,7 +1073,7 @@ namespace { // Private helpers for move_unit()
|
|||
if ( mover_valid ) {
|
||||
// MP_COUNTDOWN: added param
|
||||
undo_stack->add_move(
|
||||
*move_it_, begin_, real_end_, orig_moves_,
|
||||
move_it_.get_shared_ptr(), begin_, real_end_, orig_moves_,
|
||||
action_time_bonus, orig_village_owner, orig_dir_);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,14 +56,14 @@ undo_list::undo_action::~undo_action()
|
|||
|
||||
|
||||
struct undo_list::dismiss_action : undo_list::undo_action {
|
||||
unit dismissed_unit;
|
||||
UnitPtr dismissed_unit;
|
||||
|
||||
|
||||
explicit dismiss_action(const unit& dismissed) : undo_action(),
|
||||
dismissed_unit(dismissed)
|
||||
explicit dismiss_action(const UnitConstPtr dismissed) : undo_action(),
|
||||
dismissed_unit(new unit(*dismissed))
|
||||
{}
|
||||
explicit dismiss_action(const config & unit_cfg) : undo_action(),
|
||||
dismissed_unit(unit_cfg)
|
||||
dismissed_unit(new unit(unit_cfg))
|
||||
{}
|
||||
virtual ~dismiss_action();
|
||||
|
||||
|
@ -86,7 +86,7 @@ struct undo_list::move_action : undo_list::undo_action {
|
|||
map_location goto_hex;
|
||||
|
||||
|
||||
move_action(const unit& moved,
|
||||
move_action(const UnitConstPtr moved,
|
||||
const std::vector<map_location>::const_iterator & begin,
|
||||
const std::vector<map_location>::const_iterator & end,
|
||||
int sm, int timebonus, int orig, const map_location::DIRECTION dir) :
|
||||
|
@ -94,8 +94,8 @@ struct undo_list::move_action : undo_list::undo_action {
|
|||
starting_moves(sm),
|
||||
original_village_owner(orig),
|
||||
countdown_time_bonus(timebonus),
|
||||
starting_dir(dir == map_location::NDIRECTIONS ? moved.facing() : dir),
|
||||
goto_hex(moved.get_goto())
|
||||
starting_dir(dir == map_location::NDIRECTIONS ? moved->facing() : dir),
|
||||
goto_hex(moved->get_goto())
|
||||
{}
|
||||
move_action(const config & unit_cfg, const config & route_cfg,
|
||||
int sm, int timebonus, int orig, const map_location::DIRECTION dir) :
|
||||
|
@ -127,10 +127,10 @@ struct undo_list::recall_action : undo_list::undo_action {
|
|||
map_location recall_from;
|
||||
|
||||
|
||||
recall_action(const unit& recalled, const map_location& loc,
|
||||
recall_action(const UnitConstPtr recalled, const map_location& loc,
|
||||
const map_location& from) :
|
||||
undo_action(recalled, loc),
|
||||
id(recalled.id()),
|
||||
id(recalled->id()),
|
||||
recall_from(from)
|
||||
{}
|
||||
recall_action(const config & unit_cfg, const map_location & loc,
|
||||
|
@ -157,10 +157,10 @@ struct undo_list::recruit_action : undo_list::undo_action {
|
|||
map_location recruit_from;
|
||||
|
||||
|
||||
recruit_action(const unit& recruited, const map_location& loc,
|
||||
recruit_action(const UnitConstPtr recruited, const map_location& loc,
|
||||
const map_location& from) :
|
||||
undo_action(recruited, loc),
|
||||
u_type(recruited.type()),
|
||||
u_type(recruited->type()),
|
||||
recruit_from(from)
|
||||
{}
|
||||
recruit_action(const config & unit_cfg, const unit_type & type,
|
||||
|
@ -291,7 +291,7 @@ void undo_list::dismiss_action::write(config & cfg) const
|
|||
{
|
||||
cfg.add_child("replay_data", replay_data);
|
||||
cfg["type"] = "dismiss";
|
||||
dismissed_unit.write(cfg.add_child("unit"));
|
||||
dismissed_unit->write(cfg.add_child("unit"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -399,7 +399,7 @@ void undo_list::add_auto_shroud(bool turned_on)
|
|||
/**
|
||||
* Adds a dismissal to the undo stack.
|
||||
*/
|
||||
void undo_list::add_dismissal(const unit & u)
|
||||
void undo_list::add_dismissal(const UnitConstPtr u)
|
||||
{
|
||||
add(new dismiss_action(u));
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ void undo_list::add_dismissal(const unit & u)
|
|||
/**
|
||||
* Adds a move to the undo stack.
|
||||
*/
|
||||
void undo_list::add_move(const unit& u,
|
||||
void undo_list::add_move(const UnitConstPtr u,
|
||||
const std::vector<map_location>::const_iterator & begin,
|
||||
const std::vector<map_location>::const_iterator & end,
|
||||
int start_moves, int timebonus, int village_owner,
|
||||
|
@ -419,7 +419,7 @@ void undo_list::add_move(const unit& u,
|
|||
/**
|
||||
* Adds a recall to the undo stack.
|
||||
*/
|
||||
void undo_list::add_recall(const unit& u, const map_location& loc,
|
||||
void undo_list::add_recall(const UnitConstPtr u, const map_location& loc,
|
||||
const map_location& from)
|
||||
{
|
||||
add(new recall_action(u, loc, from));
|
||||
|
@ -428,7 +428,7 @@ void undo_list::add_recall(const unit& u, const map_location& loc,
|
|||
/**
|
||||
* Adds a recruit to the undo stack.
|
||||
*/
|
||||
void undo_list::add_recruit(const unit& u, const map_location& loc,
|
||||
void undo_list::add_recruit(const UnitConstPtr u, const map_location& loc,
|
||||
const map_location& from)
|
||||
{
|
||||
add(new recruit_action(u, loc, from));
|
||||
|
@ -648,9 +648,13 @@ bool undo_list::recall_action::undo(int side, undo_list & /*undos*/)
|
|||
return false;
|
||||
}
|
||||
|
||||
const unit &un = *un_it;
|
||||
statistics::un_recall_unit(un);
|
||||
int cost = statistics::un_recall_unit_cost(un);
|
||||
UnitPtr un = un_it.get_shared_ptr();
|
||||
if (!un) {
|
||||
return false;
|
||||
}
|
||||
|
||||
statistics::un_recall_unit(*un);
|
||||
int cost = statistics::un_recall_unit_cost(*un);
|
||||
if (cost < 0) {
|
||||
current_team.spend_gold(-current_team.recall_cost());
|
||||
}
|
||||
|
@ -829,9 +833,7 @@ bool undo_list::dismiss_action::redo(int side)
|
|||
}
|
||||
recorder.redo(replay_data);
|
||||
replay_data.clear();
|
||||
std::vector<unit>::iterator unit_it =
|
||||
find_if_matches_id(current_team.recall_list(), dismissed_unit.id());
|
||||
current_team.recall_list().erase(unit_it);
|
||||
erase_if_matches_id(current_team.recall_list(), dismissed_unit->id());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -853,15 +855,15 @@ bool undo_list::recall_action::redo(int side)
|
|||
map_location loc = route.front();
|
||||
map_location from = recall_from;
|
||||
|
||||
const std::vector<unit> & recalls = current_team.recall_list();
|
||||
std::vector<unit>::const_iterator unit_it = find_if_matches_id(recalls, id);
|
||||
const std::vector<UnitPtr > & recalls = current_team.recall_list();
|
||||
std::vector<UnitPtr >::const_iterator unit_it = find_if_matches_id(recalls, id);
|
||||
if ( unit_it == recalls.end() ) {
|
||||
ERR_NG << "Trying to redo a recall of '" << id
|
||||
<< "', but that unit is not in the recall list.";
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string &msg = find_recall_location(side, loc, from, *unit_it);
|
||||
const std::string &msg = find_recall_location(side, loc, from, **unit_it);
|
||||
if ( msg.empty() ) {
|
||||
recorder.redo(replay_data);
|
||||
replay_data.clear();
|
||||
|
|
|
@ -22,13 +22,12 @@
|
|||
|
||||
#include "vision.hpp"
|
||||
#include "../map_location.hpp"
|
||||
#include "../unit_ptr.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
#include <vector>
|
||||
|
||||
class unit;
|
||||
|
||||
|
||||
namespace actions {
|
||||
|
||||
|
@ -39,18 +38,18 @@ class undo_list : boost::noncopyable {
|
|||
/// Each type of action gets its own derived type.
|
||||
struct undo_action : boost::noncopyable {
|
||||
/// Constructor for move actions.
|
||||
undo_action(const unit& u,
|
||||
undo_action(const UnitConstPtr u,
|
||||
const std::vector<map_location>::const_iterator & begin,
|
||||
const std::vector<map_location>::const_iterator & end) :
|
||||
route(begin, end),
|
||||
view_info(new clearer_info(u))
|
||||
view_info(new clearer_info(*u))
|
||||
{
|
||||
}
|
||||
/// Constructor for recruit and recall actions.
|
||||
/// These types of actions are guaranteed to have a non-empty route.
|
||||
undo_action(const unit& u, const map_location& loc) :
|
||||
undo_action(const UnitConstPtr u, const map_location& loc) :
|
||||
route(1, loc),
|
||||
view_info(new clearer_info(u))
|
||||
view_info(new clearer_info(*u))
|
||||
{}
|
||||
/// Constructor from a config storing the view info.
|
||||
/// Does not set @a route.
|
||||
|
@ -125,18 +124,18 @@ public:
|
|||
/// Adds an auto-shroud toggle to the undo stack.
|
||||
void add_auto_shroud(bool turned_on);
|
||||
/// Adds a dismissal to the undo stack.
|
||||
void add_dismissal(const unit & u);
|
||||
void add_dismissal(const UnitConstPtr u);
|
||||
/// Adds a move to the undo stack.
|
||||
void add_move(const unit& u,
|
||||
void add_move(const UnitConstPtr u,
|
||||
const std::vector<map_location>::const_iterator & begin,
|
||||
const std::vector<map_location>::const_iterator & end,
|
||||
int start_moves, int timebonus=0, int village_owner=-1,
|
||||
const map_location::DIRECTION dir=map_location::NDIRECTIONS);
|
||||
/// Adds a recall to the undo stack.
|
||||
void add_recall(const unit& u, const map_location& loc,
|
||||
void add_recall(const UnitConstPtr u, const map_location& loc,
|
||||
const map_location& from);
|
||||
/// Adds a recruit to the undo stack.
|
||||
void add_recruit(const unit& u, const map_location& loc,
|
||||
void add_recruit(const UnitConstPtr u, const map_location& loc,
|
||||
const map_location& from);
|
||||
private:
|
||||
/// Adds a shroud update to the undo stack.
|
||||
|
|
|
@ -501,12 +501,12 @@ recall_result::recall_result(side_number side,
|
|||
|
||||
const unit * recall_result::get_recall_unit(const team &my_team)
|
||||
{
|
||||
const std::vector<unit>::const_iterator rec = find_if_matches_id(my_team.recall_list(), unit_id_);
|
||||
const std::vector<UnitPtr >::const_iterator rec = find_if_matches_id(my_team.recall_list(), unit_id_);
|
||||
if (rec == my_team.recall_list().end()) {
|
||||
set_error(E_NOT_AVAILABLE_FOR_RECALLING);
|
||||
return NULL;
|
||||
}
|
||||
return &*rec;
|
||||
return rec->get();
|
||||
}
|
||||
|
||||
bool recall_result::test_enough_gold(const team &my_team)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "property_handler.hpp"
|
||||
#include "../../config.hpp"
|
||||
#include "../../log.hpp"
|
||||
#include "../../unit.hpp"
|
||||
|
||||
#include "../formula/ai.hpp"
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "../formula/stage_side_formulas.hpp"
|
||||
#include "../formula/stage_unit_formulas.hpp"
|
||||
#include "../../log.hpp"
|
||||
#include "../../unit.hpp"
|
||||
|
||||
namespace ai {
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ public:
|
|||
, bound_unit_()
|
||||
{
|
||||
map_location loc(cfg["unit_x"] - 1, cfg["unit_y"] - 1); // lua and c++ coords differ by one
|
||||
bound_unit_ = boost::shared_ptr<unit>(new unit(*resources::units->find(loc)));
|
||||
bound_unit_ = UnitPtr(new unit(*resources::units->find(loc)));
|
||||
}
|
||||
|
||||
virtual double evaluate()
|
||||
|
@ -190,7 +190,7 @@ public:
|
|||
this->disable(); // we do not want to execute the same sticky CA twice -> will be moved out to Lua later
|
||||
}
|
||||
private:
|
||||
boost::shared_ptr<unit> bound_unit_;
|
||||
UnitPtr bound_unit_;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "../mouse_handler_base.hpp"
|
||||
#include "../resources.hpp"
|
||||
#include "../tod_manager.hpp"
|
||||
#include "../unit.hpp"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
@ -775,9 +776,9 @@ const moves_map& readonly_context_impl::get_possible_moves() const
|
|||
}
|
||||
|
||||
|
||||
const std::vector<unit>& readonly_context_impl::get_recall_list() const
|
||||
const std::vector<UnitPtr>& readonly_context_impl::get_recall_list() const
|
||||
{
|
||||
static std::vector<unit> dummy_units;
|
||||
static std::vector<UnitPtr> dummy_units;
|
||||
///@todo 1.9: check for (level_["disallow_recall"]))
|
||||
if(!current_team().persistent()) {
|
||||
return dummy_units;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "../generic_event.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "lua/unit_advancements_aspect.hpp"
|
||||
|
||||
#include "../unit_ptr.hpp"
|
||||
|
||||
//#include "../unit.hpp"
|
||||
|
||||
|
@ -298,7 +298,7 @@ public:
|
|||
virtual const moves_map& get_possible_moves() const = 0;
|
||||
|
||||
|
||||
virtual const std::vector<unit>& get_recall_list() const = 0;
|
||||
virtual const std::vector<UnitPtr>& get_recall_list() const = 0;
|
||||
|
||||
|
||||
virtual stage_ptr get_recruitment(ai_context &context) const = 0;
|
||||
|
@ -819,7 +819,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
virtual const std::vector<unit>& get_recall_list() const
|
||||
virtual const std::vector<UnitPtr>& get_recall_list() const
|
||||
{
|
||||
return target_->get_recall_list();
|
||||
}
|
||||
|
@ -1427,7 +1427,7 @@ public:
|
|||
virtual const moves_map& get_possible_moves() const;
|
||||
|
||||
|
||||
virtual const std::vector<unit>& get_recall_list() const;
|
||||
virtual const std::vector<UnitPtr>& get_recall_list() const;
|
||||
|
||||
|
||||
virtual stage_ptr get_recruitment(ai_context &context) const;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "../../mouse_handler_base.hpp"
|
||||
#include "../../resources.hpp"
|
||||
#include "../../terrain_filter.hpp"
|
||||
#include "../../unit.hpp"
|
||||
#include "../../unit_display.hpp"
|
||||
#include "../../wml_exception.hpp"
|
||||
|
||||
|
@ -655,7 +656,8 @@ public:
|
|||
: stage_(s)
|
||||
{
|
||||
}
|
||||
std::pair<std::string, double> operator()(const unit &u) {
|
||||
std::pair<std::string, double> operator()(const UnitPtr u_ptr) {
|
||||
const unit & u = *u_ptr;
|
||||
std::pair<std::string,int> p;
|
||||
p.first = u.id();
|
||||
const unit_type& u_type = u.type();
|
||||
|
@ -761,7 +763,7 @@ bool ai_default_recruitment_stage::analyze_recall_list()
|
|||
return false;
|
||||
}
|
||||
|
||||
const std::vector<unit> &recalls = current_team().recall_list();
|
||||
const std::vector<UnitPtr > &recalls = current_team().recall_list();
|
||||
|
||||
if (recalls.empty()) {
|
||||
return false;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "../../log.hpp"
|
||||
#include "../../map.hpp"
|
||||
#include "../../team.hpp"
|
||||
#include "../../unit.hpp"
|
||||
|
||||
static lg::log_domain log_ai("ai/attack");
|
||||
#define LOG_AI LOG_STREAM(info, log_ai)
|
||||
|
@ -96,7 +97,7 @@ void attack_analysis::analyze(const gamemap& map, unit_map& units,
|
|||
|
||||
for (m = movements.begin(); m != movements.end(); ++m) {
|
||||
// We fix up units map to reflect what this would look like.
|
||||
unit *up = units.extract(m->first);
|
||||
UnitPtr up = units.extract(m->first);
|
||||
up->set_location(m->second);
|
||||
units.insert(up);
|
||||
double m_aggression = aggression;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "../../map.hpp"
|
||||
#include "../../resources.hpp"
|
||||
#include "../../team.hpp"
|
||||
#include "../../unit.hpp"
|
||||
#include "../composite/goal.hpp"
|
||||
#include "../../pathfind/pathfind.hpp"
|
||||
|
||||
|
|
|
@ -810,8 +810,8 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
{
|
||||
std::vector<variant> tmp;
|
||||
|
||||
for(std::vector<unit>::const_iterator i = current_team().recall_list().begin(); i != current_team().recall_list().end(); ++i) {
|
||||
tmp.push_back( variant( new unit_callable(*i) ) );
|
||||
for(std::vector<UnitPtr >::const_iterator i = current_team().recall_list().begin(); i != current_team().recall_list().end(); ++i) {
|
||||
tmp.push_back( variant( new unit_callable(**i) ) );
|
||||
}
|
||||
|
||||
return variant( &tmp );
|
||||
|
|
|
@ -119,7 +119,7 @@ static bool to_map_location(lua_State *L, int &index, map_location &res)
|
|||
{
|
||||
if (lua_isuserdata(L, index))
|
||||
{
|
||||
unit const *u = luaW_tounit(L, index);
|
||||
const UnitConstPtr u = luaW_tounit(L, index);
|
||||
if (!u) return false;
|
||||
res = u->get_location();
|
||||
++index;
|
||||
|
@ -142,7 +142,7 @@ static int cfun_ai_get_suitable_keep(lua_State *L)
|
|||
int index = 1;
|
||||
|
||||
ai::readonly_context &context = get_readonly_context(L);
|
||||
unit const *leader;
|
||||
UnitConstPtr leader;
|
||||
if (lua_isuserdata(L, index))
|
||||
{
|
||||
leader = luaW_tounit(L, index);
|
||||
|
|
|
@ -248,15 +248,15 @@ void recruitment::execute() {
|
|||
// Add recalls.
|
||||
// Recalls are treated as recruits. While recruiting
|
||||
// we'll check if we can do a recall instead of a recruitment.
|
||||
BOOST_FOREACH(const unit& recall, current_team().recall_list()) {
|
||||
BOOST_FOREACH(const UnitConstPtr & recall, current_team().recall_list()) {
|
||||
// Check if this leader is allowed to recall this unit.
|
||||
vconfig filter = vconfig(leader->recall_filter());
|
||||
if (!recall.matches_filter(filter, map_location::null_location())) {
|
||||
if (!recall->matches_filter(filter, map_location::null_location())) {
|
||||
continue;
|
||||
}
|
||||
data.recruits.insert(recall.type_id());
|
||||
data.scores[recall.type_id()] = 0.0;
|
||||
global_recruits.insert(recall.type_id());
|
||||
data.recruits.insert(recall->type_id());
|
||||
data.scores[recall->type_id()] = 0.0;
|
||||
global_recruits.insert(recall->type_id());
|
||||
}
|
||||
|
||||
// Check if leader is in danger. (If a enemies unit can attack the leader)
|
||||
|
@ -470,19 +470,19 @@ const std::string* recruitment::get_appropriate_recall(const std::string& type,
|
|||
const data& leader_data) const {
|
||||
const std::string* best_recall_id = NULL;
|
||||
double best_recall_value = -1;
|
||||
BOOST_FOREACH(const unit& recall_unit, current_team().recall_list()) {
|
||||
if (type != recall_unit.type_id()) {
|
||||
BOOST_FOREACH(const UnitConstPtr & recall_unit, current_team().recall_list()) {
|
||||
if (type != recall_unit->type_id()) {
|
||||
continue;
|
||||
}
|
||||
// Check if this leader is allowed to recall this unit.
|
||||
vconfig filter = vconfig(leader_data.leader->recall_filter());
|
||||
if (!recall_unit.matches_filter(filter, map_location::null_location())) {
|
||||
LOG_AI_RECRUITMENT << "Refused recall because of filter: " << recall_unit.id() << "\n";
|
||||
if (!recall_unit->matches_filter(filter, map_location::null_location())) {
|
||||
LOG_AI_RECRUITMENT << "Refused recall because of filter: " << recall_unit->id() << "\n";
|
||||
continue;
|
||||
}
|
||||
double average_cost_of_advanced_unit = 0;
|
||||
int counter = 0;
|
||||
BOOST_FOREACH(const std::string& advancement, recall_unit.advances_to()) {
|
||||
BOOST_FOREACH(const std::string& advancement, recall_unit->advances_to()) {
|
||||
const unit_type* advancement_type = unit_types.find(advancement);
|
||||
if (!advancement_type) {
|
||||
continue;
|
||||
|
@ -494,16 +494,16 @@ const std::string* recruitment::get_appropriate_recall(const std::string& type,
|
|||
average_cost_of_advanced_unit /= counter;
|
||||
} else {
|
||||
// Unit don't have advancements. Use cost of unit itself.
|
||||
average_cost_of_advanced_unit = recall_unit.cost();
|
||||
average_cost_of_advanced_unit = recall_unit->cost();
|
||||
}
|
||||
double xp_quantity = static_cast<double>(recall_unit.experience()) /
|
||||
recall_unit.max_experience();
|
||||
double recall_value = recall_unit.cost() + xp_quantity * average_cost_of_advanced_unit;
|
||||
double xp_quantity = static_cast<double>(recall_unit->experience()) /
|
||||
recall_unit->max_experience();
|
||||
double recall_value = recall_unit->cost() + xp_quantity * average_cost_of_advanced_unit;
|
||||
if (recall_value < current_team().recall_cost()) {
|
||||
continue; // Unit is not worth to get recalled.
|
||||
}
|
||||
if (recall_value > best_recall_value) {
|
||||
best_recall_id = &recall_unit.id();
|
||||
best_recall_id = &recall_unit->id();
|
||||
best_recall_value = recall_value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "../util.hpp"
|
||||
#include "../resources.hpp"
|
||||
#include "../team.hpp"
|
||||
#include "../unit.hpp"
|
||||
#include "../tod_manager.hpp"
|
||||
|
||||
static lg::log_domain log_ai_testing("ai/testing");
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "../../map.hpp"
|
||||
#include "../../resources.hpp"
|
||||
#include "../../team.hpp"
|
||||
#include "../../unit.hpp"
|
||||
#include "../../pathfind/pathfind.hpp"
|
||||
#include "../../pathfind/teleport.hpp"
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "../../map.hpp"
|
||||
#include "../../resources.hpp"
|
||||
#include "../../team.hpp"
|
||||
#include "../../unit.hpp"
|
||||
#include "../../terrain_filter.hpp"
|
||||
#include "../../pathfind/pathfind.hpp"
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "../../map.hpp"
|
||||
#include "../../resources.hpp"
|
||||
#include "../../team.hpp"
|
||||
#include "../../unit.hpp"
|
||||
#include "../../unit_types.hpp"
|
||||
#include "../../wml_exception.hpp"
|
||||
#include "../../pathfind/pathfind.hpp"
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "formula_callable.hpp"
|
||||
#include "map.hpp"
|
||||
#include "team.hpp"
|
||||
#include "unit.hpp"
|
||||
|
||||
#define CALLABLE_WRAPPER_START(klass) \
|
||||
class klass##_callable : public game_logic::formula_callable { \
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "config.hpp"
|
||||
#include "team.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "gamestatus.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <cassert>
|
||||
|
@ -53,9 +54,9 @@ carryover::carryover(const team& t, const int gold, const bool add)
|
|||
, recall_list_()
|
||||
, save_id_(t.save_id())
|
||||
{
|
||||
BOOST_FOREACH(const unit& u, t.recall_list()) {
|
||||
BOOST_FOREACH(const UnitConstPtr & u, t.recall_list()) {
|
||||
recall_list_.push_back(config());
|
||||
u.write(recall_list_.back());
|
||||
u->write(recall_list_.back());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,9 +111,9 @@ void carryover::update_carryover(const team& t, const int gold, const bool add){
|
|||
current_player_ = t.current_player();
|
||||
name_ = t.name();
|
||||
previous_recruits_.insert(t.recruits().begin(), t.recruits().end());
|
||||
BOOST_FOREACH(const unit& u, t.recall_list()) {
|
||||
BOOST_FOREACH(const UnitConstPtr & u, t.recall_list()) {
|
||||
recall_list_.push_back(config());
|
||||
u.write(recall_list_.back());
|
||||
u->write(recall_list_.back());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "construct_dialog.hpp"
|
||||
|
||||
#include "display.hpp"
|
||||
#include "formula_string_utils.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "sound.hpp"
|
||||
#include "log.hpp"
|
||||
|
|
|
@ -85,20 +85,21 @@ namespace
|
|||
class delete_recall_unit : public gui::dialog_button_action
|
||||
{
|
||||
public:
|
||||
delete_recall_unit(display& disp, gui::filter_textbox& filter, const std::vector<const unit*>& units) : disp_(disp), filter_(filter), units_(units) {}
|
||||
delete_recall_unit(display& disp, gui::filter_textbox& filter, const std::vector<UnitConstPtr >& units) : disp_(disp), filter_(filter), units_(units) {}
|
||||
private:
|
||||
gui::dialog_button_action::RESULT button_pressed(int menu_selection);
|
||||
|
||||
display& disp_;
|
||||
gui::filter_textbox& filter_;
|
||||
const std::vector<const unit*>& units_;
|
||||
const std::vector<UnitConstPtr >& units_;
|
||||
};
|
||||
|
||||
gui::dialog_button_action::RESULT delete_recall_unit::button_pressed(int menu_selection)
|
||||
{
|
||||
const size_t index = size_t(filter_.get_index(menu_selection));
|
||||
if(index < units_.size()) {
|
||||
const unit &u = *(units_[index]);
|
||||
const UnitConstPtr & u_ptr = units_[index];
|
||||
const unit & u = *u_ptr;
|
||||
|
||||
//If the unit is of level > 1, or is close to advancing,
|
||||
//we warn the player about it
|
||||
|
@ -127,17 +128,17 @@ gui::dialog_button_action::RESULT delete_recall_unit::button_pressed(int menu_se
|
|||
// Remove the item from filter_textbox memory
|
||||
filter_.delete_item(menu_selection);
|
||||
//add dismissal to the undo stack
|
||||
resources::undo_stack->add_dismissal(u);
|
||||
resources::undo_stack->add_dismissal(u_ptr);
|
||||
|
||||
// Find the unit in the recall list.
|
||||
std::vector<unit>& recall_list = (*resources::teams)[u.side() -1].recall_list();
|
||||
std::vector<UnitPtr >& recall_list = (*resources::teams)[u.side() -1].recall_list();
|
||||
assert(!recall_list.empty());
|
||||
std::vector<unit>::iterator dismissed_unit =
|
||||
std::vector<UnitPtr >::iterator dismissed_unit =
|
||||
find_if_matches_id(recall_list, u.id());
|
||||
assert(dismissed_unit != recall_list.end());
|
||||
|
||||
// Record the dismissal, then delete the unit.
|
||||
synced_context::run_in_synced_context("disband", replay_helper::get_disband(dismissed_unit->id()));
|
||||
synced_context::run_in_synced_context("disband", replay_helper::get_disband((*dismissed_unit)->id()));
|
||||
//recorder.add_disband(dismissed_unit->id());
|
||||
//recall_list.erase(dismissed_unit);
|
||||
|
||||
|
@ -441,9 +442,9 @@ int recruit_dialog(display& disp, std::vector< const unit_type* >& units, const
|
|||
|
||||
|
||||
#ifdef LOW_MEM
|
||||
int recall_dialog(display& disp, std::vector< const unit* >& units, int /*side*/, const std::string& title_suffix, const int team_recall_cost)
|
||||
int recall_dialog(display& disp, std::vector< UnitConstPtr >& units, int /*side*/, const std::string& title_suffix, const int team_recall_cost)
|
||||
#else
|
||||
int recall_dialog(display& disp, std::vector< const unit* >& units, int side, const std::string& title_suffix, const int team_recall_cost)
|
||||
int recall_dialog(display& disp, std::vector< UnitConstPtr >& units, int side, const std::string& title_suffix, const int team_recall_cost)
|
||||
#endif
|
||||
{
|
||||
std::vector<std::string> options, options_to_filter;
|
||||
|
@ -462,7 +463,7 @@ int recall_dialog(display& disp, std::vector< const unit* >& units, int side, co
|
|||
options.push_back(heading.str());
|
||||
options_to_filter.push_back(options.back());
|
||||
|
||||
BOOST_FOREACH(const unit* u, units)
|
||||
BOOST_FOREACH(const UnitConstPtr & u, units)
|
||||
{
|
||||
std::stringstream option, option_to_filter;
|
||||
std::string name = u->name();
|
||||
|
@ -1207,13 +1208,13 @@ void unit_preview_pane::draw_contents()
|
|||
}
|
||||
}
|
||||
|
||||
units_list_preview_pane::units_list_preview_pane(const unit *u, TYPE type, bool on_left_side) :
|
||||
units_list_preview_pane::units_list_preview_pane(UnitConstPtr u, TYPE type, bool on_left_side) :
|
||||
unit_preview_pane(NULL, type, on_left_side),
|
||||
units_(1, u)
|
||||
{
|
||||
}
|
||||
|
||||
units_list_preview_pane::units_list_preview_pane(const std::vector<const unit *> &units,
|
||||
units_list_preview_pane::units_list_preview_pane(const std::vector<UnitConstPtr > &units,
|
||||
const gui::filter_textbox* filter, TYPE type, bool on_left_side) :
|
||||
unit_preview_pane(filter, type, on_left_side),
|
||||
units_(units)
|
||||
|
@ -1226,7 +1227,7 @@ units_list_preview_pane::units_list_preview_pane(const std::vector<unit> &units,
|
|||
units_(units.size())
|
||||
{
|
||||
for (unsigned i = 0; i < units.size(); ++i)
|
||||
units_[i] = &units[i];
|
||||
units_[i] = UnitConstPtr (new unit(units[i]));
|
||||
}
|
||||
|
||||
size_t units_list_preview_pane::size() const
|
||||
|
|
|
@ -26,6 +26,7 @@ class terrain_type;
|
|||
#include "map_location.hpp"
|
||||
#include "construct_dialog.hpp"
|
||||
#include "network.hpp"
|
||||
#include "unit_ptr.hpp"
|
||||
#include "ai/lua/unit_advancements_aspect.hpp"
|
||||
|
||||
namespace dialogs {
|
||||
|
@ -59,7 +60,7 @@ std::string load_game_dialog(display& disp, const config& terrain_config, bool*
|
|||
|
||||
int recruit_dialog(display& disp, std::vector<const unit_type*>& units, const std::vector<std::string>& items, int side, const std::string& title_suffix);
|
||||
|
||||
int recall_dialog(display& disp, std::vector<const unit*>& units, int side, const std::string& title_suffix, const int team_recall_cost);
|
||||
int recall_dialog(display& disp, std::vector<UnitConstPtr >& units, int side, const std::string& title_suffix, const int team_recall_cost);
|
||||
|
||||
/** Show unit-stats in a side-pane to unit-list, recall-list, etc. */
|
||||
class unit_preview_pane : public gui::preview_pane
|
||||
|
@ -110,8 +111,8 @@ private:
|
|||
class units_list_preview_pane : public dialogs::unit_preview_pane
|
||||
{
|
||||
public:
|
||||
units_list_preview_pane(const unit *u, TYPE type = SHOW_ALL, bool left_side = true);
|
||||
units_list_preview_pane(const std::vector<const unit *> &units,
|
||||
units_list_preview_pane(UnitConstPtr u, TYPE type = SHOW_ALL, bool left_side = true);
|
||||
units_list_preview_pane(const std::vector<UnitConstPtr > &units,
|
||||
const gui::filter_textbox *filter = NULL,
|
||||
TYPE type = SHOW_ALL, bool left_side = true);
|
||||
units_list_preview_pane(const std::vector<unit> &units,
|
||||
|
@ -123,7 +124,7 @@ private:
|
|||
const details get_details() const;
|
||||
void process_event();
|
||||
|
||||
std::vector<const unit *> units_;
|
||||
std::vector<UnitConstPtr > units_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -43,8 +43,10 @@ namespace wb {
|
|||
class manager;
|
||||
}
|
||||
|
||||
#include "animated.hpp"
|
||||
#include "display_context.hpp"
|
||||
#include "font.hpp"
|
||||
#include "image.hpp" //only needed for enums (!)
|
||||
#include "key.hpp"
|
||||
#include "team.hpp"
|
||||
#include "time_of_day.hpp"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "editor_display.hpp"
|
||||
#include "reports.hpp"
|
||||
#include "terrain_builder.hpp"
|
||||
#include "unit_map.hpp"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "serialization/binary_or_text.hpp"
|
||||
#include "serialization/parser.hpp"
|
||||
#include "team.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "wml_exception.hpp"
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "tooltips.hpp"
|
||||
#include "overlay.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "unit_types.hpp"
|
||||
|
||||
#include "editor/action/mouse/mouse_action.hpp"
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "terrain_palettes.hpp"
|
||||
|
||||
#include "../../gettext.hpp"
|
||||
#include "../../formula_string_utils.hpp"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "editor_palettes.hpp"
|
||||
|
||||
#include "../../unit_types.hpp"
|
||||
|
||||
namespace editor {
|
||||
|
||||
//std::string get_selected_terrain();
|
||||
|
|
|
@ -74,12 +74,13 @@ void game_board::set_all_units_user_end_turn() {
|
|||
}
|
||||
|
||||
void game_board::all_survivors_to_recall() {
|
||||
BOOST_FOREACH (unit & un, units_) {
|
||||
if (teams_[un.side() - 1].persistent()) {
|
||||
un.new_turn();
|
||||
un.new_scenario();
|
||||
for (unit_map::iterator it = units_.begin(); it != units_.end(); it++) {
|
||||
UnitPtr un = it.get_shared_ptr();
|
||||
if (teams_[un->side() - 1].persistent()) {
|
||||
un->new_turn();
|
||||
un->new_scenario();
|
||||
#if 0
|
||||
teams_[un.side() - 1].recall_list().push_back(un);
|
||||
teams_[un->side() - 1].recall_list().push_back(un);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -140,14 +141,14 @@ 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)
|
||||
bool game_board::try_add_unit_to_recall_list(const map_location& loc, const UnitPtr u)
|
||||
{
|
||||
if(teams_[u.side()-1].persistent()) {
|
||||
teams_[u.side()-1].recall_list().push_back(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";
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +168,7 @@ boost::optional<std::string> game_board::replace_map(const gamemap & newmap) {
|
|||
|
||||
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)) {
|
||||
if (!try_add_unit_to_recall_list(itor->get_location(), itor.get_shared_ptr())) {
|
||||
*ret = std::string("replace_map: Cannot add a unit that would become off-map to the recall list\n");
|
||||
}
|
||||
units_.erase(itor++);
|
||||
|
@ -256,9 +257,9 @@ void game_board::write_config(config & cfg) const {
|
|||
}
|
||||
//recall list
|
||||
{
|
||||
BOOST_FOREACH(const unit & j, t->recall_list()) {
|
||||
BOOST_FOREACH(const UnitConstPtr & j, t->recall_list()) {
|
||||
config& u = side.add_child("unit");
|
||||
j.write(u);
|
||||
j->write(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +323,7 @@ temporary_unit_remover::~temporary_unit_remover()
|
|||
temporary_unit_mover::temporary_unit_mover(unit_map& m, const map_location& src,
|
||||
const map_location& dst, int new_moves)
|
||||
: m_(m), src_(src), dst_(dst), old_moves_(-1),
|
||||
temp_(src == dst ? NULL : m_.extract(dst))
|
||||
temp_(src == dst ? UnitPtr() : m_.extract(dst))
|
||||
{
|
||||
std::pair<unit_map::iterator, bool> move_result = m_.move(src_, dst_);
|
||||
|
||||
|
@ -337,7 +338,7 @@ temporary_unit_mover::temporary_unit_mover(unit_map& m, const map_location& src,
|
|||
temporary_unit_mover::temporary_unit_mover(game_board& b, const map_location& src,
|
||||
const map_location& dst, int new_moves)
|
||||
: m_(b.units_), src_(src), dst_(dst), old_moves_(-1),
|
||||
temp_(src == dst ? NULL : m_.extract(dst))
|
||||
temp_(src == dst ? UnitPtr() : m_.extract(dst))
|
||||
{
|
||||
std::pair<unit_map::iterator, bool> move_result = m_.move(src_, dst_);
|
||||
|
||||
|
@ -356,7 +357,7 @@ temporary_unit_mover::temporary_unit_mover(game_board& b, const map_location& sr
|
|||
temporary_unit_mover::temporary_unit_mover(unit_map& m, const map_location& src,
|
||||
const map_location& dst)
|
||||
: m_(m), src_(src), dst_(dst), old_moves_(-1),
|
||||
temp_(src == dst ? NULL : m_.extract(dst))
|
||||
temp_(src == dst ? UnitPtr() : m_.extract(dst))
|
||||
{
|
||||
m_.move(src_, dst_);
|
||||
}
|
||||
|
@ -364,7 +365,7 @@ temporary_unit_mover::temporary_unit_mover(unit_map& m, const map_location& src,
|
|||
temporary_unit_mover::temporary_unit_mover(game_board& b, const map_location& src,
|
||||
const map_location& dst)
|
||||
: m_(b.units_), src_(src), dst_(dst), old_moves_(-1),
|
||||
temp_(src == dst ? NULL : m_.extract(dst))
|
||||
temp_(src == dst ? UnitPtr() : m_.extract(dst))
|
||||
{
|
||||
m_.move(src_, dst_);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
|
||||
class config;
|
||||
|
@ -115,7 +116,7 @@ class game_board : public display_context {
|
|||
|
||||
// Manipulator from actionwml
|
||||
|
||||
bool try_add_unit_to_recall_list(const map_location& loc, const unit& u);
|
||||
bool try_add_unit_to_recall_list(const map_location& loc, const UnitPtr u);
|
||||
boost::optional<std::string> replace_map (const gamemap & r);
|
||||
void overlay_map (const gamemap & o, const config & cfg, map_location loc, bool border);
|
||||
|
||||
|
@ -153,7 +154,7 @@ struct temporary_unit_placer
|
|||
private:
|
||||
unit_map& m_;
|
||||
const map_location loc_;
|
||||
unit *temp_;
|
||||
UnitPtr temp_;
|
||||
};
|
||||
|
||||
// Begin Temporary Unit Move Structs
|
||||
|
@ -174,7 +175,7 @@ struct temporary_unit_remover
|
|||
private:
|
||||
unit_map& m_;
|
||||
const map_location loc_;
|
||||
unit *temp_;
|
||||
UnitPtr temp_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -200,7 +201,7 @@ private:
|
|||
const map_location src_;
|
||||
const map_location dst_;
|
||||
int old_moves_;
|
||||
unit *temp_;
|
||||
UnitPtr temp_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ class game_board;
|
|||
#include "chat_events.hpp"
|
||||
#include "display.hpp"
|
||||
#include "pathfind/pathfind.hpp"
|
||||
#include "unit.hpp" // TODO: Refactor so that this is not necessary
|
||||
|
||||
#include <deque>
|
||||
|
||||
|
|
|
@ -970,10 +970,10 @@ WML_HANDLER_FUNCTION(kill, event_info, cfg)
|
|||
for(std::vector<team>::iterator pi = resources::teams->begin();
|
||||
pi!=resources::teams->end(); ++pi)
|
||||
{
|
||||
std::vector<unit>& avail_units = pi->recall_list();
|
||||
for(std::vector<unit>::iterator j = avail_units.begin(); j != avail_units.end();) {
|
||||
std::vector<UnitPtr>& avail_units = pi->recall_list();
|
||||
for(std::vector<UnitPtr>::iterator j = avail_units.begin(); j != avail_units.end();) {
|
||||
scoped_recall_unit auto_store("this_unit", pi->save_id(), j - avail_units.begin());
|
||||
if (j->matches_filter(cfg, map_location())) {
|
||||
if ((*j)->matches_filter(cfg, map_location())) {
|
||||
j = avail_units.erase(j);
|
||||
} else {
|
||||
++j;
|
||||
|
@ -1574,16 +1574,16 @@ WML_HANDLER_FUNCTION(recall, /*event_info*/, cfg)
|
|||
continue;
|
||||
}
|
||||
|
||||
std::vector<unit>& avail = (*resources::teams)[index].recall_list();
|
||||
std::vector<UnitPtr>& avail = (*resources::teams)[index].recall_list();
|
||||
std::vector<unit_map::unit_iterator> leaders = resources::units->find_leaders(index + 1);
|
||||
|
||||
for(std::vector<unit>::iterator u = avail.begin(); u != avail.end(); ++u) {
|
||||
for(std::vector<UnitPtr>::iterator u = avail.begin(); u != avail.end(); ++u) {
|
||||
DBG_NG << "checking unit against filter...\n";
|
||||
scoped_recall_unit auto_store("this_unit", player_id, u - avail.begin());
|
||||
if (u->matches_filter(unit_filter, map_location())) {
|
||||
DBG_NG << u->id() << " matched the filter...\n";
|
||||
const unit to_recruit(*u);
|
||||
const unit* pass_check = &to_recruit;
|
||||
if ((*u)->matches_filter(unit_filter, map_location())) {
|
||||
DBG_NG << (*u)->id() << " matched the filter...\n";
|
||||
const UnitPtr to_recruit = *u;
|
||||
const unit* pass_check = to_recruit.get();
|
||||
if(!cfg["check_passability"].to_bool(true)) pass_check = NULL;
|
||||
const map_location cfg_loc = cfg_to_loc(cfg);
|
||||
|
||||
|
@ -1592,7 +1592,7 @@ WML_HANDLER_FUNCTION(recall, /*event_info*/, cfg)
|
|||
DBG_NG << "...considering " + leader->id() + " as the recalling leader...\n";
|
||||
map_location loc = cfg_loc;
|
||||
if ( (leader_filter.null() || leader->matches_filter(leader_filter)) &&
|
||||
u->matches_filter(vconfig(leader->recall_filter()), map_location()) ) {
|
||||
(*u)->matches_filter(vconfig(leader->recall_filter()), map_location()) ) {
|
||||
DBG_NG << "...matched the leader filter and is able to recall the unit.\n";
|
||||
if(!resources::gameboard->map().on_board(loc))
|
||||
loc = leader->get_location();
|
||||
|
@ -1601,7 +1601,7 @@ WML_HANDLER_FUNCTION(recall, /*event_info*/, cfg)
|
|||
if(resources::gameboard->map().on_board(loc)) {
|
||||
DBG_NG << "...valid location for the recall found. Recalling.\n";
|
||||
avail.erase(u); // Erase before recruiting, since recruiting can fire more events
|
||||
actions::place_recruit(to_recruit, loc, leader->get_location(), 0, true,
|
||||
actions::place_recruit(*to_recruit, loc, leader->get_location(), 0, true,
|
||||
cfg["show"].to_bool(true), cfg["fire_event"].to_bool(false),
|
||||
true, true);
|
||||
return;
|
||||
|
@ -1617,7 +1617,7 @@ WML_HANDLER_FUNCTION(recall, /*event_info*/, cfg)
|
|||
DBG_NG << "No usable leader found, but found usable location. Recalling.\n";
|
||||
avail.erase(u); // Erase before recruiting, since recruiting can fire more events
|
||||
map_location null_location = map_location::null_location();
|
||||
actions::place_recruit(to_recruit, loc, null_location, 0, true, cfg["show"].to_bool(true),
|
||||
actions::place_recruit(*to_recruit, loc, null_location, 0, true, cfg["show"].to_bool(true),
|
||||
cfg["fire_event"].to_bool(false), true, true);
|
||||
return;
|
||||
}
|
||||
|
@ -1795,10 +1795,10 @@ WML_HANDLER_FUNCTION(role, /*event_info*/, cfg)
|
|||
}
|
||||
// Iterate over the player's recall list to find a match
|
||||
for(size_t i=0; i < pi->recall_list().size(); ++i) {
|
||||
unit& u = pi->recall_list()[i];
|
||||
UnitPtr & u = pi->recall_list()[i];
|
||||
scoped_recall_unit auto_store("this_unit", player_id, i);
|
||||
if (u.matches_filter(filter, map_location())) {
|
||||
u.set_role(cfg["role"]);
|
||||
if (u->matches_filter(filter, map_location())) {
|
||||
u->set_role(cfg["role"]);
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
|
@ -2513,16 +2513,16 @@ WML_HANDLER_FUNCTION(unstore_unit, /*event_info*/, cfg)
|
|||
|
||||
try {
|
||||
config tmp_cfg(var);
|
||||
const unit u(tmp_cfg, false);
|
||||
const UnitPtr u = UnitPtr( new unit(tmp_cfg, false));
|
||||
|
||||
preferences::encountered_units().insert(u.type_id());
|
||||
preferences::encountered_units().insert(u->type_id());
|
||||
map_location loc = cfg_to_loc(
|
||||
(cfg.has_attribute("x") && cfg.has_attribute("y")) ? cfg : vconfig(var));
|
||||
const bool advance = cfg["advance"].to_bool(true);
|
||||
if(resources::gameboard->map().on_board(loc)) {
|
||||
if (cfg["find_vacant"].to_bool()) {
|
||||
const unit* pass_check = NULL;
|
||||
if (cfg["check_passability"].to_bool(true)) pass_check = &u;
|
||||
if (cfg["check_passability"].to_bool(true)) pass_check = u.get();
|
||||
loc = pathfind::find_vacant_tile(
|
||||
loc,
|
||||
pathfind::VACANT_ANY,
|
||||
|
@ -2530,7 +2530,7 @@ WML_HANDLER_FUNCTION(unstore_unit, /*event_info*/, cfg)
|
|||
}
|
||||
|
||||
resources::units->erase(loc);
|
||||
resources::units->add(loc, u);
|
||||
resources::units->add(loc, *u);
|
||||
|
||||
std::string text = cfg["text"];
|
||||
play_controller *controller = resources::controller;
|
||||
|
@ -2547,19 +2547,19 @@ WML_HANDLER_FUNCTION(unstore_unit, /*event_info*/, cfg)
|
|||
&& (loop_limit > 0) )
|
||||
{
|
||||
loop_limit--;
|
||||
int total_opt = unit_helper::number_of_possible_advances(u);
|
||||
bool use_dialog = side == u.side() &&
|
||||
int total_opt = unit_helper::number_of_possible_advances(*u);
|
||||
bool use_dialog = side == u->side() &&
|
||||
(*resources::teams)[side - 1].is_human();
|
||||
config selected = mp_sync::get_user_choice("choose",
|
||||
unstore_unit_advance_choice(total_opt, loc, use_dialog));
|
||||
dialogs::animate_unit_advancement(loc, selected["value"], cfg["fire_event"].to_bool(false), cfg["animate"].to_bool(true));
|
||||
}
|
||||
} else {
|
||||
if(advance && u.advances()) {
|
||||
if(advance && u->advances()) {
|
||||
WRN_NG << "Cannot advance units when unstoring to the recall list." << std::endl;
|
||||
}
|
||||
|
||||
team& t = (*resources::teams)[u.side()-1];
|
||||
team& t = (*resources::teams)[u->side()-1];
|
||||
|
||||
if(t.persistent()) {
|
||||
|
||||
|
@ -2570,12 +2570,12 @@ WML_HANDLER_FUNCTION(unstore_unit, /*event_info*/, cfg)
|
|||
// replaced by the wrong unit.
|
||||
if(t.recall_list().size() > 1) {
|
||||
std::vector<size_t> desciptions;
|
||||
for(std::vector<unit>::const_iterator citor =
|
||||
for(std::vector<UnitPtr>::const_iterator citor =
|
||||
t.recall_list().begin();
|
||||
citor != t.recall_list().end(); ++citor) {
|
||||
|
||||
const size_t desciption =
|
||||
citor->underlying_id();
|
||||
(*citor)->underlying_id();
|
||||
if(std::find(desciptions.begin(), desciptions.end(),
|
||||
desciption) != desciptions.end()) {
|
||||
|
||||
|
@ -2593,29 +2593,29 @@ WML_HANDLER_FUNCTION(unstore_unit, /*event_info*/, cfg)
|
|||
* @todo it would be better to change recall_list() from
|
||||
* a vector to a map and use the underlying_id as key.
|
||||
*/
|
||||
const size_t key = u.underlying_id();
|
||||
for(std::vector<unit>::iterator itor =
|
||||
const size_t key = u->underlying_id();
|
||||
for(std::vector<UnitPtr>::iterator itor =
|
||||
t.recall_list().begin();
|
||||
itor != t.recall_list().end(); ++itor) {
|
||||
|
||||
LOG_NG << "Replaced unit '"
|
||||
<< key << "' on the recall list\n";
|
||||
if(itor->underlying_id() == key) {
|
||||
if((*itor)->underlying_id() == key) {
|
||||
t.recall_list().erase(itor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
t.recall_list().push_back(u);
|
||||
} else {
|
||||
ERR_NG << "Cannot unstore unit: recall list is empty for player " << u.side()
|
||||
ERR_NG << "Cannot unstore unit: recall list is empty for player " << u->side()
|
||||
<< " and the map location is invalid.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// If we unstore a leader make sure the team gets a leader if not the loading
|
||||
// in MP might abort since a side without a leader has a recall list.
|
||||
if(u.can_recruit()) {
|
||||
(*resources::teams)[u.side() - 1].have_leader();
|
||||
if(u->can_recruit()) {
|
||||
(*resources::teams)[u->side() - 1].have_leader();
|
||||
}
|
||||
|
||||
} catch (game::game_error &e) {
|
||||
|
|
|
@ -89,13 +89,13 @@ namespace { // Support functions
|
|||
if(counts == default_counts && match_count) {
|
||||
break;
|
||||
}
|
||||
const std::vector<unit>& avail_units = team->recall_list();
|
||||
for(std::vector<unit>::const_iterator unit = avail_units.begin(); unit!=avail_units.end(); ++unit) {
|
||||
const std::vector<UnitPtr>& avail_units = team->recall_list();
|
||||
for(std::vector<UnitPtr>::const_iterator unit = avail_units.begin(); unit!=avail_units.end(); ++unit) {
|
||||
if(counts == default_counts && match_count) {
|
||||
break;
|
||||
}
|
||||
scoped_recall_unit auto_store("this_unit", team->save_id(), unit - avail_units.begin());
|
||||
if ( unit->matches_filter(*u) ) {
|
||||
if ( (*unit)->matches_filter(*u) ) {
|
||||
++match_count;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1061,8 +1061,8 @@ void encounter_start_units(const unit_map& units){
|
|||
|
||||
static void encounter_recallable_units(const std::vector<team>& teams){
|
||||
BOOST_FOREACH(const team& t, teams) {
|
||||
BOOST_FOREACH(const unit& u, t.recall_list()) {
|
||||
encountered_units_set.insert(u.type_id());
|
||||
BOOST_FOREACH(const UnitConstPtr & u, t.recall_list()) {
|
||||
encountered_units_set.insert(u->type_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,8 +253,7 @@ protected:
|
|||
//seen before
|
||||
config u_tmp = u;
|
||||
u_tmp["side"] = str_cast(side_);
|
||||
unit new_unit(u_tmp, true);
|
||||
t_->recall_list().push_back(new_unit);
|
||||
t_->recall_list().push_back(UnitPtr(new unit(u_tmp,true)));
|
||||
} else {
|
||||
//not seen before
|
||||
unit_configs_.push_back(&u);
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "../../gamestatus.hpp"
|
||||
#include "../../resources.hpp"
|
||||
#include "../../team.hpp"
|
||||
#include "../../unit.hpp"
|
||||
#include "../../unit_map.hpp"
|
||||
#include "../../ai/manager.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
@ -414,19 +416,19 @@ public:
|
|||
}
|
||||
|
||||
if(selected == 3) {
|
||||
const std::vector<unit> recall_list
|
||||
const std::vector<UnitPtr> recall_list
|
||||
= resources::teams
|
||||
? resources::teams->at(side_ - 1).recall_list()
|
||||
: std::vector<unit>();
|
||||
: std::vector<UnitPtr>();
|
||||
|
||||
std::stringstream s;
|
||||
FOREACH(const AUTO & u, recall_list)
|
||||
{
|
||||
s << "id=\"" << u.id() << "\" (" << u.type_id() << ")\nL"
|
||||
<< u.level() << "; " << u.experience() << "/"
|
||||
<< u.max_experience() << " xp; " << u.hitpoints() << "/"
|
||||
<< u.max_hitpoints() << " hp\n";
|
||||
FOREACH(const AUTO & str, u.get_traits_list())
|
||||
s << "id=\"" << u->id() << "\" (" << u->type_id() << ")\nL"
|
||||
<< u->level() << "; " << u->experience() << "/"
|
||||
<< u->max_experience() << " xp; " << u->hitpoints() << "/"
|
||||
<< u->max_hitpoints() << " hp\n";
|
||||
FOREACH(const AUTO & str, u->get_traits_list())
|
||||
{
|
||||
s << "\t" << str << std::endl;
|
||||
}
|
||||
|
@ -437,16 +439,16 @@ public:
|
|||
}
|
||||
|
||||
if(selected == 4) {
|
||||
const std::vector<unit> recall_list
|
||||
const std::vector<UnitPtr> recall_list
|
||||
= resources::teams
|
||||
? resources::teams->at(side_ - 1).recall_list()
|
||||
: std::vector<unit>();
|
||||
: std::vector<UnitPtr>();
|
||||
|
||||
config c;
|
||||
FOREACH(const AUTO & u, recall_list)
|
||||
{
|
||||
config c_unit;
|
||||
u.write(c_unit);
|
||||
u->write(c_unit);
|
||||
c.add_child("unit", c_unit);
|
||||
}
|
||||
model_.set_inspect_window_text(config_to_string(c));
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
//#include "gettext.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "unit.hpp"
|
||||
|
||||
//
|
||||
//#include <boost/foreach.hpp>
|
||||
|
||||
|
|
|
@ -667,7 +667,7 @@ void menu_handler::recall(int side_num, const map_location &last_hex)
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<const unit*> recall_list_team;
|
||||
std::vector<UnitConstPtr > recall_list_team;
|
||||
{ wb::future_map future; // ensures recall list has planned recalls removed
|
||||
recall_list_team = actions::get_recalls(side_num, last_hex);
|
||||
}
|
||||
|
@ -676,7 +676,7 @@ void menu_handler::recall(int side_num, const map_location &last_hex)
|
|||
|
||||
|
||||
DBG_WB <<"menu_handler::recall: Contents of wb-modified recall list:\n";
|
||||
BOOST_FOREACH(const unit* unit, recall_list_team)
|
||||
BOOST_FOREACH(const UnitConstPtr & unit, recall_list_team)
|
||||
{
|
||||
DBG_WB << unit->name() << " [" << unit->id() <<"]\n";
|
||||
}
|
||||
|
|
|
@ -1033,8 +1033,8 @@ int mouse_handler::show_attack_dialog(const map_location& attacker_loc, const ma
|
|||
}
|
||||
}
|
||||
if (items.empty()) {
|
||||
dialogs::units_list_preview_pane attacker_preview(&*attacker, dialogs::unit_preview_pane::SHOW_BASIC, true);
|
||||
dialogs::units_list_preview_pane defender_preview(&*defender, dialogs::unit_preview_pane::SHOW_BASIC, false);
|
||||
dialogs::units_list_preview_pane attacker_preview(attacker.get_shared_ptr(), dialogs::unit_preview_pane::SHOW_BASIC, true);
|
||||
dialogs::units_list_preview_pane defender_preview(defender.get_shared_ptr(), dialogs::unit_preview_pane::SHOW_BASIC, false);
|
||||
std::vector<gui::preview_pane*> preview_panes;
|
||||
preview_panes.push_back(&attacker_preview);
|
||||
preview_panes.push_back(&defender_preview);
|
||||
|
@ -1051,8 +1051,8 @@ int mouse_handler::show_attack_dialog(const map_location& attacker_loc, const ma
|
|||
std::vector<gui::dialog_button_info> buttons;
|
||||
buttons.push_back(gui::dialog_button_info(&ap_displayer, _("Damage Calculations")));
|
||||
|
||||
dialogs::units_list_preview_pane attacker_preview(&*attacker, dialogs::unit_preview_pane::SHOW_BASIC, true);
|
||||
dialogs::units_list_preview_pane defender_preview(&*defender, dialogs::unit_preview_pane::SHOW_BASIC, false);
|
||||
dialogs::units_list_preview_pane attacker_preview(attacker.get_shared_ptr(), dialogs::unit_preview_pane::SHOW_BASIC, true);
|
||||
dialogs::units_list_preview_pane defender_preview(defender.get_shared_ptr(), dialogs::unit_preview_pane::SHOW_BASIC, false);
|
||||
std::vector<gui::preview_pane*> preview_panes;
|
||||
preview_panes.push_back(&attacker_preview);
|
||||
preview_panes.push_back(&defender_preview);
|
||||
|
|
|
@ -513,8 +513,8 @@ static int impl_unit_collect(lua_State *L)
|
|||
*/
|
||||
static int impl_unit_equality(lua_State* L)
|
||||
{
|
||||
unit* left = luaW_checkunit(L, 1);
|
||||
unit* right = luaW_checkunit(L, 2);
|
||||
UnitPtr left = luaW_checkunit(L, 1);
|
||||
UnitPtr right = luaW_checkunit(L, 2);
|
||||
const bool equal = left->underlying_id() == right->underlying_id();
|
||||
lua_pushboolean(L, equal);
|
||||
return 1;
|
||||
|
@ -530,7 +530,7 @@ static int impl_unit_get(lua_State *L)
|
|||
{
|
||||
lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
unit const *pu = lu->get();
|
||||
const UnitConstPtr pu = lu->get();
|
||||
|
||||
if (strcmp(m, "valid") == 0)
|
||||
{
|
||||
|
@ -613,7 +613,7 @@ static int impl_unit_set(lua_State *L)
|
|||
{
|
||||
lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
unit *pu = lu->get();
|
||||
UnitPtr pu = lu->get();
|
||||
if (!pu) return luaL_argerror(L, 1, "unknown unit");
|
||||
unit &u = *pu;
|
||||
|
||||
|
@ -653,7 +653,7 @@ static int impl_unit_status_get(lua_State *L)
|
|||
if (!lua_istable(L, 1))
|
||||
return luaL_typerror(L, 1, "unit status");
|
||||
lua_rawgeti(L, 1, 1);
|
||||
unit const *u = luaW_tounit(L, -1);
|
||||
const UnitConstPtr u = luaW_tounit(L, -1);
|
||||
if (!u) return luaL_argerror(L, 1, "unknown unit");
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
lua_pushboolean(L, u->get_state(m));
|
||||
|
@ -671,7 +671,7 @@ static int impl_unit_status_set(lua_State *L)
|
|||
if (!lua_istable(L, 1))
|
||||
return luaL_typerror(L, 1, "unit status");
|
||||
lua_rawgeti(L, 1, 1);
|
||||
unit *u = luaW_tounit(L, -1);
|
||||
UnitPtr u = luaW_tounit(L, -1);
|
||||
if (!u) return luaL_argerror(L, 1, "unknown unit");
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
u->set_state(m, luaW_toboolean(L, 3));
|
||||
|
@ -689,7 +689,7 @@ static int impl_unit_variables_get(lua_State *L)
|
|||
if (!lua_istable(L, 1))
|
||||
return luaL_typerror(L, 1, "unit variables");
|
||||
lua_rawgeti(L, 1, 1);
|
||||
unit const *u = luaW_tounit(L, -1);
|
||||
const UnitConstPtr u = luaW_tounit(L, -1);
|
||||
if (!u) return luaL_argerror(L, 1, "unknown unit");
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
return_cfgref_attrib("__cfg", u->variables());
|
||||
|
@ -708,7 +708,7 @@ static int impl_unit_variables_set(lua_State *L)
|
|||
if (!lua_istable(L, 1))
|
||||
return luaL_typerror(L, 1, "unit variables");
|
||||
lua_rawgeti(L, 1, 1);
|
||||
unit *u = luaW_tounit(L, -1);
|
||||
UnitPtr u = luaW_tounit(L, -1);
|
||||
if (!u) return luaL_argerror(L, 1, "unknown unit");
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
if (strcmp(m, "__cfg") == 0) {
|
||||
|
@ -838,7 +838,7 @@ static int intf_match_unit(lua_State *L)
|
|||
return luaL_typerror(L, 1, "unit");
|
||||
|
||||
lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
|
||||
unit *u = lu->get();
|
||||
UnitPtr u = lu->get();
|
||||
if (!u) return luaL_argerror(L, 1, "unit not found");
|
||||
|
||||
vconfig filter = luaW_checkvconfig(L, 2, true);
|
||||
|
@ -850,8 +850,9 @@ static int intf_match_unit(lua_State *L)
|
|||
|
||||
if (int side = lu->on_recall_list()) {
|
||||
team &t = (*resources::teams)[side - 1];
|
||||
std::vector<UnitPtr>::iterator it = find_if_matches_id(t.recall_list(), u->id());
|
||||
scoped_recall_unit auto_store("this_unit",
|
||||
t.save_id(), u - &t.recall_list()[0]);
|
||||
t.save_id(), it - t.recall_list().begin());
|
||||
lua_pushboolean(L, u->matches_filter(filter, map_location()));
|
||||
return 1;
|
||||
}
|
||||
|
@ -880,15 +881,16 @@ static int intf_get_recall_units(lua_State *L)
|
|||
int i = 1, s = 1;
|
||||
BOOST_FOREACH(team &t, *resources::teams)
|
||||
{
|
||||
BOOST_FOREACH(unit &u, t.recall_list())
|
||||
BOOST_FOREACH(UnitPtr & u, t.recall_list())
|
||||
{
|
||||
if (!filter.null()) {
|
||||
std::vector<UnitPtr>::iterator it = find_if_matches_id(t.recall_list(), u->id());
|
||||
scoped_recall_unit auto_store("this_unit",
|
||||
t.save_id(), &u - &t.recall_list()[0]);
|
||||
if (!u.matches_filter(filter, map_location()))
|
||||
t.save_id(), it - t.recall_list().begin());
|
||||
if (!u->matches_filter(filter, map_location()))
|
||||
continue;
|
||||
}
|
||||
new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(s, u.underlying_id());
|
||||
new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(s, u->underlying_id());
|
||||
lua_pushvalue(L, 1);
|
||||
lua_setmetatable(L, 3);
|
||||
lua_rawseti(L, 2, i);
|
||||
|
@ -1749,7 +1751,7 @@ static int intf_find_path(lua_State *L)
|
|||
int arg = 1;
|
||||
map_location src, dst;
|
||||
unit_map &units = *resources::units;
|
||||
const unit *u = NULL;
|
||||
UnitConstPtr u = UnitConstPtr();
|
||||
|
||||
if (lua_isuserdata(L, arg))
|
||||
{
|
||||
|
@ -1763,7 +1765,7 @@ static int intf_find_path(lua_State *L)
|
|||
++arg;
|
||||
src.y = luaL_checkinteger(L, arg) - 1;
|
||||
unit_map::const_unit_iterator ui = units.find(src);
|
||||
if (ui.valid()) u = &*ui;
|
||||
if (ui.valid()) u = ui.get_shared_ptr();
|
||||
++arg;
|
||||
}
|
||||
|
||||
|
@ -1859,7 +1861,7 @@ static int intf_find_path(lua_State *L)
|
|||
static int intf_find_reach(lua_State *L)
|
||||
{
|
||||
int arg = 1;
|
||||
const unit *u = NULL;
|
||||
UnitConstPtr u = UnitConstPtr();
|
||||
|
||||
if (lua_isuserdata(L, arg))
|
||||
{
|
||||
|
@ -1875,7 +1877,7 @@ static int intf_find_reach(lua_State *L)
|
|||
unit_map::const_unit_iterator ui = resources::units->find(src);
|
||||
if (!ui.valid())
|
||||
return luaL_argerror(L, 1, "unit not found");
|
||||
u = &*ui;
|
||||
u = ui.get_shared_ptr();
|
||||
++arg;
|
||||
}
|
||||
|
||||
|
@ -1944,7 +1946,7 @@ static int intf_find_reach(lua_State *L)
|
|||
static int intf_find_cost_map(lua_State *L)
|
||||
{
|
||||
int arg = 1;
|
||||
const unit *u = luaW_tounit(L, arg, true);
|
||||
UnitConstPtr u = luaW_tounit(L, arg, true);
|
||||
vconfig filter = vconfig::unconstructed_vconfig();
|
||||
luaW_tovconfig(L, arg, filter);
|
||||
|
||||
|
@ -1955,7 +1957,7 @@ static int intf_find_cost_map(lua_State *L)
|
|||
|
||||
if (u) // 1. arg - unit
|
||||
{
|
||||
real_units.push_back(u);
|
||||
real_units.push_back(u.get());
|
||||
}
|
||||
else if (!filter.null()) // 1. arg - filter
|
||||
{
|
||||
|
@ -2147,7 +2149,7 @@ static int intf_put_unit(lua_State *L)
|
|||
int unit_arg = 1;
|
||||
|
||||
lua_unit *lu = NULL;
|
||||
unit *u = NULL;
|
||||
UnitPtr u = UnitPtr();
|
||||
map_location loc;
|
||||
if (lua_isnumber(L, 1)) {
|
||||
unit_arg = 3;
|
||||
|
@ -2180,7 +2182,7 @@ static int intf_put_unit(lua_State *L)
|
|||
if (!resources::gameboard->map().on_board(loc))
|
||||
return luaL_argerror(L, 1, "invalid location");
|
||||
}
|
||||
u = new unit(cfg, true);
|
||||
u = UnitPtr (new unit(cfg, true));
|
||||
}
|
||||
|
||||
resources::screen->invalidate(loc);
|
||||
|
@ -2206,7 +2208,7 @@ static int intf_put_unit(lua_State *L)
|
|||
static int intf_put_recall_unit(lua_State *L)
|
||||
{
|
||||
lua_unit *lu = NULL;
|
||||
unit *u = NULL;
|
||||
UnitPtr u = UnitPtr();
|
||||
int side = lua_tointeger(L, 2);
|
||||
if (unsigned(side) > resources::teams->size()) side = 0;
|
||||
|
||||
|
@ -2220,25 +2222,25 @@ static int intf_put_recall_unit(lua_State *L)
|
|||
else
|
||||
{
|
||||
config cfg = luaW_checkconfig(L, 1);
|
||||
u = new unit(cfg, true);
|
||||
u = UnitPtr(new unit(cfg, true));
|
||||
}
|
||||
|
||||
if (!side) side = u->side();
|
||||
team &t = (*resources::teams)[side - 1];
|
||||
if (!t.persistent())
|
||||
return luaL_argerror(L, 2, "nonpersistent side");
|
||||
std::vector<unit> &rl = t.recall_list();
|
||||
std::vector<UnitPtr> &rl = t.recall_list();
|
||||
|
||||
// Avoid duplicates in the recall list.
|
||||
size_t uid = u->underlying_id();
|
||||
std::vector<unit>::iterator i = rl.begin();
|
||||
std::vector<UnitPtr>::iterator i = rl.begin();
|
||||
while (i != rl.end()) {
|
||||
if (i->underlying_id() == u->underlying_id()) {
|
||||
if ((*i)->underlying_id() == u->underlying_id()) {
|
||||
i = rl.erase(i);
|
||||
} else ++i;
|
||||
}
|
||||
|
||||
rl.push_back(*u);
|
||||
rl.push_back(u);
|
||||
if (lu) {
|
||||
if (lu->on_map())
|
||||
resources::units->erase(u->get_location());
|
||||
|
@ -2258,7 +2260,7 @@ static int intf_extract_unit(lua_State *L)
|
|||
if (!luaW_hasmetatable(L, 1, getunitKey))
|
||||
return luaL_typerror(L, 1, "unit");
|
||||
lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
|
||||
unit *u = lu->get();
|
||||
UnitPtr u = lu->get();
|
||||
if (!u) return luaL_argerror(L, 1, "unit not found");
|
||||
|
||||
if (lu->on_map()) {
|
||||
|
@ -2267,9 +2269,10 @@ static int intf_extract_unit(lua_State *L)
|
|||
u->clear_haloes();
|
||||
} else if (int side = lu->on_recall_list()) {
|
||||
team &t = (*resources::teams)[side - 1];
|
||||
unit *v = new unit(*u);
|
||||
std::vector<unit> &rl = t.recall_list();
|
||||
rl.erase(rl.begin() + (u - &rl[0]));
|
||||
UnitPtr v = UnitPtr(new unit(*u));
|
||||
std::vector<UnitPtr> &rl = t.recall_list();
|
||||
std::vector<UnitPtr>::iterator it = find_if_matches_id(t.recall_list(), u->id());
|
||||
rl.erase(rl.begin() + (it - rl.begin()));
|
||||
u = v;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -2290,22 +2293,18 @@ static int intf_find_vacant_tile(lua_State *L)
|
|||
{
|
||||
int x = luaL_checkint(L, 1) - 1, y = luaL_checkint(L, 2) - 1;
|
||||
|
||||
const unit *u = NULL;
|
||||
bool fake_unit = false;
|
||||
UnitPtr u = UnitPtr();
|
||||
if (!lua_isnoneornil(L, 3)) {
|
||||
if (luaW_hasmetatable(L, 3, getunitKey)) {
|
||||
u = static_cast<lua_unit *>(lua_touserdata(L, 3))->get();
|
||||
} else {
|
||||
config cfg = luaW_checkconfig(L, 3);
|
||||
u = new unit(cfg, false);
|
||||
fake_unit = true;
|
||||
u.reset(new unit(cfg, false));
|
||||
}
|
||||
}
|
||||
|
||||
map_location res = find_vacant_tile(map_location(x, y),
|
||||
pathfind::VACANT_ANY, u);
|
||||
|
||||
if (fake_unit) delete u;
|
||||
pathfind::VACANT_ANY, u.get());
|
||||
|
||||
if (!res.valid()) return 0;
|
||||
lua_pushinteger(L, res.x + 1);
|
||||
|
@ -2338,7 +2337,7 @@ static int intf_float_label(lua_State *L)
|
|||
static int intf_create_unit(lua_State *L)
|
||||
{
|
||||
config cfg = luaW_checkconfig(L, 1);
|
||||
unit *u = new unit(cfg, true);
|
||||
UnitPtr u = UnitPtr(new unit(cfg, true));
|
||||
new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(u);
|
||||
lua_pushlightuserdata(L
|
||||
, getunitKey);
|
||||
|
@ -2354,8 +2353,8 @@ static int intf_create_unit(lua_State *L)
|
|||
*/
|
||||
static int intf_copy_unit(lua_State *L)
|
||||
{
|
||||
unit const *u = luaW_checkunit(L, 1);
|
||||
new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(new unit(*u));
|
||||
UnitPtr u = luaW_checkunit(L, 1);
|
||||
new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(UnitPtr(new unit(*u)));
|
||||
lua_pushlightuserdata(L
|
||||
, getunitKey);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
|
@ -2373,7 +2372,7 @@ static int intf_copy_unit(lua_State *L)
|
|||
*/
|
||||
static int intf_unit_resistance(lua_State *L)
|
||||
{
|
||||
unit const *u = luaW_checkunit(L, 1);
|
||||
const UnitConstPtr u = luaW_checkunit(L, 1);
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
bool a = luaW_toboolean(L, 3);
|
||||
|
||||
|
@ -2395,7 +2394,7 @@ static int intf_unit_resistance(lua_State *L)
|
|||
*/
|
||||
static int intf_unit_movement_cost(lua_State *L)
|
||||
{
|
||||
unit const *u = luaW_checkunit(L, 1);
|
||||
const UnitConstPtr u = luaW_checkunit(L, 1);
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
t_translation::t_terrain t = t_translation::read_terrain_code(m);
|
||||
lua_pushinteger(L, u->movement_cost(t));
|
||||
|
@ -2410,7 +2409,7 @@ static int intf_unit_movement_cost(lua_State *L)
|
|||
*/
|
||||
static int intf_unit_defense(lua_State *L)
|
||||
{
|
||||
unit const *u = luaW_checkunit(L, 1);
|
||||
const UnitConstPtr u = luaW_checkunit(L, 1);
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
t_translation::t_terrain t = t_translation::read_terrain_code(m);
|
||||
lua_pushinteger(L, u->defense_modifier(t));
|
||||
|
@ -2425,7 +2424,7 @@ static int intf_unit_defense(lua_State *L)
|
|||
*/
|
||||
static int intf_unit_ability(lua_State *L)
|
||||
{
|
||||
unit const *u = luaW_checkunit(L, 1);
|
||||
const UnitConstPtr u = luaW_checkunit(L, 1);
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
lua_pushboolean(L, u->get_ability_bool(m));
|
||||
return 1;
|
||||
|
@ -2438,7 +2437,7 @@ static int intf_unit_ability(lua_State *L)
|
|||
*/
|
||||
static int intf_transform_unit(lua_State *L)
|
||||
{
|
||||
unit *u = luaW_checkunit(L, 1);
|
||||
UnitPtr u = luaW_checkunit(L, 1);
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
const unit_type *utp = unit_types.find(m);
|
||||
if (!utp) return luaL_argerror(L, 2, "unknown unit type");
|
||||
|
@ -2533,7 +2532,7 @@ static int intf_simulate_combat(lua_State *L)
|
|||
{
|
||||
int arg_num = 1, att_w = -1, def_w = -1;
|
||||
|
||||
unit const *att = luaW_checkunit(L, arg_num);
|
||||
UnitConstPtr att = luaW_checkunit(L, arg_num);
|
||||
++arg_num;
|
||||
if (lua_isnumber(L, arg_num)) {
|
||||
att_w = lua_tointeger(L, arg_num) - 1;
|
||||
|
@ -2542,7 +2541,7 @@ static int intf_simulate_combat(lua_State *L)
|
|||
++arg_num;
|
||||
}
|
||||
|
||||
unit const *def = luaW_checkunit(L, arg_num, true);
|
||||
UnitConstPtr def = luaW_checkunit(L, arg_num, true);
|
||||
++arg_num;
|
||||
if (lua_isnumber(L, arg_num)) {
|
||||
def_w = lua_tointeger(L, arg_num) - 1;
|
||||
|
@ -2552,7 +2551,7 @@ static int intf_simulate_combat(lua_State *L)
|
|||
}
|
||||
|
||||
battle_context context(*resources::units, att->get_location(),
|
||||
def->get_location(), att_w, def_w, 0.0, NULL, att);
|
||||
def->get_location(), att_w, def_w, 0.0, NULL, att.get());
|
||||
|
||||
luaW_pushsimdata(L, context.get_attacker_combatant());
|
||||
luaW_pushsimdata(L, context.get_defender_combatant());
|
||||
|
@ -3298,7 +3297,7 @@ static int intf_get_traits(lua_State* L)
|
|||
*/
|
||||
static int intf_add_modification(lua_State *L)
|
||||
{
|
||||
unit *u = luaW_checkunit(L, 1);
|
||||
UnitPtr u = luaW_checkunit(L, 1);
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
std::string sm = m;
|
||||
if (sm != "advance" && sm != "object" && sm != "trait")
|
||||
|
|
|
@ -386,21 +386,20 @@ bool luaW_getglobal(lua_State *L, ...)
|
|||
|
||||
lua_unit::~lua_unit()
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
unit *lua_unit::get()
|
||||
UnitPtr lua_unit::get()
|
||||
{
|
||||
if (ptr) return ptr;
|
||||
if (side) {
|
||||
BOOST_FOREACH(unit &u, (*resources::teams)[side - 1].recall_list()) {
|
||||
if (u.underlying_id() == uid) return &u;
|
||||
BOOST_FOREACH(UnitPtr &u, (*resources::teams)[side - 1].recall_list()) {
|
||||
if (u->underlying_id() == uid) return u;
|
||||
}
|
||||
return NULL;
|
||||
return UnitPtr();
|
||||
}
|
||||
unit_map::unit_iterator ui = resources::units->find(uid);
|
||||
if (!ui.valid()) return NULL;
|
||||
return &*ui;
|
||||
if (!ui.valid()) return UnitPtr();
|
||||
return ui.get_shared_ptr(); //&*ui would not be legal, must get new shared_ptr by copy ctor because the unit_map itself is holding a boost shared pointer.
|
||||
}
|
||||
|
||||
// Having this function here not only simplifies other code, it allows us to move
|
||||
|
@ -414,24 +413,24 @@ bool lua_unit::put_map(const map_location &loc)
|
|||
resources::units->erase(loc);
|
||||
std::pair<unit_map::unit_iterator, bool> res = resources::units->insert(ptr);
|
||||
if (res.second) {
|
||||
ptr = NULL;
|
||||
ptr.reset();
|
||||
uid = res.first->underlying_id();
|
||||
} else {
|
||||
ERR_LUA << "Could not move unit " << ptr->underlying_id() << " onto map location " << loc << '\n';
|
||||
return false;
|
||||
}
|
||||
} else if (side) { // recall list
|
||||
std::vector<unit> &recall_list = (*resources::teams)[side - 1].recall_list();
|
||||
std::vector<unit>::iterator it = recall_list.begin();
|
||||
std::vector<UnitPtr> &recall_list = (*resources::teams)[side - 1].recall_list();
|
||||
std::vector<UnitPtr>::iterator it = recall_list.begin();
|
||||
for(; it != recall_list.end(); ++it) {
|
||||
if (it->underlying_id() == uid) {
|
||||
if ((*it)->underlying_id() == uid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it != recall_list.end()) {
|
||||
side = 0;
|
||||
// uid may be changed by unit_map on insertion
|
||||
uid = resources::units->replace(loc, *it).first->underlying_id();
|
||||
uid = resources::units->replace(loc, **it).first->underlying_id();
|
||||
recall_list.erase(it);
|
||||
} else {
|
||||
ERR_LUA << "Could not find unit " << uid << " on recall list of side " << side << '\n';
|
||||
|
@ -454,17 +453,17 @@ bool lua_unit::put_map(const map_location &loc)
|
|||
return true;
|
||||
}
|
||||
|
||||
unit *luaW_tounit(lua_State *L, int index, bool only_on_map)
|
||||
UnitPtr luaW_tounit(lua_State *L, int index, bool only_on_map)
|
||||
{
|
||||
if (!luaW_hasmetatable(L, index, getunitKey)) return NULL;
|
||||
if (!luaW_hasmetatable(L, index, getunitKey)) return UnitPtr();
|
||||
lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, index));
|
||||
if (only_on_map && !lu->on_map()) return NULL;
|
||||
if (only_on_map && !lu->on_map()) return UnitPtr();
|
||||
return lu->get();
|
||||
}
|
||||
|
||||
unit *luaW_checkunit(lua_State *L, int index, bool only_on_map)
|
||||
UnitPtr luaW_checkunit(lua_State *L, int index, bool only_on_map)
|
||||
{
|
||||
unit *u = luaW_tounit(L, index, only_on_map);
|
||||
UnitPtr u = luaW_tounit(L, index, only_on_map);
|
||||
if (!u) luaL_typerror(L, index, "unit");
|
||||
return u;
|
||||
}
|
||||
|
|
|
@ -19,16 +19,16 @@
|
|||
#include <string>
|
||||
#include "config.hpp" // forward declaration of the nested type config::attribute_value is not possible
|
||||
#include "lua_types.hpp" // the luatype typedef
|
||||
#include "unit_ptr.hpp"
|
||||
|
||||
struct lua_State;
|
||||
class t_string;
|
||||
class vconfig;
|
||||
class unit;
|
||||
|
||||
|
||||
/**
|
||||
* Converts a Lua value to a unit pointer.
|
||||
*/
|
||||
unit *luaW_tounit(lua_State *L, int index, bool only_on_map = false);
|
||||
UnitPtr luaW_tounit(lua_State *L, int index, bool only_on_map = false);
|
||||
|
||||
/**
|
||||
* Displays a message in the chat window.
|
||||
|
@ -123,7 +123,7 @@ bool luaW_getglobal(lua_State *L, ...);
|
|||
/**
|
||||
* Converts a Lua value to a unit pointer.
|
||||
*/
|
||||
unit *luaW_checkunit(lua_State *L, int index, bool only_on_map = false);
|
||||
UnitPtr luaW_checkunit(lua_State *L, int index, bool only_on_map = false);
|
||||
|
||||
bool luaW_toboolean(lua_State *L, int n);
|
||||
|
||||
|
@ -137,18 +137,18 @@ struct map_location;
|
|||
class lua_unit
|
||||
{
|
||||
size_t uid;
|
||||
unit *ptr;
|
||||
UnitPtr ptr;
|
||||
int side;
|
||||
lua_unit(lua_unit const &);
|
||||
|
||||
public:
|
||||
lua_unit(size_t u): uid(u), ptr(NULL), side(0) {}
|
||||
lua_unit(unit *u): uid(0), ptr(u), side(0) {}
|
||||
lua_unit(int s, size_t u): uid(u), ptr(NULL), side(s) {}
|
||||
lua_unit(size_t u): uid(u), ptr(), side(0) {}
|
||||
lua_unit(UnitPtr u): uid(0), ptr(u), side(0) {}
|
||||
lua_unit(int s, size_t u): uid(u), ptr(), side(s) {}
|
||||
~lua_unit();
|
||||
bool on_map() const { return !ptr && side == 0; }
|
||||
int on_recall_list() const { return side; }
|
||||
unit *get();
|
||||
UnitPtr get();
|
||||
|
||||
// Clobbers loc
|
||||
bool put_map(const map_location &loc);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "team.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
#include "network.hpp"
|
||||
#include "unit.hpp"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
@ -137,10 +138,11 @@ bool side_filter::match_internal(const team &t) const
|
|||
}
|
||||
}
|
||||
if(!found && unit_filter["search_recall_list"].to_bool(false)) {
|
||||
const std::vector<unit>& recall_list = t.recall_list();
|
||||
BOOST_FOREACH(const unit& u, recall_list) {
|
||||
scoped_recall_unit this_unit("this_unit", t.save_id(), &u - &recall_list[0]);
|
||||
if(u.matches_filter(unit_filter, u.get_location(), flat_)) {
|
||||
const std::vector<UnitPtr>& recall_list = t.recall_list();
|
||||
BOOST_FOREACH(const UnitConstPtr & u, recall_list) {
|
||||
std::vector<UnitPtr>::const_iterator it = find_if_matches_id(recall_list, u->id());
|
||||
scoped_recall_unit this_unit("this_unit", t.save_id(), it - recall_list.begin());
|
||||
if(u->matches_filter(unit_filter, u->get_location(), flat_)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ SYNCED_COMMAND_HANDLER_FUNCTION(disband, child, /*use_undo*/, /*show*/, error_ha
|
|||
team ¤t_team = (*resources::teams)[current_team_num - 1];
|
||||
|
||||
const std::string& unit_id = child["value"];
|
||||
std::vector<unit>::iterator disband_unit =
|
||||
std::vector<UnitPtr>::iterator disband_unit =
|
||||
find_if_matches_id(current_team.recall_list(), unit_id);
|
||||
|
||||
if(disband_unit != current_team.recall_list().end()) {
|
||||
|
|
13
src/team.hpp
13
src/team.hpp
|
@ -17,8 +17,13 @@
|
|||
#include "color_range.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "make_enum.hpp"
|
||||
#include "map_location.hpp"
|
||||
#include "savegame_config.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "SDL.h" //Apparently needed b/c of SDL_Color
|
||||
#include "unit_ptr.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
class gamemap;
|
||||
|
||||
|
@ -180,8 +185,8 @@ public:
|
|||
{ countdown_time_ = amount; }
|
||||
int action_bonus_count() const { return action_bonus_count_; }
|
||||
void set_action_bonus_count(const int count) { action_bonus_count_ = count; }
|
||||
std::vector<unit>& recall_list() {return recall_list_;}
|
||||
const std::vector<unit>& recall_list() const {return recall_list_;}
|
||||
std::vector<UnitPtr >& recall_list() {return recall_list_;}
|
||||
const std::vector<UnitPtr >& recall_list() const {return recall_list_;}
|
||||
void set_current_player(const std::string& player)
|
||||
{ info_.current_player = player; }
|
||||
|
||||
|
@ -344,7 +349,7 @@ private:
|
|||
mutable int countdown_time_;
|
||||
int action_bonus_count_;
|
||||
|
||||
std::vector<unit> recall_list_;
|
||||
std::vector<UnitPtr > recall_list_;
|
||||
std::string last_recruit_;
|
||||
|
||||
bool calculate_enemies(size_t index) const;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "team.hpp"
|
||||
#include "terrain_filter.hpp"
|
||||
#include "tod_manager.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "variable.hpp"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
|
|
@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE( track_real_unit_by_underlying_id ) {
|
|||
BOOST_CHECK(ui->underlying_id() == orc1_side0_real.underlying_id());
|
||||
}
|
||||
|
||||
unit* extracted_unit = unit_map.extract(hex);
|
||||
UnitPtr extracted_unit = unit_map.extract(hex);
|
||||
|
||||
{
|
||||
unit_map::unit_iterator ui = unit_map.find(underlying_id);
|
||||
|
@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE( track_real_unit_by_underlying_id ) {
|
|||
}
|
||||
|
||||
unit_map.insert(extracted_unit);
|
||||
extracted_unit = NULL;
|
||||
extracted_unit.reset();
|
||||
|
||||
{
|
||||
unit_map::unit_iterator ui = unit_map.find(underlying_id);
|
||||
|
@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE( track_fake_unit_by_underlying_id ) {
|
|||
BOOST_CHECK(ui->underlying_id() == orc1_side0_fake.underlying_id());
|
||||
}
|
||||
|
||||
unit* extracted_unit = unit_map.extract(hex);
|
||||
UnitPtr extracted_unit = unit_map.extract(hex);
|
||||
|
||||
{
|
||||
unit_map::unit_iterator ui = unit_map.find(underlying_id);
|
||||
|
@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE( track_fake_unit_by_underlying_id ) {
|
|||
}
|
||||
|
||||
unit_map.insert(extracted_unit);
|
||||
extracted_unit = NULL;
|
||||
extracted_unit.reset();
|
||||
|
||||
{
|
||||
unit_map::unit_iterator ui = unit_map.find(underlying_id);
|
||||
|
@ -240,7 +240,7 @@ BOOST_AUTO_TEST_CASE( track_real_unit_by_iterator ) {
|
|||
|
||||
BOOST_CHECK(unit_iterator.valid());
|
||||
|
||||
unit* extracted_unit = unit_map.extract(hex);
|
||||
UnitPtr extracted_unit = unit_map.extract(hex);
|
||||
|
||||
BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
|
||||
|
||||
|
@ -277,7 +277,7 @@ BOOST_AUTO_TEST_CASE( track_fake_unit_by_iterator ) {
|
|||
|
||||
BOOST_CHECK(unit_iterator.valid());
|
||||
|
||||
unit* extracted_unit = unit_map.extract(hex);
|
||||
UnitPtr extracted_unit = unit_map.extract(hex);
|
||||
|
||||
BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ struct dummy_action: action{
|
|||
void remove_temp_modifier(unit_map&){}
|
||||
void draw_hex(const map_location&){}
|
||||
map_location get_numbering_hex() const { return map_location(); }
|
||||
unit* get_unit() const { return 0; }
|
||||
UnitPtr get_unit() const { return UnitPtr(); }
|
||||
fake_unit_ptr get_fake_unit(){ return fake_unit_ptr(); }
|
||||
error check_validity() const { return OK; }
|
||||
};
|
||||
|
|
39
src/unit.cpp
39
src/unit.cpp
|
@ -71,6 +71,22 @@ namespace {
|
|||
const std::string leader_crown_path = "misc/leader-crown.png";
|
||||
}
|
||||
|
||||
/**
|
||||
* Intrusive Pointer interface
|
||||
*
|
||||
**/
|
||||
|
||||
void intrusive_ptr_add_ref(const unit * u)
|
||||
{
|
||||
++(u->ref_count_);
|
||||
}
|
||||
|
||||
void intrusive_ptr_release(const unit * u)
|
||||
{
|
||||
if (--(u->ref_count_) == 0)
|
||||
delete u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string ID to a unit_type.
|
||||
* Throws a game_error exception if the string does not correspond to a type.
|
||||
|
@ -2902,40 +2918,45 @@ bool unit::matches_id(const std::string& unit_id) const
|
|||
return id_ == unit_id;
|
||||
}
|
||||
|
||||
bool find_if_matches_helper(const UnitPtr & ptr, const std::string & unit_id)
|
||||
{
|
||||
return ptr->matches_id(unit_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to find units in vectors by their ID. (Convenience wrapper)
|
||||
* @returns what std::find_if() returns.
|
||||
*/
|
||||
std::vector<unit>::iterator find_if_matches_id(
|
||||
std::vector<unit> &unit_list, // Not const so we can get a non-const iterator to return.
|
||||
std::vector<UnitPtr >::iterator find_if_matches_id(
|
||||
std::vector<UnitPtr > &unit_list, // Not const so we can get a non-const iterator to return.
|
||||
const std::string &unit_id)
|
||||
{
|
||||
return std::find_if(unit_list.begin(), unit_list.end(),
|
||||
boost::bind(&unit::matches_id, _1, unit_id));
|
||||
boost::bind(&find_if_matches_helper, _1, unit_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to find units in vectors by their ID. (Convenience wrapper; const version)
|
||||
* @returns what std::find_if() returns.
|
||||
*/
|
||||
std::vector<unit>::const_iterator find_if_matches_id(
|
||||
const std::vector<unit> &unit_list,
|
||||
std::vector<UnitPtr >::const_iterator find_if_matches_id(
|
||||
const std::vector<UnitPtr > &unit_list,
|
||||
const std::string &unit_id)
|
||||
{
|
||||
return std::find_if(unit_list.begin(), unit_list.end(),
|
||||
boost::bind(&unit::matches_id, _1, unit_id));
|
||||
boost::bind(&find_if_matches_helper, _1, unit_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to erase units from vectors by their ID. (Convenience wrapper)
|
||||
* @returns what std::vector<>::erase() returns.
|
||||
*/
|
||||
std::vector<unit>::iterator erase_if_matches_id(
|
||||
std::vector<unit> &unit_list,
|
||||
std::vector<UnitPtr >::iterator erase_if_matches_id(
|
||||
std::vector<UnitPtr > &unit_list,
|
||||
const std::string &unit_id)
|
||||
{
|
||||
return unit_list.erase(std::remove_if(unit_list.begin(), unit_list.end(),
|
||||
boost::bind(&unit::matches_id, _1, unit_id)),
|
||||
boost::bind(&find_if_matches_helper, _1, unit_id)),
|
||||
unit_list.end());
|
||||
}
|
||||
|
||||
|
|
18
src/unit.hpp
18
src/unit.hpp
|
@ -23,6 +23,7 @@
|
|||
#include "unit_animation.hpp"
|
||||
#include "unit_types.hpp"
|
||||
#include "unit_map.hpp"
|
||||
#include "unit_ptr.hpp"
|
||||
|
||||
class display;
|
||||
class gamemap;
|
||||
|
@ -391,7 +392,12 @@ public:
|
|||
const std::string& effect_image_mods() const;
|
||||
std::string image_mods() const;
|
||||
|
||||
long ref_count() const { return ref_count_; }
|
||||
friend void intrusive_ptr_add_ref(const unit *);
|
||||
friend void intrusive_ptr_release(const unit *);
|
||||
private:
|
||||
mutable long ref_count_; //used by intrusive_ptr
|
||||
|
||||
void advance_to(const config &old_cfg, const unit_type &t,
|
||||
bool use_traits);
|
||||
|
||||
|
@ -534,16 +540,16 @@ private:
|
|||
};
|
||||
|
||||
/// Used to find units in vectors by their ID. (Convenience wrapper)
|
||||
std::vector<unit>::iterator find_if_matches_id(
|
||||
std::vector<unit> &unit_list,
|
||||
std::vector<UnitPtr >::iterator find_if_matches_id(
|
||||
std::vector<UnitPtr > &unit_list,
|
||||
const std::string &unit_id);
|
||||
/// Used to find units in vectors by their ID. (Convenience wrapper)
|
||||
std::vector<unit>::const_iterator find_if_matches_id(
|
||||
const std::vector<unit> &unit_list,
|
||||
std::vector<UnitPtr >::const_iterator find_if_matches_id(
|
||||
const std::vector<UnitPtr > &unit_list,
|
||||
const std::string &unit_id);
|
||||
/// Used to erase units from vectors by their ID. (Convenience wrapper)
|
||||
std::vector<unit>::iterator erase_if_matches_id(
|
||||
std::vector<unit> &unit_list,
|
||||
std::vector<UnitPtr >::iterator erase_if_matches_id(
|
||||
std::vector<UnitPtr > &unit_list,
|
||||
const std::string &unit_id);
|
||||
|
||||
/** Returns the number of units of the side @a side_num. */
|
||||
|
|
|
@ -65,16 +65,16 @@ unit_map::~unit_map() {
|
|||
unit_map::t_umap::iterator unit_map::begin_core() const {
|
||||
self_check();
|
||||
t_umap::iterator i = umap_.begin();
|
||||
while (i != umap_.end() && (i->second.unit == NULL)) { ++i; }
|
||||
while (i != umap_.end() && (!i->second.unit)) { ++i; }
|
||||
return i;
|
||||
}
|
||||
|
||||
std::pair<unit_map::unit_iterator, bool> unit_map::add(const map_location &l, const unit &u) {
|
||||
self_check();
|
||||
unit *p = new unit(u);
|
||||
UnitPtr p = UnitPtr (new unit(u)); //TODO: should this instead take a shared pointer to a unit, rather than make a copy?
|
||||
p->set_location(l);
|
||||
std::pair<unit_map::unit_iterator, bool> res( insert(p) );
|
||||
if(res.second == false) { delete p; }
|
||||
if(res.second == false) { p.reset(); }
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -91,8 +91,8 @@ std::pair<unit_map::unit_iterator, bool> unit_map::move(const map_location &src,
|
|||
if(src == dst){ return std::make_pair(make_unit_iterator(uit), true);}
|
||||
|
||||
//Fail if there is no unit to move
|
||||
unit *p = uit->second.unit;
|
||||
if(p == NULL){ return std::make_pair(make_unit_iterator(uit), false);}
|
||||
UnitPtr p = uit->second.unit;
|
||||
if(!p){ return std::make_pair(make_unit_iterator(uit), false);}
|
||||
|
||||
p->set_location(dst);
|
||||
|
||||
|
@ -125,7 +125,7 @@ The one oddity is that to facilitate non-invalidating iterators the list
|
|||
sometimes has NULL pointers which should be used when they correspond
|
||||
to uids previously used.
|
||||
*/
|
||||
std::pair<unit_map::unit_iterator, bool> unit_map::insert(unit *p) {
|
||||
std::pair<unit_map::unit_iterator, bool> unit_map::insert(UnitPtr p) {
|
||||
self_check();
|
||||
assert(p);
|
||||
|
||||
|
@ -139,7 +139,7 @@ std::pair<unit_map::unit_iterator, bool> unit_map::insert(unit *p) {
|
|||
}
|
||||
|
||||
unit_pod upod;
|
||||
upod.unit = p;
|
||||
upod.unit = p ;
|
||||
|
||||
DBG_NG << "Adding unit " << p->underlying_id() << " - " << p->id()
|
||||
<< " to location: (" << loc << ")\n";
|
||||
|
@ -148,12 +148,12 @@ std::pair<unit_map::unit_iterator, bool> unit_map::insert(unit *p) {
|
|||
|
||||
if (! uinsert.second) {
|
||||
//If the pod is empty reinsert the unit in the same list element
|
||||
if ( uinsert.first->second.unit == NULL) {
|
||||
if (!uinsert.first->second.unit) {
|
||||
unit_pod &opod = uinsert.first->second;
|
||||
opod.unit = p;
|
||||
opod.unit = p ;
|
||||
assert(opod.ref_count != 0);
|
||||
} else {
|
||||
unit *q = uinsert.first->second.unit;
|
||||
UnitPtr q = uinsert.first->second.unit;
|
||||
ERR_NG << "Trying to add " << p->name()
|
||||
<< " - " << p->id() << " - " << p->underlying_id()
|
||||
<< " (" << loc << ") over " << q->name()
|
||||
|
@ -191,7 +191,7 @@ std::pair<unit_map::unit_iterator, bool> unit_map::insert(unit *p) {
|
|||
umap_.erase(uinsert.first);
|
||||
} else {
|
||||
//undo a reinsertion
|
||||
uinsert.first->second.unit = NULL;
|
||||
uinsert.first->second.unit.reset();
|
||||
}
|
||||
DBG_NG << "Trying to add " << p->name()
|
||||
<< " - " << p->id() << " at location ("<<loc <<"); Occupied by "
|
||||
|
@ -238,7 +238,7 @@ void unit_map::clear(bool force) {
|
|||
for (t_umap::iterator i = umap_.begin(); i != umap_.end(); ++i) {
|
||||
if (is_valid(i)) {
|
||||
DBG_NG << "Delete unit " << i->second.unit->underlying_id() << "\n";
|
||||
delete i->second.unit;
|
||||
i->second.unit.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,14 +246,14 @@ void unit_map::clear(bool force) {
|
|||
umap_.clear();
|
||||
}
|
||||
|
||||
unit *unit_map::extract(const map_location &loc) {
|
||||
UnitPtr unit_map::extract(const map_location &loc) {
|
||||
self_check();
|
||||
t_lmap::iterator i = lmap_.find(loc);
|
||||
if (i == lmap_.end()) { return NULL; }
|
||||
if (i == lmap_.end()) { return UnitPtr(); }
|
||||
|
||||
t_umap::iterator uit(i->second);
|
||||
|
||||
unit *u = uit->second.unit;
|
||||
UnitPtr u = uit->second.unit;
|
||||
size_t uid( u->underlying_id() );
|
||||
|
||||
DBG_NG << "Extract unit " << uid << " - " << u->id()
|
||||
|
@ -264,7 +264,7 @@ unit *unit_map::extract(const map_location &loc) {
|
|||
umap_.erase(uit);
|
||||
} else {
|
||||
//Soft extraction keeps the old lit item if any iterators reference it
|
||||
uit->second.unit = NULL;
|
||||
uit->second.unit.reset();
|
||||
}
|
||||
|
||||
lmap_.erase(i);
|
||||
|
@ -276,16 +276,16 @@ unit *unit_map::extract(const map_location &loc) {
|
|||
|
||||
size_t unit_map::erase(const map_location &loc) {
|
||||
self_check();
|
||||
unit *u = extract(loc);
|
||||
UnitPtr u = extract(loc);
|
||||
if (!u) return 0;
|
||||
delete u;
|
||||
u.reset();
|
||||
return 1;
|
||||
}
|
||||
|
||||
unit_map::unit_iterator unit_map::find(size_t id) {
|
||||
self_check();
|
||||
t_umap::iterator i(umap_.find(id));
|
||||
if((i != umap_.end()) && i->second.unit==NULL){ i = umap_.end() ;}
|
||||
if((i != umap_.end()) && !i->second.unit){ i = umap_.end() ;}
|
||||
return make_unit_iterator<t_umap::iterator>( i );
|
||||
}
|
||||
|
||||
|
@ -343,14 +343,14 @@ bool unit_map::self_check() const {
|
|||
good=false;
|
||||
ERR_NG << "unit_map pod ref_count <0 is " << uit->second.ref_count<< std::endl;
|
||||
}
|
||||
if(uit->second.unit != NULL){
|
||||
if(uit->second.unit){
|
||||
uit->second.unit->id(); //crash if bad pointer
|
||||
}
|
||||
if(uit->first <= 0){
|
||||
good=false;
|
||||
ERR_NG << "unit_map umap uid <=0 is " << uit->first << std::endl;
|
||||
}
|
||||
if(uit->second.unit == NULL && uit->second.ref_count == 0 ){
|
||||
if(!uit->second.unit && uit->second.ref_count == 0 ){
|
||||
good=false;
|
||||
ERR_NG << "unit_map umap unit==NULL when refcount == 0" << std::endl;
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ bool unit_map::has_unit(const unit * const u) const
|
|||
assert(u);
|
||||
|
||||
BOOST_FOREACH(const t_umap::value_type& item, umap_) {
|
||||
if(item.second.unit == u) {
|
||||
if(item.second.unit.get() == u) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "utils/reference_counter.hpp"
|
||||
#include "map_location.hpp"
|
||||
#include "unit_ptr.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <list>
|
||||
|
@ -28,8 +29,6 @@
|
|||
|
||||
//#define DEBUG_UNIT_MAP
|
||||
|
||||
class unit;
|
||||
|
||||
/**
|
||||
* Container associating units to locations.
|
||||
* An indirection location -> underlying_id -> unit ensures that iterators
|
||||
|
@ -94,12 +93,12 @@ class unit_map {
|
|||
struct unit_pod {
|
||||
|
||||
unit_pod()
|
||||
: unit(NULL)
|
||||
: unit()
|
||||
, ref_count()
|
||||
{
|
||||
}
|
||||
|
||||
class unit * unit;
|
||||
UnitPtr unit;
|
||||
mutable n_ref_counter::t_ref_counter<signed int> ref_count;
|
||||
};
|
||||
|
||||
|
@ -132,7 +131,7 @@ public:
|
|||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef int difference_type;
|
||||
typedef typename iter_types::value_type value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef boost::intrusive_ptr<value_type> pointer;
|
||||
typedef value_type& reference;
|
||||
typedef typename iter_types::container_type container_type;
|
||||
typedef typename iter_types::iterator_type iterator_type;
|
||||
|
@ -178,6 +177,10 @@ public:
|
|||
assert(valid());
|
||||
tank_->self_check();
|
||||
return i_->second.unit; }
|
||||
pointer get_shared_ptr() const { // This is exactly the same as operator-> but it's slightly more readable, and can replace &*iter syntax easily.
|
||||
assert(valid());
|
||||
tank_->self_check();
|
||||
return i_->second.unit; }
|
||||
reference operator*() const {
|
||||
tank_->self_check();
|
||||
assert(valid());
|
||||
|
@ -189,7 +192,7 @@ public:
|
|||
iterator_type new_i(i_);
|
||||
do{
|
||||
++new_i;
|
||||
}while ((new_i != the_map().end()) && (new_i->second.unit == NULL)) ;
|
||||
}while ((new_i != the_map().end()) && (!new_i->second.unit)) ;
|
||||
dec();
|
||||
i_ = new_i;
|
||||
inc();
|
||||
|
@ -210,7 +213,7 @@ public:
|
|||
dec();
|
||||
do {
|
||||
--i_ ;
|
||||
}while(i_ != begin && (i_->second.unit == NULL));
|
||||
}while(i_ != begin && (!i_->second.unit));
|
||||
inc();
|
||||
|
||||
valid_exit();
|
||||
|
@ -225,7 +228,7 @@ public:
|
|||
|
||||
bool valid() const {
|
||||
if(valid_for_dereference()) {
|
||||
return i_->second.unit != NULL;
|
||||
return i_->second.unit;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -254,7 +257,7 @@ public:
|
|||
void dec() {
|
||||
if( valid_ref_count() ){
|
||||
assert(i_->second.ref_count != 0);
|
||||
if( (--(i_->second.ref_count) == 0) && (i_->second.unit == NULL) ){
|
||||
if( (--(i_->second.ref_count) == 0) && (!i_->second.unit) ){
|
||||
iterator_type old = i_++;
|
||||
tank_->umap_.erase(old);
|
||||
}
|
||||
|
@ -334,7 +337,7 @@ public:
|
|||
* will be generated.
|
||||
* @note The map takes ownership of the pointed object, only if it succeeds.
|
||||
*/
|
||||
std::pair<unit_iterator, bool> insert(unit *p);
|
||||
std::pair<unit_iterator, bool> insert(UnitPtr p);
|
||||
|
||||
/**
|
||||
* Moves a unit from location @a src to location @a dst.
|
||||
|
@ -371,7 +374,7 @@ public:
|
|||
* The unit is no longer owned by the map.
|
||||
* It can be reinserted later, if needed.
|
||||
*/
|
||||
unit *extract(const map_location &loc);
|
||||
UnitPtr extract(const map_location &loc);
|
||||
|
||||
///Checks invariants. For debugging purposes only. Doesn't do anything in non-debug mode.
|
||||
bool self_check() const
|
||||
|
|
32
src/unit_ptr.hpp
Normal file
32
src/unit_ptr.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Copyright (C) 2014 by Chris Beck <render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
// The purpose of this header is to forward declare the UnitPtr, if it
|
||||
// is an intrusive pointer then this requires some boilerplate taken
|
||||
// care of here.
|
||||
|
||||
#ifndef UNIT_PTR_H_INCLUDED
|
||||
#define UNIT_PTR_H_INCLUDED
|
||||
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
|
||||
class unit;
|
||||
|
||||
void intrusive_ptr_add_ref(const unit *);
|
||||
void intrusive_ptr_release(const unit *);
|
||||
|
||||
typedef boost::intrusive_ptr<unit> UnitPtr;
|
||||
typedef boost::intrusive_ptr<const unit> UnitConstPtr;
|
||||
|
||||
#endif
|
|
@ -428,7 +428,7 @@ void scoped_recall_unit::activate()
|
|||
if(team_it != teams.end()) {
|
||||
if(team_it->recall_list().size() > recall_index_) {
|
||||
config &tmp_cfg = store();
|
||||
team_it->recall_list()[recall_index_].write(tmp_cfg);
|
||||
team_it->recall_list()[recall_index_]->write(tmp_cfg);
|
||||
tmp_cfg["x"] = "recall";
|
||||
tmp_cfg["y"] = "recall";
|
||||
LOG_NG << "auto-storing $" << name() << " for player: " << player_
|
||||
|
|
|
@ -116,7 +116,7 @@ action::~action()
|
|||
|
||||
size_t action::get_unit_id() const
|
||||
{
|
||||
unit *ret = get_unit();
|
||||
UnitPtr ret = get_unit();
|
||||
return ret ? ret->underlying_id() : 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
virtual map_location get_numbering_hex() const = 0;
|
||||
|
||||
/** Return the unit targeted by this action. Null if unit doesn't exist. */
|
||||
virtual unit* get_unit() const = 0;
|
||||
virtual UnitPtr get_unit() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the id of the unit targeted by this action.
|
||||
|
|
|
@ -48,8 +48,8 @@ highlighter::highlighter(unit_map& unit_map, side_actions_ptr side_actions)
|
|||
: unit_map_(unit_map)
|
||||
, mouseover_hex_()
|
||||
, exclusive_display_hexes_()
|
||||
, owner_unit_(NULL)
|
||||
, selection_candidate_(NULL)
|
||||
, owner_unit_()
|
||||
, selection_candidate_()
|
||||
, selected_action_()
|
||||
, main_highlight_()
|
||||
, secondary_highlights_()
|
||||
|
@ -79,10 +79,10 @@ void highlighter::set_mouseover_hex(const map_location& hex)
|
|||
//if we're right over a unit, just highlight all of this unit's actions
|
||||
unit_map::iterator it = unit_map_.find(hex);
|
||||
if(it != unit_map_.end()) {
|
||||
selection_candidate_ = &(*it);
|
||||
selection_candidate_ = it.get_shared_ptr();
|
||||
|
||||
if(resources::teams->at(it->side()-1).get_side_actions()->unit_has_actions(*it)) {
|
||||
owner_unit_ = &(*it);
|
||||
owner_unit_ = it.get_shared_ptr();
|
||||
}
|
||||
|
||||
//commented code below is to also select the first action of this unit as
|
||||
|
@ -121,7 +121,7 @@ void highlighter::clear()
|
|||
{
|
||||
unhighlight();
|
||||
main_highlight_.reset();
|
||||
owner_unit_ = NULL;
|
||||
owner_unit_.reset();
|
||||
secondary_highlights_.clear();
|
||||
selected_action_.reset();
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ action_ptr highlighter::get_bump_target()
|
|||
return selected_action_.lock();
|
||||
}
|
||||
|
||||
unit* highlighter::get_selection_target()
|
||||
UnitPtr highlighter::get_selection_target()
|
||||
{
|
||||
if(owner_unit_) {
|
||||
return owner_unit_;
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
action_ptr get_execute_target();
|
||||
action_ptr get_delete_target();
|
||||
action_ptr get_bump_target();
|
||||
unit* get_selection_target();
|
||||
UnitPtr get_selection_target();
|
||||
|
||||
/// @return the action that currently receives the highlight focus
|
||||
weak_action_ptr get_main_highlight() { return main_highlight_; }
|
||||
|
@ -79,8 +79,8 @@ private:
|
|||
|
||||
map_location mouseover_hex_;
|
||||
std::set<map_location> exclusive_display_hexes_;
|
||||
unit* owner_unit_;
|
||||
unit* selection_candidate_;
|
||||
UnitPtr owner_unit_;
|
||||
UnitPtr selection_candidate_;
|
||||
|
||||
weak_action_ptr selected_action_;
|
||||
weak_action_ptr main_highlight_;
|
||||
|
|
|
@ -326,8 +326,8 @@ void manager::post_delete_action(action_ptr action)
|
|||
|
||||
side_actions_ptr side_actions = resources::teams->at(action->team_index()).get_side_actions();
|
||||
|
||||
unit *actor = action->get_unit();
|
||||
if(actor != NULL) { // The unit might have died following the execution of an attack
|
||||
UnitPtr actor = action->get_unit();
|
||||
if(actor) { // The unit might have died following the execution of an attack
|
||||
side_actions::iterator action_it = side_actions->find_last_action_of(*actor);
|
||||
if(action_it != side_actions->end()) {
|
||||
move_ptr move = boost::dynamic_pointer_cast<class move>(*action_it);
|
||||
|
|
|
@ -117,12 +117,12 @@ void mapbuilder::process(side_actions &sa, side_actions::iterator action_it)
|
|||
{
|
||||
action_ptr action = *action_it;
|
||||
bool acted=false;
|
||||
unit* unit = action->get_unit();
|
||||
UnitPtr unit = action->get_unit();
|
||||
if(!unit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(acted_this_turn_.find(unit) == acted_this_turn_.end()) {
|
||||
if(acted_this_turn_.find(unit.get()) == acted_this_turn_.end()) {
|
||||
//reset MP
|
||||
unit->set_movement(unit->total_movement());
|
||||
acted=true;
|
||||
|
@ -134,9 +134,9 @@ void mapbuilder::process(side_actions &sa, side_actions::iterator action_it)
|
|||
|
||||
if(erval != action::OK) {
|
||||
// We do not delete obstructed moves, nor invalid actions caused by obstructed moves.
|
||||
if(has_invalid_actions_.find(unit) == has_invalid_actions_.end()) {
|
||||
if(has_invalid_actions_.find(unit.get()) == has_invalid_actions_.end()) {
|
||||
if(erval == action::TOO_FAR || (erval == action::LOCATION_OCCUPIED && boost::dynamic_pointer_cast<move>(action))) {
|
||||
has_invalid_actions_.insert(unit);
|
||||
has_invalid_actions_.insert(unit.get());
|
||||
invalid_actions_.push_back(action_it);
|
||||
} else {
|
||||
sa.remove_action(action_it, false);
|
||||
|
@ -149,10 +149,10 @@ void mapbuilder::process(side_actions &sa, side_actions::iterator action_it)
|
|||
}
|
||||
|
||||
// We do not keep invalid actions replaced by a valid one.
|
||||
std::set<class unit const*>::iterator invalid_it = has_invalid_actions_.find(unit);
|
||||
std::set<class unit const*>::iterator invalid_it = has_invalid_actions_.find(unit.get());
|
||||
if(invalid_it != has_invalid_actions_.end()) {
|
||||
for(std::list<side_actions::iterator>::iterator it = invalid_actions_.begin(); it != invalid_actions_.end();) {
|
||||
if((**it)->get_unit() == unit) {
|
||||
if((**it)->get_unit().get() == unit.get()) {
|
||||
sa.remove_action(*it, false);
|
||||
it = invalid_actions_.erase(it);
|
||||
} else {
|
||||
|
@ -163,7 +163,7 @@ void mapbuilder::process(side_actions &sa, side_actions::iterator action_it)
|
|||
}
|
||||
|
||||
if(acted) {
|
||||
acted_this_turn_.insert(unit);
|
||||
acted_this_turn_.insert(unit.get());
|
||||
}
|
||||
|
||||
action->apply_temp_modifier(unit_map_);
|
||||
|
@ -181,8 +181,8 @@ void mapbuilder::post_visit_team(size_t turn)
|
|||
move_ptr move = boost::dynamic_pointer_cast<class move>(action);
|
||||
if(move) {
|
||||
move->set_turn_number(0);
|
||||
if(move->get_route().steps.size() > 1 && seen.count(move->get_unit()) == 0) {
|
||||
seen.insert(move->get_unit());
|
||||
if(move->get_route().steps.size() > 1 && seen.count(move->get_unit().get()) == 0) {
|
||||
seen.insert(move->get_unit().get());
|
||||
move->set_turn_number(turn + 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -275,13 +275,13 @@ void move::execute(bool& success, bool& complete)
|
|||
}
|
||||
}
|
||||
|
||||
unit* move::get_unit() const
|
||||
UnitPtr move::get_unit() const
|
||||
{
|
||||
unit_map::iterator itor = resources::units->find(unit_underlying_id_);
|
||||
if (itor.valid())
|
||||
return &*itor;
|
||||
return itor.get_shared_ptr();
|
||||
else
|
||||
return NULL;
|
||||
return UnitPtr();
|
||||
}
|
||||
|
||||
map_location move::get_source_hex() const
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
virtual error check_validity() const;
|
||||
|
||||
/** Return the unit targeted by this action. Null if unit doesn't exist. */
|
||||
virtual unit* get_unit() const;
|
||||
virtual UnitPtr get_unit() const;
|
||||
/** @return pointer to the fake unit used only for visuals */
|
||||
virtual fake_unit_ptr get_fake_unit() { return fake_unit_; }
|
||||
|
||||
|
|
|
@ -71,11 +71,11 @@ recall::recall(config const& cfg, bool hidden)
|
|||
{
|
||||
// Construct and validate temp_unit_
|
||||
size_t underlying_id = cfg["temp_unit_"];
|
||||
BOOST_FOREACH(unit const& recall_unit, resources::teams->at(team_index()).recall_list())
|
||||
BOOST_FOREACH(const UnitConstPtr & recall_unit, resources::teams->at(team_index()).recall_list())
|
||||
{
|
||||
if(recall_unit.underlying_id()==underlying_id)
|
||||
if(recall_unit->underlying_id()==underlying_id)
|
||||
{
|
||||
temp_unit_.reset(new unit(recall_unit));
|
||||
temp_unit_.reset(new unit(*recall_unit)); //TODO: is it necessary to make a copy?
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -144,21 +144,21 @@ void recall::apply_temp_modifier(unit_map& unit_map)
|
|||
<< "] at position " << temp_unit_->get_location() << ".\n";
|
||||
|
||||
//temporarily remove unit from recall list
|
||||
std::vector<unit>& recalls = resources::teams->at(team_index()).recall_list();
|
||||
std::vector<unit>::iterator it = find_if_matches_id(recalls, temp_unit_->id());
|
||||
std::vector<UnitPtr>& recalls = resources::teams->at(team_index()).recall_list();
|
||||
std::vector<UnitPtr>::iterator it = find_if_matches_id(recalls, temp_unit_->id());
|
||||
assert(it != recalls.end());
|
||||
|
||||
//Add cost to money spent on recruits.
|
||||
int cost = resources::teams->at(team_index()).recall_cost();
|
||||
if (it->recall_cost() > -1) {
|
||||
cost = it->recall_cost();
|
||||
if ((*it)->recall_cost() > -1) {
|
||||
cost = (*it)->recall_cost();
|
||||
}
|
||||
|
||||
recalls.erase(it);
|
||||
|
||||
// Temporarily insert unit into unit_map
|
||||
//unit map takes ownership of temp_unit
|
||||
unit_map.insert(temp_unit_.release());
|
||||
unit_map.insert(temp_unit_);
|
||||
|
||||
resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(cost);
|
||||
// Update gold in top bar
|
||||
|
@ -167,11 +167,11 @@ void recall::apply_temp_modifier(unit_map& unit_map)
|
|||
|
||||
void recall::remove_temp_modifier(unit_map& unit_map)
|
||||
{
|
||||
temp_unit_.reset(unit_map.extract(recall_hex_));
|
||||
temp_unit_ = unit_map.extract(recall_hex_);
|
||||
assert(temp_unit_.get());
|
||||
|
||||
//Put unit back into recall list
|
||||
resources::teams->at(team_index()).recall_list().push_back(*temp_unit_);
|
||||
resources::teams->at(team_index()).recall_list().push_back(temp_unit_);
|
||||
}
|
||||
|
||||
void recall::draw_hex(map_location const& hex)
|
||||
|
@ -209,7 +209,7 @@ action::error recall::check_validity() const
|
|||
return LOCATION_OCCUPIED;
|
||||
}
|
||||
//Check that unit to recall is still in side's recall list
|
||||
const std::vector<unit>& recalls = (*resources::teams)[team_index()].recall_list();
|
||||
const std::vector<UnitPtr>& recalls = (*resources::teams)[team_index()].recall_list();
|
||||
if( find_if_matches_id(recalls, temp_unit_->id()) == recalls.end() ) {
|
||||
return UNIT_UNAVAILABLE;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
virtual map_location get_numbering_hex() const { return recall_hex_; }
|
||||
|
||||
/** @return pointer to a copy of the recall unit. */
|
||||
virtual unit* get_unit() const { return temp_unit_.get(); }
|
||||
virtual UnitPtr get_unit() const { return temp_unit_; }
|
||||
/** @return pointer to the fake unit used only for visuals */
|
||||
virtual fake_unit_ptr get_fake_unit() { return fake_unit_; }
|
||||
|
||||
|
@ -81,7 +81,7 @@ private:
|
|||
virtual void do_hide();
|
||||
virtual void do_show();
|
||||
|
||||
std::auto_ptr<unit> temp_unit_;
|
||||
UnitPtr temp_unit_;
|
||||
map_location recall_hex_;
|
||||
fake_unit_ptr fake_unit_;
|
||||
};
|
||||
|
|
|
@ -129,7 +129,7 @@ void recruit::apply_temp_modifier(unit_map& unit_map)
|
|||
|
||||
// Temporarily insert unit into unit_map
|
||||
// unit map takes ownership of temp_unit
|
||||
unit_map.insert(temp_unit_.release());
|
||||
unit_map.insert(temp_unit_);
|
||||
|
||||
// Update gold in the top bar
|
||||
resources::screen->invalidate_game_status();
|
||||
|
@ -138,7 +138,7 @@ void recruit::apply_temp_modifier(unit_map& unit_map)
|
|||
void recruit::remove_temp_modifier(unit_map& unit_map)
|
||||
{
|
||||
//Unit map gives back ownership of temp_unit_
|
||||
temp_unit_.reset(unit_map.extract(recruit_hex_));
|
||||
temp_unit_ = unit_map.extract(recruit_hex_);
|
||||
assert(temp_unit_.get());
|
||||
}
|
||||
|
||||
|
@ -164,14 +164,14 @@ void recruit::redraw()
|
|||
}
|
||||
|
||||
|
||||
std::auto_ptr<unit> recruit::create_corresponding_unit()
|
||||
UnitPtr recruit::create_corresponding_unit()
|
||||
{
|
||||
unit_type const* type = unit_types.find(unit_name_);
|
||||
assert(type);
|
||||
int side_num = team_index() + 1;
|
||||
//real_unit = false needed to avoid generating random traits and causing OOS
|
||||
bool real_unit = false;
|
||||
std::auto_ptr<unit> result(new unit(*type, side_num, real_unit));
|
||||
UnitPtr result(new unit(*type, side_num, real_unit));
|
||||
result->set_movement(0, true);
|
||||
result->set_attacks(0);
|
||||
return result; //ownership gets transferred to returned auto_ptr copy
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
virtual map_location get_numbering_hex() const { return recruit_hex_; }
|
||||
|
||||
/** @return pointer to a fake unit representing the one that will eventually be recruited. */
|
||||
virtual unit* get_unit() const { return temp_unit_.get(); }
|
||||
virtual UnitPtr get_unit() const { return temp_unit_; }
|
||||
/** @return pointer to the fake unit used only for visuals */
|
||||
virtual fake_unit_ptr get_fake_unit() { return fake_unit_; }
|
||||
|
||||
|
@ -82,7 +82,7 @@ protected:
|
|||
std::string unit_name_;
|
||||
map_location recruit_hex_;
|
||||
//Temp unit to insert in the future unit map when needed
|
||||
std::auto_ptr<unit> temp_unit_;
|
||||
UnitPtr temp_unit_;
|
||||
fake_unit_ptr fake_unit_;
|
||||
int cost_;
|
||||
|
||||
|
@ -92,7 +92,7 @@ private:
|
|||
virtual void do_hide();
|
||||
virtual void do_show();
|
||||
|
||||
std::auto_ptr<unit> create_corresponding_unit();
|
||||
UnitPtr create_corresponding_unit();
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, recruit_ptr recruit);
|
||||
|
|
|
@ -453,9 +453,9 @@ namespace
|
|||
move_ptr second_;
|
||||
|
||||
void check_recruit_recall(const map_location &loc) {
|
||||
unit const* leader = second_->get_unit();
|
||||
const UnitConstPtr leader = second_->get_unit();
|
||||
if(leader->can_recruit() && can_recruit_on(*leader, loc)) {
|
||||
if(unit const* backup_leader = find_backup_leader(*leader)) {
|
||||
if(const UnitConstPtr backup_leader = find_backup_leader(*leader)) {
|
||||
side_actions::iterator it = sa_.find_first_action_of(*backup_leader);
|
||||
if(!(it == sa_.end() || position_ < it)) {
|
||||
return; //backup leader but he moves before us, refuse bump
|
||||
|
@ -487,9 +487,9 @@ side_actions::iterator side_actions::bump_earlier(side_actions::iterator positio
|
|||
side_actions::iterator previous = position - 1;
|
||||
|
||||
//Verify we're not moving an action out-of-order compared to other action of the same unit
|
||||
unit const* previous_ptr = (*previous)->get_unit();
|
||||
unit const* current_ptr = (*position)->get_unit();
|
||||
if(previous_ptr && current_ptr && previous_ptr == current_ptr) {
|
||||
const UnitConstPtr previous_ptr = (*previous)->get_unit();
|
||||
const UnitConstPtr current_ptr = (*position)->get_unit();
|
||||
if(previous_ptr && current_ptr && previous_ptr.get() == current_ptr.get()) {
|
||||
return end();
|
||||
}
|
||||
|
||||
|
@ -859,16 +859,16 @@ side_actions::net_cmd side_actions::make_net_cmd_refresh() const
|
|||
void side_actions::raw_turn_shift()
|
||||
{
|
||||
//find units who still have plans for turn 0 (i.e. were too lazy to finish their jobs)
|
||||
std::set<unit const*> lazy_units;
|
||||
std::set<UnitConstPtr> lazy_units;
|
||||
BOOST_FOREACH(action_ptr const& act, iter_turn(0)) {
|
||||
unit const* u = act->get_unit();
|
||||
UnitConstPtr u = act->get_unit();
|
||||
if(u) {
|
||||
lazy_units.insert(u);
|
||||
}
|
||||
}
|
||||
|
||||
//push their plans back one turn
|
||||
std::set<unit const*>::iterator lazy_end = lazy_units.end();
|
||||
std::set<UnitConstPtr>::iterator lazy_end = lazy_units.end();
|
||||
iterator itor = end();
|
||||
while(itor != begin()) {
|
||||
--itor;
|
||||
|
|
|
@ -96,13 +96,13 @@ suppose_dead::~suppose_dead()
|
|||
resources::screen->invalidate(loc_);
|
||||
}
|
||||
|
||||
unit* suppose_dead::get_unit() const
|
||||
UnitPtr suppose_dead::get_unit() const
|
||||
{
|
||||
unit_map::iterator itor = resources::units->find(unit_underlying_id_);
|
||||
if (itor.valid())
|
||||
return &*itor;
|
||||
return itor.get_shared_ptr();
|
||||
else
|
||||
return NULL;
|
||||
return UnitPtr();
|
||||
}
|
||||
|
||||
void suppose_dead::accept(visitor& v)
|
||||
|
@ -116,12 +116,12 @@ void suppose_dead::execute(bool& success, bool& complete)
|
|||
void suppose_dead::apply_temp_modifier(unit_map& unit_map)
|
||||
{
|
||||
// Remove the unit
|
||||
unit const* removed_unit = unit_map.extract(loc_);
|
||||
const UnitConstPtr removed_unit = unit_map.extract(loc_);
|
||||
DBG_WB << "Suppose dead: Temporarily removing unit " << removed_unit->name() << " [" << removed_unit->id()
|
||||
<< "] from (" << loc_ << ")\n";
|
||||
|
||||
// Just check to make sure we removed the unit we expected to remove
|
||||
assert(get_unit() == removed_unit);
|
||||
assert(get_unit().get() == removed_unit.get());
|
||||
}
|
||||
|
||||
void suppose_dead::remove_temp_modifier(unit_map& unit_map)
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
virtual ~suppose_dead();
|
||||
|
||||
/** Return the unit targeted by this action. Null if unit doesn't exist. */
|
||||
virtual unit* get_unit() const;
|
||||
virtual UnitPtr get_unit() const;
|
||||
/** @return null pointer */
|
||||
virtual fake_unit_ptr get_fake_unit() { return fake_unit_ptr(); }
|
||||
/** Return the location at which this action was planned. */
|
||||
|
|
|
@ -61,19 +61,19 @@ side_actions_ptr current_side_actions()
|
|||
return side_actions;
|
||||
}
|
||||
|
||||
unit const* find_backup_leader(unit const& leader)
|
||||
UnitConstPtr find_backup_leader(const unit & leader)
|
||||
{
|
||||
assert(leader.can_recruit());
|
||||
assert(resources::gameboard->map().is_keep(leader.get_location()));
|
||||
BOOST_FOREACH(unit const& unit, *resources::units)
|
||||
for (unit_map::const_iterator unit = resources::units->begin(); unit != resources::units->end(); unit++)
|
||||
{
|
||||
if (unit.can_recruit() && unit.id() != leader.id())
|
||||
if (unit->can_recruit() && unit->id() != leader.id())
|
||||
{
|
||||
if ( can_recruit_on(unit, leader.get_location()) )
|
||||
return &unit;
|
||||
if ( can_recruit_on(*unit, leader.get_location()) )
|
||||
return unit.get_shared_ptr();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return UnitConstPtr();
|
||||
}
|
||||
|
||||
unit* find_recruiter(size_t team_index, map_location const& hex)
|
||||
|
|
|
@ -47,7 +47,7 @@ side_actions_ptr current_side_actions();
|
|||
* For a given leader on a keep, find another leader on another keep in the same castle.
|
||||
* @retval NULL if no such leader has been found
|
||||
*/
|
||||
unit const* find_backup_leader(unit const& leader);
|
||||
UnitConstPtr find_backup_leader(unit const& leader);
|
||||
|
||||
/**
|
||||
* @return a leader from the specified team who can recruit on the specified hex
|
||||
|
|
Loading…
Add table
Reference in a new issue