Пример #1
0
  private boolean canFaceDownBeShownTo(final PlayerView viewer) {
    if (!isFaceDown()) {
      return true;
    }
    if (viewer.hasKeyword("CanSeeOpponentsFaceDownCards")) {
      return true;
    }

    // special viewing permissions for viewer
    if (mayPlayerLook(viewer)) {
      return true;
    }

    // if viewer is controlled by another player, also check if face can be shown to that player
    final PlayerView mindSlaveMaster = viewer.getMindSlaveMaster();
    if (mindSlaveMaster != null && canFaceDownBeShownTo(mindSlaveMaster)) {
      return true;
    }
    if (isInZone(EnumSet.of(ZoneType.Battlefield, ZoneType.Stack, ZoneType.Sideboard))
        && getController().equals(viewer)) {
      return true;
    }
    if (getController().isOpponentOf(viewer) && getCurrentState().getOpponentMayLook()) {
      return true;
    }
    return false;
  }
Пример #2
0
  @Override
  protected void drawOnContainer(Graphics g) {
    // draw target arrows immediately above stack for active item only
    if (activeItem != null) {
      Vector2 arrowOrigin =
          new Vector2(
              activeItem.getLeft()
                  + VStack.CARD_WIDTH * FCardPanel.TARGET_ORIGIN_FACTOR_X
                  + VStack.PADDING
                  + VStack.BORDER_THICKNESS,
              activeItem.getTop()
                  + VStack.CARD_HEIGHT * FCardPanel.TARGET_ORIGIN_FACTOR_Y
                  + VStack.PADDING
                  + VStack.BORDER_THICKNESS);

      PlayerView activator = activeStackInstance.getActivatingPlayer();
      arrowOrigin = arrowOrigin.add(screenPos.x, screenPos.y);

      StackItemView instance = activeStackInstance;
      while (instance != null) {
        for (CardView c : instance.getTargetCards()) {
          TargetingOverlay.drawArrow(g, arrowOrigin, c, activator.isOpponentOf(c.getController()));
        }
        for (PlayerView p : instance.getTargetPlayers()) {
          TargetingOverlay.drawArrow(g, arrowOrigin, p, activator.isOpponentOf(p));
        }
        instance = instance.getSubInstance();
      }
    }
  }
Пример #3
0
  private boolean canBeShownTo(final PlayerView viewer) {
    if (viewer == null) {
      return false;
    }

    ZoneType zone = getZone();
    if (zone == null) {
      return true;
    } // cards outside any zone are visible to all

    final PlayerView controller = getController();
    switch (zone) {
      case Ante:
      case Command:
      case Exile:
      case Battlefield:
      case Graveyard:
      case Flashback:
      case Stack:
        // cards in these zones are visible to all
        return true;
      case Hand:
        if (controller.hasKeyword("Play with your hand revealed.")) {
          return true;
        }
        // $FALL-THROUGH$
      case Sideboard:
        // face-up cards in these zones are hidden to opponents unless they specify otherwise
        if (controller.isOpponentOf(viewer) && !getCurrentState().getOpponentMayLook()) {
          break;
        }
        return true;
      case Library:
      case PlanarDeck:
        // cards in these zones are hidden to all unless they specify otherwise
        if (viewer != null && viewer.equals(controller) && getCurrentState().getYouMayLook()) {
          return true;
        }
        if (controller.isOpponentOf(viewer) && getCurrentState().getOpponentMayLook()) {
          return true;
        }
        break;
      case SchemeDeck:
        // true for now, to actually see the Scheme cards (can't see deck anyway)
        return true;
    }

    // special viewing permissions for viewer
    if (mayPlayerLook(viewer)) {
      return true;
    }

    // if viewer is controlled by another player, also check if card can be shown to that player
    PlayerView mindSlaveMaster = controller.getMindSlaveMaster();
    if (mindSlaveMaster != null && mindSlaveMaster == viewer) {
      return canBeShownTo(controller);
    }
    return false;
  }
Пример #4
0
  public void showRewards() {
    view.getBtnRestart().setVisible(false);
    final QuestController qc = FModel.getQuest();

    // After the first game, reset the card shop pool to be able to buy back anted cards
    if (lastGame.getNumPlayedGamesInMatch() == 0) {
      qc.getCards().clearShopList();
      qc.getCards().getShopList();
    }

    final LobbyPlayer questLobbyPlayer = GamePlayerUtil.getQuestPlayer();
    PlayerView player = null;
    for (final PlayerView p : lastGame.getPlayers()) {
      if (p.isLobbyPlayer(questLobbyPlayer)) {
        player = p;
      }
    }
    final PlayerView questPlayer = player;

    final boolean matchIsNotOver = !lastGame.isMatchOver();
    if (matchIsNotOver) {
      view.getBtnQuit().setText("Quit (-15 Credits)");
    } else {
      view.getBtnContinue().setVisible(false);
      if (wonMatch) {
        view.getBtnQuit().setText("Great!");
      } else {
        view.getBtnQuit().setText("OK");
      }
    }

    // give controller a chance to run remaining logic on a separate thread
    view.showRewards(
        new Runnable() {
          @Override
          public void run() {
            if (isAnte) {
              // Won/lost cards should already be calculated (even in a draw)
              final GameOutcome.AnteResult anteResult = lastGame.getAnteResult(questPlayer);
              if (anteResult != null) {
                if (anteResult.wonCards != null) {
                  qc.getCards().addAllCards(anteResult.wonCards);
                }
                if (anteResult.lostCards != null) {
                  qc.getCards().loseCards(anteResult.lostCards);
                }
                anteReport(anteResult.wonCards, anteResult.lostCards);
              }
            }

            if (matchIsNotOver) {
              return;
            } // skip remaining logic if match isn't over yet

            // TODO: We don't have a enum for difficulty?
            final int difficulty = qData.getAchievements().getDifficulty();

            final int wins = qData.getAchievements().getWin();
            // Win case
            if (wonMatch) {
              // Standard event reward credits
              awardEventCredits();

              // Challenge reward credits
              if (qEvent instanceof QuestEventChallenge) {
                awardChallengeWin();
              } else {
                awardSpecialReward("Special bonus reward"); // If any
                // Random rare for winning against a very hard deck
                if (qEvent.getDifficulty() == QuestEventDifficulty.EXPERT) {
                  awardRandomRare("You've won a random rare for winning against a very hard deck.");
                }
              }

              awardWinStreakBonus();

              // Random rare given at 50% chance (65% with luck upgrade)
              if (getLuckyCoinResult()) {
                awardRandomRare("You've won a random rare.");
              }

              // Award jackpot every 80 games won (currently 10 rares)

              if ((wins > 0) && (((wins + 1) % 80) == 0)) {
                awardJackpot();
              }

            }
            // Lose case
            else {
              penalizeLoss();
            }

            // Grant booster on a win, or on a loss in easy mode
            if (wonMatch || difficulty == 0) {
              final int outcome = wonMatch ? wins : qData.getAchievements().getLost();
              final int winsPerBooster =
                  FModel.getQuestPreferences()
                      .getPrefInt(
                          DifficultyPrefs.WINS_BOOSTER, qData.getAchievements().getDifficulty());
              if (winsPerBooster > 0 && (outcome + 1) % winsPerBooster == 0) {
                awardBooster();
              }
            }
          }
        });
  }
Пример #5
0
 void updateTargetPlayers(SpellAbilityStackInstance si) {
   set(
       TrackableProperty.TargetPlayers,
       PlayerView.getCollection(si.getTargetChoices().getTargetPlayers()));
 }
Пример #6
0
 void updateActivatingPlayer(SpellAbilityStackInstance si) {
   set(TrackableProperty.ActivatingPlayer, PlayerView.get(si.getActivatingPlayer()));
 }
Пример #7
0
  @Override
  public void resolve(SpellAbility sa) {
    final Card host = sa.getHostCard();
    final Player player = sa.getActivatingPlayer();
    final Game game = player.getGame();
    Player chooser = player;
    int numToDig = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa);

    final ZoneType srcZone =
        sa.hasParam("SourceZone")
            ? ZoneType.smartValueOf(sa.getParam("SourceZone"))
            : ZoneType.Library;

    final ZoneType destZone1 =
        sa.hasParam("DestinationZone")
            ? ZoneType.smartValueOf(sa.getParam("DestinationZone"))
            : ZoneType.Hand;
    final ZoneType destZone2 =
        sa.hasParam("DestinationZone2")
            ? ZoneType.smartValueOf(sa.getParam("DestinationZone2"))
            : ZoneType.Library;

    int libraryPosition =
        sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : -1;
    int destZone1ChangeNum = 1;
    final boolean mitosis = sa.hasParam("Mitosis");
    String changeValid = sa.hasParam("ChangeValid") ? sa.getParam("ChangeValid") : "";
    // andOrValid is for cards with "creature card and/or a land card"
    String andOrValid = sa.hasParam("AndOrValid") ? sa.getParam("AndOrValid") : "";
    final boolean anyNumber = sa.hasParam("AnyNumber");

    final int libraryPosition2 =
        sa.hasParam("LibraryPosition2") ? Integer.parseInt(sa.getParam("LibraryPosition2")) : -1;
    final boolean optional = sa.hasParam("Optional");
    final boolean noMove = sa.hasParam("NoMove");
    final boolean skipReorder = sa.hasParam("SkipReorder");

    // A hack for cards like Explorer's Scope that need to ensure that a card is revealed to the
    // player activating the ability
    final boolean forceRevealToController = sa.hasParam("ForceRevealToController");

    // These parameters are used to indicate that a dialog box must be show to the player asking if
    // the player wants to proceed
    // with an optional ability, otherwise the optional ability is skipped.
    final boolean mayBeSkipped = sa.hasParam("PromptToSkipOptionalAbility");
    final String optionalAbilityPrompt =
        sa.hasParam("OptionalAbilityPrompt") ? sa.getParam("OptionalAbilityPrompt") : "";

    boolean changeAll = false;
    boolean allButOne = false;
    final List<String> keywords = new ArrayList<String>();
    if (sa.hasParam("Keywords")) {
      keywords.addAll(Arrays.asList(sa.getParam("Keywords").split(" & ")));
    }

    if (sa.hasParam("ChangeNum")) {
      if (sa.getParam("ChangeNum").equalsIgnoreCase("All")) {
        changeAll = true;
      } else if (sa.getParam("ChangeNum").equalsIgnoreCase("AllButOne")) {
        allButOne = true;
      } else {
        destZone1ChangeNum = AbilityUtils.calculateAmount(host, sa.getParam("ChangeNum"), sa);
      }
    }

    final TargetRestrictions tgt = sa.getTargetRestrictions();
    final List<Player> tgtPlayers = getTargetPlayers(sa);

    if (sa.hasParam("Choser")) {
      final List<Player> choosers =
          AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Choser"), sa);
      if (!choosers.isEmpty()) {
        chooser = choosers.get(0);
      }
    }

    for (final Player p : tgtPlayers) {
      if (tgt != null && !p.canBeTargetedBy(sa)) {
        continue;
      }
      final CardCollection top = new CardCollection();
      final CardCollection rest = new CardCollection();
      final PlayerZone sourceZone = p.getZone(srcZone);

      numToDig = Math.min(numToDig, sourceZone.size());
      for (int i = 0; i < numToDig; i++) {
        top.add(sourceZone.get(i));
      }

      if (!top.isEmpty()) {
        DelayedReveal delayedReveal = null;
        boolean hasRevealed = true;
        if (sa.hasParam("Reveal")) {
          game.getAction().reveal(top, p, false);
        } else if (sa.hasParam("RevealOptional")) {
          String question = "Reveal: " + Lang.joinHomogenous(top) + "?";

          hasRevealed = p.getController().confirmAction(sa, null, question);
          if (hasRevealed) {
            game.getAction().reveal(top, p);
          }
        } else if (sa.hasParam("RevealValid")) {
          final String revealValid = sa.getParam("RevealValid");
          final CardCollection toReveal =
              CardLists.getValidCards(top, revealValid, host.getController(), host);
          if (!toReveal.isEmpty()) {
            game.getAction().reveal(toReveal, host.getController());
            if (sa.hasParam("RememberRevealed")) {
              for (final Card one : toReveal) {
                host.addRemembered(one);
              }
            }
          }
          // Singletons.getModel().getGameAction().revealToCopmuter(top.toArray());
          // - for when it exists
        } else if (!sa.hasParam("NoLooking")) {
          // show the user the revealed cards
          delayedReveal = new DelayedReveal(top, srcZone, PlayerView.get(p));

          if (noMove) {
            // Let the activating player see the cards even if they're not moved
            game.getAction().revealTo(top, player);
          }
        }

        if (sa.hasParam("RememberRevealed") && !sa.hasParam("RevealValid") && hasRevealed) {
          for (final Card one : top) {
            host.addRemembered(one);
          }
        }

        if (!noMove) {
          CardCollection movedCards;
          CardCollection andOrCards;
          for (final Card c : top) {
            rest.add(c);
          }
          CardCollection valid;
          if (mitosis) {
            valid = sharesNameWithCardOnBattlefield(game, top);
            andOrCards = new CardCollection();
          } else if (!changeValid.isEmpty()) {
            if (changeValid.contains("ChosenType")) {
              changeValid = changeValid.replace("ChosenType", host.getChosenType());
            }
            valid =
                CardLists.getValidCards(top, changeValid.split(","), host.getController(), host);
            if (!andOrValid.equals("")) {
              andOrCards =
                  CardLists.getValidCards(top, andOrValid.split(","), host.getController(), host);
              andOrCards.removeAll((Collection<?>) valid);
              valid.addAll(andOrCards);
            } else {
              andOrCards = new CardCollection();
            }
          } else {
            valid = top;
            andOrCards = new CardCollection();
          }

          if (forceRevealToController) {
            // Force revealing the card to the player activating the ability (e.g. Explorer's Scope)
            game.getAction().revealTo(top, player);
          }

          // Optional abilities that use a dialog box to prompt the user to skip the ability (e.g.
          // Explorer's Scope, Quest for Ula's Temple)
          if (optional && mayBeSkipped && !valid.isEmpty()) {
            String prompt =
                !optionalAbilityPrompt.isEmpty()
                    ? optionalAbilityPrompt
                    : "Would you like to proceed with the optional ability for "
                        + sa.getHostCard()
                        + "?\n\n("
                        + sa.getDescription()
                        + ")";
            if (!p.getController()
                .confirmAction(sa, null, prompt.replace("CARDNAME", sa.getHostCard().getName()))) {
              return;
            }
          }

          if (changeAll) {
            movedCards = new CardCollection(valid);
          } else if (sa.hasParam("RandomChange")) {
            int numChanging = Math.min(destZone1ChangeNum, valid.size());
            movedCards = CardLists.getRandomSubList(valid, numChanging);
          } else if (allButOne) {
            movedCards = new CardCollection(valid);
            String prompt;
            if (destZone2.equals(ZoneType.Library) && libraryPosition2 == 0) {
              prompt = "Choose a card to leave on top of {player's} library";
            } else {
              prompt = "Choose a card to leave in {player's} " + destZone2.name();
            }

            Card chosen =
                chooser
                    .getController()
                    .chooseSingleEntityForEffect(valid, delayedReveal, sa, prompt, false, p);
            movedCards.remove(chosen);
            if (sa.hasParam("RandomOrder")) {
              CardLists.shuffle(movedCards);
            }
          } else {
            int j = 0;
            String prompt;

            if (sa.hasParam("PrimaryPrompt")) {
              prompt = sa.getParam("PrimaryPrompt");
            } else {
              prompt = "Choose a card to put into " + destZone1.name();
              if (destZone1.equals(ZoneType.Library)) {
                if (libraryPosition == -1) {
                  prompt = "Choose a card to put on the bottom of {player's} library";
                } else if (libraryPosition == 0) {
                  prompt = "Choose a card to put on top of {player's} library";
                }
              }
            }

            movedCards = new CardCollection();
            while (j < destZone1ChangeNum || (anyNumber && j < numToDig)) {
              // let user get choice
              Card chosen = null;
              if (!valid.isEmpty()) {
                chosen =
                    chooser
                        .getController()
                        .chooseSingleEntityForEffect(
                            valid, delayedReveal, sa, prompt, anyNumber || optional, p);
              } else {
                chooser.getController().notifyOfValue(sa, null, "No valid cards");
              }

              if (chosen == null) {
                break;
              }

              movedCards.add(chosen);
              valid.remove(chosen);
              if (!andOrValid.equals("")) {
                andOrCards.remove(chosen);
                if (!chosen.isValid(andOrValid.split(","), host.getController(), host)) {
                  valid = new CardCollection(andOrCards);
                } else if (!chosen.isValid(changeValid.split(","), host.getController(), host)) {
                  valid.removeAll((Collection<?>) andOrCards);
                }
              }
              j++;
            }

            if (!changeValid.isEmpty()) {
              game.getAction()
                  .reveal(
                      movedCards,
                      chooser,
                      true,
                      chooser
                          + " picked "
                          + (movedCards.size() == 1 ? "this card" : "these cards")
                          + " from ");
            }
          }
          if (sa.hasParam("ForgetOtherRemembered")) {
            host.clearRemembered();
          }
          Collections.reverse(movedCards);
          for (Card c : movedCards) {
            final PlayerZone zone = c.getOwner().getZone(destZone1);

            if (zone.is(ZoneType.Library)
                || zone.is(ZoneType.PlanarDeck)
                || zone.is(ZoneType.SchemeDeck)) {
              if (libraryPosition == -1 || libraryPosition > zone.size()) {
                libraryPosition = zone.size();
              }
              c = game.getAction().moveTo(zone, c, libraryPosition);
            } else {
              c = game.getAction().moveTo(zone, c);
              if (destZone1.equals(ZoneType.Battlefield)) {
                for (final String kw : keywords) {
                  c.addExtrinsicKeyword(kw);
                }
                if (sa.hasParam("Tapped")) {
                  c.setTapped(true);
                }
              }
            }

            if (sa.hasParam("ExileFaceDown")) {
              c.setState(CardStateName.FaceDown, true);
            }
            if (sa.hasParam("Imprint")) {
              host.addImprintedCard(c);
            }
            if (sa.hasParam("ForgetOtherRemembered")) {
              host.clearRemembered();
            }
            if (sa.hasParam("RememberChanged")) {
              host.addRemembered(c);
            }
            rest.remove(c);
          }

          // now, move the rest to destZone2
          if (destZone2 == ZoneType.Library
              || destZone2 == ZoneType.PlanarDeck
              || destZone2 == ZoneType.SchemeDeck) {
            CardCollection afterOrder = rest;
            if (sa.hasParam("RestRandomOrder")) {
              CardLists.shuffle(afterOrder);
            } else if (!skipReorder && rest.size() > 1) {
              afterOrder =
                  (CardCollection) chooser.getController().orderMoveToZoneList(rest, destZone2);
            }
            if (libraryPosition2 != -1) {
              // Closest to top
              Collections.reverse(afterOrder);
            }
            for (final Card c : afterOrder) {
              if (destZone2 == ZoneType.Library) {
                game.getAction().moveToLibrary(c, libraryPosition2);
              } else {
                game.getAction().moveToVariantDeck(c, destZone2, libraryPosition2);
              }
            }
          } else {
            // just move them randomly
            for (int i = 0; i < rest.size(); i++) {
              Card c = rest.get(i);
              final PlayerZone toZone = c.getOwner().getZone(destZone2);
              c = game.getAction().moveTo(toZone, c);
              if (destZone2.equals(ZoneType.Battlefield) && !keywords.isEmpty()) {
                for (final String kw : keywords) {
                  c.addExtrinsicKeyword(kw);
                }
              }
            }
          }
        }
      }
    }
  }
Пример #8
0
 void updateChosenPlayer(Card c) {
   set(TrackableProperty.ChosenPlayer, PlayerView.get(c.getChosenPlayer()));
 }
Пример #9
0
 void updateController(Card c) {
   set(TrackableProperty.Controller, PlayerView.get(c.getController()));
 }
Пример #10
0
 void updateOwner(Card c) {
   set(TrackableProperty.Owner, PlayerView.get(c.getOwner()));
 }