mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Merge pull request #1797 from Robbatog/evolving_wilds_world
Evolving wilds world
This commit is contained in:
@@ -137,22 +137,22 @@ public class GameFormat implements Comparable<GameFormat> {
|
|||||||
this.filterRules = this.buildFilterRules();
|
this.filterRules = this.buildFilterRules();
|
||||||
this.filterPrinted = this.buildFilterPrinted();
|
this.filterPrinted = this.buildFilterPrinted();
|
||||||
}
|
}
|
||||||
private Predicate<PaperCard> buildFilter(boolean printed) {
|
protected Predicate<PaperCard> buildFilter(boolean printed) {
|
||||||
Predicate<PaperCard> p = Predicates.not(IPaperCard.Predicates.names(this.bannedCardNames_ro));
|
Predicate<PaperCard> p = Predicates.not(IPaperCard.Predicates.names(this.getBannedCardNames()));
|
||||||
if (!this.allowedSetCodes_ro.isEmpty()) {
|
if (!this.getAllowedSetCodes().isEmpty()) {
|
||||||
p = Predicates.and(p, printed ?
|
p = Predicates.and(p, printed ?
|
||||||
IPaperCard.Predicates.printedInSets(this.allowedSetCodes_ro, printed) :
|
IPaperCard.Predicates.printedInSets(this.getAllowedSetCodes(), printed) :
|
||||||
StaticData.instance().getCommonCards().wasPrintedInSets(this.allowedSetCodes_ro));
|
StaticData.instance().getCommonCards().wasPrintedInSets(this.getAllowedSetCodes()));
|
||||||
}
|
}
|
||||||
if (!this.allowedRarities.isEmpty()) {
|
if (!this.getAllowedRarities().isEmpty()) {
|
||||||
List<Predicate<? super PaperCard>> crp = Lists.newArrayList();
|
List<Predicate<? super PaperCard>> crp = Lists.newArrayList();
|
||||||
for (CardRarity cr: this.allowedRarities) {
|
for (CardRarity cr: this.getAllowedRarities()) {
|
||||||
crp.add(StaticData.instance().getCommonCards().wasPrintedAtRarity(cr));
|
crp.add(StaticData.instance().getCommonCards().wasPrintedAtRarity(cr));
|
||||||
}
|
}
|
||||||
p = Predicates.and(p, Predicates.or(crp));
|
p = Predicates.and(p, Predicates.or(crp));
|
||||||
}
|
}
|
||||||
if (!this.additionalCardNames_ro.isEmpty()) {
|
if (!this.getAdditionalCards().isEmpty()) {
|
||||||
p = Predicates.or(p, IPaperCard.Predicates.names(this.additionalCardNames_ro));
|
p = Predicates.or(p, IPaperCard.Predicates.names(this.getAdditionalCards()));
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -241,7 +241,7 @@ public class GameFormat implements Comparable<GameFormat> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSetLegal(final String setCode) {
|
public boolean isSetLegal(final String setCode) {
|
||||||
return this.allowedSetCodes_ro.isEmpty() || this.allowedSetCodes_ro.contains(setCode);
|
return this.getAllowedSetCodes().isEmpty() || this.getAllowedSetCodes().contains(setCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPoolLegal(final CardPool allCards) {
|
private boolean isPoolLegal(final CardPool allCards) {
|
||||||
@@ -257,7 +257,7 @@ public class GameFormat implements Comparable<GameFormat> {
|
|||||||
{
|
{
|
||||||
final List<PaperCard> erroneousCI = new ArrayList<>();
|
final List<PaperCard> erroneousCI = new ArrayList<>();
|
||||||
for (Entry<PaperCard, Integer> poolEntry : allCards) {
|
for (Entry<PaperCard, Integer> poolEntry : allCards) {
|
||||||
if (!filterRules.apply(poolEntry.getKey())) {
|
if (!getFilterRules().apply(poolEntry.getKey())) {
|
||||||
erroneousCI.add(poolEntry.getKey());
|
erroneousCI.add(poolEntry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,12 +270,12 @@ public class GameFormat implements Comparable<GameFormat> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check number of restricted and legendary-restricted cards
|
// Check number of restricted and legendary-restricted cards
|
||||||
if(!restrictedCardNames_ro.isEmpty() || restrictedLegendary ) {
|
if(!getRestrictedCards().isEmpty() || isRestrictedLegendary() ) {
|
||||||
final List<PaperCard> erroneousRestricted = new ArrayList<>();
|
final List<PaperCard> erroneousRestricted = new ArrayList<>();
|
||||||
for (Entry<PaperCard, Integer> poolEntry : allCards) {
|
for (Entry<PaperCard, Integer> poolEntry : allCards) {
|
||||||
boolean isRestricted = restrictedCardNames_ro.contains(poolEntry.getKey().getName());
|
boolean isRestricted = getRestrictedCards().contains(poolEntry.getKey().getName());
|
||||||
boolean isLegendaryNonPlaneswalker = poolEntry.getKey().getRules().getType().isLegendary()
|
boolean isLegendaryNonPlaneswalker = poolEntry.getKey().getRules().getType().isLegendary()
|
||||||
&& !poolEntry.getKey().getRules().getType().isPlaneswalker() && restrictedLegendary;
|
&& !poolEntry.getKey().getRules().getType().isPlaneswalker() && isRestrictedLegendary();
|
||||||
if( poolEntry.getValue() > 1 && (isRestricted || isLegendaryNonPlaneswalker)) {
|
if( poolEntry.getValue() > 1 && (isRestricted || isLegendaryNonPlaneswalker)) {
|
||||||
erroneousRestricted.add(poolEntry.getKey());
|
erroneousRestricted.add(poolEntry.getKey());
|
||||||
}
|
}
|
||||||
@@ -558,6 +558,10 @@ public class GameFormat implements Comparable<GameFormat> {
|
|||||||
return this.map.get("Modern");
|
return this.map.get("Modern");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GameFormat getVintage() {
|
||||||
|
return this.map.get("Vintage");
|
||||||
|
}
|
||||||
|
|
||||||
public GameFormat getFormat(String format) {
|
public GameFormat getFormat(String format) {
|
||||||
return this.map.get(format);
|
return this.map.get(format);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ Name:Random Standard
|
|||||||
Name:Random Pioneer
|
Name:Random Pioneer
|
||||||
Name:Random Modern
|
Name:Random Modern
|
||||||
Name:Random Commander
|
Name:Random Commander
|
||||||
|
Name:Evolving Wilds
|
||||||
Name:Amonkhet|Dir:Amonkhet|Sets:AKH, HOU, AKR
|
Name:Amonkhet|Dir:Amonkhet|Sets:AKH, HOU, AKR
|
||||||
Name:Jamuraa|Dir:jamuraa|Sets:5ED, ARN, MIR, VIS, WTH
|
Name:Jamuraa|Dir:jamuraa|Sets:5ED, ARN, MIR, VIS, WTH
|
||||||
Name:Kamigawa|Dir:2004 Kamigawa|Sets:CHK, BOK, SOK
|
Name:Kamigawa|Dir:2004 Kamigawa|Sets:CHK, BOK, SOK
|
||||||
|
|||||||
@@ -561,7 +561,7 @@ public final class QuestUtilCards {
|
|||||||
* @return the predicate
|
* @return the predicate
|
||||||
*/
|
*/
|
||||||
public static Predicate<CardEdition> isLegalInQuestFormat(final GameFormatQuest qFormat) {
|
public static Predicate<CardEdition> isLegalInQuestFormat(final GameFormatQuest qFormat) {
|
||||||
return GameFormatQuest.Predicates.isLegalInFormatQuest(qFormat);
|
return GameFormatQuest.QPredicates.isLegalInFormatQuest(qFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,9 +26,12 @@ import java.util.Set;
|
|||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
import forge.card.CardEdition;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
import forge.gamemodes.quest.data.GameFormatQuest;
|
import forge.gamemodes.quest.data.GameFormatQuest;
|
||||||
|
import forge.gamemodes.quest.setrotation.ISetRotation;
|
||||||
|
import forge.gamemodes.quest.setrotation.QueueRandomRotation;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.util.storage.StorageReaderFile;
|
import forge.util.storage.StorageReaderFile;
|
||||||
@@ -46,6 +49,7 @@ public class QuestWorld implements Comparable<QuestWorld>{
|
|||||||
public static final String MODERNWORLDNAME = "Random Modern";
|
public static final String MODERNWORLDNAME = "Random Modern";
|
||||||
public static final String RANDOMCOMMANDERWORLDNAME = "Random Commander";
|
public static final String RANDOMCOMMANDERWORLDNAME = "Random Commander";
|
||||||
public static final String MAINWORLDNAME = "Main world";
|
public static final String MAINWORLDNAME = "Main world";
|
||||||
|
public static final String EVOLVINGWILDSWORLDNAME = "Evolving Wilds";
|
||||||
|
|
||||||
private boolean isCustom;
|
private boolean isCustom;
|
||||||
|
|
||||||
@@ -217,6 +221,20 @@ public class QuestWorld implements Comparable<QuestWorld>{
|
|||||||
FModel.getFormats().getFormat("Commander").getBannedCardNames(),false);
|
FModel.getFormats().getFormat("Commander").getBannedCardNames(),false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useName.equalsIgnoreCase(QuestWorld.EVOLVINGWILDSWORLDNAME)){
|
||||||
|
ISetRotation rot = new QueueRandomRotation(6, 5, 1);
|
||||||
|
List<String> allowedCodes = new ArrayList<>();
|
||||||
|
for (CardEdition edition : FModel.getMagicDb().getEditionsTypeMap().get(CardEdition.Type.CORE)) {
|
||||||
|
allowedCodes.add(edition.getCode());
|
||||||
|
}
|
||||||
|
for (CardEdition edition : FModel.getMagicDb().getEditionsTypeMap().get(CardEdition.Type.EXPANSION)) {
|
||||||
|
allowedCodes.add(edition.getCode());
|
||||||
|
}
|
||||||
|
useFormat = new GameFormatQuest(QuestWorld.EVOLVINGWILDSWORLDNAME,
|
||||||
|
allowedCodes,
|
||||||
|
FModel.getFormats().getVintage().getBannedCardNames(),false, rot);
|
||||||
|
}
|
||||||
|
|
||||||
// System.out.println("Creating quest world " + useName + " (index " + useIdx + ", dir: " + useDir);
|
// System.out.println("Creating quest world " + useName + " (index " + useIdx + ", dir: " + useDir);
|
||||||
// if (useFormat != null) { System.out.println("SETS: " + sets + "\nBANNED: " + bannedCards); }
|
// if (useFormat != null) { System.out.println("SETS: " + sets + "\nBANNED: " + bannedCards); }
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,10 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
|
import forge.gamemodes.quest.setrotation.ISetRotation;
|
||||||
|
import forge.item.PaperCard;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
|
|
||||||
|
|
||||||
@@ -38,6 +39,31 @@ public final class GameFormatQuest extends GameFormat {
|
|||||||
private final boolean allowUnlocks;
|
private final boolean allowUnlocks;
|
||||||
private int unlocksUsed = 0;
|
private int unlocksUsed = 0;
|
||||||
|
|
||||||
|
private ISetRotation setRotation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getAllowedSetCodes() {
|
||||||
|
if(setRotation != null)
|
||||||
|
return setRotation.getCurrentSetCodes(super.getAllowedSetCodes());
|
||||||
|
return super.getAllowedSetCodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Predicate<PaperCard> getFilterRules() {
|
||||||
|
// Filter must be continuously rebuilt if the format is mutable
|
||||||
|
if(setRotation != null)
|
||||||
|
return super.buildFilter(false);
|
||||||
|
return super.getFilterRules();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Predicate<PaperCard> getFilterPrinted() {
|
||||||
|
// Filter must be continuously rebuilt if the format is mutable
|
||||||
|
if(setRotation != null)
|
||||||
|
return super.buildFilter(true);
|
||||||
|
return super.getFilterRules();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new game format based on two lists.
|
* Instantiates a new game format based on two lists.
|
||||||
*
|
*
|
||||||
@@ -48,11 +74,27 @@ public final class GameFormatQuest extends GameFormat {
|
|||||||
public GameFormatQuest(final String newName, final List<String> setsToAllow, final List<String> cardsToBan) {
|
public GameFormatQuest(final String newName, final List<String> setsToAllow, final List<String> cardsToBan) {
|
||||||
super(newName, setsToAllow, cardsToBan);
|
super(newName, setsToAllow, cardsToBan);
|
||||||
allowUnlocks = false;
|
allowUnlocks = false;
|
||||||
|
setRotation = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameFormatQuest(final String newName, final List<String> setsToAllow, final List<String> cardsToBan, boolean allowSetUnlocks) {
|
public GameFormatQuest(final String newName, final List<String> setsToAllow, final List<String> cardsToBan, boolean allowSetUnlocks) {
|
||||||
super(newName, setsToAllow, cardsToBan);
|
super(newName, setsToAllow, cardsToBan);
|
||||||
allowUnlocks = allowSetUnlocks;
|
allowUnlocks = allowSetUnlocks;
|
||||||
|
setRotation = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a format that uses an ISetRotation to automatically rotate sets in and out
|
||||||
|
* @param newName
|
||||||
|
* @param setsToAllow
|
||||||
|
* @param cardsToBan
|
||||||
|
* @param allowSetUnlocks
|
||||||
|
* @param setRotation an ISetRotation that determines the currently allowed sets
|
||||||
|
*/
|
||||||
|
public GameFormatQuest(final String newName, final List<String> setsToAllow, final List<String> cardsToBan, boolean allowSetUnlocks, ISetRotation setRotation) {
|
||||||
|
super(newName, setsToAllow, cardsToBan);
|
||||||
|
allowUnlocks = allowSetUnlocks;
|
||||||
|
this.setRotation = setRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,12 +102,14 @@ public final class GameFormatQuest extends GameFormat {
|
|||||||
*
|
*
|
||||||
* @param toCopy an existing format
|
* @param toCopy an existing format
|
||||||
* @param allowSetUnlocks
|
* @param allowSetUnlocks
|
||||||
|
* @param setRotation
|
||||||
*/
|
*/
|
||||||
public GameFormatQuest(final GameFormat toCopy, boolean allowSetUnlocks) {
|
public GameFormatQuest(final GameFormat toCopy, boolean allowSetUnlocks, ISetRotation setRotation) {
|
||||||
super(toCopy.getName(), toCopy.getEffectiveDate(), toCopy.getAllowedSetCodes(), toCopy.getBannedCardNames(), toCopy.getRestrictedCards(),
|
super(toCopy.getName(), toCopy.getEffectiveDate(), toCopy.getAllowedSetCodes(), toCopy.getBannedCardNames(), toCopy.getRestrictedCards(),
|
||||||
toCopy.isRestrictedLegendary(),toCopy.getAdditionalCards(), toCopy.getAllowedRarities(),
|
toCopy.isRestrictedLegendary(),toCopy.getAdditionalCards(), toCopy.getAllowedRarities(),
|
||||||
toCopy.getIndex(), FormatType.CUSTOM, FormatSubType.CUSTOM);
|
toCopy.getIndex(), FormatType.CUSTOM, FormatSubType.CUSTOM);
|
||||||
allowUnlocks = allowSetUnlocks;
|
allowUnlocks = allowSetUnlocks;
|
||||||
|
this.setRotation = setRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,7 +162,7 @@ public final class GameFormatQuest extends GameFormat {
|
|||||||
return unlocksUsed;
|
return unlocksUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract static class Predicates {
|
public abstract static class QPredicates {
|
||||||
/**
|
/**
|
||||||
* Checks if is legal in quest format.
|
* Checks if is legal in quest format.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class QuestData {
|
|||||||
this.name = name0;
|
this.name = name0;
|
||||||
|
|
||||||
if (userFormat != null) {
|
if (userFormat != null) {
|
||||||
this.format = new GameFormatQuest(userFormat, allowSetUnlocks);
|
this.format = new GameFormatQuest(userFormat, allowSetUnlocks, null);
|
||||||
}
|
}
|
||||||
this.mode = mode0;
|
this.mode = mode0;
|
||||||
this.achievements = new QuestAchievements(diff);
|
this.achievements = new QuestAchievements(diff);
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package forge.gamemodes.quest.setrotation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supplies the current rotation of set codes based on the current quest state.
|
||||||
|
* Used for quest worlds that change their sets automatically over time.
|
||||||
|
*/
|
||||||
|
public interface ISetRotation {
|
||||||
|
public List<String> getCurrentSetCodes(List<String> allowedSetCodes);
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package forge.gamemodes.quest.setrotation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import forge.model.FModel;
|
||||||
|
|
||||||
|
import static java.lang.Integer.min;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A quest world rotation style where N random concurrent sets are available at any given time.
|
||||||
|
* S of these sets are rotated out after each set of W number of wins.
|
||||||
|
*/
|
||||||
|
public class QueueRandomRotation implements ISetRotation {
|
||||||
|
|
||||||
|
private int concurrentSets;
|
||||||
|
private int rotateAfterWins;
|
||||||
|
private int setsPerRotation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getCurrentSetCodes(List<String> allSets) {
|
||||||
|
if(FModel.getQuest() == null)
|
||||||
|
return allSets;
|
||||||
|
|
||||||
|
// Each unique quest (based on name) gets its own unique set order
|
||||||
|
int seed = FModel.getQuest().getName().hashCode();
|
||||||
|
Random rnd = new Random(seed);
|
||||||
|
List<String> shuffledSets = new ArrayList<>(allSets);
|
||||||
|
Collections.shuffle(shuffledSets, rnd);
|
||||||
|
|
||||||
|
List<String> currentCodes = new ArrayList<>();
|
||||||
|
int outRotations = FModel.getQuest().getAchievements().getWin() / rotateAfterWins;
|
||||||
|
int outRotated = outRotations * setsPerRotation;
|
||||||
|
int setsToAdd = min(concurrentSets, shuffledSets.size());
|
||||||
|
for (int i = 0; i < setsToAdd; i++) {
|
||||||
|
int setToAdd = (i + outRotated) % shuffledSets.size();
|
||||||
|
currentCodes.add(shuffledSets.get(setToAdd));
|
||||||
|
}
|
||||||
|
return currentCodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueueRandomRotation(int concurrentSets, int rotateAfterWins, int setsPerRotation){
|
||||||
|
this.concurrentSets = concurrentSets;
|
||||||
|
this.rotateAfterWins = rotateAfterWins;
|
||||||
|
this.setsPerRotation = setsPerRotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user