diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java
index 91edab2d0f2..8a253db1154 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java
@@ -650,6 +650,12 @@ public class NewTableDialog extends MageDialog {
return false;
}
break;
+ case "Variant Magic - Freeform Unlimited Commander":
+ if (!options.getGameType().startsWith("Freeform Unlimited Commander")) {
+ JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Deck type Freeform+ Commander needs also a Freeform Unlimited Commander game type", "Error", JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+ break;
case "Variant Magic - Brawl":
case "Variant Magic - Duel Brawl":
if (!options.getGameType().startsWith("Brawl")) {
@@ -698,6 +704,12 @@ public class NewTableDialog extends MageDialog {
return false;
}
break;
+ case "Freeform Unlimited Commander":
+ if (!options.getDeckType().equals("Variant Magic - Freeform Unlimited Commander")) {
+ JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Deck type Freeform Unlimited Commander needs also a Freeform Unlimited Commander game type", "Error", JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+ break;
case "Brawl Two Player Duel":
case "Brawl Free For All":
if (!options.getDeckType().equals("Variant Magic - Brawl")
diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
index b0533fd92ee..097a738b7e8 100644
--- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
+++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
@@ -818,7 +818,7 @@ public class TablesPanel extends javax.swing.JPanel {
formatFilterList.add(RowFilter.regexFilter("^Constructed - Premodern", TablesTableModel.COLUMN_DECK_TYPE));
}
if (btnFormatCommander.isSelected()) {
- formatFilterList.add(RowFilter.regexFilter("^Commander|^Duel Commander|^Centurion Commander|^Penny Dreadful Commander|^Freeform Commander|^MTGO 1v1 Commander|^Duel Brawl|^Brawl", TablesTableModel.COLUMN_DECK_TYPE));
+ formatFilterList.add(RowFilter.regexFilter("^Commander|^Duel Commander|^Centurion Commander|^Penny Dreadful Commander|^Freeform Commander|^Freeform Unlimited Commander|^MTGO 1v1 Commander|^Duel Brawl|^Brawl", TablesTableModel.COLUMN_DECK_TYPE));
}
if (btnFormatTinyLeader.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Tiny", TablesTableModel.COLUMN_DECK_TYPE));
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformUnlimitedCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformUnlimitedCommander.java
new file mode 100644
index 00000000000..5878ac06237
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformUnlimitedCommander.java
@@ -0,0 +1,37 @@
+package mage.deck;
+
+import mage.cards.ExpansionSet;
+import mage.cards.Sets;
+import mage.cards.decks.Deck;
+
+public class FreeformUnlimitedCommander extends FreeformCommander {
+
+ public FreeformUnlimitedCommander() {
+ this("Freeform Unlimited Commander");
+ }
+
+ public FreeformUnlimitedCommander(String name) {
+ super(name);
+ for (ExpansionSet set : Sets.getInstance().values()) {
+ setCodes.add(set.getCode());
+ }
+
+ // no banned cards
+ this.banned.clear();
+ }
+
+ @Override
+ public int getDeckMinSize() {
+ return 0;
+ }
+
+ @Override
+ public int getSideboardMinSize() {
+ return 0;
+ }
+
+ @Override
+ public boolean validate(Deck deck) {
+ return true;
+ }
+}
diff --git a/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/pom.xml
new file mode 100644
index 00000000000..c152068d35b
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+
+
+ org.mage
+ mage-server-plugins
+ 1.4.42
+
+
+ mage-game-freeformunlimitedcommander
+ jar
+ Mage Game Freeform Unlimited Commander
+
+
+
+ ${project.groupId}
+ mage
+ ${project.version}
+
+
+ org.mage
+ mage-game-freeformunlimitedcommander
+ 1.4.42
+ compile
+
+
+ org.mage
+ mage-game-freeformcommanderfreeforall
+ 1.4.42
+ compile
+
+
+
+
+ src
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+ maven-resources-plugin
+
+ UTF-8
+
+
+
+
+
+ mage-game-freeformunlimitedcommander
+
+
+
+
+
diff --git a/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/src/mage/game/FreeformUnlimitedCommander.java b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/src/mage/game/FreeformUnlimitedCommander.java
new file mode 100644
index 00000000000..68a077cd269
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/src/mage/game/FreeformUnlimitedCommander.java
@@ -0,0 +1,19 @@
+package mage.game;
+
+import mage.constants.MultiplayerAttackOption;
+import mage.constants.RangeOfInfluence;
+import mage.game.mulligan.Mulligan;
+
+public class FreeformUnlimitedCommander extends FreeformCommanderFreeForAll {
+
+ protected int numPlayers;
+
+ public FreeformUnlimitedCommander(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
+ super(attackOption, range, mulligan, startLife);
+ }
+
+ public FreeformUnlimitedCommander(final FreeformUnlimitedCommander game) {
+ super(game);
+ this.numPlayers = game.numPlayers;
+ }
+}
diff --git a/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/src/mage/game/FreeformUnlimitedCommanderMatch.java b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/src/mage/game/FreeformUnlimitedCommanderMatch.java
new file mode 100644
index 00000000000..8a6af4e5dd7
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/src/mage/game/FreeformUnlimitedCommanderMatch.java
@@ -0,0 +1,10 @@
+package mage.game;
+
+import mage.game.match.MatchOptions;
+
+public class FreeformUnlimitedCommanderMatch extends FreeformCommanderFreeForAllMatch {
+
+ public FreeformUnlimitedCommanderMatch(MatchOptions options) {
+ super(options);
+ }
+}
diff --git a/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/src/mage/game/FreeformUnlimitedCommanderType.java b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/src/mage/game/FreeformUnlimitedCommanderType.java
new file mode 100644
index 00000000000..cf3ad35b10c
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/src/mage/game/FreeformUnlimitedCommanderType.java
@@ -0,0 +1,24 @@
+package mage.game;
+
+public class FreeformUnlimitedCommanderType extends FreeformCommanderFreeForAllType {
+
+ public FreeformUnlimitedCommanderType() {
+ this.name = "Freeform Unlimited Commander";
+ this.maxPlayers = 10;
+ this.minPlayers = 2;
+ this.numTeams = 0;
+ this.playersPerTeam = 0;
+ this.useAttackOption = true;
+ this.useRange = true;
+ this.sideboardingAllowed = false;
+ }
+
+ protected FreeformUnlimitedCommanderType(final FreeformUnlimitedCommanderType matchType) {
+ super(matchType);
+ }
+
+ @Override
+ public FreeformUnlimitedCommanderType copy() {
+ return new FreeformUnlimitedCommanderType(this);
+ }
+}
diff --git a/Mage.Server.Plugins/pom.xml b/Mage.Server.Plugins/pom.xml
index d67e9aebad6..c449b61d49b 100644
--- a/Mage.Server.Plugins/pom.xml
+++ b/Mage.Server.Plugins/pom.xml
@@ -28,6 +28,7 @@
Mage.Game.PennyDreadfulCommanderFreeForAll
Mage.Game.FreeformCommanderDuel
Mage.Game.FreeformCommanderFreeForAll
+ Mage.Game.FreeformUnlimitedCommander
Mage.Game.BrawlDuel
Mage.Game.BrawlFreeForAll
Mage.Game.OathbreakerDuel
diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml
index dfec88e164d..674531e5f88 100644
--- a/Mage.Server/config/config.xml
+++ b/Mage.Server/config/config.xml
@@ -81,6 +81,7 @@
+
@@ -176,6 +177,7 @@
+
diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml
index 02814c2b5e1..19e6b37fcb9 100644
--- a/Mage.Server/pom.xml
+++ b/Mage.Server/pom.xml
@@ -191,6 +191,12 @@
${project.version}
runtime
+
+ ${project.groupId}
+ mage-game-freeformunlimitedcommander
+ ${project.version}
+ runtime
+
${project.groupId}
mage-game-freeformcommanderduel
diff --git a/Mage.Server/release/config/config.xml b/Mage.Server/release/config/config.xml
index 40d78b18a37..46c9f625e21 100644
--- a/Mage.Server/release/config/config.xml
+++ b/Mage.Server/release/config/config.xml
@@ -75,6 +75,7 @@
+
@@ -170,6 +171,7 @@
+
diff --git a/Mage.Tests/src/test/java/org/mage/test/deck/FreeformUnlimitedCommanderTest.java b/Mage.Tests/src/test/java/org/mage/test/deck/FreeformUnlimitedCommanderTest.java
new file mode 100644
index 00000000000..c4179897bec
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/deck/FreeformUnlimitedCommanderTest.java
@@ -0,0 +1,56 @@
+package org.mage.test.deck;
+
+import mage.cards.decks.Deck;
+import mage.deck.FreeformUnlimitedCommander;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.MageTestPlayerBase;
+
+public class FreeformUnlimitedCommanderTest extends MageTestPlayerBase {
+
+ @Test
+ public void test_construct_returnsFreeformPlusCommander() {
+ // Act
+ FreeformUnlimitedCommander deck = new FreeformUnlimitedCommander();
+
+ // Assert
+ Assert.assertEquals(FreeformUnlimitedCommander.class, deck.getClass());
+ }
+
+ @Test
+ public void test_getDeckMinSize_returns0() {
+ // Arrange
+ FreeformUnlimitedCommander deck = new FreeformUnlimitedCommander();
+
+ // Act
+ int actual = deck.getDeckMinSize();
+
+ // Assert
+ Assert.assertEquals(0, actual);
+ }
+
+ @Test
+ public void test_getSideboardMinSize_returns0() {
+ // Arrange
+ FreeformUnlimitedCommander deck = new FreeformUnlimitedCommander();
+
+ // Act
+ int actual = deck.getSideboardMinSize();
+
+ // Assert
+ Assert.assertEquals(0, actual);
+ }
+
+ @Test
+ public void test_validate_returnsTrue() {
+ // Arrange
+ FreeformUnlimitedCommander deck = new FreeformUnlimitedCommander();
+ Deck example = new Deck();
+
+ // Act
+ boolean actual = deck.validate(example);
+
+ // Assert
+ Assert.assertTrue(actual);
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderMatchTest.java b/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderMatchTest.java
new file mode 100644
index 00000000000..e40706dfe5d
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderMatchTest.java
@@ -0,0 +1,64 @@
+package org.mage.test.game.FreeformUnlimitedCommander;
+
+import mage.game.FreeformUnlimitedCommanderMatch;
+import mage.game.match.Match;
+import mage.game.match.MatchOptions;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.MageTestPlayerBase;
+
+public class FreeformUnlimitedCommanderMatchTest extends MageTestPlayerBase {
+
+ @Test
+ public void test_construct_returnsFreeformPlusCommanderMatch() {
+ // Arrange
+ MatchOptions options = new MatchOptions(
+ "test name",
+ "test match name",
+ false,
+ 2
+ );
+
+ // Act
+ Match match = new FreeformUnlimitedCommanderMatch(options);
+
+ // Assert
+ Assert.assertEquals(FreeformUnlimitedCommanderMatch.class, match.getClass());
+ }
+
+ @Test
+ public void test_getName_returnsTestName() {
+ // Arrange
+ MatchOptions options = new MatchOptions(
+ "test name",
+ "test match name",
+ false,
+ 2
+ );
+ Match match = new FreeformUnlimitedCommanderMatch(options);
+
+ // Act
+ String actual = match.getName();
+
+ // Assert
+ Assert.assertEquals("test name", actual);
+ }
+
+ @Test
+ public void test_getOptions_returnsOriginalOptions() {
+ // Arrange
+ MatchOptions options = new MatchOptions(
+ "test name",
+ "test match name",
+ false,
+ 2
+ );
+ Match match = new FreeformUnlimitedCommanderMatch(options);
+
+ // Act
+ MatchOptions actual = match.getOptions();
+
+ // Assert
+ Assert.assertEquals(options, actual);
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderTest.java b/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderTest.java
new file mode 100644
index 00000000000..66ff3df89e4
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderTest.java
@@ -0,0 +1,31 @@
+package org.mage.test.game.FreeformUnlimitedCommander;
+
+import mage.constants.MultiplayerAttackOption;
+import mage.constants.RangeOfInfluence;
+import mage.game.FreeformUnlimitedCommander;
+import mage.game.mulligan.LondonMulligan;
+import mage.game.mulligan.Mulligan;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.MageTestPlayerBase;
+
+public class FreeformUnlimitedCommanderTest extends MageTestPlayerBase {
+
+ @Test
+ public void test_construct_returnsFreeformPlusCommander() {
+ // Arrange
+ Mulligan mulligan = new LondonMulligan(1);
+ int startLife = 40;
+
+ // Assert
+ FreeformUnlimitedCommander game = new FreeformUnlimitedCommander(
+ MultiplayerAttackOption.MULTIPLE,
+ RangeOfInfluence.ALL,
+ mulligan,
+ startLife
+ );
+
+ // Assert
+ Assert.assertEquals(FreeformUnlimitedCommander.class, game.getClass());
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderTypeTest.java b/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderTypeTest.java
new file mode 100644
index 00000000000..725c63384b8
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderTypeTest.java
@@ -0,0 +1,100 @@
+package org.mage.test.game.FreeformUnlimitedCommander;
+
+import mage.game.FreeformUnlimitedCommanderType;
+import mage.game.match.MatchType;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.MageTestPlayerBase;
+
+public class FreeformUnlimitedCommanderTypeTest extends MageTestPlayerBase {
+
+ @Test
+ public void test_construct_returnsFreeformPlusCommanderType() {
+ // Act
+ MatchType gameType = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertEquals(FreeformUnlimitedCommanderType.class, gameType.getClass());
+ }
+
+ @Test
+ public void test_toString_returnsFreeformPlusCommander() {
+ // Arrange
+ MatchType gametype = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertEquals("Freeform Unlimited Commander", gametype.toString());
+ }
+
+ @Test
+ public void test_getName_returnsFreeformPlusCommander() {
+ // Arrange
+ MatchType gametype = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertEquals("Freeform Unlimited Commander", gametype.getName());
+ }
+
+ @Test
+ public void test_getMinPlayers_returns3() {
+ // Arrange
+ MatchType gametype = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertEquals(2, gametype.getMinPlayers());
+ }
+
+ @Test
+ public void test_getMaxPlayers_returns10() {
+ // Arrange
+ MatchType gametype = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertEquals(10, gametype.getMaxPlayers());
+ }
+
+ @Test
+ public void test_getNumTeams_returns0() {
+ // Arrange
+ MatchType gametype = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertEquals(0, gametype.getNumTeams());
+ }
+
+ @Test
+ public void test_getPlayersPerTeam_returns0() {
+ // Arrange
+ MatchType gametype = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertEquals(0, gametype.getPlayersPerTeam());
+ }
+
+ @Test
+ public void test_isUseRange_returnsTrue() {
+ // Arrange
+ MatchType gametype = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertTrue(gametype.isUseRange());
+ }
+
+ @Test
+ public void test_isUseAttackOption_returnsTrue() {
+ // Arrange
+ MatchType gametype = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertTrue(gametype.isUseAttackOption());
+ }
+
+ @Test
+ public void test_isSideboardingAllowed_returnsFalse() {
+ // Arrange
+ MatchType gametype = new FreeformUnlimitedCommanderType();
+
+ // Assert
+ Assert.assertFalse(gametype.isSideboardingAllowed());
+ }
+}