...
 
Commits (20)
......@@ -103,19 +103,17 @@ public class PaperToken implements InventoryItemFromSet, IPaperCard {
return StringUtils.join(build, "_").replace('*', 'x').toLowerCase();
}
public PaperToken(final CardRules c) { this(c, null, null); }
public PaperToken(final CardRules c, final String fileName) { this(c, null, fileName); }
public PaperToken(final CardRules c, CardEdition edition) { this(c, edition, null); }
public PaperToken(final CardRules c, CardEdition edition0, String imageFileName) {
this.card = c;
this.name = c.getName();
this.edition = edition0;
if (imageFileName == null) {
// This shouldn't really happen. We can just use the normalized name again for the base image name
this.imageFileName = makeTokenFileName(c, edition0);
} else {
String formatEdition = null == edition || CardEdition.UNKNOWN == edition ? "" : edition.getCode();
this.imageFileName = String.format("%s%s", formatEdition, imageFileName);
String formatEdition = null == edition || CardEdition.UNKNOWN == edition ? "" : "_" + edition.getCode().toLowerCase();
this.imageFileName = String.format("%s%s", imageFileName, formatEdition);
}
}
......
......@@ -2,7 +2,9 @@ package forge.token;
import com.google.common.base.Predicate;
import com.google.common.collect.Maps;
import forge.card.*;
import forge.card.CardDb;
import forge.card.CardEdition;
import forge.card.CardRules;
import forge.item.PaperToken;
import java.util.*;
......@@ -43,7 +45,7 @@ public class TokenDb implements ITokenDatabase {
if (!tokensByName.containsKey(fullName)) {
try {
PaperToken pt = new PaperToken(rulesByName.get(tokenName), editions.get(edition));
PaperToken pt = new PaperToken(rulesByName.get(tokenName), editions.get(edition), tokenName);
tokensByName.put(fullName, pt);
return pt;
} catch(Exception e) {
......
......@@ -240,39 +240,41 @@ public class DigEffect extends SpellAbilityEffect {
}
} else {
String prompt;
if (sa.hasParam("PrimaryPrompt")) {
prompt = sa.getParam("PrimaryPrompt");
} else {
prompt = "Choose card(s) to put into " + destZone1.name();
if (destZone1.equals(ZoneType.Library)) {
if (libraryPosition == -1) {
prompt = "Choose card(s) to put on the bottom of {player's} library";
} else if (libraryPosition == 0) {
prompt = "Choose card(s) to put on top of {player's} library";
}
}
}
movedCards = new CardCollection();
if (valid.isEmpty()) {
chooser.getController().notifyOfValue(sa, null, "No valid cards");
} else {
if ( p == chooser ) { // the digger can still see all the dug cards when choosing
chooser.getController().tempShowCards(top);
}
List<Card> chosen;
if (!andOrValid.equals("")) {
valid.removeAll(andOrCards); //pfps remove andOr cards to get two two choices set up correctly
chosen = chooser.getController().chooseFromTwoListsForEffect(valid, andOrCards, optional, delayedReveal, sa, prompt, p);
} else {
int max = anyNumber ? valid.size() : Math.min(valid.size(),destZone1ChangeNum);
int min = (anyNumber || optional) ? 0 : max;
chosen = chooser.getController().chooseEntitiesForEffect(valid, min, max, delayedReveal, sa, prompt, p);
}
chooser.getController().endTempShowCards();
movedCards.addAll(chosen);
}
if (sa.hasParam("PrimaryPrompt")) {
prompt = sa.getParam("PrimaryPrompt");
} else {
prompt = "Choose card(s) to put into " + destZone1.name();
if (destZone1.equals(ZoneType.Library)) {
if (libraryPosition == -1) {
prompt = "Choose card(s) to put on the bottom of {player's} library";
} else if (libraryPosition == 0) {
prompt = "Choose card(s) to put on top of {player's} library";
}
}
}
movedCards = new CardCollection();
if (valid.isEmpty()) {
chooser.getController().notifyOfValue(sa, null, "No valid cards");
} else {
if ( p == chooser ) { // the digger can still see all the dug cards when choosing
chooser.getController().tempShowCards(top);
}
List<Card> chosen = new ArrayList<Card>();
if (!andOrValid.equals("")) {
valid.removeAll(andOrCards); //pfps remove andOr cards to get two two choices set up correctly
chosen = chooser.getController().chooseFromTwoListsForEffect(valid, andOrCards, optional, delayedReveal, sa, prompt, p);
} else {
int max = anyNumber ? valid.size() : Math.min(valid.size(),destZone1ChangeNum);
int min = (anyNumber || optional) ? 0 : max;
if ( max > 0 ) { // if max is 0 don't make a choice
chosen = chooser.getController().chooseEntitiesForEffect(valid, min, max, delayedReveal, sa, prompt, p);
}
}
chooser.getController().endTempShowCards();
movedCards.addAll(chosen);
}
if (!changeValid.isEmpty() && !sa.hasParam("ExileFaceDown") && !sa.hasParam("NoReveal")) {
game.getAction().reveal(movedCards, chooser, true,
......@@ -336,8 +338,7 @@ public class DigEffect extends SpellAbilityEffect {
CardCollection afterOrder = rest;
if (sa.hasParam("RestRandomOrder")) {
CardLists.shuffle(afterOrder);
}
else if (!skipReorder && rest.size() > 1) {
} else if (!skipReorder && rest.size() > 1) {
if (destZone2 == ZoneType.Graveyard) {
afterOrder = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, rest, destZone2);
} else {
......
......@@ -510,6 +510,9 @@ public class WrappedAbility extends Ability {
|| ApiType.RemoveCounter.equals(sa.getApi())
|| ApiType.AddOrRemoveCounter.equals(sa.getApi())
|| ApiType.MoveCounter.equals(sa.getApi())
|| ApiType.Draw.equals(sa.getApi())
|| ApiType.GainLife.equals(sa.getApi())
|| ApiType.LoseLife.equals(sa.getApi())
// Token has no Defined it should not be timestamp problems
|| ApiType.Token.equals(sa.getApi())
......
......@@ -318,11 +318,11 @@ public class GridArchetype {
if (!colourWheels.containsKey(rc))
return algd;
for (GridTribe gt : colourWheels.get(rc).tribes){
if (gt.getRunCount() < 10)
continue;
//if (gt.getRunCount() < 10)
// continue;
algd.addAll(gt.bestDecks());
}
algd.sort(GridDeck.eloComparitor);
algd.sort(GridDeck.surviveEloComparitor);
return algd;
}
......
......@@ -512,24 +512,37 @@ public class GridBoOMatch extends HostedMatch {
public boolean awarded = false;
void awardMatch(){
GridDeck winner = null;
GridDeck loser = null;
if (awarded) return;
if ( gamePoints[0] > gamePoints[1] ) {
matchPoints[0] = 1;
matchPoints[1] = 0;
winner = players[0];
loser = players[1];
} else if ( gamePoints[0] < gamePoints[1] ) {
matchPoints[0] = 0;
matchPoints[1] = 1;
winner = players[1];
loser = players[0];
} else {
matchPoints[0] = 0;
matchPoints[1] = 0;
}
for (int x=0; x<players.length; x++){
if (players[x] == null) continue;
if (matchPoints[x]>0)
players[x].addBoOResult(true);
else
players[x].addBoOResult(false);
if (winner == null || loser == null){
players[0].addBoOResult(false);
players[1].addBoOResult(false);
} else {
winner.addBoOResult(true);
loser.addBoOResult(false);
if (loser.tribe.archetype.format.ordinal() >= winner.tribe.archetype.format.ordinal()){
if (loser.determineColour().contains(winner.determineColour())){
if (loser.superiorAwe == null || GridTourney.rand.nextInt(100)<60){
loser.superiorAwe = winner;
}
}
}
}
calcElo();
......@@ -567,8 +580,8 @@ public class GridBoOMatch extends HostedMatch {
}
adjusted[0] = k_value * (eloScore[0] - expected[0]);
adjusted[1] = k_value * (eloScore[1] - expected[1]);
adjusted[0] = ((Double) k_value) * (eloScore[0] - expected[0]);
adjusted[1] = ((Double) k_value) * (eloScore[1] - expected[1]);
players[0].addElo(adjusted[0]);
players[1].addElo(adjusted[1]);
......
......@@ -29,6 +29,8 @@ public class GridDeck {
public RenColour addColour = RenColour.Colourless;
private int tiebreak = ShivaUtility.rand.nextInt(100);
public Properties geneProperties = new Properties();
public Properties deckProperties = new Properties();
public Properties matchProperties = new Properties();
......@@ -43,6 +45,7 @@ public class GridDeck {
public GridTribe tribe;
private Deck deck;
public GridDeck superiorAwe = null; // a deck that beat this in similar colours
public int id;
public String getName(){
......@@ -261,8 +264,8 @@ public class GridDeck {
}
private double eloAdjust = 0;
public void addElo(double amt){
if (GridRound.skipNumber(id,tribe.tier()))
return;
//if (GridRound.skipNumber(id,tribe.tier()))
// return;
eloAdjust += amt;
tribe.addElo(amt/25.0);
}
......@@ -308,18 +311,24 @@ public class GridDeck {
return i;
}
public void addBoOResult(boolean win){
if (getBoOLosses() < 3){
if (BoODone() && win)
deckProperties.setProperty("BoOBreakers",(getBoOBreakers()+1)+"");
else {
if (win)
deckProperties.setProperty("BoOWins",(getBoOWins()+1)+"");
else
deckProperties.setProperty("BoOLosses",(getBoOLosses()+1)+"");
} else {
if (win)
deckProperties.setProperty("BoOBreakers",(getBoOBreakers()+1)+"");
}
setSave();
}
public boolean BoODone(){
if (getBoOWins() >= tribe.winCap() || getBoOLosses() >= tribe.lossCap())
return true;
return false;
}
public double getGamePerc(){
if (getGames() == 0) return 0;
return (double) getGamePoints()/(double) (getGames()*3);
......@@ -873,7 +882,22 @@ public class GridDeck {
//System.out.println("New");
while (countDeck(true) < 60) {
getNewCard(25, tribe.colour, rand.nextInt(100)<5);
if (rand.nextInt(100) != 42){
ArrayList<GridCard> potentials = new ArrayList<>();
for (GridCard gc : mainCards){
if (gc != null && gc.getCard() != null && gc.getCount()!=0 && gc.getCount()<4) {
if (gc.getCard().getRules().getType().isBasicLand() && rand.nextInt(100)<60)
continue;
potentials.add(gc);
}
}
if (potentials.size() > 0) {
GridCard gc = potentials.get(rand.nextInt(potentials.size()));
gc.setCount(gc.getCount()+1);
}
} else
getNewCard(25, tribe.colour, rand.nextInt(100)<5);
}
// System.out.println("Singles");
......@@ -981,6 +1005,8 @@ public class GridDeck {
return deck;
}
private void buildDeck(){
if (built)
return;
deck = new Deck(tribe.getViewName()+"\n");
PaperCard pc;
......@@ -1009,10 +1035,23 @@ public class GridDeck {
}
if (deck.get(DeckSection.Main).countAll() <60) {
//System.out.println(deck.get(DeckSection.Main).countAll() + " CARDS: " + tribe.getViewName() + " - " + id);
GridTourney.activeTourney.tokenAndQuit("Not enough cards", -43);
if (!buildLoop) {
if (countDeck(true) < 60) {
load();
if (countDeck(true) < 60)
fixCounts();
}
buildLoop = true;
buildDeck();
} else {
GridTourney.activeTourney.tokenAndQuit("Not enough cards: " + getName(), -43);
}
}
built = true;
}
boolean buildLoop = false;
public static Comparator<GridDeck> breedWorthyComparitor = new Comparator<GridDeck>() {
@Override
......@@ -1024,8 +1063,8 @@ public class GridDeck {
if ( o1.getGamePoints() < o2.getGamePoints() ) return 1;
if ( o1.getGamePoints() > o2.getGamePoints() ) return -1;
if ( o1.getElo() < o2.getElo() ) return 1;
if ( o1.getElo() > o2.getElo() ) return -1;
if ( o1.getElo() + o1.tiebreak < o2.getElo() + o2.tiebreak ) return 1;
if ( o1.getElo() + o1.tiebreak > o2.getElo() + o2.tiebreak ) return -1;
return 0;
}
......@@ -1043,8 +1082,8 @@ public class GridDeck {
if ( o1.getBoOBreakers() < o2.getBoOBreakers() ) return 1;
if ( o1.getBoOBreakers() > o2.getBoOBreakers() ) return -1;
if ( o1.getElo() < o2.getElo() ) return 1;
if ( o1.getElo() > o2.getElo() ) return -1;
if ( o1.getElo() + o1.tiebreak < o2.getElo() + o2.tiebreak ) return 1;
if ( o1.getElo() + o1.tiebreak > o2.getElo() + o2.tiebreak ) return -1;
return 0;
}
......@@ -1069,6 +1108,28 @@ public class GridDeck {
return 0;
}
};
public static Comparator<GridDeck> surviveEloComparitor = new Comparator<GridDeck>() {
@Override
public int compare(GridDeck o1, GridDeck o2) {
if (o1.surviveCount() < 3 && o2.surviveCount() > 3)
return 1;
else if (o1.surviveCount() > 3 && o2.surviveCount() < 3)
return -1;
else if (o1.surviveCount() < 3 && o2.surviveCount() < 3){
if ( o1.surviveCount() < o2.surviveCount() ) return 1;
if ( o1.surviveCount() > o2.surviveCount() ) return -1;
}
if ( o1.getElo() < o2.getElo() ) return 1;
if ( o1.getElo() > o2.getElo() ) return -1;
if ( o1.getElo() < o2.getElo() ) return 1;
if ( o1.getElo() > o2.getElo() ) return -1;
return 0;
}
};
public int getAvatar() {
return 21;
......@@ -1298,17 +1359,17 @@ public class GridDeck {
}
private GridDeck randomOverOption(){
Integer[] options = new Integer[]{1,1,2,2,2,3};
Integer[] options = new Integer[]{1,1,2,2,2,3,5};
if (tribe.archetype.isSeeded()) {
if (tribe.id == 0)
options = new Integer[]{4,4,4,4,2,2,3,3};
options = new Integer[]{4,4,4,4,2,2,3,3,5};
else
options = new Integer[]{4,4,1,2,2,2,3,3};
options = new Integer[]{4,4,1,2,2,2,3,3,5};
} else if (tribe.archetype.hasKeyword())
options = new Integer[]{1,1,1,2,2,2,2,3};
options = new Integer[]{1,1,1,2,2,2,2,3,5};
if (tribe.colour.equals(RenColour.Rainbow) && rand.nextInt(200)<50){
options = new Integer[]{2,2,2,1,3};
options = new Integer[]{2,2,2,1,3,5};
}
int selected = options[ShivaUtility.rand.nextInt(options.length)];
......@@ -1332,8 +1393,8 @@ public class GridDeck {
}
if (selected == 3){
//Higher rated tribe
if (tribe.getRunCount()<20)
return randomOverOption();
/*if (tribe.getRunCount()<20)
return randomOverOption();*/
for (GridTribe t: GridTribe.tribeList) {
if (t.getElo() > tribe.getElo())
candidates.add(t);
......@@ -1347,6 +1408,12 @@ public class GridDeck {
ret.createSeed();
return ret;
}
if (selected == 5){
if (superiorAwe == null)
return randomOverOption();
ret = superiorAwe;
return ret;
}
int rnd;
......@@ -1571,13 +1638,24 @@ public class GridDeck {
basics.add(gc);
}
}
if (landcount < 22 && basics.size() > 0) {
if (landcount < 24 && basics.size() > 0 && rand.nextInt(100)<60) {
GridCard gc = basics.get(rand.nextInt(basics.size()));
gc = new GridCard(gc.getCard(),1);
addCard(gc, true);
}
}
purge0();
if (rand.nextInt(100)<5) {
for (GridCard gc : mainCards) {
if (gc != null && gc.getCard() != null && !gc.getCard().getRules().getType().isBasicLand()) {
if (gc.getCount() < 4)
// trying to improve consistancy by increasing card counds rather than having a
// whole lot of 1 copy singletons.
gc.setCount(gc.getCount() + 1);
}
}
}
//purge0();
fixCounts();
setSaveGenes();
//GridUtilities.Log(" exit");
}
......
......@@ -780,7 +780,20 @@ public class GridSet {
"Hexproof","Haste","Flash","First Strike","Vigilance","Trample","Fight","Menace","Extra Turn",
"Search","Draw","Exile","LifeGain","Graveyard","Prowess","Skulk","Deathtouch","Discard","Sacrifice",
"Deathtouch","Wall","Copy","Land","Devil","Bat","Return","Enters","Defender","Sea","Undead","Fiendish","Elfball","Aether","Lifelink","Blocker",
"Colourless","Reanimator","Drain","Prevent","Dies","Battlefield","Freebies","Indestructible", "Abilities"};
"Colourless","Reanimator","Drain","Prevent","Dies","Battlefield","Freebies","Indestructible", "Abilities",
"Multicolor"};
String seed = themes[rand.nextInt(themes.length)];
checkThemeColours(seed);
}
if (canCreateNewArch()){
ArrayList<String> tt = new ArrayList<>();
for (RenColour rx : RenColour.values){
tt.add(rx+"");
}
themes = new String[tt.size()];
for (int i = 0; i < tt.size(); i++){
themes[i] = tt.get(i);
}
String seed = themes[rand.nextInt(themes.length)];
checkThemeColours(seed);
}
......
......@@ -23,7 +23,7 @@ public class GridTourney implements Runnable {
static Random rand = new Random();
public static final boolean viewGames = true;
public static ArchID forceArch = null;//new ArchID(GridFormat.Year, RenColour.Dimir, "Surveil");
public static ArchID forceArch = null;//new ArchID(GridFormat.Arena, RenColour.Simic, "Extra Turn");
public static GridFormat highestBase = GridFormat.Origin;
public static final boolean loadPreBase = false;//ShivaUtility.rand.nextBoolean();
public static final boolean loadDerp = false;// !viewGames;
......
......@@ -353,6 +353,13 @@ public class GridTribe {
if (getBestTrueElo() >= getRunCount() || getRunCount() <= 10)
skip = false;
// even with BestTrueElo some are really derpy
if (getElo() < 1000) {
if (getRunCount() > 3 && getBestTrueElo() != 0 && getElo() + getBestTrueElo() < 1000)
skip = true;
if (getRunCount() > 10 && getElo() + getBestTrueElo() < 1000 + getRunCount())
skip = true;
}
if (!GridTourney.loadPreBase && archetype.set.format.ordinal() > GridTourney.highestBase.ordinal())
skip = true;
......@@ -680,10 +687,10 @@ public class GridTribe {
}
public int winCap(){
return getElo() >= 1050 ? 7 : 5;
return getRecordElo() >= 1050 ? 7 : 5;
}
public int lossCap(){
return getElo() >= 1050 ? 3 : 2;
return getRecordElo() >= 1050 ? 3 : 2;
}
public int maxBoOWins(){
......@@ -900,6 +907,15 @@ public class GridTribe {
}
}
if (getRunCount() > 10 && getElo() > 1000) {
boolean foundSurvivor = false;
for (GridDeck gd : decks) {
if (gd.surviveCount() > 0)
foundSurvivor = true;
}
if (!foundSurvivor)
setRunCount(-1);
}
finishRun();
}
......@@ -982,11 +998,15 @@ public class GridTribe {
loadAllDecks();
ArrayList<GridDeck> ret = new ArrayList<>();
GridDeck gd;
for (int x = 0; x < decks.length; x++){
gd = decks[x];
if (gd == null || gd.surviveCount() <= 2 /*|| gd.surviveCount() > getRunCount()/2*/)
continue;
ret.add(gd);
for (int c = 3; c >= 1; c--) {
for (int x = 0; x < decks.length; x++) {
gd = decks[x];
if (gd == null || gd.surviveCount() < c /*|| gd.surviveCount() > getRunCount()/2*/)
continue;
ret.add(gd);
}
if (ret.size() > 0)
break;
}
ret.sort(GridDeck.adjustedEloComparitor);
......
......@@ -2,6 +2,6 @@ Name:Applied Biomancy
ManaCost:G U
Types:Instant
A:SP$ Charm | Cost$ G U | MinCharmNum$ 1 | CharmNum$ 2 | Choices$ DBPump,DBUnsummon
SVar:DBPump:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +1 | NumDef$ +1 | SpellDescription$ Target creature gets +1/+1 until end of turn.
SVar:DBUnsummon:DB$ ChangeZone | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target creature to its owner's hand.
SVar:DBPump:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature to get +1/+1 | NumAtt$ +1 | NumDef$ +1 | SpellDescription$ Target creature gets +1/+1 until end of turn.
SVar:DBUnsummon:DB$ ChangeZone | ValidTgts$ Creature | TgtPrompt$ Select target creature to return to owner's hand | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target creature to its owner's hand.
Oracle:Choose one or both —\n• Target creature gets +1/+1 until end of turn.\n• Return target creature to its owner's hand.
Name:Flames of the Raze-Boar
ManaCost:5 R
Types:Instant
A:SP$ DealDamage | Cost$ 5 R | NumDmg$ 4 | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | SubAbility$ DBDealDamage | SpellDescription$ CARDNAME deals 4 damage to target creature an opponent controls. Then CARDNAME deals 2 damage to each other creature that player controls if you control a creature with power 4 or greater.
SVar:DBDealDamage:DB$ DamageAll | NumDmg$ 2 | ValidCards$ Creature.ControlledBy TargetedOrController | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | References$ X| SubAbility$ DBCleanup
A:SP$ DealDamage | Cost$ 5 R | NumDmg$ 4 | ValidTgts$ Creature.OppCtrl | RememberTargets$ True | TgtPrompt$ Select target creature an opponent controls | SubAbility$ DBDealDamage | SpellDescription$ CARDNAME deals 4 damage to target creature an opponent controls. Then CARDNAME deals 2 damage to each other creature that player controls if you control a creature with power 4 or greater.
SVar:DBDealDamage:DB$ DamageAll | NumDmg$ 2 | ValidCards$ Creature.IsNotRemembered+ControlledBy TargetedOrController | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | References$ X| SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Count$Valid Creature.powerGE4+YouCtrl
Oracle:Flames of the Raze-Boar deals 4 damage to target creature an opponent controls. Then Flames of the Raze-Boar deals 2 damage to each other creature that player controls if you control a creature with power 4 or greater.
......@@ -2,8 +2,8 @@ Name:Lavinia, Azorius Renegade
ManaCost:W U
Types:Legendary Creature Human Soldier
PT:2/2
S:Mode$ CantBeCast | ValidCard$ Card.nonCreature+nonLand | Caster$ Opponent | Description$ Each opponent can't cast noncreature spells with converted mana cost greater than the number of lands that player controls.
SVar:RemRandomDeck:True
S:Mode$ CantBeCast | ValidCard$ Card.nonCreature+nonLand+cmcGTX | Caster$ Opponent | Description$ Each opponent can't cast noncreature spells with converted mana cost greater than the number of lands that player controls.
SVar:X:Count$Valid Land.OppCtrl
T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigCounter | ManaSpent$ EQ0 | TriggerDescription$ Whenever an opponent casts a spell, if no mana was spent to cast it, counter that spell.
SVar:TrigCounter:DB$ Counter | Defined$ TriggeredSpellAbility
SVar:RemRandomDeck:True
......
......@@ -2,6 +2,6 @@ Name:Swirling Torrent
ManaCost:5 U
Types:Sorcery
A:SP$ Charm | Cost$ 5 U | MinCharmNum$ 1 | CharmNum$ 2 | Choices$ DBSubmerge,DBUnsummon
SVar:DBSubmerge:DB$ ChangeZone | ValidTgts$ Creature | Origin$ Battlefield | Destination$ Library | LibraryPosition$ 0 | SpellDescription$ Put target creature on top of its owner's library.
SVar:DBUnsummon:DB$ ChangeZone | ValidTgts$ Creature | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target creature to its owner's hand.
SVar:DBSubmerge:DB$ ChangeZone | ValidTgts$ Creature | TgtPrompt$ Select target creature to put on top of owner's library | Origin$ Battlefield | Destination$ Library | LibraryPosition$ 0 | SpellDescription$ Put target creature on top of its owner's library.
SVar:DBUnsummon:DB$ ChangeZone | ValidTgts$ Creature | TgtPrompt$ Select target creature to return to owner's hand | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target creature to its owner's hand.
Oracle:Choose one or both —\n• Put target creature on top of its owner's library.\n• Return target creature to its owner's hand.
Name:Hornet
Name:Ragavan
ManaCost:no cost
Types:Artifact Creature Insect
Colors:colorless
PT:1/1
K:Flying
K:Haste
Oracle:Flying, Haste
| TokenName$ Hornet | TokenTypes$ Artifact,Creature,Insect | TokenOwner$ You | TokenColors$ Colorless | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying<>Haste
Types:Legendary Creature Monkey
Colors:red
PT:2/1
Oracle:
\ No newline at end of file
......@@ -614,5 +614,10 @@ public class QuestController {
model.currentDeck = s;
}
public DeckConstructionRules getDeckConstructionRules(){return model.deckConstructionRules;}
public DeckConstructionRules getDeckConstructionRules(){
if (model == null) {
return null;
}
return model.deckConstructionRules;
}
}