Added multi-turn move whiteboard plans.
This commit is contained in:
parent
b4132d5332
commit
2c07b91e6e
8 changed files with 260 additions and 136 deletions
|
@ -704,7 +704,7 @@ config play_controller::to_config() const
|
|||
|
||||
void play_controller::finish_side_turn(){
|
||||
|
||||
resources::whiteboard->on_finish_side_turn();
|
||||
resources::whiteboard->on_finish_side_turn(player_number_);
|
||||
|
||||
for(unit_map::iterator uit = units_.begin(); uit != units_.end(); ++uit) {
|
||||
if (uit->side() == player_number_)
|
||||
|
|
|
@ -60,10 +60,10 @@ manager::manager():
|
|||
mapbuilder_(),
|
||||
highlighter_(),
|
||||
route_(),
|
||||
move_arrow_(),
|
||||
fake_unit_(),
|
||||
move_arrows_(),
|
||||
fake_units_(),
|
||||
key_poller_(new CKey),
|
||||
hidden_unit_hex_(),
|
||||
hidden_unit_hexes_(),
|
||||
net_buffer_(resources::teams->size()),
|
||||
team_plans_hidden_(resources::teams->size(),false)
|
||||
{
|
||||
|
@ -244,9 +244,11 @@ void manager::on_init_side()
|
|||
}
|
||||
}
|
||||
|
||||
void manager::on_finish_side_turn()
|
||||
void manager::on_finish_side_turn(int side)
|
||||
{
|
||||
wait_for_side_init_ = true;
|
||||
if(side == viewer_side())
|
||||
viewer_actions()->synced_turn_shift();
|
||||
highlighter_.reset();
|
||||
erase_temp_move();
|
||||
LOG_WB << "on_finish_side_turn()\n";
|
||||
|
@ -462,11 +464,9 @@ void manager::draw_hex(const map_location& hex)
|
|||
|
||||
void manager::on_mouseover_change(const map_location& hex)
|
||||
{
|
||||
if (hidden_unit_hex_.valid())
|
||||
{
|
||||
resources::screen->remove_exclusive_draw(hidden_unit_hex_);
|
||||
hidden_unit_hex_ = map_location();
|
||||
}
|
||||
foreach(map_location const& hex, hidden_unit_hexes_)
|
||||
resources::screen->remove_exclusive_draw(hex);
|
||||
hidden_unit_hexes_.clear();
|
||||
|
||||
map_location selected_hex = resources::screen->selected_hex();
|
||||
unit_map::iterator it;
|
||||
|
@ -539,6 +539,11 @@ void manager::create_temp_move()
|
|||
{
|
||||
route_.reset();
|
||||
|
||||
/*
|
||||
* CHECK PRE-CONDITIONS
|
||||
* (This section has multiple return paths.)
|
||||
*/
|
||||
|
||||
if(!active_
|
||||
|| wait_for_side_init_
|
||||
|| executing_actions_
|
||||
|
@ -548,11 +553,6 @@ void manager::create_temp_move()
|
|||
|
||||
assert(!has_planned_unit_map());
|
||||
|
||||
/*
|
||||
* CHECK PRE-CONDITIONS
|
||||
* (This section has multiple return paths.)
|
||||
*/
|
||||
|
||||
pathfind::marked_route const& route =
|
||||
resources::controller->get_mouse_handler_base().get_current_route();
|
||||
|
||||
|
@ -562,25 +562,6 @@ void manager::create_temp_move()
|
|||
if (!selected_unit) return;
|
||||
if (selected_unit->side() != resources::screen->viewing_side()) return;
|
||||
|
||||
//FIXME: Temporary: Don't draw move arrow if move goes beyond range.
|
||||
bool cancel = false;
|
||||
foreach (const map_location& hex, route.steps)
|
||||
{
|
||||
if (cancel)
|
||||
{
|
||||
erase_temp_move();
|
||||
return;
|
||||
}
|
||||
pathfind::marked_route::mark_map::const_iterator w =
|
||||
route.marks.find(hex);
|
||||
//We only accept an end-of-first-turn or a capture mark if this is the move's last hex.
|
||||
if (w != route.marks.end() && (w->second.turns == 1
|
||||
|| w->second.capture))
|
||||
{
|
||||
cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DONE CHECKING PRE-CONDITIONS, CREATE THE TEMP MOVE
|
||||
* (This section has only one return path.)
|
||||
|
@ -590,70 +571,110 @@ void manager::create_temp_move()
|
|||
// wb::move object
|
||||
|
||||
route_.reset(new pathfind::marked_route(route));
|
||||
//NOTE: route_.steps.back() = dst, and route_.steps.front() = src
|
||||
//NOTE: route_->steps.back() = dst, and route_->steps.front() = src
|
||||
|
||||
if (!move_arrow_)
|
||||
size_t turn = 0;
|
||||
std::vector<map_location>::iterator prev_itor = route.steps.begin();
|
||||
std::vector<map_location>::iterator curr_itor = prev_itor;
|
||||
std::vector<map_location>::iterator end_itor = route.steps.end();
|
||||
for(; curr_itor!=end_itor; ++curr_itor)
|
||||
{
|
||||
// Create temp arrow
|
||||
move_arrow_.reset(new arrow());
|
||||
move_arrow_->set_color(team::get_side_color_index(
|
||||
viewer_side()));
|
||||
move_arrow_->set_style(arrow::STYLE_HIGHLIGHTED);
|
||||
const map_location& hex = *curr_itor;
|
||||
|
||||
//search for end-of-turn marks
|
||||
pathfind::marked_route::mark_map::const_iterator w =
|
||||
route.marks.find(hex);
|
||||
if(w != route.marks.end() && w->second.turns > 0)
|
||||
{
|
||||
turn = w->second.turns-1;
|
||||
|
||||
if(turn >= move_arrows_.size())
|
||||
move_arrows_.resize(turn+1);
|
||||
if(turn >= fake_units_.size())
|
||||
fake_units_.resize(turn+1);
|
||||
|
||||
arrow_ptr& move_arrow = move_arrows_[turn];
|
||||
fake_unit_ptr& fake_unit = fake_units_[turn];
|
||||
|
||||
if(!move_arrow)
|
||||
{
|
||||
// Create temp arrow
|
||||
move_arrow.reset(new arrow());
|
||||
move_arrow->set_color(team::get_side_color_index(
|
||||
viewer_side()));
|
||||
move_arrow->set_style(arrow::STYLE_HIGHLIGHTED);
|
||||
}
|
||||
|
||||
arrow_path_t path(prev_itor,curr_itor+1);
|
||||
move_arrow->set_path(path);
|
||||
|
||||
if(path.size() >= 2)
|
||||
{
|
||||
if(!fake_unit)
|
||||
{
|
||||
// Create temp ghost unit
|
||||
fake_unit.reset(new unit(*selected_unit),
|
||||
wb::fake_unit_deleter());
|
||||
resources::screen->place_temporary_unit(fake_unit.get());
|
||||
fake_unit->set_ghosted(false);
|
||||
}
|
||||
|
||||
unit_display::move_unit(path, *fake_unit, *resources::teams,
|
||||
false); //get facing right
|
||||
fake_unit->set_location(*curr_itor);
|
||||
fake_unit->set_ghosted(false);
|
||||
|
||||
//if destination is over another unit, temporarily hide it
|
||||
resources::screen->add_exclusive_draw(fake_unit->get_location(), *fake_unit);
|
||||
hidden_unit_hexes_.push_back(fake_unit->get_location());
|
||||
}
|
||||
else //zero-hex path -- don't bother drawing a fake unit
|
||||
fake_unit.reset();
|
||||
|
||||
prev_itor = curr_itor;
|
||||
}
|
||||
}
|
||||
if (!fake_unit_)
|
||||
{
|
||||
// Create temp ghost unit
|
||||
fake_unit_.reset(new unit(*selected_unit),
|
||||
wb::fake_unit_deleter());
|
||||
resources::screen->place_temporary_unit(fake_unit_.get());
|
||||
fake_unit_->set_ghosted(false);
|
||||
}
|
||||
|
||||
move_arrow_->set_path(route_->steps);
|
||||
|
||||
unit_display::move_unit(route_->steps, *fake_unit_, *resources::teams,
|
||||
false); //get facing right
|
||||
fake_unit_->set_location(route_->steps.back());
|
||||
fake_unit_->set_ghosted(false);
|
||||
|
||||
//if destination is over another unit, temporarily hide it
|
||||
resources::screen->add_exclusive_draw(fake_unit_->get_location(), *fake_unit_);
|
||||
hidden_unit_hex_ = fake_unit_->get_location();
|
||||
//toss out old arrows and fake units
|
||||
move_arrows_.resize(turn+1);
|
||||
fake_units_.resize(turn+1);
|
||||
}
|
||||
|
||||
void manager::erase_temp_move()
|
||||
{
|
||||
if (move_arrow_)
|
||||
{
|
||||
move_arrow_.reset(); //auto-removes itself from display
|
||||
}
|
||||
if (fake_unit_)
|
||||
{
|
||||
fake_unit_.reset(); //auto-removes itself from display thanks to custom deleter in the shared_ptr
|
||||
}
|
||||
if (route_)
|
||||
{
|
||||
route_.reset();
|
||||
}
|
||||
move_arrows_.clear();
|
||||
fake_units_.clear();
|
||||
route_.reset();
|
||||
}
|
||||
|
||||
void manager::save_temp_move()
|
||||
{
|
||||
if (has_temp_move() && !executing_actions_ && !resources::controller->is_linger_mode())
|
||||
{
|
||||
arrow_ptr move_arrow;
|
||||
fake_unit_ptr fake_unit;
|
||||
side_actions& sa = *viewer_actions();
|
||||
unit const *const u = future_visible_unit(route_->steps.front());
|
||||
assert(u);
|
||||
size_t first_turn = sa.get_turn_num_of(*u);
|
||||
|
||||
move_arrow = arrow_ptr(move_arrow_);
|
||||
fake_unit = fake_unit_ptr(fake_unit_);
|
||||
assert(move_arrows_.size() == fake_units_.size());
|
||||
size_t size = move_arrows_.size();
|
||||
for(size_t i=0; i<size; ++i)
|
||||
{
|
||||
arrow_ptr move_arrow = move_arrows_[i];
|
||||
if(!arrow::valid_path(move_arrow->get_path()))
|
||||
continue;
|
||||
|
||||
viewer_actions()->queue_move(*route_, move_arrow, fake_unit);
|
||||
size_t turn = first_turn + i;
|
||||
fake_unit_ptr fake_unit = fake_units_[i];
|
||||
pathfind::marked_route route;
|
||||
route.steps = move_arrow->get_path();
|
||||
route.move_cost = path_cost(route.steps,*u);
|
||||
|
||||
sa.queue_move(turn,route,move_arrow,fake_unit);
|
||||
}
|
||||
erase_temp_move();
|
||||
|
||||
on_save_action();
|
||||
|
||||
LOG_WB << *viewer_actions() << "\n";
|
||||
|
||||
print_help_once();
|
||||
}
|
||||
}
|
||||
|
@ -668,8 +689,10 @@ void manager::save_temp_attack(const map_location& attack_from, const map_locati
|
|||
map_location source_hex;
|
||||
if (route_ && !route_->steps.empty())
|
||||
{
|
||||
move_arrow = arrow_ptr(move_arrow_);
|
||||
fake_unit = fake_unit_ptr(fake_unit_);
|
||||
assert(move_arrows_.size() == 1);
|
||||
assert(fake_units_.size() == 1);
|
||||
move_arrow = move_arrows_.front();
|
||||
fake_unit = fake_units_.front();
|
||||
|
||||
assert(route_->steps.back() == attack_from);
|
||||
source_hex = route_->steps.front();
|
||||
|
@ -693,7 +716,8 @@ void manager::save_temp_attack(const map_location& attack_from, const map_locati
|
|||
|
||||
if (weapon_choice >= 0)
|
||||
{
|
||||
viewer_actions()->queue_attack(target_hex, weapon_choice, *route_, move_arrow, fake_unit);
|
||||
side_actions& sa = *viewer_actions();
|
||||
sa.queue_attack(sa.get_turn_num_of(*attacking_unit),target_hex,weapon_choice,*route_,move_arrow,fake_unit);
|
||||
|
||||
on_save_action();
|
||||
|
||||
|
@ -718,7 +742,11 @@ bool manager::save_recruit(const std::string& name, int side_num, const map_loca
|
|||
}
|
||||
else
|
||||
{
|
||||
viewer_actions()->queue_recruit(name, recruit_hex);
|
||||
side_actions& sa = *viewer_actions();
|
||||
size_t turn = sa.num_turns();
|
||||
if(turn > 0)
|
||||
--turn;
|
||||
sa.queue_recruit(turn,name,recruit_hex);
|
||||
created_planned_recruit = true;
|
||||
|
||||
on_save_action();
|
||||
|
@ -742,7 +770,11 @@ bool manager::save_recall(const unit& unit, int side_num, const map_location& re
|
|||
}
|
||||
else
|
||||
{
|
||||
viewer_actions()->queue_recall(unit, recall_hex);
|
||||
side_actions& sa = *viewer_actions();
|
||||
size_t turn = sa.num_turns();
|
||||
if(turn > 0)
|
||||
--turn;
|
||||
sa.queue_recall(turn,unit,recall_hex);
|
||||
created_planned_recall = true;
|
||||
|
||||
on_save_action();
|
||||
|
@ -757,7 +789,8 @@ void manager::save_suppose_dead(unit& curr_unit, map_location const& loc)
|
|||
{
|
||||
if(active_ && !executing_actions_ && !resources::controller->is_linger_mode())
|
||||
{
|
||||
viewer_actions()->queue_suppose_dead(curr_unit,loc);
|
||||
side_actions& sa = *viewer_actions();
|
||||
sa.queue_suppose_dead(sa.get_turn_num_of(curr_unit),curr_unit,loc);
|
||||
on_save_action();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
* The on_* methods below inform the whiteboard of specific events
|
||||
*/
|
||||
void on_init_side();
|
||||
void on_finish_side_turn();
|
||||
void on_finish_side_turn(int side);
|
||||
void on_mouseover_change(const map_location& hex);
|
||||
void on_deselect_hex(){ erase_temp_move();}
|
||||
void on_gamestate_change();
|
||||
|
@ -109,7 +109,7 @@ public:
|
|||
/// Creates a temporary visual arrow, that follows the cursor, for move creation purposes
|
||||
void create_temp_move();
|
||||
/// Informs whether an arrow is being displayed for move creation purposes
|
||||
bool has_temp_move() const { return route_ && fake_unit_ && move_arrow_; }
|
||||
bool has_temp_move() const { return route_ && !fake_units_.empty() && !move_arrows_.empty(); }
|
||||
/// Erase the temporary arrow
|
||||
void erase_temp_move();
|
||||
/// Creates a move action for the current side, and erases the temp move.
|
||||
|
@ -186,12 +186,12 @@ private:
|
|||
|
||||
boost::scoped_ptr<pathfind::marked_route> route_;
|
||||
|
||||
arrow_ptr move_arrow_;
|
||||
fake_unit_ptr fake_unit_;
|
||||
std::vector<arrow_ptr> move_arrows_;
|
||||
std::vector<fake_unit_ptr> fake_units_;
|
||||
|
||||
boost::scoped_ptr<CKey> key_poller_;
|
||||
|
||||
map_location hidden_unit_hex_;
|
||||
std::vector<map_location> hidden_unit_hexes_;
|
||||
|
||||
///net_buffer_[i] = whiteboard network data to be sent "from" teams[i].
|
||||
std::vector<config> net_buffer_;
|
||||
|
|
|
@ -124,7 +124,7 @@ void side_actions::get_numbers(const map_location& hex, numbers_t& result)
|
|||
|
||||
bool side_actions::execute_next()
|
||||
{
|
||||
if (!actions_.empty())
|
||||
if (!actions_.front().empty())
|
||||
{
|
||||
return execute(begin());
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ void side_actions::execute_all()
|
|||
{
|
||||
iterator position = begin();
|
||||
bool finished = execute(position);
|
||||
keep_executing = finished && !empty();
|
||||
keep_executing = finished && !actions_.front().empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ bool side_actions::execute(side_actions::iterator position)
|
|||
ERR_WB << "Modifying action queue while temp modifiers are applied!!!\n";
|
||||
}
|
||||
|
||||
if (actions_.empty() || !validate_iterator(position))
|
||||
if(actions_.empty() || !validate_iterator(position) || position.turn_num_ > 0)
|
||||
return false;
|
||||
|
||||
LOG_WB << "Before execution, " << *this << "\n";
|
||||
|
@ -253,41 +253,41 @@ void side_actions::show()
|
|||
act->show();
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::queue_move(const pathfind::marked_route& route, arrow_ptr arrow, fake_unit_ptr fake_unit)
|
||||
side_actions::iterator side_actions::queue_move(size_t turn, const pathfind::marked_route& route, arrow_ptr arrow, fake_unit_ptr fake_unit)
|
||||
{
|
||||
move_ptr new_move;
|
||||
new_move.reset(new move(team_index(), hidden_, route, arrow, fake_unit));
|
||||
return queue_action(new_move);
|
||||
return queue_action(turn,new_move);
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::queue_attack(const map_location& target_hex, int weapon_choice,
|
||||
side_actions::iterator side_actions::queue_attack(size_t turn, const map_location& target_hex, int weapon_choice,
|
||||
const pathfind::marked_route& route,
|
||||
arrow_ptr arrow, fake_unit_ptr fake_unit)
|
||||
{
|
||||
attack_ptr new_attack;
|
||||
new_attack.reset(new attack(team_index(), hidden_, target_hex, weapon_choice, route, arrow, fake_unit));
|
||||
return queue_action(new_attack);
|
||||
return queue_action(turn,new_attack);
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::queue_recruit(const std::string& unit_name, const map_location& recruit_hex)
|
||||
side_actions::iterator side_actions::queue_recruit(size_t turn, const std::string& unit_name, const map_location& recruit_hex)
|
||||
{
|
||||
recruit_ptr new_recruit;
|
||||
new_recruit.reset(new recruit(team_index(), hidden_, unit_name, recruit_hex));
|
||||
return queue_action(new_recruit);
|
||||
return queue_action(turn,new_recruit);
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::queue_recall(const unit& unit, const map_location& recall_hex)
|
||||
side_actions::iterator side_actions::queue_recall(size_t turn, const unit& unit, const map_location& recall_hex)
|
||||
{
|
||||
recall_ptr new_recall;
|
||||
new_recall.reset(new recall(team_index(), hidden_, unit, recall_hex));
|
||||
return queue_action(new_recall);
|
||||
return queue_action(turn,new_recall);
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::queue_suppose_dead(unit& curr_unit, map_location const& loc)
|
||||
side_actions::iterator side_actions::queue_suppose_dead(size_t turn, unit& curr_unit, map_location const& loc)
|
||||
{
|
||||
suppose_dead_ptr new_suppose_dead;
|
||||
new_suppose_dead.reset(new suppose_dead(team_index(),hidden_,curr_unit,loc));
|
||||
return queue_action(new_suppose_dead);
|
||||
return queue_action(turn,new_suppose_dead);
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::insert_action(iterator position, action_ptr action)
|
||||
|
@ -303,11 +303,10 @@ side_actions::iterator side_actions::insert_action(iterator position, action_ptr
|
|||
return valid_position;
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::queue_action(action_ptr action)
|
||||
side_actions::iterator side_actions::queue_action(size_t turn_num, action_ptr action)
|
||||
{
|
||||
if(resources::whiteboard->has_planned_unit_map())
|
||||
ERR_WB << "Modifying action queue while temp modifiers are applied!!!\n";
|
||||
size_t turn_num = 0; //< this will need to change eventually
|
||||
iterator result = synced_enqueue(turn_num, action);
|
||||
LOG_WB << "Inserted into turn #" << (turn_num+1) << " at position #" << actions_[turn_num].size()
|
||||
<< " : " << action <<"\n";
|
||||
|
@ -538,6 +537,14 @@ void side_actions::remove_invalid_of(unit const* u)
|
|||
}
|
||||
}
|
||||
|
||||
size_t side_actions::get_turn_num_of(unit const& u) const
|
||||
{
|
||||
const_iterator itor = const_cast<side_actions*>(this)->find_last_action_of(&u);
|
||||
if(itor == end())
|
||||
return 0;
|
||||
return itor.base_.turn_num_;
|
||||
}
|
||||
|
||||
void side_actions::validate_actions()
|
||||
{
|
||||
if (resources::whiteboard->has_planned_unit_map())
|
||||
|
@ -840,4 +847,49 @@ side_actions::const_iterator side_actions::end() const
|
|||
side_actions::const_reverse_iterator side_actions::rend() const
|
||||
{ return const_reverse_iterator(const_cast<side_actions*>(this)->rend()); }
|
||||
|
||||
void side_actions::raw_turn_shift()
|
||||
{
|
||||
//optimization
|
||||
if(actions_.size() < 2)
|
||||
return;
|
||||
|
||||
//find units who still have plans for turn 0 (i.e. were too lazy to finish their jobs)
|
||||
std::set<unit const*> lazy_units;
|
||||
foreach(action_ptr const& act, iter_turn(0))
|
||||
{
|
||||
unit const* 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();
|
||||
iterator itor = end();
|
||||
while(itor != begin())
|
||||
{
|
||||
--itor;
|
||||
action_ptr act = *itor;
|
||||
|
||||
if(lazy_units.find(act->get_unit()) != lazy_end)
|
||||
{
|
||||
raw_enqueue(itor.turn_num_+1,act);
|
||||
itor = raw_erase(itor);
|
||||
}
|
||||
}
|
||||
|
||||
//push any remaining first-turn plans into the second turn
|
||||
foreach(action_ptr act, actions_.front())
|
||||
actions_[1].push_front(act);
|
||||
actions_.front().clear();
|
||||
|
||||
//shift everything forward one turn
|
||||
actions_.pop_front();
|
||||
}
|
||||
|
||||
void side_actions::synced_turn_shift()
|
||||
{
|
||||
raw_turn_shift();
|
||||
resources::whiteboard->queue_net_cmd(team_index(),make_net_cmd_refresh());
|
||||
}
|
||||
|
||||
} //end namespace wb
|
||||
|
|
|
@ -41,7 +41,7 @@ class side_actions: public boost::enable_shared_from_this<side_actions>
|
|||
* actions_.empty() || !actions_.back().empty();
|
||||
*/
|
||||
|
||||
typedef std::vector<action_queue> contents_t;
|
||||
typedef std::deque<action_queue> contents_t;
|
||||
|
||||
public:
|
||||
class iterator;
|
||||
|
@ -144,33 +144,33 @@ public:
|
|||
* Queues a move to be executed last
|
||||
* @return The queued move's position
|
||||
*/
|
||||
iterator queue_move(const pathfind::marked_route& route,
|
||||
iterator queue_move(size_t turn_num, const pathfind::marked_route& route,
|
||||
arrow_ptr arrow, fake_unit_ptr fake_unit);
|
||||
|
||||
/**
|
||||
* Queues an attack or attack-move to be executed last
|
||||
* @return The queued attack's position
|
||||
*/
|
||||
iterator queue_attack(const map_location& target_hex, int weapon_choice, const pathfind::marked_route& route,
|
||||
iterator queue_attack(size_t turn_num, const map_location& target_hex, int weapon_choice, const pathfind::marked_route& route,
|
||||
arrow_ptr arrow, fake_unit_ptr fake_unit);
|
||||
|
||||
/**
|
||||
* Queues a recruit to be executed last
|
||||
* @return The queued recruit's position
|
||||
*/
|
||||
iterator queue_recruit(const std::string& unit_name, const map_location& recruit_hex);
|
||||
iterator queue_recruit(size_t turn_num, const std::string& unit_name, const map_location& recruit_hex);
|
||||
|
||||
/**
|
||||
* Queues a recall to be executed last
|
||||
* @return The queued recall's position
|
||||
*/
|
||||
iterator queue_recall(const unit& unit, const map_location& recall_hex);
|
||||
iterator queue_recall(size_t turn_num, const unit& unit, const map_location& recall_hex);
|
||||
|
||||
/**
|
||||
* Queues a suppose_dead to be executed last
|
||||
* @return The queued suppose_dead's position (an iterator to it)
|
||||
*/
|
||||
iterator queue_suppose_dead(unit& curr_unit, map_location const& loc);
|
||||
iterator queue_suppose_dead(size_t turn_num, unit& curr_unit, map_location const& loc);
|
||||
|
||||
/**
|
||||
* Inserts an action at the specified position. The begin() and end() functions might prove useful here.
|
||||
|
@ -182,7 +182,7 @@ public:
|
|||
* Queues an action to be executed last
|
||||
* @return The queued action's position
|
||||
*/
|
||||
iterator queue_action(action_ptr action);
|
||||
iterator queue_action(size_t turn_num, action_ptr action);
|
||||
|
||||
/**
|
||||
* Moves an action earlier in the execution order (i.e. at the front of the queue),
|
||||
|
@ -232,6 +232,9 @@ public:
|
|||
///Removes all invalid actions "attached" to the unit
|
||||
void remove_invalid_of(unit const*);
|
||||
|
||||
///Determines the appropriate turn number for the next action planned for this unit
|
||||
size_t get_turn_num_of(unit const&) const;
|
||||
|
||||
///Validates all planned actions in the queue
|
||||
void validate_actions();
|
||||
|
||||
|
@ -240,6 +243,9 @@ public:
|
|||
///Used to track gold spending by recruits/recalls when building the future unit map
|
||||
void change_gold_spent_by(int difference) { gold_spent_ += difference; assert(gold_spent_ >= 0);}
|
||||
|
||||
void side_actions::raw_turn_shift();
|
||||
void side_actions::synced_turn_shift();
|
||||
|
||||
/**
|
||||
* Network code. A net_cmd object (a config in disguise) represents a modification
|
||||
* to a side_actions object. execute_net_cmd() translates one of these into
|
||||
|
|
|
@ -105,6 +105,19 @@ unit* future_visible_unit(int on_side, map_location hex, int viewer_side)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int path_cost(std::vector<map_location> const& path, unit const& u)
|
||||
{
|
||||
assert(!path.empty());
|
||||
|
||||
int result = 0;
|
||||
gamemap const& map = *resources::game_map;
|
||||
|
||||
foreach(map_location const& loc, std::make_pair(path.begin()+1,path.end()))
|
||||
result += u.movement_cost(map[loc]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
temporary_unit_hider::temporary_unit_hider(unit& u)
|
||||
: unit_(&u)
|
||||
{unit_->set_hidden(true);}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef WB_UTILITY_HPP_
|
||||
#define WB_UTILITY_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "typedefs.hpp"
|
||||
|
||||
class unit;
|
||||
|
@ -58,6 +60,9 @@ unit* future_visible_unit(map_location hex, int viewer_side = wb::viewer_side())
|
|||
/// @param on_side Only search for units of this side.
|
||||
unit* future_visible_unit(int on_side, map_location hex, int viewer_side = wb::viewer_side());
|
||||
|
||||
/// Computes the MP cost for u to travel path
|
||||
int path_cost(std::vector<map_location> const& path, unit const& u);
|
||||
|
||||
struct temporary_unit_hider {
|
||||
temporary_unit_hider(unit& u);
|
||||
~temporary_unit_hider();
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "side_actions.hpp"
|
||||
#include "typedefs.hpp"
|
||||
|
||||
#include "foreach.hpp"
|
||||
#include "play_controller.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "team.hpp"
|
||||
|
@ -79,37 +80,51 @@ private:
|
|||
{
|
||||
Derived* const new_this = static_cast<Derived*>(this);
|
||||
|
||||
//Determine how many turns' worth of plans there are
|
||||
size_t max_turns = 0;
|
||||
foreach(team& t, *resources::teams)
|
||||
max_turns = std::max(max_turns,t.get_side_actions()->num_turns());
|
||||
|
||||
size_t const current_team = resources::controller->current_side() - 1;
|
||||
size_t const num_teams = resources::teams->size();
|
||||
for(size_t iteration = 0; iteration < num_teams; ++iteration)
|
||||
//for each turn with any planned actions
|
||||
for(size_t turn_iter=0; turn_iter<max_turns; ++turn_iter)
|
||||
{
|
||||
size_t const team_index
|
||||
= (current_team+num_teams+(reverse? -1-iteration: iteration)) % num_teams;
|
||||
team& t = resources::teams->at(team_index);
|
||||
side_actions& sa = *t.get_side_actions();
|
||||
if(!new_this->pre_visit_team(team_index,t,sa))
|
||||
continue; //< Skip this team's actions
|
||||
size_t const turn = (reverse? max_turns-1-turn_iter: turn_iter);
|
||||
|
||||
if(reverse)
|
||||
//for each team
|
||||
for(size_t team_iter = 0; team_iter < num_teams; ++team_iter)
|
||||
{
|
||||
side_actions::reverse_iterator itor = sa.rbegin();
|
||||
side_actions::reverse_iterator end = sa.rend();
|
||||
while(itor!=end) {
|
||||
++itor;
|
||||
if(!new_this->visit(team_index,t,sa,side_actions::iterator(itor)))
|
||||
return; //< Early abort
|
||||
size_t const team_index
|
||||
= (current_team+num_teams+(reverse? -1-team_iter: team_iter)) % num_teams;
|
||||
team& t = resources::teams->at(team_index);
|
||||
side_actions& sa = *t.get_side_actions();
|
||||
if(!new_this->pre_visit_team(team_index,t,sa))
|
||||
continue; //< Skip this team's actions
|
||||
|
||||
if(reverse)
|
||||
{
|
||||
side_actions::rrange_t acts = sa.riter_turn(turn);
|
||||
side_actions::reverse_iterator itor = acts.first;
|
||||
side_actions::reverse_iterator end = acts.second;
|
||||
while(itor!=end) {
|
||||
++itor;
|
||||
if(!new_this->visit(team_index,t,sa,itor.base()))
|
||||
return; //< Early abort
|
||||
}
|
||||
}
|
||||
else //forward
|
||||
{
|
||||
side_actions::range_t acts = sa.iter_turn(turn);
|
||||
side_actions::iterator itor = acts.first;
|
||||
side_actions::iterator end = acts.second;
|
||||
for(; itor!=end; ++itor)
|
||||
if(!new_this->visit(team_index,t,sa,itor))
|
||||
return; //< Early abort
|
||||
}
|
||||
if(!new_this->post_visit_team(team_index,t,sa))
|
||||
break; //< Early abort
|
||||
}
|
||||
else //forward
|
||||
{
|
||||
side_actions::iterator itor = sa.begin();
|
||||
side_actions::iterator end = sa.end();
|
||||
for(; itor!=end; ++itor)
|
||||
if(!new_this->visit(team_index,t,sa,itor))
|
||||
return; //< Early abort
|
||||
}
|
||||
if(!new_this->post_visit_team(team_index,t,sa))
|
||||
break; //< Early abort
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue