TiborB has proposed merging lp:~widelands-dev/widelands/bug-1554552 into lp:widelands.
Requested reviews: Widelands Developers (widelands-dev) Related bugs: Bug #1554552 in widelands: "wounded attacking soldiers failing to retreat" https://bugs.launchpad.net/widelands/+bug/1554552 For more details, see: https://code.launchpad.net/~widelands-dev/widelands/bug-1554552/+merge/289830 I got rid of ui32var3 task's variable, that misbehaved and replaced it with retreat_health_ variable (soldier's atribute) When you will test it, you can keep soldier's DBG window opened and watch what is going on (also with retreat_health_) -- Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-1554552 into lp:widelands.
=== modified file 'src/logic/map_objects/bob.h' --- src/logic/map_objects/bob.h 2016-02-07 09:30:20 +0000 +++ src/logic/map_objects/bob.h 2016-03-22 19:48:28 +0000 @@ -213,7 +213,7 @@ const Task * task; int32_t ivar1; int32_t ivar2; - union {int32_t ivar3; uint32_t ui32var3;}; + int32_t ivar3; ObjectPointer objvar1; std::string svar1; === modified file 'src/logic/map_objects/tribes/soldier.cc' --- src/logic/map_objects/tribes/soldier.cc 2016-03-08 08:22:28 +0000 +++ src/logic/map_objects/tribes/soldier.cc 2016-03-22 19:48:28 +0000 @@ -223,6 +223,7 @@ attack_level_ = 0; defense_level_ = 0; evade_level_ = 0; + retreat_health_ = 0; current_health_ = get_max_health(); @@ -238,6 +239,7 @@ attack_level_ = 0; defense_level_ = 0; evade_level_ = 0; + retreat_health_ = 0; current_health_ = get_max_health(); @@ -301,6 +303,11 @@ evade_level_ = evade; } +void Soldier::set_retreat_health(const uint32_t retreat) { + assert(retreat <= get_max_health()); + + retreat_health_ = retreat; +} uint32_t Soldier::get_level(TrainingAttribute const at) const { switch (at) { @@ -696,12 +703,13 @@ state.ivar3 = 0; // Counts how often the soldier is blocked in a row state.ivar1 |= CF_RETREAT_WHEN_INJURED; - state.ui32var3 = kRetreatWhenHealthDropsBelowThisPercentage * get_max_health() / 100; + set_retreat_health(kRetreatWhenHealthDropsBelowThisPercentage * get_max_health() / 100); // Injured soldiers are not allowed to attack - if (state.ui32var3 > get_current_health()) { - state.ui32var3 = get_current_health(); + if (get_retreat_health() > get_current_health()) { + set_retreat_health(get_current_health()); } + molog("[attack] starting, retreat health: %d\n", get_retreat_health()); } void Soldier::attack_update(Game & game, State & state) @@ -883,12 +891,16 @@ if (!enemy || - ((state.ivar1 & CF_RETREAT_WHEN_INJURED) && - state.ui32var3 > get_current_health() && + (get_retreat_health() > get_current_health() && defenders > 0)) { + if (get_retreat_health() > get_current_health()) { + assert(state.ivar1 & CF_RETREAT_WHEN_INJURED); + } + // Injured soldiers will try to return to safe site at home. - if (state.ui32var3 > get_current_health() && defenders) { + if (get_retreat_health() > get_current_health() && defenders) { + molog(" [attack] badly injured (%d), retreating...\n", get_current_health()); state.coords = Coords::null(); state.objvar1 = nullptr; } @@ -1016,15 +1028,19 @@ // Here goes 'configuration' if (stayhome) { state.ivar1 |= CF_DEFEND_STAYHOME; + set_retreat_health(0); } else { /* Flag defenders are not allowed to flee, to avoid abuses */ state.ivar1 |= CF_RETREAT_WHEN_INJURED; - state.ui32var3 = get_max_health() * kRetreatWhenHealthDropsBelowThisPercentage / 100; + set_retreat_health(get_max_health() * kRetreatWhenHealthDropsBelowThisPercentage / 100); // Soldier must defend even if he starts injured - if (state.ui32var3 < get_current_health()) - state.ui32var3 = get_current_health(); + // (current health is below retreat treshold) + if (get_retreat_health() > get_current_health()) { + set_retreat_health(get_current_health()); + } } + molog("[defense] retreat health set: %d\n", get_retreat_health()); } struct SoldierDistance { @@ -1128,13 +1144,15 @@ if (soldiers.empty() || - ((state.ivar1 & CF_RETREAT_WHEN_INJURED) && - get_current_health() < state.ui32var3)) + (get_current_health() < get_retreat_health())) { + if (get_retreat_health() > get_current_health()) { + assert(state.ivar1 & CF_RETREAT_WHEN_INJURED); + } - if (get_current_health() < state.ui32var3) - molog("[defense] I am heavily injured!\n"); - else + if (get_current_health() < get_retreat_health()) { + molog("[defense] I am heavily injured (%d)!\n", get_current_health()); + } else molog("[defense] no enemy soldiers found, ending task\n"); // If no enemy was found, return home @@ -1158,7 +1176,6 @@ descr().get_right_walk_anims(does_carry_ware()), true); } - molog("[defense] return home\n"); if (start_task_movepath @@ -1602,7 +1619,7 @@ if (!attackdefense || ((attackdefense->ivar1 & CF_RETREAT_WHEN_INJURED) && - attackdefense->ui32var3 > get_current_health())) + get_retreat_health() > get_current_health())) { // Retreating or non-combatant soldiers act like normal bobs return Bob::check_node_blocked(game, field, commit); @@ -1718,6 +1735,7 @@ ("Levels: %d/%d/%d/%d\n", health_level_, attack_level_, defense_level_, evade_level_); molog ("Health: %d/%d\n", current_health_, get_max_health()); + molog ("Retreat: %d\n", retreat_health_); molog ("Attack: %d-%d\n", get_min_attack(), get_max_attack()); molog ("Defense: %d%%\n", get_defense()); molog ("Evade: %d%%\n", get_evade()); === modified file 'src/logic/map_objects/tribes/soldier.h' --- src/logic/map_objects/tribes/soldier.h 2016-02-21 19:43:07 +0000 +++ src/logic/map_objects/tribes/soldier.h 2016-03-22 19:48:28 +0000 @@ -159,6 +159,7 @@ void set_attack_level (uint32_t); void set_defense_level(uint32_t); void set_evade_level (uint32_t); + void set_retreat_health (uint32_t); uint32_t get_level (TrainingAttribute) const; uint32_t get_health_level () const {return health_level_;} uint32_t get_attack_level () const {return attack_level_;} @@ -178,6 +179,7 @@ void draw_info_icon(RenderTarget &, Point, bool anchor_below) const; uint32_t get_current_health() const {return current_health_;} + uint32_t get_retreat_health() const {return retreat_health_;} uint32_t get_max_health() const; uint32_t get_min_attack() const; uint32_t get_max_attack() const; @@ -256,6 +258,7 @@ uint32_t attack_level_; uint32_t defense_level_; uint32_t evade_level_; + uint32_t retreat_health_; /// This is used to replicate walk for soldiers but only just before and /// just after figthing in a battle, to draw soldier at proper position.
_______________________________________________ Mailing list: https://launchpad.net/~widelands-dev Post to : widelands-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~widelands-dev More help : https://help.launchpad.net/ListHelp