Author: tschmitz
Date: Sat Jul 9 09:56:08 2011
New Revision: 50247
URL: http://svn.gna.org/viewcvs/wesnoth?rev=50247&view=rev
Log:
Changed behavior of whiteboard action validation.
Instead of validating actions from separate teams separately, each team's
actions are applied in turn order, starting with the player who is currently
taking his or her turn.
Modified:
trunk/src/whiteboard/manager.cpp
trunk/src/whiteboard/mapbuilder_visitor.cpp
trunk/src/whiteboard/mapbuilder_visitor.hpp
trunk/src/whiteboard/side_actions.cpp
trunk/src/whiteboard/validate_visitor.cpp
trunk/src/whiteboard/validate_visitor.hpp
Modified: trunk/src/whiteboard/manager.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/manager.cpp?rev=50247&r1=50246&r2=50247&view=diff
==============================================================================
--- trunk/src/whiteboard/manager.cpp (original)
+++ trunk/src/whiteboard/manager.cpp Sat Jul 9 09:56:08 2011
@@ -264,17 +264,14 @@
{
if (!planned_unit_map_active_)
{
- if (!viewer_actions()->empty())
- {
- validate_actions_if_needed();
- std::string message;
- for_pathfinding ? message = "Building planned
unit map for pathfinding."
- : message = "Building planned
unit map";
- log_scope2("whiteboard", message);
- is_map_for_pathfinding_ = for_pathfinding;
- mapbuilder_.reset(new
mapbuilder_visitor(*resources::units, viewer_actions(), for_pathfinding));
- mapbuilder_->build_map();
- }
+ validate_actions_if_needed();
+ std::string message;
+ for_pathfinding ? message = "Building planned unit map
for pathfinding."
+ : message = "Building planned unit map";
+ log_scope2("whiteboard", message);
+ is_map_for_pathfinding_ = for_pathfinding;
+ mapbuilder_.reset(new
mapbuilder_visitor(*resources::units, viewer_actions(), for_pathfinding));
+ mapbuilder_->build_map();
planned_unit_map_active_ = true;
}
else
Modified: trunk/src/whiteboard/mapbuilder_visitor.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/mapbuilder_visitor.cpp?rev=50247&r1=50246&r2=50247&view=diff
==============================================================================
--- trunk/src/whiteboard/mapbuilder_visitor.cpp (original)
+++ trunk/src/whiteboard/mapbuilder_visitor.cpp Sat Jul 9 09:56:08 2011
@@ -25,8 +25,11 @@
#include "recruit.hpp"
#include "side_actions.hpp"
#include "suppose_dead.hpp"
+#include "utility.hpp"
#include "foreach.hpp"
+#include "play_controller.hpp"
+#include "resources.hpp"
#include "unit.hpp"
#include "unit_map.hpp"
@@ -45,17 +48,48 @@
mapbuilder_visitor::~mapbuilder_visitor()
{
restore_normal_map();
+ //Remember that the member variable resetters_ is destructed here
+}
+
+void mapbuilder_visitor::reset_moves()
+{
+ int current_side = resources::controller->current_side();
+ foreach(unit& u, *resources::units)
+ {
+ if(u.side() != current_side)
+ {
+ boost::shared_ptr<unit_movement_resetter> temp(new
unit_movement_resetter(u));
+ resetters_.push_back(temp);
+ }
+ }
}
void mapbuilder_visitor::build_map()
{
mode_ = BUILD_PLANNED_MAP;
- foreach(action_ptr action, *side_actions_)
+
+ size_t current_team = resources::controller->current_side() - 1;
+
+ //Temporarily reset all units' moves to full EXCEPT for the ones on
current_team.
+ reset_moves();
+
+ //Apply modifiers from every team's action_queue, ...
+ size_t viewing_team = viewer_team();
+ size_t num_teams = resources::teams->size();
+ for(size_t iteration = 0; iteration < num_teams; ++iteration)
{
- if (action->is_valid())
+ //... beginning with the current_team, ...
+ size_t team_index = (current_team+iteration) % num_teams;
+
+ foreach(action_ptr act,
*resources::teams->at(team_index).get_side_actions())
{
- action->accept(*this);
+ if(act->is_valid())
+ act->accept(*this);
}
+
+ //... and ending with the viewer_team.
+ if(team_index == viewing_team)
+ break;
}
}
Modified: trunk/src/whiteboard/mapbuilder_visitor.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/mapbuilder_visitor.hpp?rev=50247&r1=50246&r2=50247&view=diff
==============================================================================
--- trunk/src/whiteboard/mapbuilder_visitor.hpp (original)
+++ trunk/src/whiteboard/mapbuilder_visitor.hpp Sat Jul 9 09:56:08 2011
@@ -24,6 +24,8 @@
#include "action.hpp"
+struct unit_movement_resetter;
+
namespace wb
{
@@ -39,8 +41,9 @@
virtual ~mapbuilder_visitor();
/**
- * Visits all the actions contained in the side_actions object passed
to the constructor,
- * and calls the appropriate visit_* method on each of them.
+ * Calls the appropriate visit_* method on each of the actions
contained in the
+ * side_actions objects of every team whose turn comes earlier in the
turn order,
+ * including (and stopping at) the viewer's team.
*/
virtual void build_map();
@@ -52,6 +55,10 @@
virtual void visit_suppose_dead(suppose_dead_ptr sup_d);
protected:
+
+ //Helper fcn: Temporarily resets all units' moves to max EXCEPT for
+ //the ones controlled by the player whose turn it is currently.
+ void reset_moves();
virtual void restore_normal_map();
@@ -67,6 +74,9 @@
};
mapbuilder_mode mode_;
+
+ //Used by reset_moves()
+ std::vector<boost::shared_ptr<unit_movement_resetter> > resetters_;
};
}
Modified: trunk/src/whiteboard/side_actions.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/side_actions.cpp?rev=50247&r1=50246&r2=50247&view=diff
==============================================================================
--- trunk/src/whiteboard/side_actions.cpp (original)
+++ trunk/src/whiteboard/side_actions.cpp Sat Jul 9 09:56:08 2011
@@ -278,11 +278,9 @@
side_actions::iterator side_actions::queue_action(action_ptr action)
{
- resources::whiteboard->queue_net_cmd(make_net_cmd_insert(end(),action));
- actions_.push_back(action);
- // Contrary to insert_action, no need to validate actions here since
we're adding to the end of the queue
- LOG_WB << "Queued: " << action <<"\n";
- return end() - 1;
+ //This method can no longer be any more efficient than the above
insert_action(), because
+ //inserting at the end of this queue may invalidate something in a
different queue.
+ return insert_action(begin(),action);
}
//move action toward front of queue
@@ -592,15 +590,13 @@
ERR_WB << "Validating action queue while temp modifiers are
applied!!!\n";
}
- if (empty()) return;
-
bool validation_finished = false;
int passes = 1;
while(!validation_finished){
log_scope2("whiteboard", "Validating actions for side "
+ lexical_cast<std::string>(team_index() + 1) +
", pass "
+ lexical_cast<std::string>(passes));
- validate_visitor validator(*resources::units,
shared_from_this());
+ validate_visitor validator(*resources::units);
validation_finished = validator.validate_actions();
++passes;
}
@@ -695,7 +691,10 @@
else
{
ERR_WB << "side_actions::execute_network_command(): received
invalid type!\n";
- }
+ return;
+ }
+
+ validate_actions();
}
side_actions::net_cmd side_actions::make_net_cmd_insert(const_iterator const&
pos, action_ptr act) const
Modified: trunk/src/whiteboard/validate_visitor.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/validate_visitor.cpp?rev=50247&r1=50246&r2=50247&view=diff
==============================================================================
--- trunk/src/whiteboard/validate_visitor.cpp (original)
+++ trunk/src/whiteboard/validate_visitor.cpp Sat Jul 9 09:56:08 2011
@@ -25,6 +25,7 @@
#include "recruit.hpp"
#include "side_actions.hpp"
#include "suppose_dead.hpp"
+#include "utility.hpp"
#include "arrow.hpp"
#include "foreach.hpp"
@@ -36,8 +37,8 @@
namespace wb
{
-validate_visitor::validate_visitor(unit_map& unit_map, side_actions_ptr
side_actions)
- : mapbuilder_visitor(unit_map, side_actions, true)
+validate_visitor::validate_visitor(unit_map& unit_map)
+ : mapbuilder_visitor(unit_map, viewer_actions(), true)
, actions_to_erase_()
{
assert(!resources::whiteboard->has_planned_unit_map());
@@ -45,17 +46,26 @@
validate_visitor::~validate_visitor()
{
+ //~mapbuilder_visitor() gets called here automatically
}
bool validate_visitor::validate_actions()
{
- int action_number = 1;
- ///@todo We can optimize this by making the side_actions::iterator
available to accept()
- foreach(action_ptr action, *side_actions_)
- {
- DBG_WB << "Action #" << action_number << "\n";
- action->accept(*this);
- ++action_number;
+ //Temporarily reset all units' moves to full EXCEPT for the ones on
viewer_side().
+ reset_moves(); //< protected fcn inherited from mapbuilder_visitor
+
+ //Apply modifiers from every team's action_queue, beginning with the
current_team.
+ size_t current_team = resources::controller->current_side() - 1;
+ size_t num_teams = resources::teams->size();
+ for(size_t iteration = 0; iteration < num_teams; ++iteration)
+ {
+ size_t team_index = (current_team+iteration) % num_teams;
+
+ side_actions& actions =
*resources::teams->at(team_index).get_side_actions();
+ side_actions::iterator itor = actions.begin();
+ side_actions::iterator end = actions.end();
+ for(; itor!=end; ++itor)
+ (*itor)->accept(*this);
}
//FIXME: by reverse iterating this can be done in a more efficiant way
@@ -120,17 +130,20 @@
if(new_route.steps.empty() || new_route.move_cost >=
pathfind::cost_calculator::getNoPathValue())
return OBSTRUCTED; //no path exists
- if(new_route.steps!=m.get_route().steps || new_route.move_cost
!= m.get_route().move_cost)
- {
- //new valid path differs from the previous one, replace
- m.set_route(new_route);
- m.calculate_move_cost();
-
- //send updated path to allies
-
resources::whiteboard->queue_net_cmd(side_actions_->make_net_cmd_replace(side_actions_->get_position_of(m_ptr),m_ptr));
-
- //@todo: Since this might lengthen the path, we
probably need a special conflict state
- // to warn the player that the initial path is no
longer possible.
+ if(m.team_index() == viewer_team()) //< Don't mess with any
other team's queue -- only our own
+ {
+ if(new_route.steps != m.get_route().steps ||
new_route.move_cost != m.get_route().move_cost)
+ {
+ //new valid path differs from the previous one,
replace
+ m.set_route(new_route);
+ m.calculate_move_cost();
+
+ //send updated path to allies
+
resources::whiteboard->queue_net_cmd(side_actions_->make_net_cmd_replace(side_actions_->get_position_of(m_ptr),m_ptr));
+
+ //@todo: Since this might lengthen the path, we
probably need a special conflict state
+ // to warn the player that the initial path is
no longer possible.
+ }
}
//Check that the unit still has enough movement to do this move
@@ -177,7 +190,8 @@
case WORTHLESS:
// Erase only if no previous invalid actions are planned for
this unit -- otherwise, just mark it invalid.
// Otherwise, we wouldn't be able to keep invalid actions that
depend on previous invalid actions.
- if(no_previous_invalids(move)) //< private helper fcn
+ if(viewer_team() == move->team_index() //< Don't mess with any
other team's queue -- only our own
+ && no_previous_invalids(move)) //< private
helper fcn
{
LOG_WB << "Worthless invalid move detected, adding to
actions_to_erase_.\n";
actions_to_erase_.insert(move);
@@ -200,8 +214,11 @@
if (!attack->target_hex_.valid()
|| resources::units->find(attack->target_hex_) ==
resources::units->end())
{
- LOG_WB << "Worthless invalid attack detected, adding to
actions_to_erase_.\n";
- actions_to_erase_.insert(attack);
+ if(viewer_team() == attack->team_index()) //< Don't mess with
any other team's queue -- only our own
+ {
+ LOG_WB << "Worthless invalid attack detected, adding to
actions_to_erase_.\n";
+ actions_to_erase_.insert(attack);
+ }
}
else //All checks pass, so call the visitor on the superclass
{
@@ -251,8 +268,11 @@
}
else
{
- LOG_WB << "Invalid recruit detected, adding to
actions_to_erase_.\n";
- actions_to_erase_.insert(recruit);
+ if(viewer_team() == recruit->team_index()) //< Don't mess with
any other team's queue -- only our own
+ {
+ LOG_WB << "Invalid recruit detected, adding to
actions_to_erase_.\n";
+ actions_to_erase_.insert(recruit);
+ }
}
}
@@ -295,8 +315,11 @@
}
else
{
- LOG_WB << "Invalid recall detected, adding to
actions_to_erase_.\n";
- actions_to_erase_.insert(recall);
+ if(viewer_team() == recall->team_index()) //< Don't mess with
any other team's queue -- only our own
+ {
+ LOG_WB << "Invalid recall detected, adding to
actions_to_erase_.\n";
+ actions_to_erase_.insert(recall);
+ }
}
}
@@ -339,8 +362,11 @@
else
//FIXME: temporary until invalid arrow styles are in: delete
invalid moves
{
- LOG_WB << "Invalid suppose_dead detected, adding to
actions_to_erase_.\n";
- actions_to_erase_.insert(sup_d);
+ if(viewer_team() == sup_d->team_index()) //< Don't mess with
any other team's queue -- only our own
+ {
+ LOG_WB << "Invalid suppose_dead detected, adding to
actions_to_erase_.\n";
+ actions_to_erase_.insert(sup_d);
+ }
}
}
Modified: trunk/src/whiteboard/validate_visitor.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/validate_visitor.hpp?rev=50247&r1=50246&r2=50247&view=diff
==============================================================================
--- trunk/src/whiteboard/validate_visitor.hpp (original)
+++ trunk/src/whiteboard/validate_visitor.hpp Sat Jul 9 09:56:08 2011
@@ -28,13 +28,15 @@
{
/**
- * Visits all the actions in the given side_actions, building a future unit
map as it goes,
- * and checking the validity of each action.
+ * Works like mapbuilder_visitor, but with these differences:
+ * * Instead of stopping at viewer_team, it visits all actions of every team.
+ * * actions are evaluated for validity along the way.
+ * * Some invalid actions are deleted.
*/
class validate_visitor: public mapbuilder_visitor
{
public:
- validate_visitor(unit_map& unit_map, side_actions_ptr side_actions);
+ explicit validate_visitor(unit_map& unit_map);
virtual ~validate_visitor();
/// @return false some actions had to be deleted during validation,
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits