Whiteboard: add a new "Execute all actions" command,
...bound to ctrl+y by default, and added to the actions (not context) menu. It executes actions in sequence until the first attack, or until an action fails to execute. Fulfills the feature request of bug #16807. Simplified some return type in the process in side_actions: returning iterators wasn't really useful for the execute functions.
This commit is contained in:
parent
8db7212c73
commit
ef81324150
10 changed files with 104 additions and 40 deletions
|
@ -265,6 +265,11 @@
|
|||
command=wbexecuteaction
|
||||
key=y
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=wbexecuteallactions
|
||||
key=y
|
||||
ctrl=yes
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=wbdeleteaction
|
||||
key=h
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
id=actions-menu
|
||||
title= _ "Actions"
|
||||
image=lite
|
||||
items=undo,redo,wbexecuteaction,wbdeleteaction,cycle,speak,recruit,recall,showenemymoves,bestenemymoves,wbtoggle,delayshroud,updateshroud,endturn
|
||||
items=undo,redo,wbexecuteallactions,wbexecuteaction,wbdeleteaction,cycle,speak,recruit,recall,showenemymoves,bestenemymoves,wbtoggle,delayshroud,updateshroud,endturn
|
||||
rect="+2,=,+100,="
|
||||
xanchor=fixed
|
||||
yanchor=fixed
|
||||
|
|
|
@ -105,6 +105,7 @@ const struct {
|
|||
// Whiteboard commands
|
||||
{ hotkey::HOTKEY_WB_TOGGLE, "wbtoggle", N_("Toggle planning mode"), false, hotkey::SCOPE_GAME },
|
||||
{ hotkey::HOTKEY_WB_EXECUTE_ACTION, "wbexecuteaction", N_("Execute planned action"), false, hotkey::SCOPE_GAME },
|
||||
{ hotkey::HOTKEY_WB_EXECUTE_ALL_ACTIONS, "wbexecuteallactions", N_("Execute all actions"), false, hotkey::SCOPE_GAME },
|
||||
{ hotkey::HOTKEY_WB_DELETE_ACTION, "wbdeleteaction", N_("Delete planned action"), false, hotkey::SCOPE_GAME },
|
||||
{ hotkey::HOTKEY_WB_BUMP_UP_ACTION, "wbbumpupaction", N_("Move action up queue"), false, hotkey::SCOPE_GAME },
|
||||
{ hotkey::HOTKEY_WB_BUMP_DOWN_ACTION, "wbbumpdownaction", N_("Move action down queue"), false, hotkey::SCOPE_GAME },
|
||||
|
@ -923,6 +924,9 @@ bool command_executor::execute_command(HOTKEY_COMMAND command, int /*index*/)
|
|||
case HOTKEY_WB_EXECUTE_ACTION:
|
||||
whiteboard_execute_action();
|
||||
break;
|
||||
case HOTKEY_WB_EXECUTE_ALL_ACTIONS:
|
||||
whiteboard_execute_all_actions();
|
||||
break;
|
||||
case HOTKEY_WB_DELETE_ACTION:
|
||||
whiteboard_delete_action();
|
||||
break;
|
||||
|
|
|
@ -65,6 +65,7 @@ enum HOTKEY_COMMAND {
|
|||
// Whiteboard commands
|
||||
HOTKEY_WB_TOGGLE,
|
||||
HOTKEY_WB_EXECUTE_ACTION,
|
||||
HOTKEY_WB_EXECUTE_ALL_ACTIONS,
|
||||
HOTKEY_WB_DELETE_ACTION,
|
||||
HOTKEY_WB_BUMP_UP_ACTION,
|
||||
HOTKEY_WB_BUMP_DOWN_ACTION,
|
||||
|
@ -311,6 +312,7 @@ public:
|
|||
virtual void replay_skip_animation() {}
|
||||
virtual void whiteboard_toggle() {}
|
||||
virtual void whiteboard_execute_action() {}
|
||||
virtual void whiteboard_execute_all_actions() {}
|
||||
virtual void whiteboard_delete_action() {}
|
||||
virtual void whiteboard_bump_up_action() {}
|
||||
virtual void whiteboard_bump_down_action() {}
|
||||
|
|
|
@ -225,6 +225,10 @@ void playsingle_controller::whiteboard_execute_action(){
|
|||
whiteboard_manager_->contextual_execute();
|
||||
}
|
||||
|
||||
void playsingle_controller::whiteboard_execute_all_actions(){
|
||||
whiteboard_manager_->execute_all_actions();
|
||||
}
|
||||
|
||||
void playsingle_controller::whiteboard_delete_action(){
|
||||
whiteboard_manager_->contextual_delete();
|
||||
}
|
||||
|
@ -1020,6 +1024,7 @@ bool playsingle_controller::can_execute_command(hotkey::HOTKEY_COMMAND command,
|
|||
case hotkey::HOTKEY_WB_TOGGLE:
|
||||
return true;
|
||||
case hotkey::HOTKEY_WB_EXECUTE_ACTION:
|
||||
case hotkey::HOTKEY_WB_EXECUTE_ALL_ACTIONS:
|
||||
case hotkey::HOTKEY_WB_DELETE_ACTION:
|
||||
return resources::whiteboard->can_execute_hotkey();
|
||||
case hotkey::HOTKEY_WB_BUMP_UP_ACTION:
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
// Whiteboard hotkeys
|
||||
virtual void whiteboard_toggle();
|
||||
virtual void whiteboard_execute_action();
|
||||
virtual void whiteboard_execute_all_actions();
|
||||
virtual void whiteboard_delete_action();
|
||||
virtual void whiteboard_bump_up_action();
|
||||
virtual void whiteboard_bump_down_action();
|
||||
|
|
|
@ -90,6 +90,11 @@ void manager::print_help_once()
|
|||
//print_to_chat("[execute action]", "'" + hk_execute.get_name() + "'");
|
||||
hotkeys << "Execute: " << hk_execute.get_name() << ", ";
|
||||
}
|
||||
const hotkey::hotkey_item& hk_execute_all = hotkey::get_hotkey(hotkey::HOTKEY_WB_EXECUTE_ALL_ACTIONS);
|
||||
if(!hk_execute_all.null()) {
|
||||
//print_to_chat("[execute action]", "'" + hk_execute_all.get_name() + "'");
|
||||
hotkeys << "Execute all: " << hk_execute_all.get_name() << ", ";
|
||||
}
|
||||
const hotkey::hotkey_item& hk_delete = hotkey::get_hotkey(hotkey::HOTKEY_WB_DELETE_ACTION);
|
||||
if(!hk_delete.null()) {
|
||||
//print_to_chat("[delete action]", "'" + hk_delete.get_name() + "'");
|
||||
|
@ -598,6 +603,19 @@ void manager::contextual_execute()
|
|||
}
|
||||
}
|
||||
|
||||
void manager::execute_all_actions()
|
||||
{
|
||||
if (!(executing_actions_ || viewer_actions()->empty() || resources::controller->is_linger_mode())
|
||||
&& resources::controller->current_side() == resources::screen->viewing_side())
|
||||
{
|
||||
erase_temp_move();
|
||||
validate_viewer_actions();
|
||||
executing_actions_ = true;
|
||||
viewer_actions()->execute_all();
|
||||
executing_actions_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void manager::contextual_delete()
|
||||
{
|
||||
if (!(executing_actions_ || viewer_actions()->empty() || resources::controller->is_linger_mode()))
|
||||
|
|
|
@ -123,6 +123,8 @@ public:
|
|||
|
||||
/** Executes first action in the queue for current side */
|
||||
void contextual_execute();
|
||||
/** Executes all actions in the queue in sequence */
|
||||
void execute_all_actions();
|
||||
/** Deletes last action in the queue for current side */
|
||||
void contextual_delete();
|
||||
/** Moves the action determined by the UI toward the beginning of the queue */
|
||||
|
|
|
@ -139,7 +139,7 @@ void side_actions::draw_hex(const map_location& hex)
|
|||
}
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::execute_next()
|
||||
bool side_actions::execute_next()
|
||||
{
|
||||
if (!actions_.empty())
|
||||
{
|
||||
|
@ -147,51 +147,75 @@ side_actions::iterator side_actions::execute_next()
|
|||
}
|
||||
else
|
||||
{
|
||||
return end();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::execute(side_actions::iterator position)
|
||||
void side_actions::execute_all()
|
||||
{
|
||||
if (actions_.empty())
|
||||
{
|
||||
WRN_WB << "\"Execute All\" attempt with empty queue.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (resources::whiteboard->has_planned_unit_map())
|
||||
{
|
||||
ERR_WB << "Modifying action queue while temp modifiers are applied!!!\n";
|
||||
}
|
||||
|
||||
LOG_WB << "Before executing all actions, " << *this << "\n";
|
||||
|
||||
bool keep_executing = true;
|
||||
while (keep_executing)
|
||||
{
|
||||
iterator position = begin();
|
||||
|
||||
bool is_attack = boost::dynamic_pointer_cast<attack>(*position);
|
||||
bool finished = execute(position);
|
||||
|
||||
keep_executing = finished && !is_attack && !empty();
|
||||
}
|
||||
}
|
||||
|
||||
bool side_actions::execute(side_actions::iterator position)
|
||||
{
|
||||
if (resources::whiteboard->has_planned_unit_map())
|
||||
{
|
||||
ERR_WB << "Modifying action queue while temp modifiers are applied!!!\n";
|
||||
}
|
||||
|
||||
if (!actions_.empty() && validate_iterator(position))
|
||||
{
|
||||
LOG_WB << "Before execution, " << *this << "\n";
|
||||
size_t distance = std::distance(begin(), position);
|
||||
action_ptr action = *position;
|
||||
bool finished;
|
||||
try {
|
||||
finished = action->execute();
|
||||
} catch (end_turn_exception e) {
|
||||
actions_.erase(position);
|
||||
LOG_WB << "End turn exception caught during execution, deleting action. " << *this << "\n";
|
||||
validate_actions();
|
||||
throw;
|
||||
}
|
||||
if (actions_.empty() || !validate_iterator(position))
|
||||
return false;
|
||||
|
||||
if (finished)
|
||||
{
|
||||
actions_.erase(position);
|
||||
LOG_WB << "After execution and deletion, " << *this << "\n";
|
||||
validate_actions();
|
||||
return begin() + distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
actions_.erase(position);
|
||||
actions_.insert(end(), action);
|
||||
LOG_WB << "After execution *without* deletion, " << *this << "\n";
|
||||
validate_actions();
|
||||
return end() - 1;
|
||||
}
|
||||
LOG_WB << "Before execution, " << *this << "\n";
|
||||
action_ptr action = *position;
|
||||
bool finished;
|
||||
try {
|
||||
finished = action->execute();
|
||||
} catch (end_turn_exception e) {
|
||||
actions_.erase(position);
|
||||
LOG_WB << "End turn exception caught during execution, deleting action. " << *this << "\n";
|
||||
validate_actions();
|
||||
throw;
|
||||
}
|
||||
|
||||
if (finished)
|
||||
{
|
||||
actions_.erase(position);
|
||||
LOG_WB << "After execution and deletion, " << *this << "\n";
|
||||
validate_actions();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return end();
|
||||
//Idea that needs refining: move action at the end of the queue if it failed executing:
|
||||
//actions_.erase(position);
|
||||
//actions_.insert(end(), action);
|
||||
|
||||
LOG_WB << "After execution *without* deletion, " << *this << "\n";
|
||||
validate_actions();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,18 +64,21 @@ public:
|
|||
|
||||
/**
|
||||
* Executes the first action in the queue, and then deletes it.
|
||||
* @return An iterator to the action itself if not finished, or else to the new first in line.
|
||||
* Returns end() if no actions remain.
|
||||
* @return true - if the action was completed successfully
|
||||
*/
|
||||
iterator execute_next();
|
||||
bool execute_next();
|
||||
|
||||
/**
|
||||
* Execute all actions in sequence until the fist attack, or until an action fails to execute.
|
||||
*/
|
||||
void execute_all();
|
||||
|
||||
/**
|
||||
* Executes the specified action, if it exists in the queue.
|
||||
* If the action is not finished, it's moved at the end of the queue.
|
||||
* @return An iterator to the action itself if not finished, or else the next action in the queue.
|
||||
* Returns end() if no actions remain.
|
||||
* @return true - if the action was completed successfully
|
||||
*/
|
||||
iterator execute(iterator position);
|
||||
bool execute(iterator position);
|
||||
|
||||
/**
|
||||
* Returns the iterator for the first (executed earlier) action within the actions queue.
|
||||
|
|
Loading…
Add table
Reference in a new issue