diff --git a/.gitattributes b/.gitattributes
index 0afd349226b..fee353731b7 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -14335,6 +14335,7 @@ forge-gui/res/cardsfolder/t/thorn_of_amethyst.txt svneol=native#text/plain
forge-gui/res/cardsfolder/t/thorn_thallid.txt svneol=native#text/plain
forge-gui/res/cardsfolder/t/thorn_thrash_viashino.txt svneol=native#text/plain
forge-gui/res/cardsfolder/t/thornbite_staff.txt -text
+forge-gui/res/cardsfolder/t/thornbow_archer.txt -text
forge-gui/res/cardsfolder/t/thorncaster_sliver.txt -text
forge-gui/res/cardsfolder/t/thornling.txt svneol=native#text/plain
forge-gui/res/cardsfolder/t/thornscape_apprentice.txt svneol=native#text/plain
diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java
index 4331c2e4dc2..39b9486de62 100644
--- a/forge-game/src/main/java/forge/game/player/Player.java
+++ b/forge-game/src/main/java/forge/game/player/Player.java
@@ -62,6 +62,7 @@ import forge.game.zone.ZoneType;
import forge.item.IPaperCard;
import forge.util.Aggregates;
import forge.util.collect.FCollection;
+import forge.util.Expressions;
import forge.util.Lang;
import forge.util.MyRandom;
@@ -69,6 +70,8 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentSkipListMap;
+import org.apache.commons.lang3.StringUtils;
+
/**
*
* Abstract Player class.
@@ -1727,7 +1730,7 @@ public class Player extends GameEntity implements Comparable {
@Override
public final boolean isValid(final String restriction, final Player sourceController, final Card source) {
- final String[] incR = restriction.split("\\.");
+ final String[] incR = restriction.split("\\.", 2);
if (incR[0].equals("Opponent")) {
if (equals(sourceController) || !isOpponentOf(sourceController)) {
@@ -1860,6 +1863,15 @@ public class Player extends GameEntity implements Comparable {
if (getPoisonCounters() <= 0) {
return false;
}
+ } else if (property.startsWith("controls")) {
+ final String[] type = property.substring(8).split("_");
+ final CardCollectionView list = CardLists.getValidCards(getCardsIn(ZoneType.Battlefield), type[0], sourceController, source);
+ String comparator = type[1];
+ String compareTo = comparator.substring(2);
+ int y = StringUtils.isNumeric(compareTo) ? Integer.parseInt(compareTo) : 0;
+ if (!Expressions.compare(list.size(), comparator, y)) {
+ return false;
+ }
} else if (property.startsWith("withMore")) {
final String cardType = property.split("sThan")[0].substring(8);
final Player controller = "Active".equals(property.split("sThan")[1]) ? game.getPhaseHandler().getPlayerTurn() : sourceController;
diff --git a/forge-gui/res/cardsfolder/d/disorder.txt b/forge-gui/res/cardsfolder/d/disorder.txt
index 9f9affdea5f..6b237e0b734 100644
--- a/forge-gui/res/cardsfolder/d/disorder.txt
+++ b/forge-gui/res/cardsfolder/d/disorder.txt
@@ -1,14 +1,7 @@
Name:Disorder
ManaCost:1 R
Types:Sorcery
-A:SP$ DamageAll | Cost$ 1 R | ValidCards$ Creature.White | NumDmg$ 2 | SubAbility$ RepeatedDisorder | RememberDamaged$ True | SpellDescription$ Disorder deals 2 damage to each white creature and each player who controls a white creature.
-SVar:RepeatedDisorder:DB$ RepeatEach | Cost$ 2 W W | RepeatPlayers$ Player | RepeatSubAbility$ DisorderPlayerDmg | SubAbility$ DBCleanup
-SVar:DisorderPlayerDmg:DB$ DealDamage | Defined$ Player.IsRemembered | ConditionCheckSVar$ DisorderX | ConditionSVarCompare$ GE1 | NumDmg$ 2 | References$ DisorderX,StillInPlay,AlreadyDestroyed
-SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
-#Seeing as it should seal the damage to the creatures and players simultaneously, check whether the player DID have white creatures before the creature damage.
-SVar:AlreadyDestroyed:RememberedLKI$Valid Creature.White+RememberedPlayerCtrl
-SVar:StillInPlay:Count$Valid Creature.White+RememberedPlayerCtrl
-SVar:DisorderX:SVar$AlreadyDestroyed/Plus.StillInPlay
+A:SP$ DamageAll | Cost$ 1 R | ValidCards$ Creature.White | ValidPlayers$ Player.controlsCreature.White_GE1 | NumDmg$ 2 | SpellDescription$ Disorder deals 2 damage to each white creature and each player who controls a white creature.
SVar:RemRandomDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/disorder.jpg
Oracle:Disorder deals 2 damage to each white creature and each player who controls a white creature.
diff --git a/forge-gui/res/cardsfolder/t/thornbow_archer.txt b/forge-gui/res/cardsfolder/t/thornbow_archer.txt
new file mode 100644
index 00000000000..41988f7ee9d
--- /dev/null
+++ b/forge-gui/res/cardsfolder/t/thornbow_archer.txt
@@ -0,0 +1,9 @@
+Name:Thornbow Archer
+ManaCost:B
+Types:Creature Elf Archer
+PT:1/2
+T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigLoseLife | TriggerDescription$ Whenever CARDNAME attacks, each opponent who doesn't control an Elf loses 1 life.
+SVar:TrigLoseLife:AB$ LoseLife | Cost$ 0 | Defined$ Player.Opponent+controlsElf_EQ0 | LifeAmount$ 1
+SVar:HasAttackEffect:TRUE
+SVar:Picture:http://www.wizards.com/global/images/magic/general/thornbow_archer.jpg
+Oracle:Whenever Infectious Horror attacks, each opponent who doesn't control an Elf loses 1 life.