Merge remote-tracking branch 'upstream/master' into collector-number-in-card-list-and-card-db-refactoring

This commit is contained in:
leriomaggio
2021-07-21 17:32:02 +01:00
488 changed files with 2679 additions and 1017 deletions

View File

@@ -14,9 +14,9 @@ import forge.model.FModel;
public class CardThemedDeckGenerator extends DeckProxy implements Comparable<CardThemedDeckGenerator> {
public static List<DeckProxy> getMatrixDecks(GameFormat format, boolean isForAi){
final List<DeckProxy> decks = new ArrayList<>();
for(String card: CardArchetypeLDAGenerator.ldaPools.get(format.getName()).keySet()) {
for (String card: CardArchetypeLDAGenerator.ldaPools.get(format.getName()).keySet()) {
//exclude non AI playables as keycards for AI decks
if(isForAi&&FModel.getMagicDb().getCommonCards().getUniqueByName(card).getRules().getAiHints().getRemAIDecks()){
if (isForAi&&FModel.getMagicDb().getCommonCards().getUniqueByName(card).getRules().getAiHints().getRemAIDecks()) {
continue;
}
decks.add(new CardThemedDeckGenerator(card, format, isForAi));
@@ -42,7 +42,6 @@ public class CardThemedDeckGenerator extends DeckProxy implements Comparable<Car
return CardEdition.UNKNOWN;
}
@Override
public String getName() {
return name;

View File

@@ -189,17 +189,13 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
// to try and avoid adding purely random cards.
addThirdColorCards(numSpellsNeeded - deckList.size());
// 8. Check for DeckNeeds cards.
checkRemRandomDeckCards();
// 9. If there are still less than 22 non-land cards add off-color
// cards. This should be avoided.
addRandomCards(numSpellsNeeded - deckList.size());
// 10. Add non-basic lands that were drafted.
// 8. Add non-basic lands that were drafted.
addNonBasicLands();
// 11. Fill up with basic lands.
// 9. Check for DeckNeeds cards.
checkRemRandomDeckCards();
// 10. Fill up with basic lands.
final int[] clrCnts = calculateLandNeeds();
if (landsNeeded > 0) {
addLands(clrCnts, landSetCode);
@@ -352,33 +348,40 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
// total of all ClrCnts
int totalColor = 0;
int numColors = 0;
for (int i = 0; i < 5; i++) {
totalColor += clrCnts[i];
if (clrCnts[i] > 0) {
numColors++;
}
}
if (totalColor == 0) {
// TODO: Technically this can happen in a colorless deck.
throw new RuntimeException("Add Lands to empty deck list!");
}
// do not update landsNeeded until after the loop, because the
// calculation involves landsNeeded
// First, add 2 land of each required color. This prevents the AI from including
// a splash card with no viable way to cast it.
for (int i = 0; i < 5; i++) {
if (clrCnts[i] > 0) {
// calculate number of lands for each color
float p = (float) clrCnts[i] / (float) totalColor;
if (numColors == 2) {
// In the normal two-color case, constrain to within 40% and 60% so that the AI
// doesn't put too few lands of the lesser color, risking getting screwed on that color.
// Don't do this for the odd case where a third color had to be added to the deck.
p = Math.min(Math.max(p, 0.4f), 0.6f);
int nLand = 2;
System.out.printf("Basics[%s]: %d cards%n", MagicColor.Constant.BASIC_LANDS.get(i), nLand);
for (int j = 0; j < nLand; j++) {
deckList.add(getBasicLand(i, landSetCode));
}
int nLand = Math.round(landsNeeded * p); // desired truncation to int
}
}
for (int i = 0; i < 5; i++) {
int slotsRemaining = 40-deckList.size(); // How many to still distribute
if (clrCnts[i] > 0) {
// calculate proportion of mana symbols for each remaining color
float p = (float) clrCnts[i] / (float) totalColor;
// Rounding prefers WUBRG order, as a side effect.
int nLand = Math.round(slotsRemaining * p); // Round up/down
if (logToConsole) {
System.out.printf("Basics[%s]: %d/%d = %f%% = %d cards%n", MagicColor.Constant.BASIC_LANDS.get(i), clrCnts[i], totalColor, 100*p, nLand);
}
totalColor -= clrCnts[i];
// if appropriate snow-covered lands are available, add them
for (final PaperCard cp : basicLands) {
@@ -394,14 +397,6 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
}
}
// A common problem at this point is that p in the above loop was exactly 1/2,
// and nLand rounded up for both colors, so that one too many lands was added.
// So if the deck size is > 40, remove the last land added.
// Otherwise, the fixDeckSize() method would remove random cards.
while (deckList.size() > 40) {
deckList.remove(deckList.size() - 1);
}
deckList.addAll(snowLands);
aiPlayables.removeAll(snowLands);
}
@@ -505,7 +500,7 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
hasColor = Predicates.or(new DeckGeneratorBase.MatchColorIdentity(colors),
DeckGeneratorBase.COLORLESS_CARDS);
final Iterable<PaperCard> threeColorList = Iterables.filter(aiPlayables,
final Iterable<PaperCard> threeColorList = Iterables.filter(rankedOthers,
Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
for (final PaperCard card : threeColorList) {
if (num > 0) {
@@ -611,6 +606,8 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
availableList.add(card);
if (card.getRules().getType().isCreature()) {
numCreatures++;
} else if (card.getRules().getType().isLand()) {
// Do nothing, it will be replaced with basics later.
} else {
numOthers++;
}

View File

@@ -153,8 +153,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
setCurrentPlayer(Iterables.getFirst(gameControllers.keySet(), null));
}
}
}
else {
} else {
gameControllers.put(player, gameController);
}
}
@@ -270,7 +269,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
private final Set<CardView> selectableCards = Sets.newHashSet();
public void setSelectables(final Iterable<CardView> cards) {
for ( CardView cv : cards ) { selectableCards.add(cv); }
for (CardView cv : cards) { selectableCards.add(cv); }
}
public void clearSelectables() {
selectableCards.clear();
@@ -285,12 +284,12 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
public void setgamePause(boolean pause) { gamePause = pause; }
public void pauseMatch() {
IGameController controller = spectator;
if(controller != null && !isGamePaused())
if (controller != null && !isGamePaused())
controller.selectButtonOk();
}
public void resumeMatch() {
IGameController controller = spectator;
if(controller != null && isGamePaused())
if (controller != null && isGamePaused())
controller.selectButtonOk();
}
@@ -315,12 +314,10 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
// Concede each player on this Gui (except mind-controlled players)
c.concede();
}
}
else {
} else {
return false;
}
}
else {
} else {
return !ignoreConcedeChain;
}
if (gameView.isGameOver()) {

View File

@@ -392,8 +392,8 @@ public final class InputSelectTargets extends InputSyncronizedBase {
@Override
protected void onStop() {
getController().getGui().clearSelectables();
super.onStop();
getController().getGui().clearSelectables();
super.onStop();
}
}

View File

@@ -121,7 +121,7 @@ public class Puzzle extends GameState implements InventoryItem, Comparable<Puzzl
goalCard.setOwner(human);
goalCard.setImageKey("t:puzzle");
goalCard.setName("Puzzle Goal");
goalCard.addType("Effect");
goalCard.setImmutable(true);
goalCard.setOracleText(getGoalDescription());
int turnCorr = 0;

View File

@@ -200,8 +200,7 @@ public class CardDetailUtil {
if (ptText.length() > 0) {
ptText.insert(0, "P/T: ");
ptText.append(" - ").append("Loy: ");
}
else {
} else {
ptText.append("Loyalty: ");
}
@@ -221,7 +220,7 @@ public class CardDetailUtil {
String curColors = "";
// do not show current colors for temp effect cards, emblems and the like
if (state.getType().isEmblem() || state.getType().hasSubtype("Effect")) {
if (state.getCard().isImmutable()) {
return "";
}
@@ -275,16 +274,14 @@ public class CardDetailUtil {
// Token
if (card.isToken()) {
if(card.getCurrentState().getType().hasSubtype("Effect"))
area.append("Effect");
else if(card.getCurrentState().getType().isEmblem())
area.append("Emblem");
else
area.append("Token");
area.append("Token");
} else if (card.isTokenCard()) {
area.append("Token card");
} else if (card.isEmblem()) {
area.append("Emblem");
} else if (card.isImmutable()) {
area.append("Effect");
}
// card text
if (area.length() != 0) {
area.append("\n");
@@ -299,7 +296,6 @@ public class CardDetailUtil {
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null) :
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState().getName(), card.getRightSplitState().getName()) : null );
// LEVEL [0-9]+-[0-9]+
// LEVEL [0-9]+\+
@@ -575,7 +571,7 @@ public class CardDetailUtil {
if (area.length() != 0) {
area.append("\n");
}
area.append("Until leaves the Battlefield: ").append(card.getUntilLeavesBattlefield());
area.append("Exiled until this leaves the battlefield: ").append(card.getUntilLeavesBattlefield());
}
// must block

View File

@@ -72,7 +72,7 @@ public final class CardScriptInfo {
final String filename = name.toLowerCase().replaceAll("[^-a-z0-9\\s]","").replaceAll("[-\\s]","_").replaceAll("__","_") + ".txt";
String[] folders = { String.valueOf(filename.charAt(0)), "upcoming"};
for(String folder : folders){
for (String folder : folders) {
final File file = new File(ForgeConstants.CARD_DATA_DIR + folder + File.separator + filename);
if (file.exists()) {
script = new CardScriptInfo(FileUtil.readFileToString(file), file);

View File

@@ -104,7 +104,7 @@ public final class GamePlayerUtil {
final String oldPlayerName = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
String newPlayerName;
try{
try {
if (StringUtils.isBlank(oldPlayerName)) {
newPlayerName = getVerifiedPlayerName(getPlayerNameUsingFirstTimePrompt(), oldPlayerName);
} else {

View File

@@ -277,8 +277,6 @@ public class HumanCostDecision extends CostDecisionMakerBase {
return exileFromSame(cost, list, c, payableZone);
}
// Inputs
// Exile<Num/Type{/TypeDescription}>
@@ -482,6 +480,22 @@ public class HumanCostDecision extends CostDecisionMakerBase {
return PaymentDecision.number(c);
}
@Override
public PaymentDecision visit(final CostRollDice cost) {
final String amount = cost.getAmount();
Integer c = cost.convertAmount();
if (c == null) {
c = AbilityUtils.calculateAmount(source, amount, ability);
}
if (!player.getController().confirmPayment(cost, Localizer.getInstance().getMessage("lblDoYouWantRollNDiceAction", String.valueOf(c), "d" + cost.getType()), ability)) {
return null;
}
return PaymentDecision.number(c);
}
@Override
public PaymentDecision visit(final CostGainControl cost) {
final String amount = cost.getAmount();

View File

@@ -349,6 +349,18 @@ public class HumanPlay {
else
part.payAsDecided(p, pd, sourceAbility);
}
else if (part instanceof CostRollDice) {
if (!part.canPay(sourceAbility, p)) {
return false;
}
PaymentDecision pd = part.accept(hcd);
if (pd == null)
return false;
else
part.payAsDecided(p, pd, sourceAbility);
}
else if (part instanceof CostDamage) {
if (!part.canPay(sourceAbility, p)) {
return false;

View File

@@ -334,7 +334,6 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
String errMsg;
if (newMain.size() < deckMinSize) {
errMsg = TextUtil.concatNoSpace(localizer.getMessage("lblTooFewCardsMainDeck", String.valueOf(deckMinSize)));
} else {
errMsg = TextUtil.concatNoSpace(localizer.getMessage("lblTooManyCardsSideboard", String.valueOf(sbMax)));
}
@@ -1324,7 +1323,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
}
if (sa.hasParam("TokenScript")) {
sa.setActivatingPlayer(player);
Card protoType = TokenInfo.getProtoType(sa.getParam("TokenScript"), sa);
Card protoType = TokenInfo.getProtoType(sa.getParam("TokenScript"), sa, null);
for (String type : protoType.getType().getCreatureTypes()) {
Integer count = typesInDeck.get(type);
if (count == null) {
@@ -1340,7 +1339,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
if (sa != null) {
if (sa.hasParam("TokenScript")) {
sa.setActivatingPlayer(player);
Card protoType = TokenInfo.getProtoType(sa.getParam("TokenScript"), sa);
Card protoType = TokenInfo.getProtoType(sa.getParam("TokenScript"), sa, null);
for (String type : protoType.getType().getCreatureTypes()) {
Integer count = typesInDeck.get(type);
if (count == null) {