mirror of
https://github.com/correl/mage.git
synced 2025-01-12 19:25:44 +00:00
Merge pull request #1 from magefree/master
Updating master by merging their master
This commit is contained in:
commit
0da4e10c49
137 changed files with 3299 additions and 699 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,6 +4,7 @@ syntax: glob
|
|||
Mage.Client/*.dck
|
||||
Mage.Client/db
|
||||
Mage.Client/gamelogs
|
||||
Mage.Client/gamelogsJson
|
||||
Mage.Client/*.log
|
||||
Mage.Client/plugins/images
|
||||
Mage.Client/plugins/plugin.data
|
||||
|
@ -135,3 +136,4 @@ client_secrets.json
|
|||
|
||||
dependency-reduced-pom.xml
|
||||
mage-bundle
|
||||
/Mage.Client/game-*.json
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.mage</groupId>
|
||||
|
@ -15,6 +15,7 @@
|
|||
<name>Mage Client</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage</artifactId>
|
||||
|
@ -68,6 +69,11 @@
|
|||
<artifactId>jetlang</artifactId>
|
||||
<version>0.2.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk-s3</artifactId>
|
||||
<version>1.11.286</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jgoodies</groupId>
|
||||
<artifactId>forms</artifactId>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package mage.client;
|
||||
|
||||
import java.util.*;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.client.chat.LocalCommands;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.constants.ManaType;
|
||||
import mage.constants.PlayerAction;
|
||||
import mage.game.match.MatchOptions;
|
||||
|
@ -14,8 +16,6 @@ import mage.remote.Session;
|
|||
import mage.remote.SessionImpl;
|
||||
import mage.view.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by IGOUDT on 15-9-2016.
|
||||
*/
|
||||
|
@ -26,8 +26,9 @@ public final class SessionHandler {
|
|||
public static void startSession(MageFrame mageFrame) {
|
||||
|
||||
session = new SessionImpl(mageFrame);
|
||||
session.setJsonLogActive("true".equals(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_LOG_AUTO_SAVE, "true")));
|
||||
}
|
||||
|
||||
|
||||
public static void ping() {
|
||||
session.ping();
|
||||
}
|
||||
|
@ -322,7 +323,7 @@ public final class SessionHandler {
|
|||
}
|
||||
|
||||
public static void updateDeck(UUID tableId, DeckCardLists deckCardLists) {
|
||||
session.updateDeck(tableId, deckCardLists);
|
||||
session.updateDeck(tableId, deckCardLists);
|
||||
}
|
||||
|
||||
public static boolean emailAuthToken(Connection connection) {
|
||||
|
@ -330,10 +331,10 @@ public final class SessionHandler {
|
|||
}
|
||||
|
||||
public static boolean resetPassword(Connection connection) {
|
||||
return session.resetPassword(connection);
|
||||
return session.resetPassword(connection);
|
||||
}
|
||||
|
||||
public static boolean register(Connection connection) {
|
||||
return session.register(connection);
|
||||
return session.register(connection);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -853,7 +853,7 @@
|
|||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Unique"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Singleton rules."/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Show only the first found card of every card name."/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="4"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
|
@ -871,7 +871,6 @@
|
|||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkUniqueActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
|
||||
<Component class="javax.swing.JButton" name="jButtonSearch">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Search"/>
|
||||
|
|
|
@ -51,6 +51,10 @@ import mage.client.MageFrame;
|
|||
import mage.client.cards.*;
|
||||
import mage.client.constants.Constants.SortBy;
|
||||
import mage.client.deckeditor.table.TableModel;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_NAMES;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_RULES;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_TYPES;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_UNIQUE;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import mage.client.util.gui.FastSearchUtil;
|
||||
import mage.client.util.sets.ConstructedFormats;
|
||||
|
@ -144,9 +148,11 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
mainTable.setOpaque(false);
|
||||
cbSortBy.setEnabled(false);
|
||||
chkPiles.setEnabled(false);
|
||||
// chkNames.setEnabled(true);
|
||||
// chkTypes.setEnabled(true);
|
||||
// chkRules.setEnabled(true);
|
||||
|
||||
chkNames.setSelected("true".equals(MageFrame.getPreferences().get(KEY_DECK_EDITOR_SEARCH_NAMES, "true")));
|
||||
chkTypes.setSelected("true".equals(MageFrame.getPreferences().get(KEY_DECK_EDITOR_SEARCH_TYPES, "true")));
|
||||
chkRules.setSelected("true".equals(MageFrame.getPreferences().get(KEY_DECK_EDITOR_SEARCH_RULES, "true")));
|
||||
chkUnique.setSelected("true".equals(MageFrame.getPreferences().get(KEY_DECK_EDITOR_SEARCH_UNIQUE, "true")));
|
||||
|
||||
mainTable.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
|
@ -172,6 +178,10 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
public void cleanUp() {
|
||||
this.cardGrid.clear();
|
||||
this.mainModel.clear();
|
||||
MageFrame.getPreferences().put(KEY_DECK_EDITOR_SEARCH_NAMES, Boolean.toString(chkNames.isSelected()));
|
||||
MageFrame.getPreferences().put(KEY_DECK_EDITOR_SEARCH_RULES, Boolean.toString(chkRules.isSelected()));
|
||||
MageFrame.getPreferences().put(KEY_DECK_EDITOR_SEARCH_TYPES, Boolean.toString(chkTypes.isSelected()));
|
||||
MageFrame.getPreferences().put(KEY_DECK_EDITOR_SEARCH_UNIQUE, Boolean.toString(chkUnique.isSelected()));
|
||||
}
|
||||
|
||||
public void changeGUISize() {
|
||||
|
@ -413,12 +423,12 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
try {
|
||||
java.util.List<Card> filteredCards = new ArrayList<>();
|
||||
setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
||||
|
||||
|
||||
boolean chkPD = chkPennyDreadful.isSelected();
|
||||
if (chkPD) {
|
||||
generatePennyDreadfulHash();
|
||||
}
|
||||
|
||||
|
||||
if (limited) {
|
||||
for (Card card : cards) {
|
||||
if (filter.match(card, null)) {
|
||||
|
@ -1063,10 +1073,10 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
chkRulesActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
chkUnique.setSelected(true);
|
||||
chkUnique.setText("Unique");
|
||||
chkUnique.setToolTipText("Singleton results only.");
|
||||
chkUnique.setToolTipText("Show only the first found card of every card name.");
|
||||
chkUnique.setFocusable(false);
|
||||
chkUnique.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
|
||||
chkUnique.setMaximumSize(new java.awt.Dimension(69, 16));
|
||||
|
@ -1079,7 +1089,6 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
jButtonSearch.setText("Search");
|
||||
jButtonSearch.setToolTipText("Performs the search.");
|
||||
jButtonSearch.addActionListener(new java.awt.event.ActionListener() {
|
||||
|
@ -1126,7 +1135,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
.addComponent(chkTypes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chkRules, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGap(5, 5, 5)
|
||||
.addComponent(chkUnique, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(5, 5, 5)
|
||||
.addComponent(cardCountLabel)
|
||||
|
@ -1357,9 +1366,9 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_chkTypesActionPerformed
|
||||
|
||||
private void chkRulesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkRulesActionPerformed
|
||||
private void chkRulesActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_chkRulesActionPerformed
|
||||
}
|
||||
|
||||
private void chkUniqueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkRulesActionPerformed
|
||||
// TODO add your handling code here:
|
||||
|
@ -1442,8 +1451,8 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
private javax.swing.JCheckBox chkPennyDreadful;
|
||||
private javax.swing.JCheckBox chkPiles;
|
||||
private javax.swing.JCheckBox chkRules;
|
||||
private javax.swing.JCheckBox chkUnique;
|
||||
private javax.swing.JCheckBox chkTypes;
|
||||
private javax.swing.JCheckBox chkUnique;
|
||||
private javax.swing.JButton jButtonAddToMain;
|
||||
private javax.swing.JButton jButtonAddToSideboard;
|
||||
private javax.swing.JButton jButtonClean;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblMountain" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblForest" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
|
@ -40,31 +40,30 @@
|
|||
<Component id="lblSwamp" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="ckbFullArtLands" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="btnAutoAdd" pref="122" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="btnAutoAdd" alignment="0" pref="85" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="spnMountain" alignment="0" pref="85" max="32767" attributes="0"/>
|
||||
<Component id="spnIsland" alignment="0" pref="85" max="32767" attributes="0"/>
|
||||
<Component id="spnForest" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="spnSwamp" alignment="0" pref="85" max="32767" attributes="0"/>
|
||||
<Component id="spnPlains" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnAdd" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnCancel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="spnMountain" alignment="0" pref="85" max="32767" attributes="0"/>
|
||||
<Component id="spnIsland" alignment="0" pref="85" max="32767" attributes="0"/>
|
||||
<Component id="spnForest" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="spnSwamp" alignment="0" pref="85" max="32767" attributes="0"/>
|
||||
<Component id="spnPlains" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="panelSet" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -74,7 +73,7 @@
|
|||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblLandSet" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="panelSet" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="panelSet" min="-2" pref="23" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
|
@ -102,12 +101,13 @@
|
|||
<Component id="spnSwamp" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="ckbFullArtLands" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnAutoAdd" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnAdd" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnAutoAdd" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -238,5 +238,11 @@
|
|||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JCheckBox" name="ckbFullArtLands">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Only use full art lands"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="For example, lands from ZEN/UST/HOU"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
|
|
@ -36,6 +36,7 @@ import javax.swing.DefaultComboBoxModel;
|
|||
import javax.swing.JLayeredPane;
|
||||
import mage.Mana;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.FrameStyle;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.repository.CardCriteria;
|
||||
import mage.cards.repository.CardInfo;
|
||||
|
@ -134,7 +135,7 @@ public class AddLandDialog extends MageDialog {
|
|||
this.setVisible(true);
|
||||
}
|
||||
|
||||
private void addLands(String landName, int number) {
|
||||
private void addLands(String landName, int number, boolean useFullArt) {
|
||||
String landSetName = (String) cbLandSet.getSelectedItem();
|
||||
|
||||
CardCriteria criteria = new CardCriteria();
|
||||
|
@ -157,9 +158,28 @@ public class AddLandDialog extends MageDialog {
|
|||
cards = CardRepository.instance.findCards(criteria);
|
||||
}
|
||||
|
||||
for (int i = 0; i < number; i++) {
|
||||
int foundLands = 0;
|
||||
int foundNoneAfter = 0;
|
||||
for (int i = 0; foundLands != number && foundNoneAfter < 1000; i++) {
|
||||
Card land = cards.get(RandomUtil.nextInt(cards.size())).getMockCard();
|
||||
deck.getCards().add(land);
|
||||
boolean useLand = !useFullArt;
|
||||
if (useFullArt && (land.getFrameStyle() == FrameStyle.BFZ_FULL_ART_BASIC
|
||||
|| land.getFrameStyle() == FrameStyle.UGL_FULL_ART_BASIC
|
||||
|| land.getFrameStyle() == FrameStyle.UNH_FULL_ART_BASIC
|
||||
|| land.getFrameStyle() == FrameStyle.ZEN_FULL_ART_BASIC)) {
|
||||
useLand = true;
|
||||
}
|
||||
if (useLand) {
|
||||
deck.getCards().add(land);
|
||||
foundLands++;
|
||||
foundNoneAfter = 0;
|
||||
} else {
|
||||
foundNoneAfter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundNoneAfter >= 1000 && useFullArt) {
|
||||
MageFrame.getInstance().showMessage("Unable to add enough " + landName + "s. You encountered an error in adding chosen lands. Unable to find enough full art lands in the set " + landSetName + ".");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,6 +210,7 @@ public class AddLandDialog extends MageDialog {
|
|||
panelSet = new javax.swing.JPanel();
|
||||
cbLandSet = new javax.swing.JComboBox();
|
||||
btnSetFastSearch = new javax.swing.JButton();
|
||||
ckbFullArtLands = new javax.swing.JCheckBox();
|
||||
|
||||
jButton2.setText("jButton2");
|
||||
|
||||
|
@ -255,12 +276,15 @@ public class AddLandDialog extends MageDialog {
|
|||
});
|
||||
panelSet.add(btnSetFastSearch);
|
||||
|
||||
ckbFullArtLands.setText("Only use full art lands");
|
||||
ckbFullArtLands.setToolTipText("For example, lands from ZEN/UST/HOU");
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblMountain)
|
||||
.addComponent(lblForest, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
|
@ -269,25 +293,24 @@ public class AddLandDialog extends MageDialog {
|
|||
.addComponent(lblPains, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(lblSwamp, javax.swing.GroupLayout.Alignment.TRAILING))
|
||||
.addGap(18, 18, 18)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(ckbFullArtLands)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(btnAutoAdd, javax.swing.GroupLayout.DEFAULT_SIZE, 122, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addComponent(btnAutoAdd, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addComponent(spnMountain, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
|
||||
.addComponent(spnIsland, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
|
||||
.addComponent(spnForest, javax.swing.GroupLayout.Alignment.LEADING))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addComponent(spnSwamp, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
|
||||
.addComponent(spnPlains, javax.swing.GroupLayout.Alignment.LEADING))))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnAdd)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnCancel))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addComponent(spnMountain, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
|
||||
.addComponent(spnIsland, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
|
||||
.addComponent(spnForest, javax.swing.GroupLayout.Alignment.LEADING))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addComponent(spnSwamp, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
|
||||
.addComponent(spnPlains, javax.swing.GroupLayout.Alignment.LEADING)))
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addComponent(panelSet, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
.addComponent(panelSet, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
|
@ -295,7 +318,7 @@ public class AddLandDialog extends MageDialog {
|
|||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblLandSet)
|
||||
.addComponent(panelSet, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(panelSet, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblForest)
|
||||
|
@ -317,11 +340,12 @@ public class AddLandDialog extends MageDialog {
|
|||
.addComponent(lblSwamp)
|
||||
.addComponent(spnSwamp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(ckbFullArtLands)
|
||||
.addGap(2, 2, 2)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnAutoAdd)
|
||||
.addComponent(btnAdd)
|
||||
.addComponent(btnCancel)
|
||||
.addComponent(btnAutoAdd))
|
||||
.addContainerGap())
|
||||
.addComponent(btnCancel)))
|
||||
);
|
||||
|
||||
pack();
|
||||
|
@ -337,12 +361,13 @@ public class AddLandDialog extends MageDialog {
|
|||
int nMountain = ((Number) spnMountain.getValue()).intValue();
|
||||
int nPlains = ((Number) spnPlains.getValue()).intValue();
|
||||
int nSwamp = ((Number) spnSwamp.getValue()).intValue();
|
||||
boolean useFullArt = ckbFullArtLands.isSelected();
|
||||
|
||||
addLands("Forest", nForest);
|
||||
addLands("Island", nIsland);
|
||||
addLands("Mountain", nMountain);
|
||||
addLands("Plains", nPlains);
|
||||
addLands("Swamp", nSwamp);
|
||||
addLands("Forest", nForest, useFullArt);
|
||||
addLands("Island", nIsland, useFullArt);
|
||||
addLands("Mountain", nMountain, useFullArt);
|
||||
addLands("Plains", nPlains, useFullArt);
|
||||
addLands("Swamp", nSwamp, useFullArt);
|
||||
this.removeDialog();
|
||||
}//GEN-LAST:event_btnAddActionPerformed
|
||||
|
||||
|
@ -400,6 +425,7 @@ public class AddLandDialog extends MageDialog {
|
|||
private javax.swing.JButton btnCancel;
|
||||
private javax.swing.JButton btnSetFastSearch;
|
||||
private javax.swing.JComboBox cbLandSet;
|
||||
private javax.swing.JCheckBox ckbFullArtLands;
|
||||
private javax.swing.JButton jButton2;
|
||||
private javax.swing.JLabel lblForest;
|
||||
private javax.swing.JLabel lblIsland;
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
<Component id="lblFreeMulligans" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spnFreeMulligans" min="-2" pref="50" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chkSpectatorsAllowed" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="13" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="txtName" min="-2" pref="178" max="-2" attributes="0"/>
|
||||
|
@ -152,6 +155,7 @@
|
|||
<Component id="spnFreeMulligans" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblFreeMulligans" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="chkRollbackTurnsAllowed" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="chkSpectatorsAllowed" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="cbGameType" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
|
@ -274,6 +278,13 @@
|
|||
<Property name="toolTipText" type="java.lang.String" value="The number of mulligans a player can use without decreasing the number of drawn cards."/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkSpectatorsAllowed">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Spectators allowed"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Allow spectators to view your game."/>
|
||||
</Properties>
|
||||
</Component>
|
||||
|
||||
<Component class="javax.swing.JSpinner" name="spnFreeMulligans">
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblNumPlayers">
|
||||
|
|
|
@ -102,6 +102,7 @@ public class NewTableDialog extends MageDialog {
|
|||
lblGameType = new javax.swing.JLabel();
|
||||
cbGameType = new javax.swing.JComboBox();
|
||||
chkRollbackTurnsAllowed = new javax.swing.JCheckBox();
|
||||
chkSpectatorsAllowed = new javax.swing.JCheckBox();
|
||||
chkRated = new javax.swing.JCheckBox();
|
||||
lblFreeMulligans = new javax.swing.JLabel();
|
||||
spnFreeMulligans = new javax.swing.JSpinner();
|
||||
|
@ -151,6 +152,9 @@ public class NewTableDialog extends MageDialog {
|
|||
chkRollbackTurnsAllowed.setText("Allow rollbacks");
|
||||
chkRollbackTurnsAllowed.setToolTipText("<HTML>Allow to rollback to the start of previous turns<br>\nif all players agree.\n");
|
||||
|
||||
chkSpectatorsAllowed.setText("Allow Spectators");
|
||||
chkSpectatorsAllowed.setToolTipText("<HTML>Allow spectators to watch.\n");
|
||||
|
||||
chkRated.setText("Rated");
|
||||
chkRated.setToolTipText("Indicates if matches will be rated.");
|
||||
|
||||
|
@ -231,7 +235,9 @@ public class NewTableDialog extends MageDialog {
|
|||
.addGap(13, 13, 13)
|
||||
.addComponent(lblFreeMulligans)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(13, 13, 13)
|
||||
.addComponent(chkSpectatorsAllowed))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
|
@ -325,7 +331,8 @@ public class NewTableDialog extends MageDialog {
|
|||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblFreeMulligans)
|
||||
.addComponent(chkRollbackTurnsAllowed))
|
||||
.addComponent(chkRollbackTurnsAllowed)
|
||||
.addComponent(chkSpectatorsAllowed))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblGameType)))
|
||||
|
@ -401,6 +408,7 @@ public class NewTableDialog extends MageDialog {
|
|||
options.setRange((RangeOfInfluence) this.cbRange.getSelectedItem());
|
||||
options.setWinsNeeded((Integer) this.spnNumWins.getValue());
|
||||
options.setRollbackTurnsAllowed(chkRollbackTurnsAllowed.isSelected());
|
||||
options.setSpectatorsAllowed(chkSpectatorsAllowed.isSelected());
|
||||
options.setRated(chkRated.isSelected());
|
||||
options.setFreeMulligans((Integer) this.spnFreeMulligans.getValue());
|
||||
options.setPassword(this.txtPassword.getText());
|
||||
|
@ -658,6 +666,7 @@ public class NewTableDialog extends MageDialog {
|
|||
}
|
||||
this.spnNumWins.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_WINS + versionStr, "2")));
|
||||
this.chkRollbackTurnsAllowed.setSelected(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_ROLLBACK_TURNS_ALLOWED + versionStr, "Yes").equals("Yes"));
|
||||
this.chkSpectatorsAllowed.setSelected(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_SPECTATORS_ALLOWED + versionStr, "Yes").equals("Yes"));
|
||||
this.chkRated.setSelected(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_RATED + versionStr, "No").equals("Yes"));
|
||||
this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_FREE_MULLIGANS + versionStr, "0")));
|
||||
|
||||
|
@ -739,6 +748,7 @@ public class NewTableDialog extends MageDialog {
|
|||
private javax.swing.JComboBox cbSkillLevel;
|
||||
private javax.swing.JComboBox cbTimeLimit;
|
||||
private javax.swing.JCheckBox chkRollbackTurnsAllowed;
|
||||
private javax.swing.JCheckBox chkSpectatorsAllowed;
|
||||
private javax.swing.JCheckBox chkRated;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
|
|
|
@ -25,17 +25,18 @@
|
|||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="saveButton" min="-2" pref="100" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="exitButton" min="-2" pref="100" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="tabsPanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="saveButton" min="-2" pref="100" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="exitButton" min="-2" pref="100" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tabsPanel" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
|
@ -94,10 +95,10 @@
|
|||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="main_game" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="main_gamelog" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="main_gamelog" min="-2" pref="107" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="main_battlefield" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="154" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="121" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -121,9 +122,10 @@
|
|||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="cbDraftLogAutoSave" max="32767" attributes="0"/>
|
||||
<Component id="cbGameLogAutoSave" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="cbDraftLogAutoSave" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cbGameJsonLogAutoSave" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cbGameLogAutoSave" alignment="0" min="-2" pref="505" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
|
@ -134,7 +136,10 @@
|
|||
<Group type="102" attributes="0">
|
||||
<Component id="cbGameLogAutoSave" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cbDraftLogAutoSave" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cbDraftLogAutoSave" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cbGameJsonLogAutoSave" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -143,7 +148,7 @@
|
|||
<Component class="javax.swing.JCheckBox" name="cbGameLogAutoSave">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Auto save game logs (to "../Mage.Client/gamelogs/" directory)"/>
|
||||
<Property name="text" type="java.lang.String" value="Save game logs (to "../Mage.Client/gamelogs/" directory)"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="The logs of all your games will be saved to the mentioned folder if this option is switched on."/>
|
||||
</Properties>
|
||||
<Events>
|
||||
|
@ -153,13 +158,23 @@
|
|||
<Component class="javax.swing.JCheckBox" name="cbDraftLogAutoSave">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Auto save draft logs (to "../Mage.Client/gamelogs/" directory)"/>
|
||||
<Property name="text" type="java.lang.String" value="Save draft logs (to "../Mage.Client/gamelogs/" directory)"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="The logs of all your games will be saved to the mentioned folder if this option is switched on."/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbDraftLogAutoSaveActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="cbGameJsonLogAutoSave">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Save JSON game logs (to "../Mage.Client/gamelogsJson/" directory)"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="The JSON logs of all your games will be saved to the mentioned folder if this option is switched on."/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbGameJsonLogAutoSaveActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="main_card">
|
||||
|
@ -221,7 +236,7 @@
|
|||
<Property name="toolTipText" type="java.lang.String" value="Write the card's name on the card to make the card name more recognizable."/>
|
||||
<Property name="actionCommand" type="java.lang.String" value=""/>
|
||||
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
|
||||
<Color id="Default Cursor"/>
|
||||
<Color id="Standardcursor"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
|
@ -252,7 +267,7 @@
|
|||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Show the path Xmage is expecting for this card's image (only displays if missing)"/>
|
||||
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
|
||||
<Color id="Default Cursor"/>
|
||||
<Color id="Standardcursor"/>
|
||||
</Property>
|
||||
<Property name="label" type="java.lang.String" value="Display image path for missing images"/>
|
||||
</Properties>
|
||||
|
@ -289,7 +304,7 @@
|
|||
<Component id="cbAskMoveToGraveOrder" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="showAbilityPickerForced" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="255" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="177" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -4318,7 +4333,7 @@
|
|||
</Group>
|
||||
<Component id="cbUseDefaultImageFolder" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="270" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="308" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
|
@ -5743,7 +5758,7 @@
|
|||
<Component id="jLabel17" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="198" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="201" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -6008,7 +6023,7 @@
|
|||
<Component id="keyToggleRecordMacro" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="controlsDescriptionLabel" pref="441" max="32767" attributes="0"/>
|
||||
<Component id="controlsDescriptionLabel" pref="478" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
|
|
|
@ -65,12 +65,11 @@ import javax.swing.filechooser.FileFilter;
|
|||
import mage.client.MageFrame;
|
||||
import mage.client.SessionHandler;
|
||||
import mage.client.components.KeyBindButton;
|
||||
import static mage.client.constants.Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR;
|
||||
import mage.client.util.Config;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import mage.client.util.ImageHelper;
|
||||
import mage.client.util.gui.BufferedImageBuilder;
|
||||
|
||||
import static mage.client.constants.Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR;
|
||||
import static mage.constants.Constants.DEFAULT_AVATAR_ID;
|
||||
import static mage.constants.Constants.MAX_AVATAR_ID;
|
||||
import static mage.constants.Constants.MIN_AVATAR_ID;
|
||||
|
@ -79,6 +78,7 @@ import mage.players.net.UserGroup;
|
|||
import mage.players.net.UserSkipPrioritySteps;
|
||||
import mage.remote.Connection;
|
||||
import mage.remote.Connection.ProxyType;
|
||||
import mage.remote.Session;
|
||||
import mage.view.UserRequestMessage;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
@ -122,6 +122,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
|
||||
public static final String KEY_GAME_LOG_AUTO_SAVE = "gameLogAutoSave";
|
||||
public static final String KEY_DRAFT_LOG_AUTO_SAVE = "draftLogAutoSave";
|
||||
public static final String KEY_JSON_GAME_LOG_AUTO_SAVE = "gameLogJsonAutoSave";
|
||||
|
||||
public static final String KEY_CARD_IMAGES_USE_DEFAULT = "cardImagesUseDefault";
|
||||
public static final String KEY_CARD_IMAGES_PATH = "cardImagesPath";
|
||||
|
@ -191,6 +192,11 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
public static final String KEY_DECK_EDITOR_LAST_SORT = "deckEditorLastSort";
|
||||
public static final String KEY_DECK_EDITOR_LAST_SEPARATE_CREATURES = "deckEditorLastSeparateCreatures";
|
||||
|
||||
public static final String KEY_DECK_EDITOR_SEARCH_NAMES = "deckEditorSearchNames";
|
||||
public static final String KEY_DECK_EDITOR_SEARCH_TYPES = "deckEditorSearchTypes";
|
||||
public static final String KEY_DECK_EDITOR_SEARCH_RULES = "deckEditorSearchRules";
|
||||
public static final String KEY_DECK_EDITOR_SEARCH_UNIQUE = "deckEditorSearchUnique";
|
||||
|
||||
// positions of divider bars
|
||||
public static final String KEY_TABLES_DIVIDER_LOCATION_1 = "tablePanelDividerLocation1";
|
||||
public static final String KEY_TABLES_DIVIDER_LOCATION_2 = "tablePanelDividerLocation2";
|
||||
|
@ -229,6 +235,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
public static final String KEY_NEW_TABLE_GAME_TYPE = "newTableGameType";
|
||||
public static final String KEY_NEW_TABLE_NUMBER_OF_WINS = "newTableNumberOfWins";
|
||||
public static final String KEY_NEW_TABLE_ROLLBACK_TURNS_ALLOWED = "newTableRollbackTurnsAllowed";
|
||||
public static final String KEY_NEW_TABLE_SPECTATORS_ALLOWED = "newTableSpectatorsAllowed";
|
||||
public static final String KEY_NEW_TABLE_NUMBER_OF_FREE_MULLIGANS = "newTableNumberOfFreeMulligans";
|
||||
public static final String KEY_NEW_TABLE_DECK_FILE = "newTableDeckFile";
|
||||
public static final String KEY_NEW_TABLE_RANGE = "newTableRange";
|
||||
|
@ -405,6 +412,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
main_gamelog = new javax.swing.JPanel();
|
||||
cbGameLogAutoSave = new javax.swing.JCheckBox();
|
||||
cbDraftLogAutoSave = new javax.swing.JCheckBox();
|
||||
cbGameJsonLogAutoSave = new javax.swing.JCheckBox();
|
||||
main_card = new javax.swing.JPanel();
|
||||
showCardName = new javax.swing.JCheckBox();
|
||||
tooltipDelayLabel = new javax.swing.JLabel();
|
||||
|
@ -599,7 +607,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
main_gamelog.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Game log"));
|
||||
|
||||
cbGameLogAutoSave.setSelected(true);
|
||||
cbGameLogAutoSave.setText("Auto save game logs (to \"../Mage.Client/gamelogs/\" directory)");
|
||||
cbGameLogAutoSave.setText("Save game logs (to \"../Mage.Client/gamelogs/\" directory)");
|
||||
cbGameLogAutoSave.setToolTipText("The logs of all your games will be saved to the mentioned folder if this option is switched on.");
|
||||
cbGameLogAutoSave.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
|
@ -608,7 +616,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
});
|
||||
|
||||
cbDraftLogAutoSave.setSelected(true);
|
||||
cbDraftLogAutoSave.setText("Auto save draft logs (to \"../Mage.Client/gamelogs/\" directory)");
|
||||
cbDraftLogAutoSave.setText("Save draft logs (to \"../Mage.Client/gamelogs/\" directory)");
|
||||
cbDraftLogAutoSave.setToolTipText("The logs of all your games will be saved to the mentioned folder if this option is switched on.");
|
||||
cbDraftLogAutoSave.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
|
@ -616,15 +624,25 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
}
|
||||
});
|
||||
|
||||
cbGameJsonLogAutoSave.setSelected(true);
|
||||
cbGameJsonLogAutoSave.setText("Save JSON game logs (to \"../Mage.Client/gamelogsJson/\" directory)");
|
||||
cbGameJsonLogAutoSave.setToolTipText("The JSON logs of all your games will be saved to the mentioned folder if this option is switched on.");
|
||||
cbGameJsonLogAutoSave.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cbGameJsonLogAutoSaveActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.jdesktop.layout.GroupLayout main_gamelogLayout = new org.jdesktop.layout.GroupLayout(main_gamelog);
|
||||
main_gamelog.setLayout(main_gamelogLayout);
|
||||
main_gamelogLayout.setHorizontalGroup(
|
||||
main_gamelogLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(main_gamelogLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.add(main_gamelogLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
|
||||
.add(cbDraftLogAutoSave, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(cbGameLogAutoSave, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.add(main_gamelogLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(cbDraftLogAutoSave)
|
||||
.add(cbGameJsonLogAutoSave)
|
||||
.add(cbGameLogAutoSave, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 505, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
main_gamelogLayout.setVerticalGroup(
|
||||
|
@ -632,7 +650,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(main_gamelogLayout.createSequentialGroup()
|
||||
.add(cbGameLogAutoSave)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(cbDraftLogAutoSave))
|
||||
.add(cbDraftLogAutoSave)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(cbGameJsonLogAutoSave)
|
||||
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
main_card.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Card"));
|
||||
|
@ -784,7 +805,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(cbShowStormCounter, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(cbAskMoveToGraveOrder, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(showAbilityPickerForced, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap(255, Short.MAX_VALUE))
|
||||
.addContainerGap(177, Short.MAX_VALUE))
|
||||
);
|
||||
main_gameLayout.setVerticalGroup(
|
||||
main_gameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
|
@ -859,10 +880,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(main_game, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(main_gamelog, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.add(main_gamelog, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 107, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(main_battlefield, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(154, Short.MAX_VALUE))
|
||||
.addContainerGap(121, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
main_card.getAccessibleContext().setAccessibleName("Game panel");
|
||||
|
@ -1581,7 +1602,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(cbNumberOfDownloadThreads, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 153, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
|
||||
.add(cbUseDefaultImageFolder))
|
||||
.add(0, 270, Short.MAX_VALUE)))
|
||||
.add(0, 308, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
panelCardImagesLayout.setVerticalGroup(
|
||||
|
@ -2386,7 +2407,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(connection_serversLayout.createSequentialGroup()
|
||||
.add(141, 141, 141)
|
||||
.add(jLabel17)))
|
||||
.addContainerGap(198, Short.MAX_VALUE))
|
||||
.addContainerGap(201, Short.MAX_VALUE))
|
||||
);
|
||||
connection_serversLayout.setVerticalGroup(
|
||||
connection_serversLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
|
@ -2625,7 +2646,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(keyEndStep, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.add(keyToggleRecordMacro, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(controlsDescriptionLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 441, Short.MAX_VALUE)))
|
||||
.add(controlsDescriptionLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
tabControlsLayout.setVerticalGroup(
|
||||
|
@ -2707,16 +2728,16 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(saveButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 100, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(exitButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 100, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.add(6, 6, 6))
|
||||
.add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.add(tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
|
||||
.add(org.jdesktop.layout.GroupLayout.LEADING, tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(layout.createSequentialGroup()
|
||||
.add(0, 0, Short.MAX_VALUE)
|
||||
.add(saveButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 100, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(exitButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 100, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
|
||||
.add(6, 6, 6))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
|
@ -2748,6 +2769,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
save(prefs, dialog.cbAskMoveToGraveOrder, KEY_GAME_ASK_MOVE_TO_GRAVE_ORDER, "true", "false", UPDATE_CACHE_POLICY);
|
||||
save(prefs, dialog.cbGameLogAutoSave, KEY_GAME_LOG_AUTO_SAVE, "true", "false", UPDATE_CACHE_POLICY);
|
||||
save(prefs, dialog.cbDraftLogAutoSave, KEY_DRAFT_LOG_AUTO_SAVE, "true", "false", UPDATE_CACHE_POLICY);
|
||||
save(prefs, dialog.cbGameJsonLogAutoSave, KEY_JSON_GAME_LOG_AUTO_SAVE, "true", "false", UPDATE_CACHE_POLICY);
|
||||
|
||||
String paramName = KEY_BATTLEFIELD_FEEDBACK_COLORIZING_MODE;
|
||||
int paramValue = dialog.cbBattlefieldFeedbackColorizingMode.getSelectedIndex();
|
||||
|
@ -3193,9 +3215,16 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
}//GEN-LAST:event_showFullImagePathActionPerformed
|
||||
|
||||
private void cbBattlefieldFeedbackColorizingModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbBattlefieldFeedbackColorizingModeActionPerformed
|
||||
|
||||
|
||||
}//GEN-LAST:event_cbBattlefieldFeedbackColorizingModeActionPerformed
|
||||
|
||||
private void cbGameJsonLogAutoSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbGameJsonLogAutoSaveActionPerformed
|
||||
Session session = SessionHandler.getSession();
|
||||
if (session != null) {
|
||||
session.setJsonLogActive(cbGameJsonLogAutoSave.isSelected());
|
||||
}
|
||||
}//GEN-LAST:event_cbGameJsonLogAutoSaveActionPerformed
|
||||
|
||||
private void showProxySettings() {
|
||||
Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem();
|
||||
switch (proxyType) {
|
||||
|
@ -3310,6 +3339,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
|
||||
load(prefs, dialog.cbGameLogAutoSave, KEY_GAME_LOG_AUTO_SAVE, "true");
|
||||
load(prefs, dialog.cbDraftLogAutoSave, KEY_DRAFT_LOG_AUTO_SAVE, "true");
|
||||
load(prefs, dialog.cbGameJsonLogAutoSave, KEY_JSON_GAME_LOG_AUTO_SAVE, "true", "false");
|
||||
|
||||
String feedbackParam = "";
|
||||
try {
|
||||
|
@ -3864,6 +3894,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
private javax.swing.JCheckBox cbEnableGameSounds;
|
||||
private javax.swing.JCheckBox cbEnableOtherSounds;
|
||||
private javax.swing.JCheckBox cbEnableSkipButtonsSounds;
|
||||
private javax.swing.JCheckBox cbGameJsonLogAutoSave;
|
||||
private javax.swing.JCheckBox cbGameLogAutoSave;
|
||||
private javax.swing.JComboBox cbNumberOfDownloadThreads;
|
||||
private javax.swing.JCheckBox cbPassPriorityActivation;
|
||||
|
|
|
@ -47,6 +47,8 @@ import mage.client.util.audio.AudioManager;
|
|||
import mage.client.util.object.SaveObjectUtil;
|
||||
import mage.interfaces.callback.CallbackClient;
|
||||
import mage.interfaces.callback.ClientCallback;
|
||||
import mage.remote.ActionData;
|
||||
import mage.remote.Session;
|
||||
import mage.utils.CompressUtil;
|
||||
import mage.view.*;
|
||||
import mage.view.ChatMessage.MessageType;
|
||||
|
@ -102,7 +104,6 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
break;
|
||||
case CHATMESSAGE: {
|
||||
ChatMessage message = (ChatMessage) callback.getData();
|
||||
|
||||
// Drop messages from ignored users
|
||||
if (message.getUsername() != null && IgnoreList.IGNORED_MESSAGE_TYPES.contains(message.getMessageType())) {
|
||||
final String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> "");
|
||||
|
@ -183,6 +184,7 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
case GAME_INIT: {
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_INIT", callback.getObjectId(), (GameView) callback.getData());
|
||||
panel.init((GameView) callback.getData());
|
||||
}
|
||||
break;
|
||||
|
@ -190,6 +192,13 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
case GAME_OVER: {
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
Session session = SessionHandler.getSession();
|
||||
if (session.isJsonLogActive()) {
|
||||
appendJsonEvent("GAME_OVER", callback.getObjectId(), callback.getData());
|
||||
ActionData actionData = appendJsonEvent("GAME_OVER", callback.getObjectId(), callback.getData());
|
||||
String logFileName = "game-" + actionData.gameId + ".json";
|
||||
S3Uploader.upload(logFileName, actionData.gameId.toString());
|
||||
}
|
||||
panel.endMessage((String) callback.getData(), callback.getMessageId());
|
||||
}
|
||||
break;
|
||||
|
@ -201,6 +210,7 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_ASK", callback.getObjectId(), message);
|
||||
panel.ask(message.getMessage(), message.getGameView(), callback.getMessageId(), message.getOptions());
|
||||
}
|
||||
break;
|
||||
|
@ -208,8 +218,10 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
case GAME_TARGET: // e.g. Pick triggered ability
|
||||
{
|
||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_TARGET", callback.getObjectId(), message);
|
||||
panel.pickTarget(message.getMessage(), message.getCardsView(), message.getGameView(),
|
||||
message.getTargets(), message.isFlag(), message.getOptions(), callback.getMessageId());
|
||||
}
|
||||
|
@ -217,8 +229,10 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
}
|
||||
case GAME_SELECT: {
|
||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_SELECT", callback.getObjectId(), message);
|
||||
panel.select(message.getMessage(), message.getGameView(), callback.getMessageId(), message.getOptions());
|
||||
}
|
||||
break;
|
||||
|
@ -226,6 +240,7 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
case GAME_CHOOSE_ABILITY: {
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_CHOOSE_PILE", callback.getObjectId(), callback.getData());
|
||||
panel.pickAbility((AbilityPickerView) callback.getData());
|
||||
}
|
||||
break;
|
||||
|
@ -234,15 +249,18 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_CHOOSE_PILE", callback.getObjectId(), message);
|
||||
panel.pickPile(message.getMessage(), message.getPile1(), message.getPile2());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GAME_CHOOSE_CHOICE: {
|
||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_CHOOSE_CHOICE", callback.getObjectId(), message);
|
||||
panel.getChoice(message.getChoice(), callback.getObjectId());
|
||||
}
|
||||
break;
|
||||
|
@ -251,35 +269,45 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_PLAY_MANA", callback.getObjectId(), message);
|
||||
panel.playMana(message.getMessage(), message.getGameView(), message.getOptions(), callback.getMessageId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GAME_PLAY_XMANA: {
|
||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_PLAY_XMANA", callback.getObjectId(), message);
|
||||
panel.playXMana(message.getMessage(), message.getGameView(), callback.getMessageId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GAME_GET_AMOUNT: {
|
||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_GET_AMOUNT", callback.getObjectId(), message);
|
||||
|
||||
panel.getAmount(message.getMin(), message.getMax(), message.getMessage());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GAME_UPDATE: {
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_UPDATE", callback.getObjectId(), callback.getData());
|
||||
|
||||
panel.updateGame((GameView) callback.getData());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case END_GAME_INFO:
|
||||
MageFrame.getInstance().showGameEndDialog((GameEndView) callback.getData());
|
||||
|
||||
break;
|
||||
case SHOW_USERMESSAGE:
|
||||
List<String> messageData = (List<String>) callback.getData();
|
||||
|
@ -293,6 +321,7 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_INFORM", callback.getObjectId(), message);
|
||||
panel.inform(message.getMessage(), message.getGameView(), callback.getMessageId());
|
||||
}
|
||||
}
|
||||
|
@ -376,6 +405,17 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
});
|
||||
}
|
||||
|
||||
private ActionData appendJsonEvent(String name, UUID gameId, Object value) {
|
||||
Session session = SessionHandler.getSession();
|
||||
if (session.isJsonLogActive()) {
|
||||
ActionData actionData = new ActionData(name, gameId);
|
||||
actionData.value = value;
|
||||
session.appendJsonLog(actionData);
|
||||
return actionData;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void createChatStartMessage(ChatPanelBasic chatPanel) {
|
||||
chatPanel.setStartMessageDone(true);
|
||||
ChatPanelBasic usedPanel = chatPanel;
|
||||
|
|
45
Mage.Client/src/main/java/mage/client/remote/S3Uploader.java
Normal file
45
Mage.Client/src/main/java/mage/client/remote/S3Uploader.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package mage.client.remote;
|
||||
|
||||
import com.amazonaws.AmazonClientException;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.services.s3.transfer.TransferManager;
|
||||
import com.amazonaws.services.s3.transfer.Upload;
|
||||
import java.io.File;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
public class S3Uploader {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(S3Uploader.class);
|
||||
|
||||
public static Boolean upload(String filePath, String keyName) throws Exception {
|
||||
String existingBucketName = System.getenv("S3_BUCKET") != null ? System.getenv("S3_BUCKET")
|
||||
: "xmage-game-logs-dev";
|
||||
|
||||
String accessKeyId = System.getenv("AWS_ACCESS_ID");
|
||||
String secretKeyId = System.getenv("AWS_SECRET_KEY");
|
||||
|
||||
if (accessKeyId == null || "".equals(accessKeyId)
|
||||
|| secretKeyId == null || "".equals(secretKeyId)
|
||||
|| existingBucketName == null || "".equals(existingBucketName)) {
|
||||
logger.info("Aborting json log sync.");
|
||||
return false;
|
||||
}
|
||||
|
||||
String path = new File("./" + filePath).getCanonicalPath();
|
||||
logger.info("Syncing " + path + " to bucket: " + existingBucketName + " with AWS Access Id: " + accessKeyId);
|
||||
|
||||
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKeyId, secretKeyId);
|
||||
TransferManager tm = new TransferManager(awsCreds);
|
||||
Upload upload = tm.upload(existingBucketName, "/game/" + keyName + ".json", new File(path));
|
||||
|
||||
try {
|
||||
upload.waitForUploadResult();
|
||||
logger.info("Sync Complete For " + path + " to bucket: " + existingBucketName + " with AWS Access Id: " + accessKeyId);
|
||||
new File(path);
|
||||
return true;
|
||||
} catch (AmazonClientException amazonClientException) {
|
||||
logger.fatal("Unable to upload file, upload was aborted.", amazonClientException);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1444,11 +1444,14 @@ class TableTableModel extends AbstractTableModel {
|
|||
if (tables[arg0].isTournament()) {
|
||||
return "Show";
|
||||
} else {
|
||||
owner = tables[arg0].getControllerName();
|
||||
owner = tables[arg0].getControllerName();
|
||||
if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) {
|
||||
return "";
|
||||
}
|
||||
return "Watch";
|
||||
if (tables[arg0].getSpectatorsAllowed()) {
|
||||
return "Watch";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
package org.mage.card.arcane;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.FilteredImageSource;
|
||||
import java.awt.image.ImageProducer;
|
||||
|
@ -18,13 +26,18 @@ import java.nio.file.Paths;
|
|||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
|
||||
import mage.cards.repository.ExpansionRepository;
|
||||
import mage.client.constants.Constants;
|
||||
import mage.client.constants.Constants.ResourceSetSize;
|
||||
import mage.client.constants.Constants.ResourceSymbolSize;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import mage.client.util.ImageHelper;
|
||||
import mage.client.util.gui.BufferedImageBuilder;
|
||||
|
@ -36,13 +49,6 @@ import org.apache.batik.transcoder.TranscodingHints;
|
|||
import org.apache.batik.transcoder.image.ImageTranscoder;
|
||||
import org.apache.batik.util.SVGConstants;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import mage.client.constants.Constants;
|
||||
import mage.client.constants.Constants.ResourceSymbolSize;
|
||||
import mage.client.constants.Constants.ResourceSetSize;
|
||||
|
||||
import org.jdesktop.swingx.graphics.ShadowRenderer;
|
||||
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
public final class ManaSymbols {
|
||||
|
@ -71,9 +77,14 @@ public final class ManaSymbols {
|
|||
private static final Map<String, Dimension> setImagesExist = new HashMap<>();
|
||||
private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}");
|
||||
private static String cachedPath;
|
||||
private static final String[] symbols = new String[]{"0", "1", "10", "11", "12", "15", "16", "2", "3", "4", "5", "6", "7", "8", "9", "B", "BG",
|
||||
"BR", "G", "GU", "GW", "R", "RG", "RW", "S", "T", "U", "UB", "UR", "W", "WB", "WU",
|
||||
"WP", "UP", "BP", "RP", "GP", "X", "C", "E"};
|
||||
private static final String[] symbols = new String[]{"0", "1", "10", "11", "12", "15", "16", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"B", "BG", "BR", "BP", "2B",
|
||||
"G", "GU", "GW", "GP", "2G",
|
||||
"R", "RG", "RW", "RP", "2R",
|
||||
"S", "T",
|
||||
"U", "UB", "UR", "UP", "2U",
|
||||
"W", "WB", "WU", "WP", "2W",
|
||||
"X", "C", "E"};
|
||||
|
||||
private static final JLabel labelRender = new JLabel(); // render mana text
|
||||
|
||||
|
@ -93,22 +104,21 @@ public final class ManaSymbols {
|
|||
// save symbol images in png for html replacement in texts
|
||||
// you can add bigger size for better quality
|
||||
Map<String, BufferedImage> pngImages = manaImages.get(50);
|
||||
if (pngImages != null){
|
||||
if (pngImages != null) {
|
||||
|
||||
File pngPath = new File(getResourceSymbolsPath(ResourceSymbolSize.PNG));
|
||||
if (!pngPath.exists()) {
|
||||
pngPath.mkdirs();
|
||||
}
|
||||
|
||||
for(String symbol: symbols){
|
||||
try
|
||||
{
|
||||
for (String symbol : symbols) {
|
||||
try {
|
||||
BufferedImage image = pngImages.get(symbol);
|
||||
if (image != null){
|
||||
if (image != null) {
|
||||
File newFile = new File(pngPath.getPath() + File.separator + symbol + ".png");
|
||||
ImageIO.write(image, "png", newFile);
|
||||
}
|
||||
}catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Can't generate png image for symbol:" + symbol);
|
||||
}
|
||||
}
|
||||
|
@ -222,8 +232,7 @@ public final class ManaSymbols {
|
|||
// load SVG image
|
||||
// base loader code: https://stackoverflow.com/questions/11435671/how-to-get-a-buffererimage-from-a-svg
|
||||
// resize code: https://vibranttechie.wordpress.com/2015/05/15/svg-loading-to-javafx-stage-and-auto-scaling-when-stage-resize/
|
||||
|
||||
if (useShadow && ((resizeToWidth <= 0) || (resizeToHeight <= 0))){
|
||||
if (useShadow && ((resizeToWidth <= 0) || (resizeToHeight <= 0))) {
|
||||
throw new IllegalArgumentException("Must use non zero sizes for shadow.");
|
||||
}
|
||||
|
||||
|
@ -234,12 +243,12 @@ public final class ManaSymbols {
|
|||
// These defaults emphasize quality and precision, and
|
||||
// are more similar to the defaults of other SVG viewers.
|
||||
// SVG documents can still override these defaults.
|
||||
String css = "svg {" +
|
||||
"shape-rendering: geometricPrecision;" +
|
||||
"text-rendering: geometricPrecision;" +
|
||||
"color-rendering: optimizeQuality;" +
|
||||
"image-rendering: optimizeQuality;" +
|
||||
"}";
|
||||
String css = "svg {"
|
||||
+ "shape-rendering: geometricPrecision;"
|
||||
+ "text-rendering: geometricPrecision;"
|
||||
+ "color-rendering: optimizeQuality;"
|
||||
+ "image-rendering: optimizeQuality;"
|
||||
+ "}";
|
||||
File cssFile = File.createTempFile("batik-default-override-", ".css");
|
||||
FileWriter w = new FileWriter(cssFile);
|
||||
w.write(css);
|
||||
|
@ -250,7 +259,7 @@ public final class ManaSymbols {
|
|||
// resize
|
||||
int shadowX = 0;
|
||||
int shadowY = 0;
|
||||
if(useShadow) {
|
||||
if (useShadow) {
|
||||
// shadow size (16px image: 1px left, 2px bottom)
|
||||
shadowX = 1 * Math.round(1f / 16f * resizeToWidth);
|
||||
shadowY = 2 * Math.round(1f / 16f * resizeToHeight);
|
||||
|
@ -258,11 +267,11 @@ public final class ManaSymbols {
|
|||
resizeToHeight = resizeToHeight - shadowY;
|
||||
};
|
||||
|
||||
if(resizeToWidth > 0){
|
||||
transcoderHints.put(ImageTranscoder.KEY_WIDTH, (float)resizeToWidth); //your image width
|
||||
if (resizeToWidth > 0) {
|
||||
transcoderHints.put(ImageTranscoder.KEY_WIDTH, (float) resizeToWidth); //your image width
|
||||
}
|
||||
if(resizeToHeight > 0){
|
||||
transcoderHints.put(ImageTranscoder.KEY_HEIGHT, (float)resizeToHeight); //your image height
|
||||
if (resizeToHeight > 0) {
|
||||
transcoderHints.put(ImageTranscoder.KEY_HEIGHT, (float) resizeToHeight); //your image height
|
||||
}
|
||||
|
||||
transcoderHints.put(ImageTranscoder.KEY_XML_PARSER_VALIDATING, Boolean.FALSE);
|
||||
|
@ -293,14 +302,13 @@ public final class ManaSymbols {
|
|||
t.transcode(input, null);
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Couldn't convert svg file: " + svgFile + " , reason: " + e.getMessage());
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
cssFile.delete();
|
||||
}
|
||||
|
||||
BufferedImage originImage = imagePointer[0];
|
||||
|
||||
if(useShadow && (originImage.getWidth() > 0)){
|
||||
if (useShadow && (originImage.getWidth() > 0)) {
|
||||
// draw shadow
|
||||
// origin image was reduces in sizes to fit shadow
|
||||
// see https://stackoverflow.com/a/40833715/1276632
|
||||
|
@ -309,10 +317,11 @@ public final class ManaSymbols {
|
|||
ImageProducer prod = new FilteredImageSource(originImage.getSource(), new RGBImageFilter() {
|
||||
@Override
|
||||
public int filterRGB(int x, int y, int rgb) {
|
||||
if (rgb == 0)
|
||||
if (rgb == 0) {
|
||||
return 0;
|
||||
else
|
||||
} else {
|
||||
return 0xff000000;
|
||||
}
|
||||
}
|
||||
});
|
||||
// create whe black image
|
||||
|
@ -325,7 +334,7 @@ public final class ManaSymbols {
|
|||
// draw original image
|
||||
g.drawImage(originImage, 0, 0, null);
|
||||
return result;
|
||||
}else{
|
||||
} else {
|
||||
// return origin image without shadow
|
||||
return originImage;
|
||||
}
|
||||
|
@ -340,23 +349,22 @@ public final class ManaSymbols {
|
|||
ShadowRenderer renderer = new ShadowRenderer(shadowSize, 0.5f,
|
||||
Color.GRAY);
|
||||
return renderer.createShadow(base);
|
||||
*/
|
||||
|
||||
*/
|
||||
//imagePointer[0];
|
||||
}
|
||||
|
||||
public static File getSymbolFileNameAsSVG(String symbol){
|
||||
public static File getSymbolFileNameAsSVG(String symbol) {
|
||||
return new File(getResourceSymbolsPath(ResourceSymbolSize.SVG) + symbol + ".svg");
|
||||
}
|
||||
|
||||
private static BufferedImage loadSymbolAsSVG(String symbol, int resizeToWidth, int resizeToHeight){
|
||||
private static BufferedImage loadSymbolAsSVG(String symbol, int resizeToWidth, int resizeToHeight) {
|
||||
|
||||
File sourceFile = getSymbolFileNameAsSVG(symbol);
|
||||
return loadSymbolAsSVG(sourceFile, resizeToWidth, resizeToHeight);
|
||||
}
|
||||
|
||||
private static BufferedImage loadSymbolAsSVG(File sourceFile, int resizeToWidth, int resizeToHeight){
|
||||
try{
|
||||
private static BufferedImage loadSymbolAsSVG(File sourceFile, int resizeToWidth, int resizeToHeight) {
|
||||
try {
|
||||
// no need to resize svg (lib already do it on load)
|
||||
return loadSVG(sourceFile, resizeToWidth, resizeToHeight, true);
|
||||
|
||||
|
@ -366,12 +374,12 @@ public final class ManaSymbols {
|
|||
}
|
||||
}
|
||||
|
||||
private static File getSymbolFileNameAsGIF(String symbol, int size){
|
||||
private static File getSymbolFileNameAsGIF(String symbol, int size) {
|
||||
|
||||
ResourceSymbolSize needSize = null;
|
||||
if (size <= 15){
|
||||
if (size <= 15) {
|
||||
needSize = ResourceSymbolSize.SMALL;
|
||||
}else if (size <= 25){
|
||||
} else if (size <= 25) {
|
||||
needSize = ResourceSymbolSize.MEDIUM;
|
||||
} else {
|
||||
needSize = ResourceSymbolSize.LARGE;
|
||||
|
@ -380,20 +388,20 @@ public final class ManaSymbols {
|
|||
return new File(getResourceSymbolsPath(needSize) + symbol + ".gif");
|
||||
}
|
||||
|
||||
private static BufferedImage loadSymbolAsGIF(String symbol, int resizeToWidth, int resizeToHeight){
|
||||
private static BufferedImage loadSymbolAsGIF(String symbol, int resizeToWidth, int resizeToHeight) {
|
||||
File file = getSymbolFileNameAsGIF(symbol, resizeToWidth);
|
||||
return loadSymbolAsGIF(file, resizeToWidth, resizeToHeight);
|
||||
}
|
||||
|
||||
private static BufferedImage loadSymbolAsGIF(File sourceFile, int resizeToWidth, int resizeToHeight){
|
||||
private static BufferedImage loadSymbolAsGIF(File sourceFile, int resizeToWidth, int resizeToHeight) {
|
||||
|
||||
BufferedImage image = null;
|
||||
|
||||
try {
|
||||
if ((resizeToWidth == 15) || (resizeToWidth == 25)){
|
||||
if ((resizeToWidth == 15) || (resizeToWidth == 25)) {
|
||||
// normal size
|
||||
image = ImageIO.read(sourceFile);
|
||||
}else{
|
||||
} else {
|
||||
// resize size
|
||||
image = ImageIO.read(sourceFile);
|
||||
|
||||
|
@ -407,7 +415,7 @@ public final class ManaSymbols {
|
|||
return null;
|
||||
}
|
||||
|
||||
return image;
|
||||
return image;
|
||||
}
|
||||
|
||||
private static boolean loadSymbolImages(int size) {
|
||||
|
@ -454,7 +462,7 @@ public final class ManaSymbols {
|
|||
|
||||
private static void renameSymbols(String path) {
|
||||
File file = new File(path);
|
||||
if (!file.exists()){
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -475,7 +483,7 @@ public final class ManaSymbols {
|
|||
}
|
||||
}
|
||||
|
||||
private static String getResourceSymbolsPath(ResourceSymbolSize needSize){
|
||||
private static String getResourceSymbolsPath(ResourceSymbolSize needSize) {
|
||||
// return real path to symbols (default or user defined)
|
||||
|
||||
String path = CardImageUtils.getImagesDir() + Constants.RESOURCE_PATH_SYMBOLS + File.separator;
|
||||
|
@ -503,15 +511,14 @@ public final class ManaSymbols {
|
|||
}
|
||||
|
||||
// fix double separator if size folder is not set
|
||||
while(path.endsWith(File.separator))
|
||||
{
|
||||
while (path.endsWith(File.separator)) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
|
||||
return path + File.separator;
|
||||
}
|
||||
|
||||
private static String getResourceSetsPath(ResourceSetSize needSize){
|
||||
private static String getResourceSetsPath(ResourceSetSize needSize) {
|
||||
// return real path to sets icons (default or user defined)
|
||||
|
||||
String path = CardImageUtils.getImagesDir() + Constants.RESOURCE_PATH_SYMBOLS + File.separator;
|
||||
|
@ -533,8 +540,7 @@ public final class ManaSymbols {
|
|||
}
|
||||
|
||||
// fix double separator if size folder is not set
|
||||
while(path.endsWith(File.separator))
|
||||
{
|
||||
while (path.endsWith(File.separator)) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
|
||||
|
@ -592,10 +598,7 @@ public final class ManaSymbols {
|
|||
Graphics2D gg = image.createGraphics();
|
||||
manaPanel.paint(gg);
|
||||
g.drawImage(image, x, y, null);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
*/
|
||||
// OLD version with custom draw
|
||||
Map<String, BufferedImage> sizedSymbols = manaImages.get(symbolWidth);
|
||||
if (manaCost.isEmpty()) {
|
||||
|
@ -627,8 +630,8 @@ public final class ManaSymbols {
|
|||
int stringWidth = labelRender.getFontMetrics(labelFont).stringWidth(labelText);
|
||||
int componentWidth = labelRender.getWidth();
|
||||
// Find out how much the font can grow in width.
|
||||
double widthRatio = (double)componentWidth / (double)stringWidth;
|
||||
int newFontSize = (int)(labelFont.getSize() * widthRatio);
|
||||
double widthRatio = (double) componentWidth / (double) stringWidth;
|
||||
int newFontSize = (int) (labelFont.getSize() * widthRatio);
|
||||
int componentHeight = labelRender.getHeight();
|
||||
// Pick a new font size so it will not be larger than the height of label.
|
||||
int fontSizeToUse = Math.min(newFontSize, componentHeight);
|
||||
|
@ -638,11 +641,11 @@ public final class ManaSymbols {
|
|||
// render component to new position
|
||||
// need to copy graphics, overvise it draw at top left corner
|
||||
// https://stackoverflow.com/questions/4974268/java-paint-problem
|
||||
Graphics2D labelG = (Graphics2D)g.create(x, y, symbolWidth, symbolWidth);
|
||||
Graphics2D labelG = (Graphics2D) g.create(x, y, symbolWidth, symbolWidth);
|
||||
labelG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
labelG.fillOval(x + 1, y + 1, symbolWidth - 2, symbolWidth - 2);
|
||||
labelRender.paint(labelG);
|
||||
}else {
|
||||
} else {
|
||||
// ICON draw
|
||||
g.drawImage(image, x, y, null);
|
||||
}
|
||||
|
@ -666,12 +669,12 @@ public final class ManaSymbols {
|
|||
TOOLTIP,
|
||||
}
|
||||
|
||||
private static String filePathToUrl(String path){
|
||||
private static String filePathToUrl(String path) {
|
||||
// convert file path to uri path (for html docs)
|
||||
if((path != null) && (!path.equals(""))){
|
||||
if ((path != null) && (!path.equals(""))) {
|
||||
File file = new File(path);
|
||||
return file.toURI().toString();
|
||||
}else{
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -680,7 +683,6 @@ public final class ManaSymbols {
|
|||
|
||||
// mana cost to HTML images (urls to files)
|
||||
// do not use it for new code - try to suppotr svg render
|
||||
|
||||
int symbolSize;
|
||||
switch (type) {
|
||||
case TABLE:
|
||||
|
@ -702,22 +704,20 @@ public final class ManaSymbols {
|
|||
|
||||
// auto size
|
||||
ResourceSymbolSize needSize = null;
|
||||
if (symbolSize <= 15){
|
||||
if (symbolSize <= 15) {
|
||||
needSize = ResourceSymbolSize.SMALL;
|
||||
}else if (symbolSize <= 25){
|
||||
} else if (symbolSize <= 25) {
|
||||
needSize = ResourceSymbolSize.MEDIUM;
|
||||
} else {
|
||||
needSize = ResourceSymbolSize.LARGE;
|
||||
}
|
||||
|
||||
// replace every {symbol} to <img> link
|
||||
|
||||
// ignore data backup
|
||||
String replaced = value
|
||||
.replace("{source}", "|source|")
|
||||
.replace("{this}", "|this|");
|
||||
|
||||
|
||||
// not need to add different images (width and height do the work)
|
||||
// use best png size (generated on startup) TODO: add reload images after update
|
||||
String htmlImagesPath = getResourceSymbolsPath(ResourceSymbolSize.PNG);
|
||||
|
@ -725,8 +725,8 @@ public final class ManaSymbols {
|
|||
.replace("$", "@S@"); // paths with $ will rise error, need escape that
|
||||
|
||||
replaced = REPLACE_SYMBOLS_PATTERN.matcher(replaced).replaceAll(
|
||||
"<img src='" + filePathToUrl(htmlImagesPath) + "$1$2" + ".png' alt='$1$2' width="
|
||||
+ symbolSize + " height=" + symbolSize + '>');
|
||||
"<img src='" + filePathToUrl(htmlImagesPath) + "$1$2" + ".png' alt='$1$2' width="
|
||||
+ symbolSize + " height=" + symbolSize + '>');
|
||||
|
||||
// ignore data restore
|
||||
replaced = replaced
|
||||
|
@ -774,4 +774,3 @@ public final class ManaSymbols {
|
|||
return sizedSymbols.get(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import com.google.common.collect.AbstractIterator;
|
|||
import java.io.File;
|
||||
import static java.lang.String.format;
|
||||
import java.util.Iterator;
|
||||
|
||||
import mage.client.constants.Constants;
|
||||
import org.mage.plugins.card.dl.DownloadJob;
|
||||
import static org.mage.plugins.card.dl.DownloadJob.fromURL;
|
||||
|
@ -42,7 +41,7 @@ public class GathererSymbols implements Iterable<DownloadJob> {
|
|||
public GathererSymbols() {
|
||||
outDir = new File(getImagesDir() + Constants.RESOURCE_PATH_SYMBOLS);
|
||||
|
||||
if (!outDir.exists()){
|
||||
if (!outDir.exists()) {
|
||||
outDir.mkdirs();
|
||||
}
|
||||
}
|
||||
|
@ -76,8 +75,9 @@ public class GathererSymbols implements Iterable<DownloadJob> {
|
|||
File dst = new File(dir, symbol + ".gif");
|
||||
|
||||
/**
|
||||
* Handle a bug on Gatherer where a few symbols are missing at the large size.
|
||||
* Fall back to using the medium symbol for those cases.
|
||||
* Handle a bug on Gatherer where a few symbols are missing
|
||||
* at the large size. Fall back to using the medium symbol
|
||||
* for those cases.
|
||||
*/
|
||||
int modSizeIndex = sizeIndex;
|
||||
if (sizeIndex == 2) {
|
||||
|
@ -93,7 +93,7 @@ public class GathererSymbols implements Iterable<DownloadJob> {
|
|||
break;
|
||||
|
||||
default:
|
||||
// Nothing to do, symbol is available in the large size
|
||||
// Nothing to do, symbol is available in the large size
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -268,7 +268,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
supportedSets.add("V17"); // From the Vault: Transform
|
||||
supportedSets.add("UST"); // Unstable
|
||||
supportedSets.add("RIX"); // Rivals of Ixalan
|
||||
// supportedSets.add("A25"); // Masters 25
|
||||
supportedSets.add("A25"); // Masters 25
|
||||
// supportedSets.add("DOM"); // Dominaria
|
||||
// supportedSets.add("M19"); // Core 2019
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-common</artifactId>
|
||||
|
@ -25,6 +25,7 @@
|
|||
<artifactId>jspf-core</artifactId>
|
||||
<version>0.9.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.remoting</groupId>
|
||||
<artifactId>jboss-remoting</artifactId>
|
||||
|
@ -50,7 +51,11 @@
|
|||
<artifactId>trove</artifactId>
|
||||
<version>1.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!-- to get the reference to local repository with com\googlecode\jspf\jspf-core\0.9.1\ -->
|
||||
<repositories>
|
||||
|
|
138
Mage.Common/src/main/java/mage/remote/ActionData.java
Normal file
138
Mage.Common/src/main/java/mage/remote/ActionData.java
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright 2018 nanarpuss_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.remote;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.FieldAttributes;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ActionData {
|
||||
|
||||
@Expose
|
||||
public UUID gameId;
|
||||
@Expose
|
||||
public String sessionId;
|
||||
@Expose
|
||||
public String type;
|
||||
@Expose
|
||||
public Object value;
|
||||
@Expose
|
||||
public String message;
|
||||
|
||||
public String toJson() {
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
Gson gson = gsonBuilder.setExclusionStrategies(new CustomExclusionStrategy()).create();
|
||||
|
||||
return gson.toJson(this);
|
||||
}
|
||||
|
||||
public ActionData(String type, UUID gameId, String sessionId) {
|
||||
this.type = type;
|
||||
this.sessionId = sessionId;
|
||||
this.gameId = gameId;
|
||||
}
|
||||
|
||||
public ActionData(String type, UUID gameId) {
|
||||
this.type = type;
|
||||
this.gameId = gameId;
|
||||
}
|
||||
|
||||
public class CustomExclusionStrategy implements ExclusionStrategy {
|
||||
|
||||
// FIXME: Very crude way of whitelisting, as it applies to all levels of the JSON tree.
|
||||
private final java.util.Set<String> KEEP = new java.util.HashSet<>(
|
||||
java.util.Arrays.asList(
|
||||
new String[]{
|
||||
"id",
|
||||
"choice",
|
||||
"damage",
|
||||
"abilityType",
|
||||
"ability",
|
||||
"abilities",
|
||||
"method",
|
||||
"data",
|
||||
"options",
|
||||
"life",
|
||||
"players",
|
||||
"zone",
|
||||
"step",
|
||||
"phase",
|
||||
"attackers",
|
||||
"blockers",
|
||||
"tapped",
|
||||
"damage",
|
||||
"combat",
|
||||
"paid",
|
||||
"hand",
|
||||
"stack",
|
||||
"convertedManaCost",
|
||||
"gameId",
|
||||
"canPlayInHand",
|
||||
"gameView",
|
||||
"sessionId",
|
||||
"power",
|
||||
"choices",
|
||||
"targets",
|
||||
"loyalty",
|
||||
"toughness",
|
||||
"power",
|
||||
"type",
|
||||
"priorityTime",
|
||||
"manaCost",
|
||||
"value",
|
||||
"message",
|
||||
"cardsView",
|
||||
"name",
|
||||
"count",
|
||||
"counters",
|
||||
"battlefield",
|
||||
"parentId"
|
||||
}));
|
||||
|
||||
public CustomExclusionStrategy() {
|
||||
}
|
||||
|
||||
// This method is called for all fields. if the method returns true the
|
||||
// field is excluded from serialization
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
String name = f.getName();
|
||||
return !KEEP.contains(name);
|
||||
}
|
||||
|
||||
// This method is called for all classes. If the method returns true the
|
||||
// class is excluded.
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,8 +24,7 @@
|
|||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
*/
|
||||
package mage.remote;
|
||||
|
||||
import mage.remote.interfaces.ChatSession;
|
||||
|
@ -46,4 +45,5 @@ import mage.remote.interfaces.Testable;
|
|||
*/
|
||||
public interface Session extends ClientData, Connect, GamePlay, GameTypes, ServerState, ChatSession, Feedback, PlayerActions, Replays, Testable {
|
||||
|
||||
public void appendJsonLog(ActionData actionData);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,11 @@
|
|||
*/
|
||||
package mage.remote;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
@ -86,6 +90,7 @@ public class SessionImpl implements Session {
|
|||
private static boolean debugMode = false;
|
||||
|
||||
private boolean canceled = false;
|
||||
private boolean jsonLogActive = false;
|
||||
|
||||
static {
|
||||
debugMode = System.getProperty("debug.mage") != null;
|
||||
|
@ -798,6 +803,9 @@ public class SessionImpl implements Session {
|
|||
public boolean sendPlayerUUID(UUID gameId, UUID data) {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
ActionData actionData = new ActionData("SEND_PLAYER_UUID", gameId, getSessionId());
|
||||
actionData.value = data;
|
||||
appendJsonLog(actionData);
|
||||
server.sendPlayerUUID(gameId, sessionId, data);
|
||||
return true;
|
||||
}
|
||||
|
@ -813,6 +821,10 @@ public class SessionImpl implements Session {
|
|||
public boolean sendPlayerBoolean(UUID gameId, boolean data) {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
ActionData actionData = new ActionData("SEND_PLAYER_BOOLEAN", gameId, getSessionId());
|
||||
actionData.value = data;
|
||||
appendJsonLog(actionData);
|
||||
|
||||
server.sendPlayerBoolean(gameId, sessionId, data);
|
||||
return true;
|
||||
}
|
||||
|
@ -828,6 +840,10 @@ public class SessionImpl implements Session {
|
|||
public boolean sendPlayerInteger(UUID gameId, int data) {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
ActionData actionData = new ActionData("SEND_PLAYER_INTEGER", gameId, getSessionId());
|
||||
actionData.value = data;
|
||||
appendJsonLog(actionData);
|
||||
|
||||
server.sendPlayerInteger(gameId, sessionId, data);
|
||||
return true;
|
||||
}
|
||||
|
@ -843,6 +859,10 @@ public class SessionImpl implements Session {
|
|||
public boolean sendPlayerString(UUID gameId, String data) {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
ActionData actionData = new ActionData("SEND_PLAYER_STRING", gameId, getSessionId());
|
||||
actionData.value = data;
|
||||
appendJsonLog(actionData);
|
||||
|
||||
server.sendPlayerString(gameId, sessionId, data);
|
||||
return true;
|
||||
}
|
||||
|
@ -858,6 +878,9 @@ public class SessionImpl implements Session {
|
|||
public boolean sendPlayerManaType(UUID gameId, UUID playerId, ManaType data) {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
ActionData actionData = new ActionData("SEND_PLAYER_MANA_TYPE", gameId, getSessionId());
|
||||
actionData.value = data;
|
||||
appendJsonLog(actionData);
|
||||
server.sendPlayerManaType(gameId, playerId, sessionId, data);
|
||||
return true;
|
||||
}
|
||||
|
@ -869,6 +892,25 @@ public class SessionImpl implements Session {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendJsonLog(ActionData actionData) {
|
||||
if (isJsonLogActive()) {
|
||||
String dir = "gamelogsJson";
|
||||
File saveDir = new File(dir);
|
||||
//Existence check
|
||||
if (!saveDir.exists()) {
|
||||
saveDir.mkdirs();
|
||||
}
|
||||
actionData.sessionId = getSessionId();
|
||||
String logFileName = dir + File.separator + "game-" + actionData.gameId + ".json";
|
||||
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(logFileName, true)))) {
|
||||
out.println(actionData.toJson());
|
||||
} catch (IOException e) {
|
||||
logger.error("Cant write JSON game log file - " + logFileName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DraftPickView sendCardPick(UUID draftId, UUID cardId, Set<UUID> hiddenCards) {
|
||||
try {
|
||||
|
@ -1274,6 +1316,11 @@ public class SessionImpl implements Session {
|
|||
public boolean sendPlayerAction(PlayerAction passPriorityAction, UUID gameId, Object data) {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
ActionData actionData = new ActionData("SEND_PLAYER_ACTION", gameId, getSessionId());
|
||||
|
||||
actionData.value = passPriorityAction + (data != null ? " " + data.toString() : "");
|
||||
appendJsonLog(actionData);
|
||||
|
||||
server.sendPlayerAction(passPriorityAction, gameId, sessionId, data);
|
||||
return true;
|
||||
}
|
||||
|
@ -1597,6 +1644,16 @@ public class SessionImpl implements Session {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJsonLogActive() {
|
||||
return jsonLogActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJsonLogActive(boolean jsonLogActive) {
|
||||
this.jsonLogActive = jsonLogActive;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MageAuthenticator extends Authenticator {
|
||||
|
|
|
@ -37,4 +37,8 @@ public interface ClientData {
|
|||
String getUserName();
|
||||
|
||||
boolean updatePreferencesForServer(UserData userData);
|
||||
|
||||
void setJsonLogActive(boolean active);
|
||||
|
||||
boolean isJsonLogActive();
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
|
|||
*/
|
||||
public final static int MAGE_VERSION_MAJOR = 1;
|
||||
public final static int MAGE_VERSION_MINOR = 4;
|
||||
public final static int MAGE_VERSION_PATCH = 27;
|
||||
public final static String MAGE_VERSION_MINOR_PATCH = "V4";
|
||||
public final static int MAGE_VERSION_PATCH = 28;
|
||||
public final static String MAGE_VERSION_MINOR_PATCH = "V0";
|
||||
public final static String MAGE_VERSION_INFO = "";
|
||||
|
||||
private final int major;
|
||||
|
|
|
@ -53,6 +53,8 @@ import mage.target.Target;
|
|||
import mage.target.Targets;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -61,11 +63,17 @@ public class CardView extends SimpleCardView {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected UUID parentId;
|
||||
@Expose
|
||||
protected String name;
|
||||
@Expose
|
||||
protected String displayName;
|
||||
@Expose
|
||||
protected List<String> rules;
|
||||
@Expose
|
||||
protected String power;
|
||||
@Expose
|
||||
protected String toughness;
|
||||
@Expose
|
||||
protected String loyalty = "";
|
||||
protected String startingLoyalty;
|
||||
protected EnumSet<CardType> cardTypes;
|
||||
|
@ -110,7 +118,6 @@ public class CardView extends SimpleCardView {
|
|||
protected ArtRect artRect = ArtRect.NORMAL;
|
||||
|
||||
protected List<UUID> targets;
|
||||
|
||||
protected UUID pairedCard;
|
||||
protected List<UUID> bandedCards;
|
||||
protected boolean paid;
|
||||
|
|
|
@ -32,6 +32,11 @@ import java.io.Serializable;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import mage.choices.Choice;
|
||||
|
||||
/**
|
||||
|
@ -39,18 +44,29 @@ import mage.choices.Choice;
|
|||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class GameClientMessage implements Serializable {
|
||||
@Expose
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Expose
|
||||
private GameView gameView;
|
||||
@Expose
|
||||
private CardsView cardsView;
|
||||
@Expose
|
||||
private CardsView cardsView2;
|
||||
@Expose
|
||||
private String message;
|
||||
@Expose
|
||||
private boolean flag;
|
||||
@Expose
|
||||
private String[] strings;
|
||||
@Expose
|
||||
private Set<UUID> targets;
|
||||
@Expose
|
||||
private int min;
|
||||
@Expose
|
||||
private int max;
|
||||
@Expose
|
||||
private Map<String, Serializable> options;
|
||||
@Expose
|
||||
private Choice choice;
|
||||
|
||||
public GameClientMessage(GameView gameView) {
|
||||
|
@ -155,4 +171,11 @@ public class GameClientMessage implements Serializable {
|
|||
return choice;
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
Gson gson = new GsonBuilder()
|
||||
.excludeFieldsWithoutExposeAnnotation()
|
||||
.create();
|
||||
return gson.toJson(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,11 +28,17 @@
|
|||
package mage.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.cards.Card;
|
||||
|
@ -54,6 +60,8 @@ import mage.game.stack.StackObject;
|
|||
import mage.players.Player;
|
||||
import mage.watchers.common.CastSpellLastTurnWatcher;
|
||||
import org.apache.log4j.Logger;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -64,7 +72,6 @@ public class GameView implements Serializable {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(GameView.class);
|
||||
|
||||
private final int priorityTime;
|
||||
private final List<PlayerView> players = new ArrayList<>();
|
||||
private CardsView hand;
|
||||
|
@ -351,4 +358,8 @@ public class GameView implements Serializable {
|
|||
return rollbackTurnsAllowed;
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
Gson gson = new GsonBuilder().create();
|
||||
return gson.toJson(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
package mage.view;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -36,6 +38,7 @@ import java.util.UUID;
|
|||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class SimpleCardView implements Serializable {
|
||||
@Expose
|
||||
protected UUID id;
|
||||
protected String expansionSetCode;
|
||||
protected String tokenSetCode;
|
||||
|
|
|
@ -65,6 +65,7 @@ public class TableView implements Serializable {
|
|||
private final boolean limited;
|
||||
private final boolean rated;
|
||||
private final boolean passworded;
|
||||
private final boolean spectatorsAllowed;
|
||||
|
||||
public TableView(Table table) {
|
||||
this.tableId = table.getId();
|
||||
|
@ -139,6 +140,7 @@ public class TableView implements Serializable {
|
|||
this.limited = table.getMatch().getOptions().isLimited();
|
||||
this.rated = table.getMatch().getOptions().isRated();
|
||||
this.passworded = !table.getMatch().getOptions().getPassword().isEmpty();
|
||||
this.spectatorsAllowed = table.getMatch().getOptions().isSpectatorsAllowed();
|
||||
} else {
|
||||
// TOURNAMENT
|
||||
if (table.getTournament().getOptions().getNumberRounds() > 0) {
|
||||
|
@ -186,6 +188,7 @@ public class TableView implements Serializable {
|
|||
this.limited = table.getTournament().getOptions().getMatchOptions().isLimited();
|
||||
this.rated = table.getTournament().getOptions().getMatchOptions().isRated();
|
||||
this.passworded = !table.getTournament().getOptions().getPassword().isEmpty();
|
||||
this.spectatorsAllowed = table.getTournament().getOptions().isWatchingAllowed();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,6 +203,11 @@ public class TableView implements Serializable {
|
|||
public String getControllerName() {
|
||||
return controllerName;
|
||||
}
|
||||
|
||||
public boolean getSpectatorsAllowed() {
|
||||
return spectatorsAllowed;
|
||||
}
|
||||
|
||||
|
||||
public String getGameType() {
|
||||
return gameType;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-counter-plugin</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-plugins</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.mage</groupId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-deck-constructed</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-deck-limited</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-canadianhighlanderduel</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-commanderduel</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-commanderfreeforall</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-freeforall</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-momirduel</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-momirfreeforall</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-tinyleadersduel</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-twoplayerduel</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-ai-draftbot</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-ai-ma</artifactId>
|
||||
|
|
|
@ -522,7 +522,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
|
|||
continue;
|
||||
}
|
||||
if (!sim.checkIfGameIsOver()
|
||||
&& action.isUsesStack()) {
|
||||
&& (action.isUsesStack() || action instanceof PassAbility)) {
|
||||
// only pass if the last action uses the stack
|
||||
UUID nextPlayerId = sim.getPlayerList().get();
|
||||
do {
|
||||
|
@ -533,8 +533,8 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
|
|||
SimulationNode2 newNode = new SimulationNode2(node, sim, action, depth, currentPlayer.getId());
|
||||
sim.checkStateAndTriggered();
|
||||
int val;
|
||||
if (action instanceof PassAbility) {
|
||||
// Stop to simulate deeper if PassAbility
|
||||
if (action instanceof PassAbility && sim.getStack().isEmpty()) {
|
||||
// Stop to simulate deeper if PassAbility and stack is empty
|
||||
val = GameStateEvaluator2.evaluate(this.getId(), sim);
|
||||
} else {
|
||||
val = addActions(newNode, depth - 1, alpha, beta);
|
||||
|
|
|
@ -109,6 +109,12 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
|
|||
}
|
||||
return false;
|
||||
case DECLARE_BLOCKERS:
|
||||
printOutState(game);
|
||||
if (actions.isEmpty()) {
|
||||
calculateActions(game);
|
||||
}
|
||||
act(game);
|
||||
return true;
|
||||
case FIRST_COMBAT_DAMAGE:
|
||||
case COMBAT_DAMAGE:
|
||||
case END_COMBAT:
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-ai</artifactId>
|
||||
|
|
|
@ -1312,6 +1312,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
if (numAvailable < 0) {
|
||||
numAvailable = 0;
|
||||
}
|
||||
if (numAvailable > max) {
|
||||
numAvailable = max;
|
||||
}
|
||||
return numAvailable;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-ai-mcts</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-aiminimax</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-human</artifactId>
|
||||
|
|
|
@ -1111,11 +1111,13 @@ public class HumanPlayer extends PlayerImpl {
|
|||
if (object == null) {
|
||||
return;
|
||||
}
|
||||
Spell spell = game.getStack().getSpell(abilityToCast.getSourceId());
|
||||
if (spell != null && !spell.isResolving()
|
||||
&& spell.isDoneActivatingManaAbilities()) {
|
||||
game.informPlayer(this, "You can no longer use activated mana abilities to pay for the current spell. Cancel and recast the spell and activate mana abilities first.");
|
||||
return;
|
||||
if (AbilityType.SPELL.equals(abilityToCast.getAbilityType())) {
|
||||
Spell spell = game.getStack().getSpell(abilityToCast.getSourceId());
|
||||
if (spell != null && !spell.isResolving()
|
||||
&& spell.isDoneActivatingManaAbilities()) {
|
||||
game.informPlayer(this, "You can no longer use activated mana abilities to pay for the current spell. Cancel and recast the spell and activate mana abilities first.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Zone zone = game.getState().getZone(object.getId());
|
||||
if (zone != null) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-tournament-boosterdraft</artifactId>
|
||||
|
|
|
@ -0,0 +1,641 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.tournament.cubes;
|
||||
|
||||
import mage.game.draft.DraftCube;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class LegacyCube2018February extends DraftCube {
|
||||
|
||||
public LegacyCube2018February() {
|
||||
super("MTGO Legacy Cube February 2018 (600 cards)");
|
||||
cubeCards.add(new DraftCube.CardIdentity("Abbot of Keral Keep", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Abrade", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Abrupt Decay", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Abyssal Persecutor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Acidic Slime", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Act of Aggression", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Adanto Vanguard", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ajani Goldmane", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ajani Vengeant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Anafenza, Kin-Tree Spirit", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ancestral Vision", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ancient Tomb", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Angel of Invention", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Angel of Serenity", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Anger of the Gods", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Anguished Unmaking", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Animate Dead", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Approach of the Second Sun", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Arbor Elf", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Arc Trail", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Archangel Avacyn", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Arid Mesa", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Armageddon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ashiok, Nightmare Weaver", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Assemble the Legion", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Augur of Bolas", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Avacyn's Pilgrim", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Avalanche Riders", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Avenger of Zendikar", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Badlands", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Baleful Strix", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Banefire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Baneslayer Angel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Banisher Priest", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Banishing Light", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Baral, Chief of Compliance", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Batterskull", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bayou", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Beast Within", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bedlam Reveler", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Birds of Paradise", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Birthing Pod", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bitterblossom", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blackcleave Cliffs", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blade Splicer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blood Crypt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bloodbraid Elf", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bloodghast", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bloodstained Mire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bloom Tender", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blooming Marsh", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bogardan Hellkite", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bomat Courier", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bone Shredder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bonfire of the Damned", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Boros Charm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Boros Reckoner", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Botanical Sanctum", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Brainstorm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Breeding Pool", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Brimaz, King of Oreskos", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Brimstone Volley", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bruna, the Fading Light", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Buried Alive", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Burst Lightning", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Careful Consideration", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Careful Study", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Carnage Tyrant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Cathartic Reunion", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Celestial Colonnade", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Censor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chain Lightning", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chainer's Edict", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chandra's Phoenix", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chandra, Fire of Kaladesh", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chandra, Flamecaller", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chandra, Pyromaster", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chandra, Torch of Defiance", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Char", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chart a Course", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chord of Calling", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chromatic Lantern", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("City of Brass", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Clifftop Retreat", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Cloudgoat Ranger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Coalition Relic", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Coldsteel Heart", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Collective Brutality", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Collective Defiance", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Collective Effort", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Compulsive Research", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Concealed Courtyard", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Condemn", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Consecrated Sphinx", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Control Magic", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Copperline Gorge", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Council's Judgment", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Counterspell", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Courser of Kruphix", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Crater's Claws", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Craterhoof Behemoth", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Creeping Tar Pit", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Crux of Fate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Cryptic Command", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Cultivate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Cyclonic Rift", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Damnation", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dark Confidant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dark Petition", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dark Ritual", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Darkslick Shores", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Day of Judgment", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Daze", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Deathrite Shaman", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Deceiver Exarch", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Declaration in Stone", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Delver of Secrets", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Den Protector", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Deranged Hermit", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Desecration Demon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Devil's Play", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Devoted Druid", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Disallow", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Disfigure", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dismember", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dismiss", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dissipate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dissolve", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Distended Mindbender", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Domri Rade", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Doom Blade", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Atarka", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Dromoka", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Ojutai", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Silumgar", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dragonskull Summit", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Drana, Liberator of Malakir", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dread Return", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dreadbore", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dromoka's Command", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Drowned Catacomb", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dualcaster Mage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dungeon Geists", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Duplicant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Duress", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Duskwatch Recruiter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Edric, Spymaster of Trest", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elder Deep-Fiend", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Electrolyze", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elesh Norn, Grand Cenobite", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elspeth Tirel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elspeth, Knight-Errant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elspeth, Sun's Champion", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elves of Deep Shadow", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elvish Mystic", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Emeria Angel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Emrakul, the Aeons Torn", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Emrakul, the Promised End", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Entomb", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Entreat the Angels", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Erebos, God of the Dead", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Eternal Witness", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Exhume", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Explore", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Exquisite Firecraft", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fact or Fiction", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Faith's Fetters", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Falkenrath Gorger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Farseek", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fatal Push", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fauna Shaman", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fertile Ground", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Field of Ruin", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fiend Hunter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fiery Confluence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fire // Ice", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Firebolt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Flame Slash", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Flametongue Kavu", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Flickerwisp", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Flooded Strand", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Forbid", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Force of Will", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Force Spike", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Forked Bolt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Frost Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fyndhorn Elves", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gaea's Cradle", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Garruk Relentless", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Garruk Wildspeaker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Garruk, Apex Predator", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Garruk, Primal Hunter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gatekeeper of Malakir", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Geist of Saint Traft", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Genesis Wave", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Geralf's Messenger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ghor-Clan Rampager", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gideon Jura", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gideon of the Trials", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gideon, Ally of Zendikar", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gifted Aetherborn", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gifts Ungiven", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gilded Lotus", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gisela, the Broken Blade", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gitaxian Probe", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Glacial Fortress", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Glen Elendra Archmage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Glorious Anthem", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Glorybringer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Go for the Throat", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Goblin Dark-Dwellers", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Goblin Guide", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Goblin Rabblemaster", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("God-Pharaoh's Gift", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Godless Shrine", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gonti, Lord of Luxury", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Grave Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gray Merchant of Asphodel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Greater Gargadon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Green Sun's Zenith", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Greenwarden of Murasa", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Grim Lavamancer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Griselbrand", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hallowed Fountain", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hallowed Spiritkeeper", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hangarback Walker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Harbinger of the Tides", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Harmonize", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hazoret the Fervent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hellrider", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hero of Bladehold", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hero's Downfall", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hidden Dragonslayer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hinterland Harbor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hissing Quagmire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Honor of the Pure", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hordeling Outburst", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hornet Queen", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hostage Taker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hour of Devastation", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Huntmaster of the Fells", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hymn to Tourach", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hypnotic Specter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Icefall Regent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Imperial Recruiter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Impulse", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Incendiary Flow", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Incinerate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Inferno Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Inquisition of Kozilek", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Inspiring Vantage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Into the Roil", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ire Shaman", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Isamaru, Hound of Konda", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Isolated Chapel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Izzet Charm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jace Beleren", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jace, Architect of Thought", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jace, the Mind Sculptor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jace, Vryn's Prodigy", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jackal Pup", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jadelight Ranger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Joraga Treespeaker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Journey to Nowhere", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kalitas, Traitor of Ghet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Karmic Guide", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Karn Liberated", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Keiga, the Tide Star", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Keranos, God of Storms", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kiki-Jiki, Mirror Breaker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kiln Fiend", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kiora's Follower", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kiora, the Crashing Wave", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kira, Great Glass-Spinner", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kitchen Finks", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kitesail Freebooter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Knight of the Reliquary", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kodama's Reach", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kokusho, the Evening Star", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kolaghan's Command", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Koth of the Hammer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kytheon, Hero of Akros", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Land Tax", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Languish", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lavaclaw Reaches", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Legacy's Allure", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Legion's Landing", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Leonin Relic-Warder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lightning Bolt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lightning Greaves", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lightning Helix", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lightning Mauler", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lightning Strike", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Liliana of the Veil", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Liliana Vess", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Liliana, Death's Majesty", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Liliana, Heretical Healer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Liliana, the Last Hope", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lingering Souls", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Linvala, Keeper of Silence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Linvala, the Preserver", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Living Death", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Llanowar Elves", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Looter il-Kor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lotus Cobra", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Loxodon Warhammer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lumbering Falls", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Maelstrom Pulse", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Magma Jet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Makeshift Mannequin", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Malicious Affliction", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Man-o'-War", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mana Confluence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mana Tithe", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Managorger Hydra", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Manic Vandal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Marsh Flats", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Martial Coup", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Massacre Wurm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Master of the Wild Hunt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Master of Waves", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Maze of Ith", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mentor of the Meek", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Merfolk Looter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mimic Vat", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mind Stone", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mirari's Wake", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mirran Crusader", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mirror Entity", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Miscalculation", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mishra's Factory", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Misty Rainforest", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mizzium Mortars", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mogg War Marshal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Monastery Mentor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Monastery Swiftspear", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mother of Runes", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mulldrifter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Murderous Cut", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Murderous Redcap", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mutavault", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Myr Battlesphere", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mystic Snake", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nahiri, the Harbinger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Natural Order", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nature's Lore", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Necromancy", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Needle Spires", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Negate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nekrataal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nevinyrral's Disk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nicol Bolas, God-Pharaoh", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nicol Bolas, Planeswalker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nightveil Specter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nimble Obstructionist", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nissa, Vastwood Seer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nissa, Vital Force", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nissa, Voice of Zendikar", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nissa, Worldwaker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Noble Hierarch", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Noxious Gearhulk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nykthos, Shrine to Nyx", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oath of Nissa", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ob Nixilis Reignited", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oblivion Ring", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oblivion Stone", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Obstinate Baloth", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Old Man of the Sea", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Olivia Voldaren", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oona's Prowler", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ophiomancer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Opposition", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Opt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oracle of Mul Daya", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oust", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Outpost Siege", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Overgrown Battlement", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Overgrown Tomb", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pack Rat", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pact of Negation", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Parallax Wave", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Part the Waterveil", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Path to Exile", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pernicious Deed", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pestermite", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Phantasmal Image", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Phyrexian Arena", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Phyrexian Metamorph", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Phyrexian Obliterator", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Phyrexian Rager", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Phyrexian Revoker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pia and Kiran Nalaar", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pillar of Flame", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Plateau", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Polluted Delta", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Polukranos, World Eater", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ponder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Porcelain Legionnaire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Precinct Captain", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Preordain", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Primal Command", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Primeval Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Profane Command", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Purphoros, God of the Forge", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pyroclasm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Qasali Pridemage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Quarantine Field", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Raging Ravine", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Raise the Alarm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rakdos's Return", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ral Zarek", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rampaging Baloths", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rampaging Ferocidon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rampant Growth", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ravages of War", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ravenous Chupacabra", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Razaketh, the Foulblooded", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Razorverge Thicket", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Read the Bones", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Reanimate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Reckless Bushwhacker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Reclamation Sage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Recruiter of the Guard", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Recurring Nightmare", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Reflecting Pool", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Reflector Mage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Regrowth", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rekindling Phoenix", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Relic of Progenitus", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Remand", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Remove Soul", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Repeal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Restoration Angel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Reveillark", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rift Bolt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Riftwing Cloudskate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rishadan Port", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rishkar, Peema Renegade", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Roast", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rofellos, Llanowar Emissary", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rootbound Crag", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rune-Scarred Demon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sacred Foundry", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sakura-Tribe Elder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sarkhan, the Dragonspeaker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Savannah", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Scalding Tarn", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Scavenging Ooze", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Scrapheap Scrounger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Scrubland", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sea Gate Oracle", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Seachrome Coast", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Seal of Fire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Search for Azcanta", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Search for Tomorrow", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Searing Spear", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Secure the Wastes", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Seeker of the Way", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Selfless Spirit", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Selvala, Heart of the Wilds", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sensei's Divining Top", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Serendib Efreet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Serum Visions", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Settle the Wreckage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shaman of Forgotten Ways", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shambling Vent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shardless Agent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shelldock Isle", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sheoldred, Whispering One", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Show and Tell", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shriekmaw", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Siege-Gang Commander", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Silverblade Paladin", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Skinrender", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Skymarcher Aspirant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Slagstorm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Slaughter Pact", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Smuggler's Copter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Snapcaster Mage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sneak Attack", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Solemn Simulacrum", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Song of the Dryads", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sorin Markov", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sorin, Solemn Visitor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Soulfire Grand Master", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sower of Temptation", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spear of Heliod", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spectral Procession", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spell Queller", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spellskite", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sphinx's Revelation", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spirebluff Canal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Splinter Twin", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Staggershock", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Steam Vents", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stirring Wildwood", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stoke the Flames", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stomping Ground", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stoneforge Mystic", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stormbreath Dragon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stormchaser Mage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stratus Dancer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stroke of Genius", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stromkirk Noble", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Student of Warfare", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sublime Archangel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sulfur Falls", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sun Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sundering Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sunpetal Grove", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Supreme Verdict", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Surrak, the Hunt Caller", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of Body and Mind", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of Feast and Famine", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of Fire and Ice", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of Light and Shadow", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of War and Peace", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Swords to Plowshares", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sylvan Advocate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sylvan Caryatid", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sylvan Library", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Taiga", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Talrand, Sky Summoner", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tamiyo, the Moon Sage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tangle Wire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tarmogoyf", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tasigur, the Golden Fang", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Teferi, Mage of Zhalfir", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Temple Garden", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Terastodon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Terminate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Terminus", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tetzimoc, Primal Death", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thalia, Guardian of Thraben", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thalia, Heretic Cathar", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thassa, God of the Sea", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("The Scarab God", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thing in the Ice", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thirst for Knowledge", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thoughtseize", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thragtusk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thrun, the Last Troll", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thunderbreak Regent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thundermaw Hellkite", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tidehollow Sculler", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Time Warp", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tireless Tracker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tooth and Nail", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Torch Fiend", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tower of the Magistrate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Toxic Deluge", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Treachery", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tropical Island", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Trygon Predator", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tundra", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ugin, the Spirit Dragon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ulamog, the Ceaseless Hunger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ultimate Price", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Umezawa's Jitte", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Unburial Rites", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Underground Sea", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Underworld Connections", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Unexpectedly Absent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Upheaval", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Utopia Sprawl", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vampire Hexmage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vampire Nighthawk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vendilion Clique", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Venser, Shaper Savant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Verdant Catacombs", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Verdurous Gearhulk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vindicate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Volcanic Island", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Volrath's Stronghold", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vraska's Contempt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vraska, Relic Seeker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Walking Ballista", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wall of Blossoms", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wall of Omens", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wandering Fumarole", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wasteland", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Watery Grave", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Whip of Erebos", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Whirler Rogue", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Whisperwood Elemental", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wickerbough Elder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Windbrisk Heights", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Windswept Heath", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wolfir Silverheart", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wood Elves", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wooded Foothills", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Woodfall Primus", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Woodland Cemetery", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wrath of God", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wretched Confluence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wurmcoil Engine", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Xenagos, the Reveler", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Yavimaya Elder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Young Pyromancer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Zealous Conscripts", ""));
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-tournament-constructed</artifactId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-tournament-sealed</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
|
|
|
@ -110,12 +110,13 @@
|
|||
<draftCube name="Timothee Simonot's Twisted Color Pie Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.TimotheeSimonotsTwistedColorPieCube"/>
|
||||
<draftCube name="MTGO Cube March 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGOMarchCube2014"/>
|
||||
<draftCube name="MTGO Legacy Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube"/>
|
||||
<draftCube name="MTGO Legacy Cube March 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/>
|
||||
<draftCube name="MTGO Legacy Cube September 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
|
||||
<draftCube name="MTGO Legacy Cube January 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
|
||||
<draftCube name="MTGO Legacy Cube September 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
|
||||
<draftCube name="MTGO Legacy Cube January 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
|
||||
<draftCube name="MTGO Legacy Cube April 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/>
|
||||
<draftCube name="MTGO Legacy Cube 2015 March" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/>
|
||||
<draftCube name="MTGO Legacy Cube 2015 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
|
||||
<draftCube name="MTGO Legacy Cube 2016 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
|
||||
<draftCube name="MTGO Legacy Cube 2016 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
|
||||
<draftCube name="MTGO Legacy Cube 2017 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
|
||||
<draftCube name="MTGO Legacy Cube 2017 April" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/>
|
||||
<draftCube name="MTGO Legacy Cube 2018 February" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube2018February"/>
|
||||
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/>
|
||||
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
|
||||
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ModernCube2017"/>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-server</artifactId>
|
||||
|
@ -76,6 +76,12 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.16.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>mage-game-commanderfreeforall</artifactId>
|
||||
|
|
|
@ -107,12 +107,13 @@
|
|||
<draftCube name="Timothee Simonot's Twisted Color Pie Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.TimotheeSimonotsTwistedColorPieCube"/>
|
||||
<draftCube name="MTGO Cube March 2014" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.MTGOMarchCube2014"/>
|
||||
<draftCube name="MTGO Legacy Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCube"/>
|
||||
<draftCube name="MTGO Legacy Cube March 2015" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/>
|
||||
<draftCube name="MTGO Legacy Cube September 2015" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
|
||||
<draftCube name="MTGO Legacy Cube January 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
|
||||
<draftCube name="MTGO Legacy Cube September 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
|
||||
<draftCube name="MTGO Legacy Cube January 2017" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
|
||||
<draftCube name="MTGO Legacy Cube April 2017" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/>
|
||||
<draftCube name="MTGO Legacy Cube 2015 March" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/>
|
||||
<draftCube name="MTGO Legacy Cube 2015 September" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
|
||||
<draftCube name="MTGO Legacy Cube 2016 January" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
|
||||
<draftCube name="MTGO Legacy Cube 2016 September" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
|
||||
<draftCube name="MTGO Legacy Cube 2017 January" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
|
||||
<draftCube name="MTGO Legacy Cube 2017 April" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/>
|
||||
<draftCube name="MTGO Legacy Cube 2018 February" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCube2018February"/>
|
||||
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegendaryCube"/>
|
||||
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
|
||||
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.ModernCube2017"/>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.27</version>
|
||||
<version>1.4.28</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.mage</groupId>
|
||||
|
|
|
@ -63,7 +63,7 @@ public class AnimationModule extends CardImpl {
|
|||
public AnimationModule(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
|
||||
|
||||
// Whenever one or more +1/+1 counters are placed on a permanent you control, you may pay {1}. If you do, create a 1/1 colorless Servo artifact creature token.
|
||||
// Whenever one or more +1/+1 counters are put on a permanent you control, you may pay {1}. If you do, create a 1/1 colorless Servo artifact creature token.
|
||||
this.addAbility(new AnimationModuleTriggeredAbility());
|
||||
|
||||
// {3}, {T}: Choose a counter on target permanent or player. Give that permanent or player another counter of that kind.
|
||||
|
@ -117,7 +117,7 @@ class AnimationModuleTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever one or more +1/+1 counters are placed on a permanent you control, you may pay {1}. If you do, create a 1/1 colorless Servo artifact creature token.";
|
||||
return "Whenever one or more +1/+1 counters are put on a permanent you control, you may pay {1}. If you do, create a 1/1 colorless Servo artifact creature token.";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ package mage.cards.a;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.OnEventTriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
|
@ -37,7 +37,7 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.constants.TargetController;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -46,7 +46,7 @@ import mage.game.events.GameEvent;
|
|||
public class ArchwingDragon extends CardImpl {
|
||||
|
||||
public ArchwingDragon(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
|
||||
this.subtype.add(SubType.DRAGON);
|
||||
|
||||
this.power = new MageInt(4);
|
||||
|
@ -54,8 +54,10 @@ public class ArchwingDragon extends CardImpl {
|
|||
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
this.addAbility(HasteAbility.getInstance());
|
||||
|
||||
// At the beginning of the end step, return Archwing Dragon to its owner's hand.
|
||||
this.addAbility(new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", new ReturnToHandSourceEffect(true), false));
|
||||
this.addAbility(new BeginningOfEndStepTriggeredAbility(new ReturnToHandSourceEffect(true), TargetController.ANY, false));
|
||||
|
||||
}
|
||||
|
||||
public ArchwingDragon(final ArchwingDragon card) {
|
||||
|
|
|
@ -69,7 +69,7 @@ public class BloodcrazedHoplite extends CardImpl {
|
|||
|
||||
// Heroic - Whenever you cast a spell that targets Bloodcrazed Hoplite, put a +1/+1 counter on it.
|
||||
this.addAbility(new HeroicAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(), false)));
|
||||
// Whenever a +1/+1 counter is placed on Bloodcrazed Hoplite, remove a +1/+1 counter from target creature an opponent controls.
|
||||
// Whenever a +1/+1 counter is put on Bloodcrazed Hoplite, remove a +1/+1 counter from target creature an opponent controls.
|
||||
Ability ability = new BloodcrazedHopliteTriggeredAbility();
|
||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||
this.addAbility(ability);
|
||||
|
@ -112,6 +112,6 @@ class BloodcrazedHopliteTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever a +1/+1 counter is placed on {this}, " + super.getRule();
|
||||
return "Whenever a +1/+1 counter is put on {this}, " + super.getRule();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import mage.constants.*;
|
|||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.permanent.AnotherPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
@ -56,6 +57,7 @@ public class BrothersYamazaki extends CardImpl {
|
|||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
|
||||
static {
|
||||
filter.add(new AnotherPredicate());
|
||||
filter.add(new NamePredicate("Brothers Yamazaki"));
|
||||
}
|
||||
|
||||
|
|
121
Mage.Sets/src/mage/cards/b/BuildersBane.java
Normal file
121
Mage.Sets/src/mage/cards/b/BuildersBane.java
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetArtifactPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sinsedrix
|
||||
*/
|
||||
public class BuildersBane extends CardImpl {
|
||||
|
||||
public BuildersBane(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{R}");
|
||||
|
||||
// Destroy X target artifacts. Builder's Bane deals damage to each player equal to the number of artifacts he or she controlled put into a graveyard this way.
|
||||
this.getSpellAbility().addTarget(new TargetArtifactPermanent());
|
||||
this.getSpellAbility().addEffect(new BuildersBaneEffect());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adjustTargets(Ability ability, Game game) {
|
||||
if (ability instanceof SpellAbility) {
|
||||
ability.getTargets().clear();
|
||||
int xValue = ability.getManaCostsToPay().getX();
|
||||
ability.addTarget(new TargetArtifactPermanent(xValue, xValue));
|
||||
}
|
||||
}
|
||||
|
||||
public BuildersBane(final BuildersBane card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuildersBane copy() {
|
||||
return new BuildersBane(this);
|
||||
}
|
||||
}
|
||||
|
||||
class BuildersBaneEffect extends OneShotEffect {
|
||||
|
||||
public BuildersBaneEffect() {
|
||||
super(Outcome.DestroyPermanent);
|
||||
this.staticText = "Destroy X target artifacts. {this} deals damage to each player equal to the number of artifacts he or she controlled put into a graveyard this way";
|
||||
}
|
||||
|
||||
public BuildersBaneEffect(final BuildersBaneEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuildersBaneEffect copy() {
|
||||
return new BuildersBaneEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Map<UUID, Integer> destroyedArtifactPerPlayer = new HashMap<>();
|
||||
|
||||
// Destroy X target artifacts.
|
||||
for (UUID targetID : this.targetPointer.getTargets(game, source)) {
|
||||
Permanent permanent = game.getPermanent(targetID);
|
||||
if (permanent != null) {
|
||||
if (permanent.destroy(source.getSourceId(), game, false)) {
|
||||
if (game.getState().getZone(permanent.getId()) == Zone.GRAVEYARD) {
|
||||
destroyedArtifactPerPlayer.merge(permanent.getControllerId(), 1, Integer::sum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Builder's Bane deals damage to each player equal to the number of artifacts he or she controlled put into a graveyard this way.
|
||||
for (Map.Entry<UUID, Integer> entry : destroyedArtifactPerPlayer.entrySet()) {
|
||||
Player player = game.getPlayer(entry.getKey());
|
||||
if(player != null) {
|
||||
player.damage(entry.getValue(), source.getSourceId(), game, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@ public class CorpsejackMenace extends CardImpl {
|
|||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// If one or more +1/+1 counters would be placed on a creature you control, twice that many +1/+1 counters are placed on it instead.
|
||||
// If one or more +1/+1 counters would be put on a creature you control, twice that many +1/+1 counters are put on it instead.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CorpsejackMenaceReplacementEffect()));
|
||||
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ class CorpsejackMenaceReplacementEffect extends ReplacementEffectImpl {
|
|||
|
||||
CorpsejackMenaceReplacementEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false);
|
||||
staticText = "If one or more +1/+1 counters would be placed on a creature you control, twice that many +1/+1 counters are placed on it instead";
|
||||
staticText = "If one or more +1/+1 counters would be put on a creature you control, twice that many +1/+1 counters are put on it instead";
|
||||
}
|
||||
|
||||
CorpsejackMenaceReplacementEffect(final CorpsejackMenaceReplacementEffect effect) {
|
||||
|
|
91
Mage.Sets/src/mage/cards/c/Crevasse.java
Normal file
91
Mage.Sets/src/mage/cards/c/Crevasse.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class Crevasse extends CardImpl {
|
||||
|
||||
public Crevasse(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
|
||||
|
||||
// Creatures with mountainwalk can be blocked as though they didn't have mountainwalk.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CrevasseEffect()));
|
||||
}
|
||||
|
||||
public Crevasse(final Crevasse card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Crevasse copy() {
|
||||
return new Crevasse(this);
|
||||
}
|
||||
}
|
||||
|
||||
class CrevasseEffect extends AsThoughEffectImpl {
|
||||
|
||||
public CrevasseEffect() {
|
||||
super(AsThoughEffectType.BLOCK_MOUNTAINWALK, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "Creatures with mountainwalk can be blocked as though they didn't have mountainwalk";
|
||||
}
|
||||
|
||||
public CrevasseEffect(final CrevasseEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrevasseEffect copy() {
|
||||
return new CrevasseEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -27,18 +27,22 @@
|
|||
*/
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.CurseOfTheSwineBoarToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
|
@ -58,7 +62,7 @@ public class CurseOfTheSwine extends CardImpl {
|
|||
|
||||
@Override
|
||||
public void adjustTargets(Ability ability, Game game) {
|
||||
if (ability instanceof SpellAbility) {
|
||||
if (ability instanceof SpellAbility && ability.getAbilityType().equals(AbilityType.SPELL)) {
|
||||
ability.getTargets().clear();
|
||||
ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX()));
|
||||
}
|
||||
|
@ -92,15 +96,24 @@ class CurseOfTheSwineEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
|
||||
Permanent creature = game.getPermanent(targetId);
|
||||
if (creature != null) {
|
||||
if (creature.moveToExile(null, null, source.getSourceId(), game) || creature.moveToZone(Zone.COMMAND, source.getSourceId(), game, false)) {
|
||||
CurseOfTheSwineBoarToken swineToken = new CurseOfTheSwineBoarToken();
|
||||
swineToken.putOntoBattlefield(1, game, source.getSourceId(), creature.getControllerId());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Map<UUID, Integer> playersWithTargets = new HashMap<>();
|
||||
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
|
||||
Permanent creature = game.getPermanent(targetId);
|
||||
if (creature != null) {
|
||||
if (controller.moveCards(creature, Zone.EXILED, source, game)) {
|
||||
playersWithTargets.put(creature.getControllerId(), playersWithTargets.getOrDefault(creature.getControllerId(), 0) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
CurseOfTheSwineBoarToken swineToken = new CurseOfTheSwineBoarToken();
|
||||
for (UUID playerId : playersWithTargets.keySet()) {
|
||||
swineToken.putOntoBattlefield(playersWithTargets.get(playerId), game, source.getSourceId(), playerId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
91
Mage.Sets/src/mage/cards/d/Deadfall.java
Normal file
91
Mage.Sets/src/mage/cards/d/Deadfall.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class Deadfall extends CardImpl {
|
||||
|
||||
public Deadfall(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
|
||||
|
||||
// Creatures with forestwalk can be blocked as though they didn't have forestwalk.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DeadfallEffect()));
|
||||
}
|
||||
|
||||
public Deadfall(final Deadfall card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deadfall copy() {
|
||||
return new Deadfall(this);
|
||||
}
|
||||
}
|
||||
|
||||
class DeadfallEffect extends AsThoughEffectImpl {
|
||||
|
||||
public DeadfallEffect() {
|
||||
super(AsThoughEffectType.BLOCK_FORESTWALK, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "Creatures with forestwalk can be blocked as though they didn't have forestwalk";
|
||||
}
|
||||
|
||||
public DeadfallEffect(final DeadfallEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeadfallEffect copy() {
|
||||
return new DeadfallEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -35,7 +35,6 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.DamageEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
@ -53,7 +52,7 @@ public class DinosaurHunter extends CardImpl {
|
|||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// Whenever Dinosaur Hunter deals combat damage to a Dinosaur, destroy that creature.
|
||||
// Whenever Dinosaur Hunter deals damage to a Dinosaur, destroy that creature.
|
||||
this.addAbility(new DinosaurHunterAbility());
|
||||
}
|
||||
|
||||
|
@ -89,11 +88,10 @@ class DinosaurHunterAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (((DamageEvent) event).isCombatDamage()
|
||||
&& event.getSourceId().equals(getSourceId())) {
|
||||
if (event.getSourceId().equals(getSourceId())) {
|
||||
Permanent targetPermanet = game.getPermanentOrLKIBattlefield(event.getTargetId());
|
||||
if (targetPermanet.hasSubtype(SubType.DINOSAUR, game)) {
|
||||
getEffects().get(0).setTargetPointer(new FixedTarget(targetPermanet, game));
|
||||
getEffects().setTargetPointer(new FixedTarget(targetPermanet, game));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +100,6 @@ class DinosaurHunterAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever {this} deals combat damage to a Dinosaur, destroy that creature.";
|
||||
return "Whenever {this} deals damage to a Dinosaur, destroy that creature.";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class DoublingSeason extends CardImpl {
|
|||
// If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CreateTwiceThatManyTokensEffect()));
|
||||
|
||||
// If an effect would place one or more counters on a permanent you control, it places twice that many of those counters on that permanent instead.
|
||||
// If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DoublingSeasonCounterEffect()));
|
||||
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ class DoublingSeasonCounterEffect extends ReplacementEffectImpl {
|
|||
|
||||
DoublingSeasonCounterEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false);
|
||||
staticText = "If an effect would place one or more counters on a permanent you control, it places twice that many of those counters on that permanent instead";
|
||||
staticText = "If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead";
|
||||
}
|
||||
|
||||
DoublingSeasonCounterEffect(final DoublingSeasonCounterEffect effect) {
|
||||
|
|
|
@ -31,7 +31,6 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.PutIntoGraveFromAnywhereSourceTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.effects.common.ShuffleIntoLibrarySourceEffect;
|
||||
import mage.abilities.keyword.FearAbility;
|
||||
|
@ -105,11 +104,7 @@ class DreadTriggeredAbility extends TriggeredAbilityImpl {
|
|||
if (event.getPlayerId().equals(this.getControllerId())) {
|
||||
Permanent permanent = game.getPermanent(event.getSourceId());
|
||||
if (permanent != null && permanent.isCreature()) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
if (effect instanceof DestroyTargetEffect) {
|
||||
effect.setTargetPointer(new FixedTarget(event.getSourceId()));
|
||||
}
|
||||
}
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent, game));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class EnduringScalelord extends CardImpl {
|
|||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Whenever one or more +1/+1 counters are place on another creature you control, you may put a +1/+1 counter on Enduring Scaleguard.
|
||||
// Whenever one or more +1/+1 counters are put on another creature you control, you may put a +1/+1 counter on Enduring Scaleguard.
|
||||
this.addAbility(new EnduringScalelordTriggeredAbility());
|
||||
|
||||
}
|
||||
|
@ -109,6 +109,6 @@ class EnduringScalelordTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever one or more +1/+1 counters are place on another creature you control, you may put a +1/+1 counter on {this}.";
|
||||
return "Whenever one or more +1/+1 counters are put on another creature you control, you may put a +1/+1 counter on {this}.";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ class ExhumeEffect extends OneShotEffect {
|
|||
FilterCreatureCard filterCreatureCard = new FilterCreatureCard("creature card from your graveyard");
|
||||
filterCreatureCard.add(new OwnerIdPredicate(playerId));
|
||||
TargetCardInGraveyard target = new TargetCardInGraveyard(filterCreatureCard);
|
||||
target.setNotTarget(true);
|
||||
if (target.canChoose(playerId, game)
|
||||
&& player.chooseTarget(outcome, target, source, game)) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
|
|
|
@ -59,11 +59,11 @@ public class FairgroundsTrumpeter extends CardImpl {
|
|||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// At the beginning of each end step, if a +1/+1 counter was placed on a permanent under your control this turn, put a +1/+1 counter on Fairgrounds Trumpeter.
|
||||
// At the beginning of each end step, if a +1/+1 counter was put on a permanent under your control this turn, put a +1/+1 counter on Fairgrounds Trumpeter.
|
||||
this.addAbility(new ConditionalTriggeredAbility(new BeginningOfEndStepTriggeredAbility(
|
||||
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
|
||||
TargetController.ANY, false), FairgroundsTrumpeterCondition.instance,
|
||||
"At the beginning of each end step, if a +1/+1 counter was placed on a permanent under your control this turn, put a +1/+1 counter on {this}."),
|
||||
"At the beginning of each end step, if a +1/+1 counter was put on a permanent under your control this turn, put a +1/+1 counter on {this}."),
|
||||
new FairgroundsTrumpeterWatcher());
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ enum FairgroundsTrumpeterCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "if a +1/+1 counter was placed on a permanent under your control this turn";
|
||||
return "if a +1/+1 counter was put on a permanent under your control this turn";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ public class FathomMage extends CardImpl {
|
|||
// has greater power or toughness than this creature, put a +1/+1 counter on this creature.)
|
||||
this.addAbility(new EvolveAbility());
|
||||
|
||||
//Whenever a +1/+1 counter is placed on Fathom Mage, you may draw a card.
|
||||
//Whenever a +1/+1 counter is put on Fathom Mage, you may draw a card.
|
||||
this.addAbility(new FathomMageTriggeredAbility());
|
||||
}
|
||||
|
||||
|
@ -102,6 +102,6 @@ class FathomMageTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever a +1/+1 counter is placed on {this}, " + super.getRule();
|
||||
return "Whenever a +1/+1 counter is put on {this}, " + super.getRule();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public class FlourishingDefenses extends CardImpl {
|
|||
public FlourishingDefenses(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{G}");
|
||||
|
||||
// Whenever a -1/-1 counter is placed on a creature, you may create a 1/1 green Elf Warrior creature token.
|
||||
// Whenever a -1/-1 counter is put on a creature, you may create a 1/1 green Elf Warrior creature token.
|
||||
this.addAbility(new FlourishingDefensesTriggeredAbility());
|
||||
|
||||
}
|
||||
|
@ -98,6 +98,6 @@ class FlourishingDefensesTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever a -1/-1 counter is placed on a creature, you may create a 1/1 green Elf Warrior creature token.";
|
||||
return "Whenever a -1/-1 counter is put on a creature, you may create a 1/1 green Elf Warrior creature token.";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,12 +30,13 @@ package mage.cards.g;
|
|||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.costs.common.TapTargetCost;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
|
@ -48,6 +49,7 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -62,7 +64,7 @@ public class GiltLeafArchdruid extends CardImpl {
|
|||
}
|
||||
|
||||
public GiltLeafArchdruid(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
|
||||
this.subtype.add(SubType.ELF);
|
||||
this.subtype.add(SubType.DRUID);
|
||||
|
||||
|
@ -73,7 +75,7 @@ public class GiltLeafArchdruid extends CardImpl {
|
|||
this.addAbility(new SpellCastControllerTriggeredAbility(new DrawCardSourceControllerEffect(1), filterSpell, true));
|
||||
|
||||
// Tap seven untapped Druids you control: Gain control of all lands target player controls.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainControlAllLandsEffect(Duration.EndOfGame), new TapTargetCost(new TargetControlledCreaturePermanent(7, 7, new FilterControlledCreaturePermanent(SubType.DRUID, "Druids you control"), true)));
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GiltLeafArchdruidEffect(), new TapTargetCost(new TargetControlledCreaturePermanent(7, 7, new FilterControlledCreaturePermanent(SubType.DRUID, "Druids you control"), true)));
|
||||
ability.addTarget(new TargetPlayer());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
@ -88,38 +90,36 @@ public class GiltLeafArchdruid extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class GainControlAllLandsEffect extends ContinuousEffectImpl {
|
||||
class GiltLeafArchdruidEffect extends OneShotEffect {
|
||||
|
||||
public GainControlAllLandsEffect(Duration duration) {
|
||||
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
|
||||
public GiltLeafArchdruidEffect() {
|
||||
super(Outcome.GainControl);
|
||||
this.staticText = "gain control of all lands target player controls";
|
||||
}
|
||||
|
||||
public GainControlAllLandsEffect(final GainControlAllLandsEffect effect) {
|
||||
public GiltLeafArchdruidEffect(final GiltLeafArchdruidEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GainControlAllLandsEffect copy() {
|
||||
return new GainControlAllLandsEffect(this);
|
||||
public GiltLeafArchdruidEffect copy() {
|
||||
return new GiltLeafArchdruidEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if (targetPlayer != null && targetPlayer.isInGame()) {
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_LANDS, targetPointer.getFirst(game, source), game)) {
|
||||
if (controller != null && targetPlayer != null) {
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_LANDS, targetPlayer.getId(), game)) {
|
||||
if (permanent != null) {
|
||||
permanent.changeControllerId(source.getControllerId(), game);
|
||||
ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, true);
|
||||
effect.setTargetPointer(new FixedTarget(permanent, game));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
discard();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return "Gain control of all lands target player controls";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
99
Mage.Sets/src/mage/cards/g/GostaDirk.java
Normal file
99
Mage.Sets/src/mage/cards/g/GostaDirk.java
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.keyword.FirstStrikeAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class GostaDirk extends CardImpl {
|
||||
|
||||
public GostaDirk(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}{U}{U}");
|
||||
addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.WARRIOR);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// First strike
|
||||
this.addAbility(FirstStrikeAbility.getInstance());
|
||||
|
||||
// Creatures with islandwalk can be blocked as though they didn't have islandwalk.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GostaDirkEffect()));
|
||||
}
|
||||
|
||||
public GostaDirk(final GostaDirk card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GostaDirk copy() {
|
||||
return new GostaDirk(this);
|
||||
}
|
||||
}
|
||||
|
||||
class GostaDirkEffect extends AsThoughEffectImpl {
|
||||
|
||||
public GostaDirkEffect() {
|
||||
super(AsThoughEffectType.BLOCK_ISLANDWALK, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "Creatures with islandwalk can be blocked as though they didn't have islandwalk";
|
||||
}
|
||||
|
||||
public GostaDirkEffect(final GostaDirkEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GostaDirkEffect copy() {
|
||||
return new GostaDirkEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return true;
|
||||
}
|
||||
}
|
91
Mage.Sets/src/mage/cards/g/GreatWall.java
Normal file
91
Mage.Sets/src/mage/cards/g/GreatWall.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class GreatWall extends CardImpl {
|
||||
|
||||
public GreatWall(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
|
||||
|
||||
// Creatures with plainswalk can be blocked as though they didn't have plainswalk.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GreatWallEffect()));
|
||||
}
|
||||
|
||||
public GreatWall(final GreatWall card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GreatWall copy() {
|
||||
return new GreatWall(this);
|
||||
}
|
||||
}
|
||||
|
||||
class GreatWallEffect extends AsThoughEffectImpl {
|
||||
|
||||
public GreatWallEffect() {
|
||||
super(AsThoughEffectType.BLOCK_PLAINSWALK, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "Creatures with plainswalk can be blocked as though they didn't have plainswalk";
|
||||
}
|
||||
|
||||
public GreatWallEffect(final GreatWallEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GreatWallEffect copy() {
|
||||
return new GreatWallEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -52,7 +52,7 @@ public class HardenedScales extends CardImpl {
|
|||
public HardenedScales(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}");
|
||||
|
||||
// If one or more +1/+1 counters would be placed on a creature you control, that many plus one +1/+1 counters are placed on it instead.
|
||||
// If one or more +1/+1 counters would be put on a creature you control, that many plus one +1/+1 counters are put on it instead.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HardenedScalesEffect()));
|
||||
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ class HardenedScalesEffect extends ReplacementEffectImpl {
|
|||
|
||||
HardenedScalesEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false);
|
||||
staticText = "If one or more +1/+1 counters would be placed on a creature you control, that many plus one +1/+1 counters are placed on it instead";
|
||||
staticText = "If one or more +1/+1 counters would be put on a creature you control, that many plus one +1/+1 counters are put on it instead";
|
||||
}
|
||||
|
||||
HardenedScalesEffect(final HardenedScalesEffect effect) {
|
||||
|
|
|
@ -29,10 +29,9 @@ package mage.cards.h;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.delayed.AtTheEndOfTurnStepPostDelayedTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -52,7 +51,7 @@ import mage.target.targetpointer.FixedTarget;
|
|||
public class HeatShimmer extends CardImpl {
|
||||
|
||||
public HeatShimmer(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
|
||||
|
||||
// Create a token that's a copy of target creature. That token has haste and "At the beginning of the end step, exile this permanent."
|
||||
this.getSpellAbility().addEffect(new HeatShimmerEffect());
|
||||
|
@ -89,15 +88,15 @@ class HeatShimmerEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
|
||||
if (controller != null && permanent != null) {
|
||||
if (controller != null
|
||||
&& permanent != null) {
|
||||
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true);
|
||||
effect.setTargetPointer(new FixedTarget(permanent, game));
|
||||
effect.apply(game, source);
|
||||
for (Permanent addedToken : effect.getAddedPermanent()) {
|
||||
Effect exileEffect = new ExileTargetEffect();
|
||||
exileEffect.setTargetPointer(new FixedTarget(addedToken, game));
|
||||
new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfTurnStepPostDelayedTriggeredAbility(exileEffect), false).apply(game, source);
|
||||
}
|
||||
ExileTargetEffect exileEffect = new ExileTargetEffect();
|
||||
exileEffect.setTargetPointer(new FixedTarget(effect.getAddedPermanent().get(0), game));
|
||||
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect);
|
||||
game.addDelayedTriggeredAbility(delayedAbility, source);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -104,10 +104,7 @@ class HotSoupTriggeredAbility extends TriggeredAbilityImpl {
|
|||
Permanent equipment = game.getPermanent(this.getSourceId());
|
||||
if (equipment != null && equipment.getAttachedTo() != null) {
|
||||
if (Objects.equals(event.getTargetId(), equipment.getAttachedTo())) {
|
||||
for(Effect effect : this.getEffects())
|
||||
{
|
||||
effect.setTargetPointer(new FixedTarget(equipment.getAttachedTo()));
|
||||
}
|
||||
this.getEffects().setTargetPointer(new FixedTarget(equipment.getAttachedTo(), game));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -118,4 +115,4 @@ class HotSoupTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public String getRule() {
|
||||
return "Whenever equipped creature is dealt damage, " + super.getRule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,9 +49,9 @@ import mage.cards.CardSetInfo;
|
|||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
|
@ -69,7 +69,7 @@ import mage.target.targetpointer.FixedTarget;
|
|||
public class KheruLichLord extends CardImpl {
|
||||
|
||||
public KheruLichLord(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{G}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{G}{U}");
|
||||
this.subtype.add(SubType.ZOMBIE);
|
||||
this.subtype.add(SubType.WIZARD);
|
||||
|
||||
|
@ -166,14 +166,8 @@ class KheruLichLordReplacementEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
if (card != null) {
|
||||
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, game.getState().getZone(card.getId()), true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
129
Mage.Sets/src/mage/cards/l/LordMagnus.java
Normal file
129
Mage.Sets/src/mage/cards/l/LordMagnus.java
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.l;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.keyword.FirstStrikeAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class LordMagnus extends CardImpl {
|
||||
|
||||
public LordMagnus(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{W}{W}");
|
||||
addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.DRUID);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// First strike
|
||||
this.addAbility(FirstStrikeAbility.getInstance());
|
||||
|
||||
// Creatures with plainswalk can be blocked as though they didn't have plainswalk.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LordMagnusFirstEffect()));
|
||||
|
||||
// Creatures with forestwalk can be blocked as though they didn't have forestwalk.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LordMagnusSecondEffect()));
|
||||
}
|
||||
|
||||
public LordMagnus(final LordMagnus card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LordMagnus copy() {
|
||||
return new LordMagnus(this);
|
||||
}
|
||||
}
|
||||
|
||||
class LordMagnusFirstEffect extends AsThoughEffectImpl {
|
||||
|
||||
public LordMagnusFirstEffect() {
|
||||
super(AsThoughEffectType.BLOCK_PLAINSWALK, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "Creatures with plainswalk can be blocked as though they didn't have plainswalk";
|
||||
}
|
||||
|
||||
public LordMagnusFirstEffect(final LordMagnusFirstEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LordMagnusFirstEffect copy() {
|
||||
return new LordMagnusFirstEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class LordMagnusSecondEffect extends AsThoughEffectImpl {
|
||||
|
||||
public LordMagnusSecondEffect() {
|
||||
super(AsThoughEffectType.BLOCK_FORESTWALK, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "Creatures with forestwalk can be blocked as though they didn't have forestwalk";
|
||||
}
|
||||
|
||||
public LordMagnusSecondEffect(final LordMagnusSecondEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LordMagnusSecondEffect copy() {
|
||||
return new LordMagnusSecondEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -63,7 +63,7 @@ public class MeliraSylvokOutcast extends CardImpl {
|
|||
// You can't get poison counters.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MeliraSylvokOutcastEffect()));
|
||||
|
||||
// Creatures you control can't have -1/-1 counters placed on them.
|
||||
// Creatures you control can't have -1/-1 counters put on them.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MeliraSylvokOutcastEffect2()));
|
||||
|
||||
// Creatures your opponents control lose infect.
|
||||
|
@ -118,7 +118,7 @@ class MeliraSylvokOutcastEffect2 extends ReplacementEffectImpl {
|
|||
|
||||
public MeliraSylvokOutcastEffect2() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.PreventDamage);
|
||||
staticText = "Creatures you control can't have -1/-1 counters placed on them";
|
||||
staticText = "Creatures you control can't have -1/-1 counters put on them";
|
||||
}
|
||||
|
||||
public MeliraSylvokOutcastEffect2(final MeliraSylvokOutcastEffect2 effect) {
|
||||
|
|
|
@ -51,7 +51,7 @@ public class MelirasKeepers extends CardImpl {
|
|||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Melira's Keepers can't have counters placed on it
|
||||
// Melira's Keepers can't have counters put on it
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantHaveCountersSourceEffect()));
|
||||
}
|
||||
|
||||
|
|
99
Mage.Sets/src/mage/cards/m/MoralityShift.java
Normal file
99
Mage.Sets/src/mage/cards/m/MoralityShift.java
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public class MoralityShift extends CardImpl {
|
||||
|
||||
public MoralityShift(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{B}{B}");
|
||||
|
||||
|
||||
// Exchange your graveyard and library. Then shuffle your library.
|
||||
this.getSpellAbility().addEffect(new MoralityShiftEffect());
|
||||
|
||||
}
|
||||
|
||||
public MoralityShift(final MoralityShift card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MoralityShift copy() {
|
||||
return new MoralityShift(this);
|
||||
}
|
||||
}
|
||||
|
||||
class MoralityShiftEffect extends OneShotEffect {
|
||||
|
||||
MoralityShiftEffect() {
|
||||
super(Outcome.AIDontUseIt);
|
||||
staticText = "Exchange your graveyard and library. Then shuffle your library.";
|
||||
}
|
||||
|
||||
MoralityShiftEffect(MoralityShiftEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MoralityShiftEffect copy() {
|
||||
return new MoralityShiftEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
List<Card> copyLibrary = controller.getLibrary().getCards(game);
|
||||
Set<Card> copyGraveyard = controller.getGraveyard().getCards(game);
|
||||
controller.getLibrary().clear();
|
||||
controller.getGraveyard().clear();
|
||||
controller.getGraveyard().addAll(copyLibrary);
|
||||
controller.getLibrary().addAll(copyGraveyard, game);
|
||||
controller.shuffleLibrary(source, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
70
Mage.Sets/src/mage/cards/m/MoxLotus.java
Normal file
70
Mage.Sets/src/mage/cards/m/MoxLotus.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
|
||||
import mage.abilities.mana.SimpleManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj/psjpsj
|
||||
*/
|
||||
public class MoxLotus extends CardImpl {
|
||||
|
||||
public MoxLotus(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{15}");
|
||||
|
||||
// {t}: Add infinity (or 1*10^9 to account for a potential mana reflection) to your mana pool.
|
||||
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.ColorlessMana(1000000000), new TapSourceCost()));
|
||||
|
||||
// {100}: Add one mana of any color to your mana pool.
|
||||
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(1), new ManaCostsImpl("{100}"));
|
||||
this.addAbility(ability);
|
||||
|
||||
// You don't lose life due to mana burn.
|
||||
// Situation normal??
|
||||
}
|
||||
|
||||
public MoxLotus(final MoxLotus card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MoxLotus copy() {
|
||||
return new MoxLotus(this);
|
||||
}
|
||||
}
|
|
@ -29,7 +29,6 @@ package mage.cards.n;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -48,7 +47,7 @@ import mage.target.targetpointer.FixedTarget;
|
|||
public class NoMercy extends CardImpl {
|
||||
|
||||
public NoMercy(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}");
|
||||
|
||||
// Whenever a creature deals damage to you, destroy it.
|
||||
this.addAbility(new NoMercyTriggeredAbility());
|
||||
|
@ -88,9 +87,7 @@ public class NoMercy extends CardImpl {
|
|||
if (event.getPlayerId().equals(this.getControllerId())) {
|
||||
Permanent permanent = game.getPermanent(event.getSourceId());
|
||||
if (permanent != null && permanent.isCreature()) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(event.getSourceId()));
|
||||
}
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent, game));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,11 +107,11 @@ class PandemoniumEffect extends OneShotEffect {
|
|||
if (enteringCreature != null) {
|
||||
Permanent targetPermanent = game.getPermanent(source.getTargets().getFirstTarget());
|
||||
if (targetPermanent != null) {
|
||||
targetPermanent.damage(enteringCreature.getPower().getValue(), source.getSourceId(), game, false, true);
|
||||
targetPermanent.damage(enteringCreature.getPower().getValue(), enteringCreature.getId(), game, false, true);
|
||||
} else {
|
||||
Player targetPlayer = game.getPlayer(source.getTargets().getFirstTarget());
|
||||
if (targetPlayer != null) {
|
||||
targetPlayer.damage(enteringCreature.getPower().getValue(), source.getSourceId(), game, false, true);
|
||||
targetPlayer.damage(enteringCreature.getPower().getValue(), enteringCreature.getId(), game, false, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -52,7 +52,7 @@ public class PrimalVigor extends CardImpl {
|
|||
|
||||
// If one or more tokens would be created, twice that many of those tokens are created instead.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PrimalVigorTokenEffect()));
|
||||
// If one or more +1/+1 counters would be placed on a creature, twice that many +1/+1 counters are placed on that creature instead.
|
||||
// If one or more +1/+1 counters would be put on a creature, twice that many +1/+1 counters are put on that creature instead.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PrimalVigorCounterEffect()));
|
||||
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ class PrimalVigorCounterEffect extends ReplacementEffectImpl {
|
|||
|
||||
PrimalVigorCounterEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false);
|
||||
staticText = "If one or more +1/+1 counters would be placed on a creature, twice that many +1/+1 counters are placed on that creature instead";
|
||||
staticText = "If one or more +1/+1 counters would be put on a creature, twice that many +1/+1 counters are put on that creature instead";
|
||||
}
|
||||
|
||||
PrimalVigorCounterEffect(final PrimalVigorCounterEffect effect) {
|
||||
|
|
91
Mage.Sets/src/mage/cards/q/Quagmire.java
Normal file
91
Mage.Sets/src/mage/cards/q/Quagmire.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.q;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class Quagmire extends CardImpl {
|
||||
|
||||
public Quagmire(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
|
||||
|
||||
// Creatures with swampwalk can be blocked as though they didn't have swampwalk.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new QuagmireEffect()));
|
||||
}
|
||||
|
||||
public Quagmire(final Quagmire card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Quagmire copy() {
|
||||
return new Quagmire(this);
|
||||
}
|
||||
}
|
||||
|
||||
class QuagmireEffect extends AsThoughEffectImpl {
|
||||
|
||||
public QuagmireEffect() {
|
||||
super(AsThoughEffectType.BLOCK_SWAMPWALK, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "Creatures with swampwalk can be blocked as though they didn't have swampwalk";
|
||||
}
|
||||
|
||||
public QuagmireEffect(final QuagmireEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuagmireEffect copy() {
|
||||
return new QuagmireEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -25,34 +25,34 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
|
@ -60,12 +60,12 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public class SkullmaneBaku extends CardImpl {
|
||||
|
||||
public SkullmaneBaku(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
|
||||
this.subtype.add(SubType.SPIRIT);
|
||||
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
|
||||
// Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Skullmane Baku.
|
||||
this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance()), StaticFilters.SPIRIT_OR_ARCANE_CARD, true));
|
||||
|
||||
|
@ -85,7 +85,7 @@ public class SkullmaneBaku extends CardImpl {
|
|||
public SkullmaneBaku copy() {
|
||||
return new SkullmaneBaku(this);
|
||||
}
|
||||
|
||||
|
||||
static class SkullmaneBakuUnboostEffect extends OneShotEffect {
|
||||
|
||||
public SkullmaneBakuUnboostEffect() {
|
||||
|
@ -102,12 +102,14 @@ public class SkullmaneBaku extends CardImpl {
|
|||
int numberToUnboost = 0;
|
||||
for (Cost cost : source.getCosts()) {
|
||||
if (cost instanceof RemoveVariableCountersSourceCost) {
|
||||
numberToUnboost = ((RemoveVariableCountersSourceCost)cost).getAmount() * -1;
|
||||
numberToUnboost = ((RemoveVariableCountersSourceCost) cost).getAmount() * -1;
|
||||
}
|
||||
}
|
||||
Permanent creature = game.getPermanent(targetPointer.getFirst(game, source));
|
||||
Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (creature != null && numberToUnboost != 0) {
|
||||
creature.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(numberToUnboost, numberToUnboost, Duration.EndOfTurn)), source.getSourceId(), game, false);
|
||||
ContinuousEffect effect = new BoostTargetEffect(numberToUnboost, numberToUnboost, Duration.EndOfTurn);
|
||||
effect.setTargetPointer(new FixedTarget(creature, game));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -118,4 +120,4 @@ public class SkullmaneBaku extends CardImpl {
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
91
Mage.Sets/src/mage/cards/s/StaffOfTheAges.java
Normal file
91
Mage.Sets/src/mage/cards/s/StaffOfTheAges.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class StaffOfTheAges extends CardImpl {
|
||||
|
||||
public StaffOfTheAges(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// Creatures with landwalk abilities can be blocked as though they didn't have those abilities.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new StaffOfTheAgesEffect()));
|
||||
}
|
||||
|
||||
public StaffOfTheAges(final StaffOfTheAges card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StaffOfTheAges copy() {
|
||||
return new StaffOfTheAges(this);
|
||||
}
|
||||
}
|
||||
|
||||
class StaffOfTheAgesEffect extends AsThoughEffectImpl {
|
||||
|
||||
public StaffOfTheAgesEffect() {
|
||||
super(AsThoughEffectType.BLOCK_LANDWALK, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "Creatures with landwalk abilities can be blocked as though they didn't have those abilities";
|
||||
}
|
||||
|
||||
public StaffOfTheAgesEffect(final StaffOfTheAgesEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StaffOfTheAgesEffect copy() {
|
||||
return new StaffOfTheAgesEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -53,7 +53,7 @@ public class Tatterkite extends CardImpl {
|
|||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Tatterkite can't have counters placed on it.
|
||||
// Tatterkite can't have counters put on it.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantHaveCountersSourceEffect()));
|
||||
|
||||
}
|
||||
|
|
91
Mage.Sets/src/mage/cards/u/Undertow.java
Normal file
91
Mage.Sets/src/mage/cards/u/Undertow.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.u;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class Undertow extends CardImpl {
|
||||
|
||||
public Undertow(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
|
||||
|
||||
// Creatures with islandwalk can be blocked as though they didn't have islandwalk.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new UndertowEffect()));
|
||||
}
|
||||
|
||||
public Undertow(final Undertow card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Undertow copy() {
|
||||
return new Undertow(this);
|
||||
}
|
||||
}
|
||||
|
||||
class UndertowEffect extends AsThoughEffectImpl {
|
||||
|
||||
public UndertowEffect() {
|
||||
super(AsThoughEffectType.BLOCK_ISLANDWALK, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "Creatures with islandwalk can be blocked as though they didn't have islandwalk";
|
||||
}
|
||||
|
||||
public UndertowEffect(final UndertowEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UndertowEffect copy() {
|
||||
return new UndertowEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return true;
|
||||
}
|
||||
}
|
168
Mage.Sets/src/mage/cards/u/UphillBattle.java
Normal file
168
Mage.Sets/src/mage/cards/u/UphillBattle.java
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.u;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.EntersTheBattlefieldEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.watchers.Watcher;
|
||||
import mage.watchers.common.CreatureWasCastWatcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author chrvanorle
|
||||
*/
|
||||
public class UphillBattle extends CardImpl {
|
||||
|
||||
public UphillBattle(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
|
||||
|
||||
// Creatures played by your opponents enter the battlefield tapped.
|
||||
Ability tapAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new UphillBattleTapEffect());
|
||||
tapAbility.addWatcher(new CreatureWasCastWatcher());
|
||||
tapAbility.addWatcher(new PlayCreatureLandWatcher());
|
||||
addAbility(tapAbility);
|
||||
}
|
||||
|
||||
public UphillBattle(final UphillBattle card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UphillBattle copy() {
|
||||
return new UphillBattle(this);
|
||||
}
|
||||
}
|
||||
|
||||
class PlayCreatureLandWatcher extends Watcher {
|
||||
|
||||
final Set<UUID> playerPlayedLand = new HashSet<>(); // player that played land
|
||||
final Set<UUID> landPlayed = new HashSet<>(); // land played
|
||||
|
||||
public PlayCreatureLandWatcher() {
|
||||
super(PlayCreatureLandWatcher.class.getSimpleName(), WatcherScope.GAME);
|
||||
}
|
||||
|
||||
public PlayCreatureLandWatcher(final PlayCreatureLandWatcher watcher) {
|
||||
super(watcher);
|
||||
playerPlayedLand.addAll(watcher.playerPlayedLand);
|
||||
landPlayed.addAll(watcher.landPlayed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayCreatureLandWatcher copy() {
|
||||
return new PlayCreatureLandWatcher(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.PLAY_LAND) {
|
||||
Card card = game.getCard(event.getTargetId());
|
||||
if (card != null
|
||||
&& card.isLand()
|
||||
&& card.isCreature()
|
||||
&& !playerPlayedLand.contains(event.getPlayerId())) {
|
||||
playerPlayedLand.add(event.getPlayerId());
|
||||
landPlayed.add(event.getTargetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
playerPlayedLand.clear();
|
||||
landPlayed.clear();
|
||||
super.reset();
|
||||
}
|
||||
|
||||
public boolean landPlayed(UUID playerId) {
|
||||
return playerPlayedLand.contains(playerId);
|
||||
}
|
||||
|
||||
public boolean wasLandPlayed(UUID landId) {
|
||||
return landPlayed.contains(landId);
|
||||
}
|
||||
}
|
||||
|
||||
class UphillBattleTapEffect extends ReplacementEffectImpl {
|
||||
|
||||
UphillBattleTapEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Tap);
|
||||
staticText = "Creatures played by your opponents enter the battlefield tapped";
|
||||
}
|
||||
|
||||
UphillBattleTapEffect(final UphillBattleTapEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Permanent target = ((EntersTheBattlefieldEvent) event).getTarget();
|
||||
CreatureWasCastWatcher creatureSpellWatcher = (CreatureWasCastWatcher) game.getState().getWatchers().get(CreatureWasCastWatcher.class.getSimpleName());
|
||||
PlayCreatureLandWatcher landWatcher = (PlayCreatureLandWatcher) game.getState().getWatchers().get(PlayCreatureLandWatcher.class.getSimpleName());
|
||||
|
||||
if (target != null
|
||||
&& ((creatureSpellWatcher != null && creatureSpellWatcher.wasCreatureCastThisTurn(target.getId()))
|
||||
|| (landWatcher != null && landWatcher.wasLandPlayed(target.getId())))) {
|
||||
target.setTapped(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
|
||||
Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
|
||||
if (permanent != null && permanent.isCreature()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UphillBattleTapEffect copy() {
|
||||
return new UphillBattleTapEffect(this);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue