fix(baal_xp): keep the leech alive when its own cycles keep failing

- leech cycle failures no longer feed the session consecutive-fail tally
  (five bad joins disabled the route for the whole session and ended the
  game); _baal_xp_rearm keeps its own local breaker and resets the
  game-level counter so the controller restarts D2R and the leech retries
- on_start_from_town: a leech that re-enters its own game on a corpse
  (died in the public game, or save-and-exit raced the death screen)
  gets pre_buff + /nopickup here - without it the char stays dead and the
  next cycle's save-and-exit has no living game to exit from
This commit is contained in:
alexpolo1
2026-09-06 08:18:47 +02:00
parent 165e4385d4
commit c40f2efad2
+32 -2
View File
@@ -455,6 +455,21 @@ class Bot:
Logger.info(f"Teleport keybind is lost upon death. Rebinding teleport to '{keybind}'")
self._char.remap_right_skill_hotkey("TELE_ACTIVE", Config().char["teleport"])
# A leech cycle that died in a public game (or whose save-and-exit raced
# the death screen) re-enters its own game on a corpse. The generic
# pickup above only fires on the town-spawn path, so handle it here too -
# without this the character stays dead and the next cycle's save-and-
# exit has no living game to exit from.
if corpse_present and self._baal_xp_only():
self._char.pre_buff()
if Config().char["enable_no_pickup"] and (not self._ran_no_pickup and not self._game_stats._nopickup_active):
self._ran_no_pickup = True
if view.enable_no_pickup():
self._game_stats._nopickup_active = True
Logger.info("Activated /nopickup")
else:
Logger.error("Failed to detect if /nopickup command was applied or not")
# Run /nopickup command to avoid picking up stuff on accident
if Config().char["enable_no_pickup"] and (not self._ran_no_pickup and not self._game_stats._nopickup_active):
self._ran_no_pickup = True
@@ -1291,6 +1306,13 @@ class Bot:
Logger.warning(f"baal_xp: {self._baal_xp_fails} cycles failed in a row — "
f"ending the game so the controller can recover")
self._baal_xp_fails = 0
# A leech cycle that failed at the join/leave/recovery stage is NOT a
# run that died in combat - it is a broken cycle that the rearm loop
# is about to retry. Counting it in the session's consecutive-fail
# tally (via _record_run_result) made five join failures disable the
# route for the whole session and end the game, so the leech could
# never self-heal. Keep the breaker local to the leech.
self._game_stats.reset_consecutive_fails()
return
self._do_runs["run_baal_xp"] = True
# Re-arm the route in the config layer too: on_maintenance re-reads
@@ -2007,7 +2029,15 @@ class Bot:
# early (low HP, run over) - the XP was collected; only a broken
# cycle (join/leave/recovery failure) is a failure.
self._game_stats.log_run_finished("run_baal_xp", not ok, None, loot=[])
self._record_run_result("run_baal_xp", not ok)
if ok:
self._record_run_result("run_baal_xp", False)
else:
# A failed leech cycle is a broken join/leave/recovery, not a run
# that died in combat - it must not feed the session's
# consecutive-fail tally, or five bad joins disable the route for
# the whole session and end the game. _baal_xp_rearm keeps its
# own breaker for that.
self._game_stats.reset_consecutive_fails()
self._game_stats.log_exp()
self._baal_xp_rearm(ok=ok)
self.trigger_or_stop("end_run")
@@ -2022,7 +2052,7 @@ class Bot:
# Best effort: get back to our own game so the bot keeps running
self._baal_xp_go_home()
self._game_stats.log_run_finished("run_baal_xp", True, None, loot=[])
self._record_run_result("run_baal_xp", True)
self._game_stats.reset_consecutive_fails()
self._baal_xp_rearm(ok=False)
self.trigger_or_stop("end_run")
finally: