Author: gabba
Date: Thu Apr 5 13:04:20 2012
New Revision: 53780
URL: http://svn.gna.org/viewcvs/wesnoth?rev=53780&view=rev
Log:
Consolidated and improved the validation code for attack and move. Fixes bug
#19613.
Modified:
trunk/src/whiteboard/attack.cpp
trunk/src/whiteboard/manager.cpp
trunk/src/whiteboard/move.cpp
trunk/src/whiteboard/side_actions.cpp
trunk/src/whiteboard/validate_visitor.cpp
Modified: trunk/src/whiteboard/attack.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/attack.cpp?rev=53780&r1=53779&r2=53780&view=diff
==============================================================================
--- trunk/src/whiteboard/attack.cpp (original)
+++ trunk/src/whiteboard/attack.cpp Thu Apr 5 13:04:20 2012
@@ -110,7 +110,9 @@
void attack::execute(bool& success, bool& complete)
{
if (!valid_) {
- complete = false;
+ success = false;
+ //Setting complete to true signifies to side_actions to delete
the planned action: nothing more to do with it.
+ complete = true;
return;
}
@@ -122,7 +124,8 @@
move::execute(m_success,m_complete);
if(!m_success) {
//Move failed for some reason, so don't attack.
- complete = false;
+ success = false;
+ complete = true;
return;
}
}
Modified: trunk/src/whiteboard/manager.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/manager.cpp?rev=53780&r1=53779&r2=53780&view=diff
==============================================================================
--- trunk/src/whiteboard/manager.cpp (original)
+++ trunk/src/whiteboard/manager.cpp Thu Apr 5 13:04:20 2012
@@ -950,9 +950,9 @@
while (sa->turn_begin(0) != sa->turn_end(0))
{
- bool action_completed;
+ bool action_successful;
try {
- action_completed = sa->execute(sa->begin());
+ action_successful = sa->execute(sa->begin());
} catch (end_level_exception&) { //satisfy the gods of WML
executing_all_actions_ = false;
throw;
@@ -968,7 +968,7 @@
return false;
}
// Interrupt on incomplete action
- if (!action_completed)
+ if (!action_successful)
{
executing_all_actions_ = false;
return false;
Modified: trunk/src/whiteboard/move.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/move.cpp?rev=53780&r1=53779&r2=53780&view=diff
==============================================================================
--- trunk/src/whiteboard/move.cpp (original)
+++ trunk/src/whiteboard/move.cpp Thu Apr 5 13:04:20 2012
@@ -194,19 +194,15 @@
void move::execute(bool& success, bool& complete)
{
if (!valid_) {
- success = complete = false;
+ success = false;
+ //Setting complete to true signifies to side_actions to delete
the planned action.
+ complete = true;
return;
}
if (get_source_hex() == get_dest_hex()) {
//zero-hex move, used by attack subclass
success = complete = true;
- return;
- }
-
- //Ensure destination hex is free
- if
(get_visible_unit(get_dest_hex(),resources::teams->at(viewer_team())) != NULL) {
- success = complete = false;
return;
}
@@ -242,7 +238,8 @@
if (final_location == route_->steps.front())
{
LOG_WB << "Move execution resulted in zero movement.\n";
- success = complete = false;
+ success = false;
+ complete = true;
}
else if (final_location.valid() &&
(unit_it = resources::units->find(final_location)) !=
resources::units->end()
@@ -266,6 +263,8 @@
}
else // Move was interrupted, probably by enemy unit sighted
{
+ success = false;
+
LOG_WB << "Move finished at (" << final_location << ")
instead of at (" << get_dest_hex() << "), analyzing\n";
std::vector<map_location>::iterator start_new_path;
bool found = false;
@@ -285,19 +284,20 @@
//FIXME: probably better to use the new
calculate_new_route instead of doing this
route_->steps = new_path;
arrow_->set_path(new_path);
- success = complete = false;
+ complete = false;
}
else //Unit ended up in location outside path, likely
due to a WML event
{
WRN_WB << "Unit ended up in location outside
path during move execution.\n";
- success = complete = true;
+ complete = true;
}
}
}
else //Unit disappeared from the map, likely due to a WML event
{
WRN_WB << "Unit disappeared from map during move execution.\n";
- success = complete = true;
+ success = false;
+ complete = true;
}
if(!complete)
Modified: trunk/src/whiteboard/side_actions.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/side_actions.cpp?rev=53780&r1=53779&r2=53780&view=diff
==============================================================================
--- trunk/src/whiteboard/side_actions.cpp (original)
+++ trunk/src/whiteboard/side_actions.cpp Thu Apr 5 13:04:20 2012
@@ -158,9 +158,10 @@
}
bool action_successful;
- bool should_erase;
+ // Determines whether action should be deleted. Interrupted moves
return action_complete == false.
+ bool action_complete;
try {
- action->execute(action_successful,should_erase);
+ action->execute(action_successful,action_complete);
} catch (end_turn_exception&) {
synced_erase(position);
LOG_WB << "End turn exception caught during execution, deleting
action. " << *this << "\n";
@@ -174,7 +175,7 @@
std::stringstream ss;
ss << "After " << (action_successful? "successful": "failed") << "
execution ";
- if(should_erase)
+ if(action_complete)
{
ss << "with deletion, ";
synced_erase(position);
Modified: trunk/src/whiteboard/validate_visitor.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/validate_visitor.cpp?rev=53780&r1=53779&r2=53780&view=diff
==============================================================================
--- trunk/src/whiteboard/validate_visitor.cpp (original)
+++ trunk/src/whiteboard/validate_visitor.cpp Thu Apr 5 13:04:20 2012
@@ -92,6 +92,11 @@
//i.e. that it's the same unit
if (m.unit_id_ != unit_it->id() || m.unit_underlying_id_ !=
unit_it->underlying_id())
return WORTHLESS;
+
+ //If the path has at least two hexes (it can have less with the attack
subclass), ensure destination hex is free
+ if (m.get_route().steps.size() >= 2 &&
get_visible_unit(m.get_dest_hex(),resources::teams->at(viewer_team())) != NULL)
{
+ return WORTHLESS;
+ }
//check that the path is good
if (m.get_source_hex() != m.get_dest_hex()) //skip zero-hex move used
by attack subclass
@@ -160,25 +165,34 @@
resources::screen->invalidate(attack->get_dest_hex());
resources::screen->invalidate(attack->target_hex_);
- //Verify that the target hex is still valid
- //and Verify that the target hex isn't empty
- if (!attack->target_hex_.valid()
- || resources::units->find(attack->target_hex_) ==
resources::units->end())
- {
- if(viewer_team() == attack->team_index()) //< Don't mess with
any other team's queue -- only our own
+ if (
+ // Verify that the unit that planned this attack exists
+ attack->get_unit()
+ // Verify that the target hex is still valid
+ && attack->target_hex_.valid()
+ // Verify that the target hex isn't empty
+ && resources::units->find(attack->target_hex_) !=
resources::units->end()
+ // Verify that the attacking unit has attacks left
+ && attack->get_unit()->attacks_left() > 0
+ // Verify that the attacker and target are enemies
+ && (*resources::teams)[attack->get_unit()->side() -
1].is_enemy(resources::units->find(attack->target_hex_)->side())
+
+ //@todo: (maybe) verify that the target hex contains
the same unit that before,
+ // comparing for example the unit ID
+ )
+ {
+ //All checks pass, so call the visitor on the superclass
+ visit(boost::static_pointer_cast<move>(attack));
+ }
+ else
+ {
+ attack->set_valid(false);
+
+ 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
- {
- //@todo: verify that the target hex contains the same unit that
before,
- // comparing for example the unit ID
-
- //@todo: Verify that the target unit is our enemy
-
- visit(boost::static_pointer_cast<move>(attack));
}
}
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits