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

Reply via email to