kolmafia / kolmafia

@@ -35,13 +35,6 @@
Loading
35 35
import net.sourceforge.kolmafia.webui.VillainLairDecorator;
36 36
37 37
public abstract class ChoiceManager {
38 -
  public static final GenericRequest CHOICE_HANDLER =
39 -
      new GenericRequest("choice.php") {
40 -
        @Override
41 -
        protected boolean shouldFollowRedirect() {
42 -
          return false;
43 -
        }
44 -
      };
45 38
46 39
  public static boolean handlingChoice = false;
47 40
  public static int lastChoice = 0;
@@ -50,8 +43,18 @@
Loading
50 43
  public static String lastDecoratedResponseText = "";
51 44
52 45
  private static int skillUses = 0;
46 +
47 +
  public static final void setSkillUses(int uses) {
48 +
    // Used for casting skills that lead to a choice adventure
49 +
    ChoiceManager.skillUses = uses;
50 +
  }
51 +
53 52
  private static boolean canWalkAway;
54 53
54 +
  public static boolean canWalkAway() {
55 +
    return ChoiceManager.canWalkAway;
56 +
  }
57 +
55 58
  private enum PostChoiceAction {
56 59
    NONE,
57 60
    INITIALIZE,
@@ -64,6 +67,14 @@
Loading
64 67
    return ChoiceManager.handlingChoice ? ChoiceManager.lastChoice : 0;
65 68
  }
66 69
70 +
  public static final int getLastChoice() {
71 +
    return ChoiceManager.lastChoice;
72 +
  }
73 +
74 +
  public static final int getLastDecision() {
75 +
    return ChoiceManager.lastDecision;
76 +
  }
77 +
67 78
  public static void initializeAfterChoice() {
68 79
    ChoiceManager.action = PostChoiceAction.INITIALIZE;
69 80
    GenericRequest request = ChoiceManager.CHOICE_HANDLER;
@@ -80,6 +91,30 @@
Loading
80 91
    ChoiceManager.action = PostChoiceAction.ASCEND;
81 92
  }
82 93
94 +
  /*
95 +
   * Here is how we automate a choice chain.
96 +
   *
97 +
   * This is invoked by:
98 +
   *
99 +
   * - GenericRequest when redirected to choice.php
100 +
   * - UseItemRequest when redirected to choice.php
101 +
   * - CampgroundRequest when automating mushroom garden
102 +
   *
103 +
   * And by user actions:
104 +
   *
105 +
   * - RelayRequest when the user hits the "auto" button on a choice page.
106 +
   * - The "choice" command from the gCLI
107 +
   * - The run_choice() function of ASH
108 +
   */
109 +
110 +
  public static final GenericRequest CHOICE_HANDLER =
111 +
      new GenericRequest("choice.php") {
112 +
        @Override
113 +
        protected boolean shouldFollowRedirect() {
114 +
          return false;
115 +
        }
116 +
      };
117 +
83 118
  public static final void processRedirectedChoiceAdventure(final String redirectLocation) {
84 119
    ChoiceManager.processChoiceAdventure(ChoiceManager.CHOICE_HANDLER, redirectLocation, null);
85 120
  }
@@ -345,6 +380,19 @@
Loading
345 380
    return true;
346 381
  }
347 382
383 +
  public static void logChoices() {
384 +
    // Log choice options to the session log
385 +
    int choice = ChoiceManager.currentChoice();
386 +
    Map<Integer, String> choices =
387 +
        ChoiceUtilities.parseChoicesWithSpoilers(ChoiceManager.lastResponseText);
388 +
    for (Map.Entry<Integer, String> entry : choices.entrySet()) {
389 +
      RequestLogger.updateSessionLog(
390 +
          "choice " + choice + "/" + entry.getKey() + ": " + entry.getValue());
391 +
    }
392 +
    // Give prettier and more verbose output to the gCLI
393 +
    ChoiceUtilities.printChoices(ChoiceManager.lastResponseText);
394 +
  }
395 +
348 396
  public static final int getDecision(int choice, String responseText) {
349 397
    String option = "choiceAdventure" + choice;
350 398
    String optionValue = Preferences.getString(option);
@@ -378,366 +426,134 @@
Loading
378 426
    return StringUtilities.parseInt(decision);
379 427
  }
380 428
381 -
  public static final int getLastChoice() {
382 -
    return ChoiceManager.lastChoice;
383 -
  }
384 -
385 -
  public static final int getLastDecision() {
386 -
    return ChoiceManager.lastDecision;
387 -
  }
388 -
389 -
  public static final void preChoice(final GenericRequest request) {
390 -
    FightRequest.choiceFollowsFight = false;
391 -
    ChoiceManager.handlingChoice = true;
392 -
    FightRequest.currentRound = 0;
393 -
394 -
    String choice = request.getFormField("whichchoice");
395 -
    String option = request.getFormField("option");
396 -
397 -
    if (choice == null || option == null) {
398 -
      // Visiting a choice page but not yet making a decision
399 -
      ChoiceManager.lastChoice = 0;
400 -
      ChoiceManager.lastDecision = 0;
401 -
      ChoiceManager.lastResponseText = null;
402 -
      ChoiceManager.lastDecoratedResponseText = null;
403 -
      return;
404 -
    }
405 -
406 -
    // We are about to take a choice option
407 -
    ChoiceManager.lastChoice = StringUtilities.parseInt(choice);
408 -
    ChoiceManager.lastDecision = StringUtilities.parseInt(option);
429 +
  private static boolean specialChoiceHandling(final int choice, final GenericRequest request) {
430 +
    String decision = null;
431 +
    switch (choice) {
432 +
      case 485:
433 +
        // Fighters of Fighting
434 +
        decision = ArcadeRequest.autoChoiceFightersOfFighting(request);
435 +
        break;
409 436
410 -
    ChoiceControl.preChoice(request);
411 -
  }
437 +
      case 600:
438 +
        // Summon Minion
439 +
        if (ChoiceManager.skillUses > 0) {
440 +
          // Add the quantity field here and let the decision get added later
441 +
          request.addFormField("quantity", String.valueOf(ChoiceManager.skillUses));
442 +
        }
443 +
        break;
412 444
413 -
  public static void postChoice0(final String urlString, final GenericRequest request) {
414 -
    if (ChoiceManager.nonInterruptingRequest(urlString, request)) {
415 -
      return;
445 +
      case 770:
446 +
      case 792:
447 +
        // Workout in Gyms - no need to do anything further?
448 +
        return true;
416 449
    }
417 450
418 -
    // If this is not actually a choice page, nothing to do here.
419 -
    if (!urlString.startsWith("choice.php")) {
420 -
      return;
451 +
    if (decision == null) {
452 +
      return false;
421 453
    }
422 454
423 -
    String text = request.responseText;
424 -
    int choice = lastChoice == 0 ? ChoiceUtilities.extractChoice(text) : lastChoice;
455 +
    request.addFormField("whichchoice", String.valueOf(choice));
456 +
    request.addFormField("option", decision);
457 +
    request.addFormField("pwd", GenericRequest.passwordHash);
458 +
    request.run();
425 459
426 -
    if (choice == 0) {
427 -
      // choice.php did not offer us any choices.
428 -
      // This would be a bug in KoL itself.
429 -
      return;
430 -
    }
460 +
    ChoiceManager.lastResponseText = request.responseText;
461 +
    ChoiceManager.lastDecoratedResponseText =
462 +
        RequestEditorKit.getFeatureRichHTML(request.getURLString(), request.responseText);
431 463
432 -
    ChoiceControl.postChoice0(choice, urlString, request);
464 +
    return true;
433 465
  }
434 466
435 -
  /**
436 -
   * Certain requests do not interrupt a choice (i.e. are accessible and do not walk away from the
437 -
   * choice)
438 -
   */
439 -
  public static boolean nonInterruptingRequest(
440 -
      final String urlString, final GenericRequest request) {
441 -
    return request.isExternalRequest
442 -
        || request.isRootsetRequest
443 -
        || request.isTopmenuRequest
444 -
        || request.isChatRequest
445 -
        || request.isChatLaunchRequest
446 -
        || request.isDescRequest
447 -
        || request.isStaticRequest
448 -
        || request.isQuestLogRequest
449 -
        ||
450 -
        // Daily Reminders
451 -
        urlString.startsWith("main.php?checkbfast")
452 -
        ||
453 -
        // Choice 1414 uses Lock Picking
454 -
        urlString.equals("skillz.php?oneskillz=195")
455 -
        ||
456 -
        // Choice 1399 uses Seek out a Bird
457 -
        urlString.equals("skillz.php?oneskillz=7323");
458 -
  }
467 +
  private static final AdventureResult MAIDEN_EFFECT = EffectPool.get(EffectPool.DREAMS_AND_LIGHTS);
459 468
460 -
  public static void postChoice1(final String urlString, final GenericRequest request) {
461 -
    if (ChoiceManager.nonInterruptingRequest(urlString, request)) {
462 -
      return;
463 -
    }
469 +
  public static String specialChoiceDecision1(
470 +
      final int choice, String decision, final int stepCount, final String responseText) {
471 +
    // A few choices have non-standard options: 0 is not Manual Control
472 +
    switch (choice) {
473 +
      case 48:
474 +
      case 49:
475 +
      case 50:
476 +
      case 51:
477 +
      case 52:
478 +
      case 53:
479 +
      case 54:
480 +
      case 55:
481 +
      case 56:
482 +
      case 57:
483 +
      case 58:
484 +
      case 59:
485 +
      case 60:
486 +
      case 61:
487 +
      case 62:
488 +
      case 63:
489 +
      case 64:
490 +
      case 65:
491 +
      case 66:
492 +
      case 67:
493 +
      case 68:
494 +
      case 69:
495 +
      case 70:
496 +
        // Choices in the Violet Fog
464 497
465 -
    // If you walked away from the choice, this is not the result of a choice.
466 -
    if (ChoiceManager.canWalkAway
467 -
        && !urlString.startsWith("choice.php")
468 -
        && !urlString.startsWith("fight.php")) {
469 -
      return;
470 -
    }
498 +
        if (decision.equals("")) {
499 +
          return VioletFogManager.handleChoice(choice);
500 +
        }
471 501
472 -
    // Things that can or need to be done BEFORE processing results.
473 -
    // Remove spent items or meat here.
502 +
        return decision;
474 503
475 -
    if (ChoiceManager.lastChoice == 0) {
476 -
      // We are viewing the choice page for the first time.
477 -
      ChoiceManager.visitChoice(request);
478 -
      return;
479 -
    }
504 +
        // Out in the Garden
505 +
      case 89:
480 506
481 -
    // If this is not actually a choice page, we were redirected.
482 -
    // Do not save this responseText
507 +
        // Handle the maidens adventure in a less random
508 +
        // fashion that's actually useful.
483 509
484 -
    String text = request.responseText;
485 -
    if (urlString.startsWith("choice.php")) {
486 -
      ChoiceManager.lastResponseText = text;
487 -
    }
510 +
        switch (StringUtilities.parseInt(decision)) {
511 +
          case 0:
512 +
            return String.valueOf(KoLConstants.RNG.nextInt(2) + 1);
513 +
          case 1:
514 +
          case 2:
515 +
            return decision;
516 +
          case 3:
517 +
            return KoLConstants.activeEffects.contains(MAIDEN_EFFECT)
518 +
                ? String.valueOf(KoLConstants.RNG.nextInt(2) + 1)
519 +
                : "3";
520 +
          case 4:
521 +
            return KoLConstants.activeEffects.contains(MAIDEN_EFFECT) ? "1" : "3";
522 +
          case 5:
523 +
            return KoLConstants.activeEffects.contains(MAIDEN_EFFECT) ? "2" : "3";
524 +
          case 6:
525 +
            return "4";
526 +
        }
527 +
        return decision;
488 528
489 -
    ChoiceControl.postChoice1(urlString, request);
529 +
        // Dungeon Fist!
530 +
      case 486:
531 +
        if (ChoiceManager.action
532 +
            == PostChoiceAction
533 +
                .NONE) { // Don't automate this if we logged in in the middle of the game -
534 +
          // the auto script isn't robust enough to handle arbitrary starting points.
535 +
          return ArcadeRequest.autoDungeonFist(stepCount, responseText);
536 +
        }
537 +
        return decision;
490 538
491 -
    // Certain choices cost meat or items when selected
492 -
    ChoiceAdventures.payCost(ChoiceManager.lastChoice, ChoiceManager.lastDecision);
493 -
  }
539 +
        // Interview With You
540 +
      case 546:
541 +
        if (ChoiceManager.action
542 +
            == PostChoiceAction
543 +
                .NONE) { // Don't automate this if we logged in in the middle of the game -
544 +
          // the auto script isn't robust enough to handle arbitrary starting points.
545 +
          return VampOutManager.autoVampOut(
546 +
              StringUtilities.parseInt(decision), stepCount, responseText);
547 +
        }
548 +
        return "0";
494 549
495 -
  public static void postChoice2(final String urlString, final GenericRequest request) {
496 -
    if (ChoiceManager.nonInterruptingRequest(urlString, request)) {
497 -
      return;
498 -
    }
499 -
500 -
    // The following are requests that may or may not be allowed at
501 -
    // any time, but we do them in automation during result
502 -
    // processing and they do not count as "walking away"
503 -
    if (urlString.startsWith("diary.php")) {
504 -
      return;
505 -
    }
506 -
507 -
    // Things that can or need to be done AFTER processing results.
508 -
    String text = request.responseText;
509 -
510 -
    // If you walked away from the choice (or we automated during
511 -
    // result processing), this is not a choice page
512 -
    if (ChoiceManager.canWalkAway
513 -
        && !urlString.startsWith("choice.php")
514 -
        && !urlString.startsWith("fight.php")) {
515 -
      // I removed the following line, but it caused issues.
516 -
      ChoiceManager.handlingChoice = false;
517 -
      return;
518 -
    }
519 -
520 -
    ChoiceManager.handlingChoice = ChoiceManager.stillInChoice(text);
521 -
522 -
    if (urlString.startsWith("choice.php") && text.contains("charpane.php")) {
523 -
      // Since a charpane refresh was requested, a turn might have been spent
524 -
      AdventureSpentDatabase.setNoncombatEncountered(true);
525 -
    }
526 -
527 -
    if (ChoiceManager.lastChoice == 0 || ChoiceManager.lastDecision == 0) {
528 -
      // This was a visit
529 -
      return;
530 -
    }
531 -
532 -
    ChoiceControl.postChoice2(urlString, request);
533 -
534 -
    SpadingManager.processChoice(urlString, text);
535 -
536 -
    if (ChoiceManager.handlingChoice) {
537 -
      ChoiceManager.visitChoice(request);
538 -
      return;
539 -
    }
540 -
541 -
    PostChoiceAction action = ChoiceManager.action;
542 -
    if (action != PostChoiceAction.NONE) {
543 -
      ChoiceManager.action = PostChoiceAction.NONE;
544 -
      switch (action) {
545 -
        case INITIALIZE:
546 -
          LoginManager.login(KoLCharacter.getUserName());
547 -
          break;
548 -
        case ASCEND:
549 -
          ValhallaManager.postAscension();
550 -
          break;
551 -
      }
552 -
    }
553 -
554 -
    // visitChoice() gets the decorated response text, but this is not a visit.
555 -
    // If this is not actually a choice page, we were redirected.
556 -
    // Do not save this responseText
557 -
    if (urlString.startsWith("choice.php")) {
558 -
      ChoiceManager.lastDecoratedResponseText =
559 -
          RequestEditorKit.getFeatureRichHTML(request.getURLString(), text);
560 -
    }
561 -
  }
562 -
563 -
  public static void handleWalkingAway(final String urlString) {
564 -
    // If we are not handling a choice, nothing to do
565 -
    if (!ChoiceManager.handlingChoice) {
566 -
      return;
567 -
    }
568 -
569 -
    // If the choice doesn't let you walk away, normal redirect
570 -
    // processing will take care of it
571 -
    if (!ChoiceManager.canWalkAway) {
572 -
      return;
573 -
    }
574 -
575 -
    // If you walked away from the choice, we're done with the choice
576 -
    if (!urlString.startsWith("choice.php")) {
577 -
      ChoiceManager.handlingChoice = false;
578 -
      return;
579 -
    }
580 -
  }
581 -
582 -
  public static void visitChoice(final GenericRequest request) {
583 -
    String text = request.responseText;
584 -
    ChoiceManager.lastChoice = ChoiceUtilities.extractChoice(text);
585 -
586 -
    if (ChoiceManager.lastChoice == 0) {
587 -
      // choice.php did not offer us any choices and we couldn't work out which choice it was.
588 -
      // This happens if taking a choice gives a response with a "next" link to choice.php.
589 -
      ChoiceManager.lastDecoratedResponseText =
590 -
          RequestEditorKit.getFeatureRichHTML(request.getURLString(), text);
591 -
      return;
592 -
    }
593 -
594 -
    SpadingManager.processChoiceVisit(ChoiceManager.lastChoice, text);
595 -
596 -
    // Must do this BEFORE we decorate the response text
597 -
    ChoiceManager.setCanWalkAway(ChoiceManager.lastChoice);
598 -
599 -
    ChoiceManager.lastResponseText = text;
600 -
601 -
    // Clear lastItemUsed, to prevent the item being "prcessed"
602 -
    // next time we simply visit the inventory.
603 -
    UseItemRequest.clearLastItemUsed();
604 -
605 -
    ChoiceControl.visitChoice(request);
606 -
607 -
    // Do this after special classes (like WumpusManager) have a
608 -
    // chance to update state in their visitChoice methods.
609 -
    ChoiceManager.lastDecoratedResponseText =
610 -
        RequestEditorKit.getFeatureRichHTML(request.getURLString(), text);
611 -
  }
612 -
613 -
  private static boolean specialChoiceHandling(final int choice, final GenericRequest request) {
614 -
    String decision = null;
615 -
    switch (choice) {
616 -
      case 485:
617 -
        // Fighters of Fighting
618 -
        decision = ArcadeRequest.autoChoiceFightersOfFighting(request);
619 -
        break;
620 -
621 -
      case 600:
622 -
        // Summon Minion
623 -
        if (ChoiceManager.skillUses > 0) {
624 -
          // Add the quantity field here and let the decision get added later
625 -
          request.addFormField("quantity", String.valueOf(ChoiceManager.skillUses));
626 -
        }
627 -
        break;
628 -
629 -
      case 770:
630 -
      case 792:
631 -
        // Workout in Gyms - no need to do anything further?
632 -
        return true;
633 -
    }
634 -
635 -
    if (decision == null) {
636 -
      return false;
637 -
    }
638 -
639 -
    request.addFormField("whichchoice", String.valueOf(choice));
640 -
    request.addFormField("option", decision);
641 -
    request.addFormField("pwd", GenericRequest.passwordHash);
642 -
    request.run();
643 -
644 -
    ChoiceManager.lastResponseText = request.responseText;
645 -
    ChoiceManager.lastDecoratedResponseText =
646 -
        RequestEditorKit.getFeatureRichHTML(request.getURLString(), request.responseText);
647 -
648 -
    return true;
649 -
  }
650 -
651 -
  private static final AdventureResult MAIDEN_EFFECT = EffectPool.get(EffectPool.DREAMS_AND_LIGHTS);
652 -
653 -
  public static String specialChoiceDecision1(
654 -
      final int choice, String decision, final int stepCount, final String responseText) {
655 -
    // A few choices have non-standard options: 0 is not Manual Control
656 -
    switch (choice) {
657 -
      case 48:
658 -
      case 49:
659 -
      case 50:
660 -
      case 51:
661 -
      case 52:
662 -
      case 53:
663 -
      case 54:
664 -
      case 55:
665 -
      case 56:
666 -
      case 57:
667 -
      case 58:
668 -
      case 59:
669 -
      case 60:
670 -
      case 61:
671 -
      case 62:
672 -
      case 63:
673 -
      case 64:
674 -
      case 65:
675 -
      case 66:
676 -
      case 67:
677 -
      case 68:
678 -
      case 69:
679 -
      case 70:
680 -
        // Choices in the Violet Fog
681 -
682 -
        if (decision.equals("")) {
683 -
          return VioletFogManager.handleChoice(choice);
684 -
        }
685 -
686 -
        return decision;
687 -
688 -
        // Out in the Garden
689 -
      case 89:
690 -
691 -
        // Handle the maidens adventure in a less random
692 -
        // fashion that's actually useful.
693 -
694 -
        switch (StringUtilities.parseInt(decision)) {
695 -
          case 0:
696 -
            return String.valueOf(KoLConstants.RNG.nextInt(2) + 1);
697 -
          case 1:
698 -
          case 2:
699 -
            return decision;
700 -
          case 3:
701 -
            return KoLConstants.activeEffects.contains(MAIDEN_EFFECT)
702 -
                ? String.valueOf(KoLConstants.RNG.nextInt(2) + 1)
703 -
                : "3";
704 -
          case 4:
705 -
            return KoLConstants.activeEffects.contains(MAIDEN_EFFECT) ? "1" : "3";
706 -
          case 5:
707 -
            return KoLConstants.activeEffects.contains(MAIDEN_EFFECT) ? "2" : "3";
708 -
          case 6:
709 -
            return "4";
710 -
        }
711 -
        return decision;
712 -
713 -
        // Dungeon Fist!
714 -
      case 486:
715 -
        if (ChoiceManager.action
716 -
            == PostChoiceAction
717 -
                .NONE) { // Don't automate this if we logged in in the middle of the game -
718 -
          // the auto script isn't robust enough to handle arbitrary starting points.
719 -
          return ArcadeRequest.autoDungeonFist(stepCount, responseText);
720 -
        }
721 -
        return decision;
722 -
723 -
        // Interview With You
724 -
      case 546:
725 -
        if (ChoiceManager.action
726 -
            == PostChoiceAction
727 -
                .NONE) { // Don't automate this if we logged in in the middle of the game -
728 -
          // the auto script isn't robust enough to handle arbitrary starting points.
729 -
          return VampOutManager.autoVampOut(
730 -
              StringUtilities.parseInt(decision), stepCount, responseText);
731 -
        }
732 -
        return "0";
733 -
734 -
        // Summon Minion is a skill
735 -
      case 600:
736 -
        if (ChoiceManager.skillUses > 0) {
737 -
          ChoiceManager.skillUses = 0;
738 -
          return "1";
739 -
        }
740 -
        return "2";
550 +
        // Summon Minion is a skill
551 +
      case 600:
552 +
        if (ChoiceManager.skillUses > 0) {
553 +
          ChoiceManager.skillUses = 0;
554 +
          return "1";
555 +
        }
556 +
        return "2";
741 557
742 558
        // Summon Horde is a skill
743 559
      case 601:
@@ -2243,38 +2059,243 @@
Loading
2243 2059
    return (desc == null) ? "unknown" : desc;
2244 2060
  }
2245 2061
2246 -
  public static final boolean registerRequest(final String urlString) {
2062 +
  /*
2063 +
   * Here are the methods called by GenericRequest at various points while
2064 +
   * processing a request.
2065 +
   *
2066 +
   * We are "handling a choice" from the time we submit a request to choice.php
2067 +
   * until we have processed the response.
2068 +
   *
2069 +
   * Since choices can lead to other choices (a "choice chain") we stay in that
2070 +
   * state until the final response is received - although the "current" choice
2071 +
   * will change along the way.
2072 +
   *
2073 +
   * This would be a good place to explain which of these methods is called
2074 +
   * where and what the intended purpose is.
2075 +
   */
2076 +
2077 +
  public static final void preChoice(final GenericRequest request) {
2078 +
    FightRequest.choiceFollowsFight = false;
2079 +
    ChoiceManager.handlingChoice = true;
2080 +
    FightRequest.currentRound = 0;
2081 +
2082 +
    String choice = request.getFormField("whichchoice");
2083 +
    String option = request.getFormField("option");
2084 +
2085 +
    if (choice == null || option == null) {
2086 +
      // Visiting a choice page but not yet making a decision
2087 +
      ChoiceManager.lastChoice = 0;
2088 +
      ChoiceManager.lastDecision = 0;
2089 +
      ChoiceManager.lastResponseText = null;
2090 +
      ChoiceManager.lastDecoratedResponseText = null;
2091 +
      return;
2092 +
    }
2093 +
2094 +
    // We are about to take a choice option
2095 +
    ChoiceManager.lastChoice = StringUtilities.parseInt(choice);
2096 +
    ChoiceManager.lastDecision = StringUtilities.parseInt(option);
2097 +
2098 +
    ChoiceControl.preChoice(request);
2099 +
  }
2100 +
2101 +
  public static void postChoice0(final String urlString, final GenericRequest request) {
2102 +
    if (ChoiceManager.nonInterruptingRequest(urlString, request)) {
2103 +
      return;
2104 +
    }
2105 +
2106 +
    // If this is not actually a choice page, nothing to do here.
2247 2107
    if (!urlString.startsWith("choice.php")) {
2248 -
      return false;
2108 +
      return;
2249 2109
    }
2250 2110
2251 -
    if (urlString.equals("choice.php")) {
2252 -
      // Continuing after a multi-fight.
2253 -
      // Handle those when the real choice comes up.
2254 -
      return true;
2111 +
    String text = request.responseText;
2112 +
    int choice = lastChoice == 0 ? ChoiceUtilities.extractChoice(text) : lastChoice;
2113 +
2114 +
    if (choice == 0) {
2115 +
      // choice.php did not offer us any choices.
2116 +
      // This would be a bug in KoL itself.
2117 +
      return;
2255 2118
    }
2256 2119
2257 -
    GenericRequest.itemMonster = null;
2120 +
    ChoiceControl.postChoice0(choice, urlString, request);
2121 +
  }
2258 2122
2259 -
    return ChoiceControl.registerRequest(urlString);
2123 +
  /**
2124 +
   * Certain requests do not interrupt a choice (i.e. are accessible and do not walk away from the
2125 +
   * choice)
2126 +
   */
2127 +
  public static boolean nonInterruptingRequest(
2128 +
      final String urlString, final GenericRequest request) {
2129 +
    return request.isExternalRequest
2130 +
        || request.isRootsetRequest
2131 +
        || request.isTopmenuRequest
2132 +
        || request.isChatRequest
2133 +
        || request.isChatLaunchRequest
2134 +
        || request.isDescRequest
2135 +
        || request.isStaticRequest
2136 +
        || request.isQuestLogRequest
2137 +
        ||
2138 +
        // Daily Reminders
2139 +
        urlString.startsWith("main.php?checkbfast")
2140 +
        ||
2141 +
        // Choice 1414 uses Lock Picking
2142 +
        urlString.equals("skillz.php?oneskillz=195")
2143 +
        ||
2144 +
        // Choice 1399 uses Seek out a Bird
2145 +
        urlString.equals("skillz.php?oneskillz=7323");
2260 2146
  }
2261 2147
2262 -
  public static final void registerDeferredChoice(final int choice, final String encounter) {
2263 -
    // If we couldn't find an encounter, do nothing
2264 -
    if (encounter == null) {
2148 +
  public static void postChoice1(final String urlString, final GenericRequest request) {
2149 +
    if (ChoiceManager.nonInterruptingRequest(urlString, request)) {
2265 2150
      return;
2266 2151
    }
2267 2152
2268 -
    ChoiceControl.registerDeferredChoice(choice, encounter);
2153 +
    // If you walked away from the choice, this is not the result of a choice.
2154 +
    if (ChoiceManager.canWalkAway
2155 +
        && !urlString.startsWith("choice.php")
2156 +
        && !urlString.startsWith("fight.php")) {
2157 +
      return;
2158 +
    }
2159 +
2160 +
    // Things that can or need to be done BEFORE processing results.
2161 +
    // Remove spent items or meat here.
2162 +
2163 +
    if (ChoiceManager.lastChoice == 0) {
2164 +
      // We are viewing the choice page for the first time.
2165 +
      ChoiceManager.visitChoice(request);
2166 +
      return;
2167 +
    }
2168 +
2169 +
    // If this is not actually a choice page, we were redirected.
2170 +
    // Do not save this responseText
2171 +
2172 +
    String text = request.responseText;
2173 +
    if (urlString.startsWith("choice.php")) {
2174 +
      ChoiceManager.lastResponseText = text;
2175 +
    }
2176 +
2177 +
    ChoiceControl.postChoice1(urlString, request);
2178 +
2179 +
    // Certain choices cost meat or items when selected
2180 +
    ChoiceAdventures.payCost(ChoiceManager.lastChoice, ChoiceManager.lastDecision);
2269 2181
  }
2270 2182
2271 -
  public static final void setSkillUses(int uses) {
2272 -
    // Used for casting skills that lead to a choice adventure
2273 -
    ChoiceManager.skillUses = uses;
2183 +
  public static void postChoice2(final String urlString, final GenericRequest request) {
2184 +
    if (ChoiceManager.nonInterruptingRequest(urlString, request)) {
2185 +
      return;
2186 +
    }
2187 +
2188 +
    // The following are requests that may or may not be allowed at
2189 +
    // any time, but we do them in automation during result
2190 +
    // processing and they do not count as "walking away"
2191 +
    if (urlString.startsWith("diary.php")) {
2192 +
      return;
2193 +
    }
2194 +
2195 +
    // Things that can or need to be done AFTER processing results.
2196 +
    String text = request.responseText;
2197 +
2198 +
    // If you walked away from the choice (or we automated during
2199 +
    // result processing), this is not a choice page
2200 +
    if (ChoiceManager.canWalkAway
2201 +
        && !urlString.startsWith("choice.php")
2202 +
        && !urlString.startsWith("fight.php")) {
2203 +
      // I removed the following line, but it caused issues.
2204 +
      ChoiceManager.handlingChoice = false;
2205 +
      return;
2206 +
    }
2207 +
2208 +
    ChoiceManager.handlingChoice = ChoiceManager.stillInChoice(text);
2209 +
2210 +
    if (urlString.startsWith("choice.php") && text.contains("charpane.php")) {
2211 +
      // Since a charpane refresh was requested, a turn might have been spent
2212 +
      AdventureSpentDatabase.setNoncombatEncountered(true);
2213 +
    }
2214 +
2215 +
    if (ChoiceManager.lastChoice == 0 || ChoiceManager.lastDecision == 0) {
2216 +
      // This was a visit
2217 +
      return;
2218 +
    }
2219 +
2220 +
    ChoiceControl.postChoice2(urlString, request);
2221 +
2222 +
    SpadingManager.processChoice(urlString, text);
2223 +
2224 +
    if (ChoiceManager.handlingChoice) {
2225 +
      ChoiceManager.visitChoice(request);
2226 +
      return;
2227 +
    }
2228 +
2229 +
    PostChoiceAction action = ChoiceManager.action;
2230 +
    if (action != PostChoiceAction.NONE) {
2231 +
      ChoiceManager.action = PostChoiceAction.NONE;
2232 +
      switch (action) {
2233 +
        case INITIALIZE:
2234 +
          LoginManager.login(KoLCharacter.getUserName());
2235 +
          break;
2236 +
        case ASCEND:
2237 +
          ValhallaManager.postAscension();
2238 +
          break;
2239 +
      }
2240 +
    }
2241 +
2242 +
    // visitChoice() gets the decorated response text, but this is not a visit.
2243 +
    // If this is not actually a choice page, we were redirected.
2244 +
    // Do not save this responseText
2245 +
    if (urlString.startsWith("choice.php")) {
2246 +
      ChoiceManager.lastDecoratedResponseText =
2247 +
          RequestEditorKit.getFeatureRichHTML(request.getURLString(), text);
2248 +
    }
2274 2249
  }
2275 2250
2276 -
  public static boolean canWalkAway() {
2277 -
    return ChoiceManager.canWalkAway;
2251 +
  public static void handleWalkingAway(final String urlString) {
2252 +
    // If we are not handling a choice, nothing to do
2253 +
    if (!ChoiceManager.handlingChoice) {
2254 +
      return;
2255 +
    }
2256 +
2257 +
    // If the choice doesn't let you walk away, normal redirect
2258 +
    // processing will take care of it
2259 +
    if (!ChoiceManager.canWalkAway) {
2260 +
      return;
2261 +
    }
2262 +
2263 +
    // If you walked away from the choice, we're done with the choice
2264 +
    if (!urlString.startsWith("choice.php")) {
2265 +
      ChoiceManager.handlingChoice = false;
2266 +
      return;
2267 +
    }
2268 +
  }
2269 +
2270 +
  public static void visitChoice(final GenericRequest request) {
2271 +
    String text = request.responseText;
2272 +
    ChoiceManager.lastChoice = ChoiceUtilities.extractChoice(text);
2273 +
2274 +
    if (ChoiceManager.lastChoice == 0) {
2275 +
      // choice.php did not offer us any choices and we couldn't work out which choice it was.
2276 +
      // This happens if taking a choice gives a response with a "next" link to choice.php.
2277 +
      ChoiceManager.lastDecoratedResponseText =
2278 +
          RequestEditorKit.getFeatureRichHTML(request.getURLString(), text);
2279 +
      return;
2280 +
    }
2281 +
2282 +
    SpadingManager.processChoiceVisit(ChoiceManager.lastChoice, text);
2283 +
2284 +
    // Must do this BEFORE we decorate the response text
2285 +
    ChoiceManager.setCanWalkAway(ChoiceManager.lastChoice);
2286 +
2287 +
    ChoiceManager.lastResponseText = text;
2288 +
2289 +
    // Clear lastItemUsed, to prevent the item being "prcessed"
2290 +
    // next time we simply visit the inventory.
2291 +
    UseItemRequest.clearLastItemUsed();
2292 +
2293 +
    ChoiceControl.visitChoice(request);
2294 +
2295 +
    // Do this after special classes (like WumpusManager) have a
2296 +
    // chance to update state in their visitChoice methods.
2297 +
    ChoiceManager.lastDecoratedResponseText =
2298 +
        RequestEditorKit.getFeatureRichHTML(request.getURLString(), text);
2278 2299
  }
2279 2300
2280 2301
  private static void setCanWalkAway(final int choice) {
@@ -2285,16 +2306,28 @@
Loading
2285 2306
    return ChoiceControl.canWalkFromChoice(choice);
2286 2307
  }
2287 2308
2288 -
  public static void logChoices() {
2289 -
    // Log choice options to the session log
2290 -
    int choice = ChoiceManager.currentChoice();
2291 -
    Map<Integer, String> choices =
2292 -
        ChoiceUtilities.parseChoicesWithSpoilers(ChoiceManager.lastResponseText);
2293 -
    for (Map.Entry<Integer, String> entry : choices.entrySet()) {
2294 -
      RequestLogger.updateSessionLog(
2295 -
          "choice " + choice + "/" + entry.getKey() + ": " + entry.getValue());
2309 +
  public static final boolean registerRequest(final String urlString) {
2310 +
    if (!urlString.startsWith("choice.php")) {
2311 +
      return false;
2296 2312
    }
2297 -
    // Give prettier and more verbose output to the gCLI
2298 -
    ChoiceUtilities.printChoices(ChoiceManager.lastResponseText);
2313 +
2314 +
    if (urlString.equals("choice.php")) {
2315 +
      // Continuing after a multi-fight.
2316 +
      // Handle those when the real choice comes up.
2317 +
      return true;
2318 +
    }
2319 +
2320 +
    GenericRequest.itemMonster = null;
2321 +
2322 +
    return ChoiceControl.registerRequest(urlString);
2323 +
  }
2324 +
2325 +
  public static final void registerDeferredChoice(final int choice, final String encounter) {
2326 +
    // If we couldn't find an encounter, do nothing
2327 +
    if (encounter == null) {
2328 +
      return;
2329 +
    }
2330 +
2331 +
    ChoiceControl.registerDeferredChoice(choice, encounter);
2299 2332
  }
2300 2333
}

@@ -727,7 +727,7 @@
Loading
727 727
  public static final String getWumpinatorURL() {
728 728
    String code = WumpusManager.getWumpinatorCode();
729 729
    String current = WumpusManager.getCurrentField();
730 -
    return "https://www.feesher.com/wumpus/wump_map.php?mapstring=" + code + current;
730 +
    return "http://www.feesher.com/wumpus/wump_map.php?mapstring=" + code + current;
731 731
  }
732 732
733 733
  public static final void invokeWumpinator() {

@@ -1902,8 +1902,7 @@
Loading
1902 1902
        StringBuilder spoilerBuffer = new StringBuilder(spoiler.toString());
1903 1903
1904 1904
        // If this decision has an item associated with it, annotate it
1905 -
        ChoiceAdventures.Option option = ((ChoiceAdventures.Option) spoiler);
1906 -
        AdventureResult[] items = option.getItems();
1905 +
        AdventureResult[] items = spoiler.getItems();
1907 1906
1908 1907
        // If this decision leads to one or more item...
1909 1908
        for (int it = 0; it < items.length; it++) {
Files Complexity Coverage
src/net/sourceforge/kolmafia 19.16% 24.53%
Project Totals (1016 files) 19.16% 24.53%
coverage-macos-latest-java-11
Build #2379035435 -
JAVA=11
OS=macos-latest
coverage-ubuntu-latest-java-17
Build #2379035435 -
JAVA=17
OS=ubuntu-latest
coverage-windows-latest-java-17
Build #2379035435 -
JAVA=17
OS=windows-latest
coverage-windows-latest-java-11
Build #2379035435 -
JAVA=11
OS=windows-latest
coverage-macos-latest-java-17
Build #2379035435 -
JAVA=17
OS=macos-latest

No yaml found.

Create your codecov.yml to customize your Codecov experience

Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading