@Override
  protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
    // This still needs to be fleshed out
    final TargetRestrictions tgt = sa.getTargetRestrictions();
    final Card source = sa.getHostCard();

    final Random r = MyRandom.getRandom();
    boolean randomReturn = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());

    List<Card> tgtCards;
    if (tgt == null) {
      tgtCards = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
      if (tgtCards.contains(source)) {
        // Protect it from something
      } else {
        // Card def = tgtCards.get(0);
        // Phase this out if it might attack me, or before it can be
        // declared as a blocker
      }

      return false;
    } else {
      if (!phasesPrefTargeting(tgt, sa, false)) {
        return false;
      }
    }

    return randomReturn;
  }
  /**
   * readFile.
   *
   * @param file a {@link java.io.File} object.
   * @return a {@link java.util.HashMap} object.
   */
  private Map<String, Integer> readFile(final String file) {

    final Map<String, Integer> map = new HashMap<>();
    final Random r = MyRandom.getRandom();

    final List<String> lines = FileUtil.readFile(file);
    for (final String line : lines) {
      if (line.trim().isEmpty()) {
        break;
      }

      if (line.startsWith(ReadPriceList.COMMENT)) {
        continue;
      }

      final String[] s = line.split("=");
      if (s.length < 2) {
        continue;
      } // skip line if not in correct format

      final String name = s[0].trim();
      final String price = s[1].trim();

      try {
        int val = Integer.parseInt(price.trim());

        if (!(MagicColor.Constant.BASIC_LANDS.contains(name)
                || MagicColor.Constant.SNOW_LANDS.contains(name))
            && !ForgeConstants.PRICES_BOOSTER_FILE.equals(file)) {
          float ff;
          if (r.nextInt(100) < 90) {
            ff = r.nextInt(10) * (float) .01;
          } else {
            // +/- 50%
            ff = r.nextInt(50) * (float) .01;
          }

          if (r.nextInt(100) < 50) {
            val = (int) (val * (1 - ff));
          } else {
            // +ff%
            val = (int) (val * (1 + ff));
          }
        }

        map.put(name, val);
      } catch (final NumberFormatException nfe) {
        Log.warn("NumberFormatException: " + nfe.getMessage());
      }
    }
    return map;
  } // readFile()
Exemple #3
0
  private void setRandomAvatar(final boolean fireListeners) {
    int random = 0;

    final List<Integer> usedAvatars = lobby.getUsedAvatars();
    do {
      random = MyRandom.getRandom().nextInt(FSkin.getAvatars().size());
    } while (usedAvatars.contains(random));
    setAvatarIndex(random);

    if (fireListeners) {
      lobby.firePlayerChangeListener(index);
    }
  }
  @Override
  public void resolve(SpellAbility sa) {
    final Card host = sa.getHostCard();
    final String[] choices = sa.getParam("Choices").split(",");
    final List<SpellAbility> abilities = new ArrayList<SpellAbility>();

    for (String s : choices) {
      abilities.add(AbilityFactory.getAbility(host.getSVar(s), host));
    }

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

    for (final Player p : tgtPlayers) {
      if (tgt != null && !p.canBeTargetedBy(sa)) {
        continue;
      }

      int idxChosen = 0;
      String chosenName;
      if (sa.hasParam("AtRandom")) {
        idxChosen = MyRandom.getRandom().nextInt(choices.length);
        chosenName = choices[idxChosen];
      } else {
        SpellAbility saChosen =
            p.getController().chooseSingleSpellForEffect(abilities, sa, "Choose one");
        idxChosen = abilities.indexOf(saChosen);
        chosenName = choices[idxChosen];
      }
      SpellAbility chosenSA = AbilityFactory.getAbility(host.getSVar(chosenName), host);
      if (sa.hasParam("ShowChoice")) {
        p.getGame()
            .getAction()
            .nofityOfValue(sa, p, abilities.get(idxChosen).getDescription(), null);
      }
      chosenSA.setActivatingPlayer(sa.getActivatingPlayer());
      ((AbilitySub) chosenSA).setParent(sa);
      AbilityUtils.resolve(chosenSA);
    }
  }
Exemple #5
0
  // NOTE: ART indices are "1" -based
  public void add(String cardName, String setCode, final int artIndex, final int amount) {
    PaperCard cp = StaticData.instance().getCommonCards().getCard(cardName, setCode, artIndex);
    boolean isCommonCard = cp != null;
    if (!isCommonCard) {
      cp = StaticData.instance().getVariantCards().getCard(cardName, setCode);
    }

    boolean artIndexExplicitlySet =
        artIndex > 0
            || Character.isDigit(cardName.charAt(cardName.length() - 1))
                && cardName.charAt(cardName.length() - 2) == CardDb.NameSetSeparator;
    int artCount = 1;

    if (cp != null) {
      setCode = cp.getEdition();
      cardName = cp.getName();
      artCount =
          isCommonCard ? StaticData.instance().getCommonCards().getArtCount(cardName, setCode) : 1;
    } else {
      cp = StaticData.instance().getCommonCards().createUnsuportedCard(cardName);
    }

    if (artIndexExplicitlySet || artCount <= 1) {
      // either a specific art index is specified, or there is only one art, so just add the card
      this.add(cp, amount);
    } else {
      // random art index specified, make sure we get different groups of cards with different art
      int[] artGroups = MyRandom.splitIntoRandomGroups(amount, artCount);
      for (int i = 1; i <= artGroups.length; i++) {
        int cnt = artGroups[i - 1];
        if (cnt <= 0) continue;
        PaperCard cp_random =
            isCommonCard
                ? StaticData.instance().getCommonCards().getCard(cardName, setCode, i)
                : StaticData.instance().getVariantCards().getCard(cardName, setCode, i);
        this.add(cp_random, cnt);
      }
    }
  }
Exemple #6
0
 /* (non-Javadoc)
  * @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility)
  */
 @Override
 protected boolean canPlayAI(Player ai, final SpellAbility sa) {
   Card object1 = null;
   Card object2 = null;
   final Card source = sa.getHostCard();
   final String type = sa.getParam("Type");
   if (sa.hasParam("Object")) {
     object1 = AbilityUtils.getDefinedCards(source, sa.getParam("Object"), sa).get(0);
   } else {
     object1 = source;
   }
   final ZoneType zone1 =
       sa.hasParam("Zone1") ? ZoneType.smartValueOf(sa.getParam("Zone1")) : ZoneType.Battlefield;
   final ZoneType zone2 =
       sa.hasParam("Zone2") ? ZoneType.smartValueOf(sa.getParam("Zone2")) : ZoneType.Hand;
   CardCollection list = new CardCollection(ai.getCardsIn(zone2));
   if (type != null) {
     list = CardLists.getValidCards(list, type, ai, source);
   }
   object2 = ComputerUtilCard.getBestAI(list);
   if (object1 == null
       || object2 == null
       || !object1.isInZone(zone1)
       || !object1.getOwner().equals(ai)) {
     return false;
   }
   if (type.equals("Aura")) {
     Card c = object1.getEnchantingCard();
     if (!c.canBeEnchantedBy(object2)) {
       return false;
     }
   }
   if (object2.getCMC() > object1.getCMC()) {
     return MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
   }
   return false;
 }
  /**
   * getLuckyCoinResult. A chance check, for rewards like random rares.
   *
   * @return boolean
   */
  private boolean getLuckyCoinResult() {
    final boolean hasCoin = qData.getAssets().getItemLevel(QuestItemType.LUCKY_COIN) >= 1;

    return MyRandom.getRandom().nextFloat() <= (hasCoin ? 0.65f : 0.5f);
  }
  /** awardBooster. Generates and displays booster pack win case. */
  private void awardBooster() {
    List<PaperCard> cardsWon;

    String title;
    if (qData.getFormat() == null) {

      final List<GameFormat> formats = new ArrayList<>();
      final String preferredFormat = FModel.getQuestPreferences().getPref(QPref.BOOSTER_FORMAT);

      GameFormat pref = null;
      for (final GameFormat f : FModel.getFormats().getOrderedList()) {
        formats.add(f);
        if (f.toString().equals(preferredFormat)) {
          pref = f;
        }
      }

      Collections.sort(formats);

      final GameFormat selected =
          SGuiChoose.getChoices("Choose bonus booster format", 1, 1, formats, pref, null).get(0);
      FModel.getQuestPreferences().setPref(QPref.BOOSTER_FORMAT, selected.toString());

      cardsWon = qData.getCards().generateQuestBooster(selected.getFilterPrinted());
      qData.getCards().addAllCards(cardsWon);

      title = "Bonus booster pack from the \"" + selected.getName() + "\" format!";

    } else {

      final List<String> sets = new ArrayList<>();

      for (final SealedProduct.Template bd : FModel.getMagicDb().getBoosters()) {
        if (bd != null && qData.getFormat().isSetLegal(bd.getEdition())) {
          sets.add(bd.getEdition());
        }
      }

      boolean customBooster = false;

      // No boosters found for current quest settings
      if (sets.isEmpty()) {
        customBooster = true;
        CardEdition.Collection editions = FModel.getMagicDb().getEditions();
        for (CardEdition edition : editions) {
          if (qData.getFormat().isSetLegal(edition.getCode())) {
            sets.add(edition.getCode());
          }
        }
      }

      int maxChoices = 1;
      if (wonMatch) {
        maxChoices++;
        final int wins = qData.getAchievements().getWin();
        if ((wins + 1) % 5 == 0) {
          maxChoices++;
        }
        if ((wins + 1) % 20 == 0) {
          maxChoices++;
        }
        if ((wins + 1) % 50 == 0) {
          maxChoices++;
        }
        maxChoices += qData.getAssets().getItemLevel(QuestItemType.MEMBERSHIP_TOKEN);
      }

      final List<CardEdition> options = new ArrayList<>();

      while (!sets.isEmpty() && maxChoices > 0) {
        final int ix = MyRandom.getRandom().nextInt(sets.size());
        final String set = sets.get(ix);
        sets.remove(ix);
        options.add(FModel.getMagicDb().getEditions().get(set));
        maxChoices--;
      }

      final CardEdition chooseEd = SGuiChoose.one("Choose bonus booster set", options);

      if (customBooster) {
        List<PaperCard> cards =
            FModel.getMagicDb()
                .getCommonCards()
                .getAllCards(Predicates.printedInSet(chooseEd.getCode()));
        final IUnOpenedProduct product = new UnOpenedProduct(getBoosterTemplate(), cards);
        cardsWon = product.get();
      } else {
        final IUnOpenedProduct product =
            new UnOpenedProduct(FModel.getMagicDb().getBoosters().get(chooseEd.getCode()));
        cardsWon = product.get();
      }

      qData.getCards().addAllCards(cardsWon);
      title = "Bonus " + chooseEd.getName() + " Booster Pack!";
    }

    if (cardsWon != null) {
      BoosterUtils.sort(cardsWon);
      view.showCards(title, cardsWon);
    }
  }
  public static DeckGroup generateSealedDeck(final boolean addBasicLands) {
    final String prompt = "Choose Sealed Deck Format";
    final LimitedPoolType poolType = SGuiChoose.oneOrNone(prompt, LimitedPoolType.values());
    if (poolType == null) {
      return null;
    }

    SealedCardPoolGenerator sd = new SealedCardPoolGenerator(poolType);
    if (sd.isEmpty()) {
      return null;
    }

    final CardPool humanPool = sd.getCardPool(true);
    if (humanPool == null) {
      return null;
    }

    // System.out.println(humanPool);

    // This seems to be limited by the MAX_DRAFT_PLAYERS constant
    // in DeckGroupSerializer.java. You could create more AI decks
    // but only the first seven would load. --BBU
    Integer rounds = SGuiChoose.getInteger("How many opponents are you willing to face?", 1, 7);
    if (rounds == null) {
      return null;
    }

    final String sDeckName =
        SOptionPane.showInputDialog(
            "Save this card pool as:", "Save Card Pool", FSkinProp.ICO_QUESTION);

    if (StringUtils.isBlank(sDeckName)) {
      return null;
    }

    final IStorage<DeckGroup> sealedDecks = FModel.getDecks().getSealed();
    if (sealedDecks.contains(sDeckName)) {
      if (!SOptionPane.showConfirmDialog(
          "'" + sDeckName + "' already exists. Do you want to replace it?",
          "Sealed Deck Game Exists")) {
        return null;
      }
      sealedDecks.delete(sDeckName);
    }

    final Deck deck = new Deck(sDeckName);
    deck.getOrCreate(DeckSection.Sideboard).addAll(humanPool);

    if (addBasicLands) {
      final int landsCount = 10;

      final boolean isZendikarSet =
          sd.getLandSetCode()
              .equals("ZEN"); // we want to generate one kind of Zendikar lands at a time only
      final boolean zendikarSetMode = MyRandom.getRandom().nextBoolean();

      for (final String element : MagicColor.Constant.BASIC_LANDS) {
        int numArt = FModel.getMagicDb().getCommonCards().getArtCount(element, sd.getLandSetCode());
        int minArtIndex = isZendikarSet ? (zendikarSetMode ? 1 : 5) : 1;
        int maxArtIndex = isZendikarSet ? minArtIndex + 3 : numArt;

        if (FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_ART_IN_POOLS)) {
          for (int i = minArtIndex; i <= maxArtIndex; i++) {
            deck.get(DeckSection.Sideboard)
                .add(element, sd.getLandSetCode(), i, numArt > 1 ? landsCount : 30);
          }
        } else {
          deck.get(DeckSection.Sideboard).add(element, sd.getLandSetCode(), 30);
        }
      }
    }

    final DeckGroup sealed = new DeckGroup(sDeckName);
    sealed.setHumanDeck(deck);
    for (int i = 0; i < rounds; i++) {
      // Generate other decks for next N opponents
      final CardPool aiPool = sd.getCardPool(false);
      if (aiPool == null) {
        return null;
      }

      sealed.addAiDeck(new SealedDeckBuilder(aiPool.toFlatList()).buildDeck());
    }

    // Rank the AI decks
    sealed.rankAiDecks(new SealedDeckComparer());

    FModel.getDecks().getSealed().add(sealed);
    return sealed;
  }