Author: sapient
Date: Tue Jul 29 05:25:14 2008
New Revision: 28255

URL: http://svn.gna.org/viewcvs/wesnoth?rev=28255&view=rev
Log:
-fix bug #12094: Event "last breath" cannot be triggered for attackers 
(untested)
-remove some extraneous code that could have caused an error with invalid 
iterator access

Modified:
    trunk/changelog
    trunk/src/actions.cpp

Modified: trunk/changelog
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/changelog?rev=28255&r1=28254&r2=28255&view=diff
==============================================================================
--- trunk/changelog (original)
+++ trunk/changelog Tue Jul 29 05:25:14 2008
@@ -34,6 +34,8 @@
      associate an id. to [time_area]s, or it won't work.
  * Miscellaneous and bug fixes:
    * Add some gcc-4.3.0 compilation fixes (patch #1083)
+   * Fixed bug #12094: Event "last breath" cannot be triggered for attackers
+
 
 
 Version 1.5.2:

Modified: trunk/src/actions.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/actions.cpp?rev=28255&r1=28254&r2=28255&view=diff
==============================================================================
--- trunk/src/actions.cpp (original)
+++ trunk/src/actions.cpp Tue Jul 29 05:25:14 2008
@@ -931,7 +931,7 @@
                attacker.fight(defender);
                const double attacker_inflict = 
static_cast<double>(d_->second.hitpoints()) - defender.average_hp();
                const double defender_inflict = 
static_cast<double>(a_->second.hitpoints()) - attacker.average_hp();
-       
+
                
attack_stats.attack_excepted_damage(attacker_inflict,defender_inflict);
        }
 
@@ -950,7 +950,7 @@
        static const std::string poison_string("poison");
 
        LOG_NG << "Fight: (" << attacker << ") vs (" << defender << ") ATT: " 
<< a_stats_->weapon->name() << " " << a_stats_->damage << "-" << 
a_stats_->num_blows << "(" << a_stats_->chance_to_hit << "%) vs DEF: " << 
(d_stats_->weapon ? d_stats_->weapon->name() : "none") << " " << 
d_stats_->damage << "-" << d_stats_->num_blows << "(" << 
d_stats_->chance_to_hit << "%)" << (defender_strikes_first ? " defender 
first-strike" : "") << "\n";
-       
+
        game_state* game_state = game_events::get_state_of_game();
 
        while(n_attacks_ > 0 || n_defends_ > 0) {
@@ -1032,9 +1032,9 @@
                                                
*a_stats_->weapon,d_stats_->weapon,
                                                
abs_n_attack_,float_text,a_stats_->drains,"");
                        }
-                       
+
                        // Used for stat calcualtion
-                       const int drains_damage = a_stats_->drains ? 
+                       const int drains_damage = a_stats_->drains ?
                                minimum<int>(damage_defender_takes / 
2,a_->second.max_hitpoints() - a_->second.hitpoints()) : 0;
                        const int damage_done = 
minimum<int>(d_->second.hitpoints(), attacker_damage_);
                        bool dies = d_->second.take_hit(damage_defender_takes);
@@ -1115,10 +1115,6 @@
                                }
                                bool attacker_invalid = false;
                                if(a_ == units_.end() || 
!attacker_loc.matches_unit(a_->second)) {
-                                       if(d_->second.hitpoints() <= 0) {
-                                               units_.erase(d_);
-                                               d_ = units_.end();
-                                       }
                                        // WML has invalidated the killing unit
                                        attacker_invalid = true;
                                }
@@ -1223,7 +1219,7 @@
                        int damage_attacker_takes;
                        if(hits) {
                                damage_attacker_takes = defender_damage_;
-                               
+
                                game_state->set_variable("damage_inflicted",
                                                         
str_cast<int>(damage_attacker_takes));
                        } else {
@@ -1297,9 +1293,6 @@
                        const int damage_done   = 
minimum<int>(a_->second.hitpoints(), defender_damage_);
                        bool dies = a_->second.take_hit(damage_attacker_takes);
                        LOG_NG << "attacker took " << damage_attacker_takes << 
(dies ? " and died" : "") << "\n";
-                       if(dies) {
-                               
unit_display::unit_die(attacker_,a_->second,a_stats_->weapon,d_stats_->weapon, 
&(d_->second));
-                       }
                        if(ran_results == NULL) {
                                config cfg;
                                cfg["hits"] = (hits ? "yes" : "no");
@@ -1361,6 +1354,28 @@
                                game_events::entity_location defender_loc(d_);
                                const int attacker_side = a_->second.side();
                                fire_event("attack_end");
+
+                               DELAY_END_LEVEL(delayed_exception, 
game_events::fire("last breath", death_loc, defender_loc));
+
+                               d_ = units_.find(defender_loc);
+                               a_ = units_.find(death_loc);
+                               if(a_ == units_.end() || 
!death_loc.matches_unit(a_->second)
+                                               || a_->second.hitpoints() > 0) {
+                                       // WML has invalidated the dying unit, 
abort
+                                       break;
+                               }
+                               bool defender_invalid = false;
+                               if(d_ == units_.end() || 
!defender_loc.matches_unit(d_->second)) {
+                                       // WML has invalidated the killing unit
+                                       defender_invalid = true;
+                               }
+                               refresh_bc();
+                               if(defender_invalid) {
+                                       unit_display::unit_die(attacker_, 
a_->second,a_stats_->weapon, NULL, NULL);
+                               } else {
+                                       unit_display::unit_die(attacker_, 
a_->second,a_stats_->weapon,d_stats_->weapon, &(d_->second));
+                               }
+
                                DELAY_END_LEVEL(delayed_exception, 
game_events::fire("die",death_loc,defender_loc));
 
                                // Don't try to call refresh_bc() here the 
attacker or defender might have


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to