mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
merge latest trunk
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -14153,6 +14153,7 @@ src/main/java/forge/quest/QuestEventDifficulty.java -text
|
||||
src/main/java/forge/quest/QuestEventDuel.java svneol=native#text/plain
|
||||
src/main/java/forge/quest/QuestEventManager.java svneol=native#text/plain
|
||||
src/main/java/forge/quest/QuestMode.java -text
|
||||
src/main/java/forge/quest/QuestRewardCard.java -text
|
||||
src/main/java/forge/quest/QuestRewardCardDuplicate.java -text
|
||||
src/main/java/forge/quest/QuestRewardCardFiltered.java -text
|
||||
src/main/java/forge/quest/QuestUtil.java svneol=native#text/plain
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Name:Abduction
|
||||
ManaCost:2 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 2 U U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigUntap | TriggerDescription$ When CARDNAME enters the battlefield, untap enchanted creature.
|
||||
SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Enchanted
|
||||
SVar:TrigUntap:AB$ Untap | Cost$ 0 | Defined$ Enchanted
|
||||
T:Mode$ ChangesZone | ValidCard$ Card.AttachedBy | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigReturnOwner | TriggerDescription$ When enchanted creature dies, return that card to the battlefield under its owner's control.
|
||||
SVar:TrigReturnOwner:AB$ ChangeZone | Cost$ 0 | Defined$ TriggeredCard | Origin$ Graveyard | Destination$ Battlefield
|
||||
SVar:PlayMain1:TRUE
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Annex
|
||||
ManaCost:2 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted land.
|
||||
K:Enchant land
|
||||
A:SP$ Attach | Cost$ 2 U U | ValidTgts$ Land | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Land.EnchantedBy | GainControl$ You | Description$ You control enchanted land.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/annex.jpg
|
||||
Oracle:Enchant land (Target a land as you cast this. This card enters the battlefield attached to that land.)\nYou control enchanted land.
|
||||
SetInfo:ONS Uncommon
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
Name:Biting Tether
|
||||
ManaCost:4 U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 4 U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, put a -1/-1 counter on enchanted creature.
|
||||
SVar:TrigPutCounter:AB$ PutCounter | Cost$ 0 | Defined$ Enchanted | CounterType$ M1M1 | CounterNum$ 1
|
||||
SVar:PlayMain1:TRUE
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/biting_tether.jpg
|
||||
Oracle:Enchant creature\nYou control enchanted creature.\nAt the beginning of your upkeep, put a -1/-1 counter on enchanted creature.
|
||||
SetInfo:SHM Uncommon
|
||||
@@ -1,10 +1,9 @@
|
||||
Name:Confiscate
|
||||
ManaCost:4 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted permanent.
|
||||
K:Enchant permanent
|
||||
A:SP$ Attach | Cost$ 4 U U | ValidTgts$ Permanent | AILogic$ GainControl
|
||||
SVar:PlayMain1:TRUE
|
||||
S:Mode$ Continuous | Affected$ Permanent.EnchantedBy | GainControl$ You | Description$ You control enchanted permanent.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/confiscate.jpg
|
||||
Oracle:Enchant permanent (Target a permanent as you cast this. This card enters the battlefield attached to that permanent.)\nYou control enchanted permanent.
|
||||
SetInfo:8ED Uncommon
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Conquer
|
||||
ManaCost:3 R R
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted land.
|
||||
K:Enchant land
|
||||
A:SP$ Attach | Cost$ 3 R R | ValidTgts$ Land | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Land.EnchantedBy | GainControl$ You | Description$ You control enchanted land.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/conquer.jpg
|
||||
Oracle:Enchant land\nYou control enchanted land.
|
||||
SetInfo:ICE Uncommon
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Control Magic
|
||||
ManaCost:2 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 2 U U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/control_magic.jpg
|
||||
Oracle:Enchant creature\nYou control enchanted creature.
|
||||
SetInfo:2ED Uncommon
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Corrupted Conscience
|
||||
ManaCost:3 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 3 U U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Infect | Description$ Enchanted creature has infect. (It deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/corrupted_conscience.jpg
|
||||
Oracle:Enchant creature\nYou control enchanted creature.\nEnchanted creature has infect. (It deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
Name:Domestication
|
||||
ManaCost:2 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 2 U U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Card.AttachedBy+powerGE4 | Execute$ TrigSac | TriggerDescription$ At the beginning of your end step, if enchanted creature's power is 4 or greater, sacrifice CARDNAME.
|
||||
SVar:TrigSac:AB$Sacrifice | Cost$ 0 | Defined$ Self
|
||||
SVar:PlayMain1:TRUE
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/domestication.jpg
|
||||
Oracle:Enchant creature\nYou control enchanted creature.\nAt the beginning of your end step, if enchanted creature's power is 4 or greater, sacrifice Domestication.
|
||||
SetInfo:ROE Uncommon
|
||||
@@ -16,9 +16,9 @@ Name:Dominating Licid
|
||||
ManaCost:1 U U
|
||||
Colors:blue
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 0 | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
A:AB$ SetState | Cost$ U | Defined$ Self | NewState$ Original | SpellDescription$ End this effect.
|
||||
SVar:RemAIDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/dominating_licid.jpg
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 U U
|
||||
Types:Enchantment Aura
|
||||
K:Enchant artifact creature
|
||||
A:SP$ Attach | Cost$ 1 U U | ValidTgts$ Creature.Artifact | AILogic$ GainControl | SpellDescription$ You control enchanted artifact creature.
|
||||
SVar:PlayMain1:TRUE
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/domineer.jpg
|
||||
Oracle:Enchant artifact creature\nYou control enchanted artifact creature.
|
||||
SetInfo:MRD Uncommon
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Enslave
|
||||
ManaCost:4 B B
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 4 B B | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ At the beginning of your upkeep, enchanted creature deals 1 damage to its owner.
|
||||
SVar:TrigDamage:AB$DealDamage | Cost$ 0 | Defined$ EnchantedOwner | DamageSource$ Enchanted | NumDmg$ 1
|
||||
SVar:PlayMain1:TRUE
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Name:Krovikan Whispers
|
||||
ManaCost:3 U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
K:Cumulative upkeep:UB
|
||||
A:SP$ Attach | Cost$ 3 U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigLoseLife | ValidCard$ Card.Self | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME is put into a graveyard from the battlefield, you lose 2 life for each age counter on it.
|
||||
SVar:TrigLoseLife:AB$ LoseLife | Cost$ 0 | LifeAmount$ X | References$ X
|
||||
SVar:X:TriggeredCard$CardCounters.AGE/Times.2
|
||||
|
||||
@@ -2,6 +2,7 @@ Name:Land Equilibrium
|
||||
ManaCost:2 U U
|
||||
Types:Enchantment
|
||||
Text:If an opponent who controls at least as many lands as you do would put a land onto the battlefield, that player instead puts that land onto the battlefield then sacrifices a land.
|
||||
SVar:SacLand:DB$ Sacrifice | SacValid$ Land | Defined$ Opponent | SpellDescription$ Opponent sacrifices a land
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/land_equilibrium.jpg
|
||||
Oracle:If an opponent who controls at least as many lands as you do would put a land onto the battlefield, that player instead puts that land onto the battlefield then sacrifices a land.
|
||||
SetInfo:LEG Rare
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Mark of the Oni
|
||||
ManaCost:2 B
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 2 B | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | IsPresent$ Demon.YouCtrl | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ At the beginning of the end step, if you control no Demons, sacrifice CARDNAME.
|
||||
SVar:TrigSac:AB$Sacrifice | Cost$ 0 | Defined$ Self
|
||||
SVar:PlayMain1:TRUE
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
Name:Mind Control
|
||||
ManaCost:3 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 3 U U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
SVar:PlayMain1:TRUE
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/mind_control.jpg
|
||||
Oracle:Enchant creature\nYou control enchanted creature.
|
||||
SetInfo:M11 Uncommon
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
Name:Mind Harness
|
||||
ManaCost:U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant red or green creature
|
||||
K:Cumulative upkeep:1
|
||||
A:SP$ Attach | Cost$ U | ValidTgts$ Creature.Red,Creature.Green | TgtPrompt$ Select target Red or Green Creature | AILogic$ GainControl
|
||||
SVar:PlayMain1:TRUE
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
SVar:RemRandomDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/mind_harness.jpg
|
||||
Oracle:Enchant red or green creature\nCumulative upkeep {1} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.)\nYou control enchanted creature.
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
Name:Persuasion
|
||||
ManaCost:3 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 3 U U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
SVar:PlayMain1:TRUE
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/persuasion.jpg
|
||||
Oracle:Enchant creature (Target a creature as you cast this. This card enters the battlefield attached to that creature.)\nYou control enchanted creature.
|
||||
SetInfo:ODY Rare
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Name:Rending Vines
|
||||
ManaCost:1 G G
|
||||
Types:Instant Arcane
|
||||
A:SP$ Destroy | Cost$ 1 G G | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | ConditionCheckSVar$ Y | ConditionSVarCompare$ LEX | References$ X,Y | SubAbility$ DBDraw | SpellDescription$ Destroy target artifact or enchantment if its converted mana cost is less than or equal to the number of cards in your hand.
|
||||
SVar:DBDraw:DB$Draw | NumCards$ 1 | SpellDescription$ Draw a card.
|
||||
A:SP$ Destroy | Cost$ 1 G G | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | ConditionCheckSVar$ Y | ConditionSVarCompare$ LEX | References$ X,Y | AITgts$ Card.cmcLTX | SubAbility$ DBDraw | SpellDescription$ Destroy target artifact or enchantment if its converted mana cost is less than or equal to the number of cards in your hand.
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ 1 | SpellDescription$ Draw a card.
|
||||
SVar:Y:Targeted$CardManaCost
|
||||
SVar:X:Count$InYourHand
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/rending_vines.jpg
|
||||
|
||||
@@ -7,6 +7,8 @@ SVar:DelTrig:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player | Execute$ T
|
||||
SVar:TrigReturn:AB$ ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Battlefield | Defined$ TriggeredCard
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Static$ True | Execute$ DBCleanup
|
||||
SVar:DBCleanup:DB$Cleanup | ClearTriggered$ True
|
||||
S:Mode$ Continuous | Affected$ Creature.YouCtrl+powerLE1+YouOwn | AddSVar$ Sac
|
||||
SVar:Sac:SVar:SacMe:3
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/shirei_shizos_caretaker.jpg
|
||||
Oracle:Whenever a creature with power 1 or less is put into your graveyard from the battlefield, you may return that card to the battlefield under your control at the beginning of the next end step if Shirei, Shizo's Caretaker is still on the battlefield.
|
||||
SetInfo:BOK Rare
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Soul Ransom
|
||||
ManaCost:2 U B
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 2 U B | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
A:AB$ Sacrifice | Cost$ Discard<2/Card> | AnyOpponent$ True | SacValid$ Self | SubAbility$ DBDraw | SpellDescription$ CARDNAME's controller sacrifices it, then draws two cards. Only any opponent may activate this ability.
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ 2 | Defined$ SourceController
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/soul_ransom.jpg
|
||||
|
||||
@@ -16,9 +16,9 @@ Name:Ghastly Haunting
|
||||
ManaCost:no cost
|
||||
Colors:blue
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 0 | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
SVar:RemAIDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/ghastly_haunting.jpg
|
||||
Oracle:Enchant creature\nYou control enchanted creature.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Spirit Away
|
||||
ManaCost:5 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 5 U U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Flying | Description$ Enchanted creature gets +2/+2 and has flying.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/spirit_away.jpg
|
||||
Oracle:Enchant creature\nYou control enchanted creature.\nEnchanted creature gets +2/+2 and has flying.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Steal Artifact
|
||||
ManaCost:2 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted artifact.
|
||||
K:Enchant artifact
|
||||
A:SP$ Attach | Cost$ 2 U U | ValidTgts$ Artifact | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Artifact.EnchantedBy | GainControl$ You | Description$ You control enchanted artifact.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/steal_artifact.jpg
|
||||
Oracle:Enchant artifact\nYou control enchanted artifact.
|
||||
SetInfo:8ED Uncommon
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Steal Enchantment
|
||||
ManaCost:U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted enchantment.
|
||||
K:Enchant enchantment
|
||||
A:SP$ Attach | Cost$ U U | ValidTgts$ Enchantment | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Enchantment.EnchantedBy | GainControl$ You | Description$ You control enchanted enchantment.
|
||||
SVar:RemAIDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/steal_enchantment.jpg
|
||||
Oracle:Enchant enchantment\nYou control enchanted enchantment.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Take Possession
|
||||
ManaCost:5 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted permanent.
|
||||
K:Split second
|
||||
K:Enchant permanent
|
||||
S:Mode$ Continuous | Affected$ Permanent.EnchantedBy | GainControl$ You | Description$ You control enchanted permanent.
|
||||
A:SP$ Attach | Cost$ 5 U U | ValidTgts$ Permanent | AILogic$ GainControl
|
||||
SVar:PlayMain1:TRUE
|
||||
SVar:Picture:http://resources.wizards.com/magic/cards/fut/en-us/card136199.jpg
|
||||
|
||||
@@ -6,6 +6,7 @@ K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other | TriggerZones$ Battlefield | Execute$ TrigReturn | TriggerDescription$ When another creature enters the battlefield, return CARDNAME to its owner's hand.
|
||||
SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | Defined$ Self | Origin$ Battlefield | Destination$ Hand
|
||||
SVar:AntiBuffedBy:Creature
|
||||
SVar:RemAIDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/timid_drake.jpg
|
||||
Oracle:Flying\nWhen another creature enters the battlefield, return Timid Drake to its owner's hand.
|
||||
SetInfo:MMQ Uncommon
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Treachery
|
||||
ManaCost:3 U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 3 U U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigUntap | TriggerDescription$ When CARDNAME enters the battlefield, untap up to five lands.
|
||||
SVar:TrigUntap:AB$ Untap | Cost$ 0 | UntapUpTo$ True | UntapType$ Land | Amount$ 5
|
||||
SVar:PlayMain1:TRUE
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name:Vapor Snare
|
||||
ManaCost:4 U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 4 U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigChangeZone | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, sacrifice CARDNAME unless you return a land you control to its owner's hand.
|
||||
SVar:TrigChangeZone:AB$ ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | Hidden$ True | ChangeType$ Land.YouCtrl | RememberChanged$ True | SubAbility$ DBSac
|
||||
SVar:DBSac:DB$ Sacrifice | Cost$ 0 | Defined$ Self | SubAbility$ DBCleanup | ConditionCheckSVar$ X | ConditionSVarCompare$ LT1
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Name:Volition Reins
|
||||
ManaCost:3 U U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted permanent.
|
||||
K:Enchant permanent
|
||||
A:SP$ Attach | Cost$ 3 U U U | ValidTgts$ Permanent | AILogic$ GainControl
|
||||
T:Mode$ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigUntap | TriggerDescription$ When CARDNAME enters the battlefield, if enchanted permanent is tapped, untap it.
|
||||
SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Enchanted
|
||||
S:Mode$ Continuous | Affected$ Permanent.EnchantedBy | GainControl$ You | Description$ You control enchanted permanent.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigUntap | TriggerDescription$ When CARDNAME enters the battlefield, if enchanted permanent is tapped, untap it.
|
||||
SVar:TrigUntap:AB$ Untap | Cost$ 0 | Defined$ Enchanted
|
||||
SVar:PlayMain1:TRUE
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/volition_reins.jpg
|
||||
Oracle:Enchant permanent\nWhen Volition Reins enters the battlefield, if enchanted permanent is tapped, untap it.\nYou control enchanted permanent.
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
Name:Yavimaya's Embrace
|
||||
ManaCost:5 G U U
|
||||
Types:Enchantment Aura
|
||||
Text:You control enchanted creature.
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 5 G U U | ValidTgts$ Creature | AILogic$ GainControl
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Trample | Description$ Enchanted creature gets +2/+2 and has trample.
|
||||
SVar:PlayMain1:TRUE
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/yavimayas_embrace.jpg
|
||||
Oracle:Enchant creature\nYou control enchanted creature.\nEnchanted creature gets +2/+2 and has trample.
|
||||
SetInfo:APC Rare
|
||||
@@ -198,7 +198,9 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
private String colorsPaid = "";
|
||||
|
||||
private Player owner = null;
|
||||
private ArrayList<Object> controllerObjects = new ArrayList<Object>();
|
||||
private Player controller = null;
|
||||
private long controllerTimestamp = 0;
|
||||
private TreeMap<Long, Player> tempControllers = new TreeMap<Long, Player>();
|
||||
|
||||
// private String rarity = "";
|
||||
private String text = "";
|
||||
@@ -3518,6 +3520,13 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
public final void addChangeControllerCommand(final Command c) {
|
||||
this.changeControllerCommandList.add(c);
|
||||
}
|
||||
|
||||
|
||||
public final void runChangeControllerCommands() {
|
||||
for (final Command c : this.changeControllerCommandList) {
|
||||
c.execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -3574,98 +3583,41 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
* @return a {@link forge.game.player.Player} object.
|
||||
*/
|
||||
public final Player getController() {
|
||||
if (this.controllerObjects.size() == 0) {
|
||||
return this.owner;
|
||||
|
||||
if (!this.tempControllers.isEmpty()) {
|
||||
final long lastTimestamp = this.tempControllers.lastKey();
|
||||
if (lastTimestamp > this.controllerTimestamp) {
|
||||
return this.tempControllers.lastEntry().getValue();
|
||||
}
|
||||
}
|
||||
final Object topController = this.controllerObjects.get(this.controllerObjects.size() - 1);
|
||||
if (topController instanceof Player) {
|
||||
return (Player) topController;
|
||||
if (this.controller != null) {
|
||||
return this.controller;
|
||||
}
|
||||
return ((Card) topController).getController();
|
||||
return this.owner;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO Write javadoc for this method.
|
||||
*
|
||||
* @param controllerObject
|
||||
* an Object
|
||||
*/
|
||||
public final void addController(final Object controllerObject) {
|
||||
final Object prevController = this.controllerObjects.size() == 0 ? this.owner : this.controllerObjects
|
||||
.get(this.controllerObjects.size() - 1);
|
||||
if (!controllerObject.equals(prevController)) {
|
||||
if (controllerObject instanceof Player) {
|
||||
for (int i = 0; i < this.controllerObjects.size(); i++) {
|
||||
if (this.controllerObjects.get(i) instanceof Player) {
|
||||
this.controllerObjects.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.controllerObjects.add(controllerObject);
|
||||
if ((Singletons.getModel().getGame().getAction() != null) && (prevController != null)) {
|
||||
Singletons.getModel().getGame().getAction().controllerChangeZoneCorrection(this);
|
||||
}
|
||||
|
||||
if (prevController != null) {
|
||||
for (final Command c : this.changeControllerCommandList) {
|
||||
c.execute();
|
||||
}
|
||||
}
|
||||
|
||||
this.updateObservers();
|
||||
}
|
||||
public final void addTempController(final Player player, final long tstamp) {
|
||||
this.tempControllers.put(tstamp, player);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO Write javadoc for this method.
|
||||
*
|
||||
* @param controllerObject
|
||||
* a Object
|
||||
*/
|
||||
public final void removeController(final Object controllerObject) {
|
||||
final Object currentController = this.getController();
|
||||
this.controllerObjects.remove(controllerObject);
|
||||
|
||||
if (!currentController.equals(this.getController())) {
|
||||
Singletons.getModel().getGame().getAction().controllerChangeZoneCorrection(this);
|
||||
|
||||
for (final Command c : this.changeControllerCommandList) {
|
||||
c.execute();
|
||||
}
|
||||
|
||||
this.updateObservers();
|
||||
}
|
||||
public final void removeTempController(final long tstamp) {
|
||||
this.tempControllers.remove(tstamp);
|
||||
}
|
||||
|
||||
public final void clearTempControllers() {
|
||||
this.tempControllers.clear();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO Write javadoc for this method.
|
||||
*/
|
||||
public final void clearControllers() {
|
||||
this.controllerObjects.clear();
|
||||
clearTempControllers();
|
||||
this.controller = null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO Write javadoc for this method.
|
||||
*
|
||||
* @return an ArrayList<Object>
|
||||
*/
|
||||
public final ArrayList<Object> getControllerObjects() {
|
||||
return this.controllerObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO Write javadoc for this method.
|
||||
*
|
||||
* @param in
|
||||
* an Object
|
||||
*/
|
||||
public final void setControllerObjects(final ArrayList<Object> in) {
|
||||
this.controllerObjects = in;
|
||||
public final void setController(final Player player, final long tstamp) {
|
||||
clearTempControllers();
|
||||
this.controller = player;
|
||||
this.controllerTimestamp = tstamp;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3678,23 +3630,8 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
*/
|
||||
public final void setOwner(final Player player) {
|
||||
this.owner = player;
|
||||
//this.updateObservers();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Setter for the field <code>controller</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return the equipped by
|
||||
*/
|
||||
/*
|
||||
* public void setController(Player player) { boolean sameController =
|
||||
* controller == null ? false : controller.isPlayer(player); controller =
|
||||
* player; if (null != controller && !sameController) { for (Command var :
|
||||
* changeControllerCommandList) var.execute(); } this.updateObservers(); }
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>equippedBy</code>.
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@@ -89,6 +90,8 @@ public class CardLists {
|
||||
return aLen - bLen;
|
||||
}
|
||||
};
|
||||
|
||||
public static final List<Card> emptyList = ImmutableList.of();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
||||
@@ -136,6 +136,7 @@ public final class CardUtil {
|
||||
newCopy.setUniqueNumber(in.getUniqueNumber());
|
||||
newCopy.setCurSetCode(in.getCurSetCode());
|
||||
newCopy.setOwner(in.getOwner());
|
||||
newCopy.setController(in.getController(), 0);
|
||||
newCopy.setFlipCard(in.isFlipCard());
|
||||
newCopy.setDoubleFaced(in.isDoubleFaced());
|
||||
newCopy.getCharacteristics().copy(in.getState(in.getCurState()));
|
||||
@@ -148,7 +149,6 @@ public final class CardUtil {
|
||||
sa.setSourceCard(in);
|
||||
}
|
||||
|
||||
newCopy.setControllerObjects(in.getControllerObjects());
|
||||
newCopy.setCounters(in.getCounters());
|
||||
newCopy.setExtrinsicKeyword(in.getExtrinsicKeyword());
|
||||
newCopy.setColor(in.getColor());
|
||||
|
||||
@@ -184,6 +184,11 @@ public class StaticEffects {
|
||||
// modify the affected card
|
||||
for (int i = 0; i < affectedCards.size(); i++) {
|
||||
final Card affectedCard = affectedCards.get(i);
|
||||
|
||||
// Gain control
|
||||
if (params.containsKey("GainControl")) {
|
||||
affectedCard.removeTempController(se.getTimestamp());
|
||||
}
|
||||
|
||||
// remove set P/T
|
||||
if (!params.containsKey("CharacteristicDefining") && setPT) {
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.google.common.base.Predicates;
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.CardUtil;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
|
||||
@@ -1254,7 +1254,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
c.setTapped(true);
|
||||
}
|
||||
if (sa.hasParam("GainControl")) {
|
||||
c.addController(sa.getSourceCard());
|
||||
c.setController(sa.getActivatingPlayer(), Singletons.getModel().getGame().getNextTimestamp());
|
||||
}
|
||||
|
||||
if (sa.hasParam("AttachedTo")) {
|
||||
|
||||
@@ -81,6 +81,9 @@ public class DiscardAi extends SpellAbilityAi {
|
||||
// Set PayX here to maximum value.
|
||||
final int cardsToDiscard = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), ai.getOpponent()
|
||||
.getCardsIn(ZoneType.Hand).size());
|
||||
if (cardsToDiscard < 1) {
|
||||
return false;
|
||||
}
|
||||
source.setSVar("PayX", Integer.toString(cardsToDiscard));
|
||||
} else {
|
||||
if (AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumCards"), sa) < 1) {
|
||||
|
||||
@@ -30,7 +30,7 @@ public class AttachEffect extends SpellAbilityEffect {
|
||||
|
||||
// The Spell_Permanent (Auras) version of this AF needs to
|
||||
// move the card into play before Attaching
|
||||
sa.getSourceCard().addController(sa.getActivatingPlayer());
|
||||
sa.getSourceCard().setController(sa.getActivatingPlayer(), 0);
|
||||
final Card c = Singletons.getModel().getGame().getAction().moveTo(sa.getActivatingPlayer().getZone(ZoneType.Battlefield), sa.getSourceCard());
|
||||
sa.setSourceCard(c);
|
||||
}
|
||||
@@ -93,8 +93,7 @@ public class AttachEffect extends SpellAbilityEffect {
|
||||
// Spellweaver Volute, Dance of the Dead, Animate Dead
|
||||
// Although honestly, I'm not sure if the three of those could
|
||||
// handle being scripted
|
||||
final boolean gainControl = "GainControl".equals(sa.getParam("AILogic"));
|
||||
handleAura(card, c, gainControl);
|
||||
handleAura(card, c);
|
||||
} else if (card.isEquipment()) {
|
||||
card.equipCard(c);
|
||||
// else if (card.isFortification())
|
||||
@@ -106,7 +105,7 @@ public class AttachEffect extends SpellAbilityEffect {
|
||||
// Curse cards
|
||||
final Player p = (Player) o;
|
||||
if (card.isAura()) {
|
||||
handleAura(card, p, false);
|
||||
handleAura(card, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,7 +120,7 @@ public class AttachEffect extends SpellAbilityEffect {
|
||||
* @param gainControl
|
||||
* the gain control
|
||||
*/
|
||||
public static void handleAura(final Card card, final GameEntity tgt, final boolean gainControl) {
|
||||
public static void handleAura(final Card card, final GameEntity tgt) {
|
||||
if (card.isEnchanting()) {
|
||||
// If this Card is already Enchanting something
|
||||
// Need to unenchant it, then clear out the commands
|
||||
@@ -133,72 +132,6 @@ public class AttachEffect extends SpellAbilityEffect {
|
||||
card.clearTriggers(); // not sure if cleartriggers is needed?
|
||||
}
|
||||
|
||||
if (gainControl) {
|
||||
// Handle GainControl Auras
|
||||
final Player[] pl = new Player[1];
|
||||
|
||||
if (tgt instanceof Card) {
|
||||
pl[0] = ((Card) tgt).getController();
|
||||
} else {
|
||||
pl[0] = (Player) tgt;
|
||||
}
|
||||
|
||||
final Command onEnchant = new Command() {
|
||||
private static final long serialVersionUID = -2519887209491512000L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final Card crd = card.getEnchantingCard();
|
||||
if (crd == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
pl[0] = crd.getController();
|
||||
|
||||
crd.addController(card);
|
||||
|
||||
} // execute()
|
||||
}; // Command
|
||||
|
||||
final Command onUnEnchant = new Command() {
|
||||
private static final long serialVersionUID = 3426441132121179288L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final Card crd = card.getEnchantingCard();
|
||||
if (crd == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (crd.isInPlay()) {
|
||||
crd.removeController(card);
|
||||
}
|
||||
|
||||
} // execute()
|
||||
}; // Command
|
||||
|
||||
final Command onChangesControl = new Command() {
|
||||
/** automatically generated serialVersionUID. */
|
||||
private static final long serialVersionUID = -65903786170234039L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final Card crd = card.getEnchantingCard();
|
||||
if (crd == null) {
|
||||
return;
|
||||
}
|
||||
crd.removeController(card); // This looks odd, but will
|
||||
// simply refresh controller
|
||||
crd.addController(card);
|
||||
} // execute()
|
||||
}; // Command
|
||||
|
||||
// Add Enchant Commands for Control changers
|
||||
card.addEnchantCommand(onEnchant);
|
||||
card.addUnEnchantCommand(onUnEnchant);
|
||||
card.addChangeControllerCommand(onChangesControl);
|
||||
}
|
||||
|
||||
final Command onLeavesPlay = new Command() {
|
||||
private static final long serialVersionUID = -639204333673364477L;
|
||||
|
||||
@@ -252,7 +185,6 @@ public class AttachEffect extends SpellAbilityEffect {
|
||||
}
|
||||
aura.setActivatingPlayer(source.getController());
|
||||
final Target tgt = aura.getTarget();
|
||||
final boolean gainControl = "GainControl".equals(aura.getParam("AILogic"));
|
||||
|
||||
if (source.getController().isHuman()) {
|
||||
if (tgt.canTgtPlayer()) {
|
||||
@@ -266,8 +198,7 @@ public class AttachEffect extends SpellAbilityEffect {
|
||||
|
||||
final Player p = GuiChoose.one(source + " - Select a player to attach to.", players);
|
||||
if (p != null) {
|
||||
handleAura(source, p, false);
|
||||
//source.enchantEntity((Player) o);
|
||||
handleAura(source, p);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
@@ -279,7 +210,7 @@ public class AttachEffect extends SpellAbilityEffect {
|
||||
|
||||
final Object o = GuiChoose.one(source + " - Select a card to attach to.", list);
|
||||
if (o instanceof Card) {
|
||||
handleAura(source, (Card) o, gainControl);
|
||||
handleAura(source, (Card) o);
|
||||
//source.enchantEntity((Card) o);
|
||||
return true;
|
||||
}
|
||||
@@ -290,11 +221,11 @@ public class AttachEffect extends SpellAbilityEffect {
|
||||
final Object o = aura.getTarget().getTargets().get(0);
|
||||
if (o instanceof Card) {
|
||||
//source.enchantEntity((Card) o);
|
||||
handleAura(source, (Card) o, gainControl);
|
||||
handleAura(source, (Card) o);
|
||||
return true;
|
||||
} else if (o instanceof Player) {
|
||||
//source.enchantEntity((Player) o);
|
||||
handleAura(source, (Player) o, false);
|
||||
handleAura(source, (Player) o);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
if (sa.hasParam("GainControl")) {
|
||||
c.addController(sa.getSourceCard());
|
||||
c.setController(sa.getActivatingPlayer(), Singletons.getModel().getGame().getNextTimestamp());
|
||||
Singletons.getModel().getGame().getAction().moveToPlay(c, sa.getActivatingPlayer());
|
||||
} else {
|
||||
final Card movedCard = Singletons.getModel().getGame().getAction().moveTo(destination, c, libraryPos);
|
||||
|
||||
@@ -386,7 +386,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
tgtC.setTapped(true);
|
||||
}
|
||||
if (sa.hasParam("GainControl")) {
|
||||
tgtC.addController(sa.getSourceCard());
|
||||
tgtC.setController(sa.getActivatingPlayer(), Singletons.getModel().getGame().getNextTimestamp());
|
||||
}
|
||||
if (sa.hasParam("AttachedTo")) {
|
||||
List<Card> list = AbilityUtils.getDefinedCards(hostCard,
|
||||
@@ -670,7 +670,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
c.setTapped(true);
|
||||
}
|
||||
if (sa.hasParam("GainControl")) {
|
||||
c.addController(sa.getSourceCard());
|
||||
c.setController(sa.getActivatingPlayer(), Singletons.getModel().getGame().getNextTimestamp());
|
||||
}
|
||||
|
||||
if (sa.hasParam("AttachedTo")) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package forge.card.ability.effects;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import forge.Card;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
@@ -56,9 +57,10 @@ public class ControlExchangeEffect extends SpellAbilityEffect {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player2 = object2.getController();
|
||||
object2.addController(object1.getController());
|
||||
object1.addController(player2);
|
||||
final Player player2 = object2.getController();
|
||||
final long tStamp = Singletons.getModel().getGame().getNextTimestamp();
|
||||
object2.setController(object1.getController(), tStamp);
|
||||
object1.setController(player2, tStamp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.List;
|
||||
|
||||
import forge.Card;
|
||||
import forge.Command;
|
||||
import forge.GameEntity;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
@@ -52,14 +51,12 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
private void doLoseControl(final Card c, final Card host, final boolean tapOnLose,
|
||||
final List<String> addedKeywords, final GameEntity newController) {
|
||||
final List<String> addedKeywords, final long tStamp) {
|
||||
if (null == c) {
|
||||
return;
|
||||
}
|
||||
if (c.isInPlay()) {
|
||||
c.removeController(newController);
|
||||
// Singletons.getModel().getGameAction().changeController(new ArrayList<Card>(c),
|
||||
// c.getController(), originalController);
|
||||
c.removeTempController(tStamp);
|
||||
|
||||
if (tapOnLose) {
|
||||
c.tap();
|
||||
@@ -105,14 +102,10 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
controllers = tgt.getTargetPlayers();
|
||||
}
|
||||
|
||||
GameEntity newController;
|
||||
Player newController;
|
||||
|
||||
if (controllers.size() == 0) {
|
||||
if (sa.isSpell()) {
|
||||
newController = sa.getActivatingPlayer();
|
||||
} else {
|
||||
newController = source;
|
||||
}
|
||||
newController = sa.getActivatingPlayer();
|
||||
} else {
|
||||
newController = controllers.get(0);
|
||||
}
|
||||
@@ -124,66 +117,62 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
return;
|
||||
}
|
||||
|
||||
final int size = tgtCards.size();
|
||||
for (int j = 0; j < size; j++) {
|
||||
final Card tgtC = tgtCards.get(j);
|
||||
final Player originalController = tgtC.getController();
|
||||
for (Card tgtC : tgtCards) {
|
||||
|
||||
if (!tgtC.equals(sa.getSourceCard()) && !sa.getSourceCard().getGainControlTargets().contains(tgtC)) {
|
||||
sa.getSourceCard().addGainControlTarget(tgtC);
|
||||
}
|
||||
|
||||
if (tgtC.isInPlay()) {
|
||||
if (!tgtC.isInPlay()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tgtC.equals(newController)) {
|
||||
tgtC.addController(newController);
|
||||
}
|
||||
// Singletons.getModel().getGameAction().changeController(new ArrayList<Card>(tgtC),
|
||||
// tgtC.getController(), newController.get(0));
|
||||
long tStamp = Singletons.getModel().getGame().getNextTimestamp();
|
||||
if (lose != null) {
|
||||
tgtC.addTempController(newController, tStamp);
|
||||
} else {
|
||||
tgtC.setController(newController, tStamp);
|
||||
}
|
||||
|
||||
if (bUntap) {
|
||||
tgtC.untap();
|
||||
}
|
||||
if (bUntap) {
|
||||
tgtC.untap();
|
||||
}
|
||||
|
||||
if (null != kws) {
|
||||
for (final String kw : kws) {
|
||||
tgtC.addExtrinsicKeyword(kw);
|
||||
}
|
||||
if (null != kws) {
|
||||
for (final String kw : kws) {
|
||||
tgtC.addExtrinsicKeyword(kw);
|
||||
}
|
||||
}
|
||||
|
||||
// end copied
|
||||
|
||||
final Card hostCard = sa.getSourceCard();
|
||||
if (lose != null) {
|
||||
if (lose.contains("LeavesPlay")) {
|
||||
sa.getSourceCard().addLeavesPlayCommand(this.getLoseControlCommand(tgtC, originalController, newController, bTapOnLose, hostCard, kws));
|
||||
sa.getSourceCard().addLeavesPlayCommand(this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws));
|
||||
}
|
||||
if (lose.contains("Untap")) {
|
||||
sa.getSourceCard().addUntapCommand(this.getLoseControlCommand(tgtC, originalController, newController, bTapOnLose, hostCard, kws));
|
||||
sa.getSourceCard().addUntapCommand(this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws));
|
||||
}
|
||||
if (lose.contains("LoseControl")) {
|
||||
sa.getSourceCard().addChangeControllerCommand(this.getLoseControlCommand(tgtC, originalController, newController, bTapOnLose, hostCard, kws));
|
||||
sa.getSourceCard().addChangeControllerCommand(this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws));
|
||||
}
|
||||
if (lose.contains("EOT")) {
|
||||
Singletons.getModel().getGame().getEndOfTurn().addAt(this.getLoseControlCommand(tgtC, originalController, newController, bTapOnLose, hostCard, kws));
|
||||
Singletons.getModel().getGame().getEndOfTurn().addAt(this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws));
|
||||
}
|
||||
}
|
||||
|
||||
if (destroyOn != null) {
|
||||
if (destroyOn.contains("LeavesPlay")) {
|
||||
sa.getSourceCard().addLeavesPlayCommand(this.getDestroyCommand(tgtC, hostCard, bNoRegen));
|
||||
sa.getSourceCard().addLeavesPlayCommand(this.getDestroyCommand(tgtC, source, bNoRegen));
|
||||
}
|
||||
if (destroyOn.contains("Untap")) {
|
||||
sa.getSourceCard().addUntapCommand(this.getDestroyCommand(tgtC, hostCard, bNoRegen));
|
||||
sa.getSourceCard().addUntapCommand(this.getDestroyCommand(tgtC, source, bNoRegen));
|
||||
}
|
||||
if (destroyOn.contains("LoseControl")) {
|
||||
sa.getSourceCard().addChangeControllerCommand(this.getDestroyCommand(tgtC, hostCard, bNoRegen));
|
||||
sa.getSourceCard().addChangeControllerCommand(this.getDestroyCommand(tgtC, source, bNoRegen));
|
||||
}
|
||||
}
|
||||
|
||||
sa.getSourceCard().clearGainControlReleaseCommands();
|
||||
sa.getSourceCard().addGainControlReleaseCommand(this.getLoseControlCommand(tgtC, originalController, newController, bTapOnLose, hostCard, kws));
|
||||
sa.getSourceCard().addGainControlReleaseCommand(this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws));
|
||||
|
||||
} // end foreach target
|
||||
}
|
||||
@@ -239,13 +228,13 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
* a {@link forge.game.player.Player} object.
|
||||
* @return a {@link forge.Command} object.
|
||||
*/
|
||||
private Command getLoseControlCommand(final Card c, final Player originalController, final GameEntity newController,
|
||||
private Command getLoseControlCommand(final Card c, final long tStamp,
|
||||
final boolean bTapOnLose, final Card hostCard, final List<String> kws) {
|
||||
final Command loseControl = new Command() {
|
||||
private static final long serialVersionUID = 878543373519872418L;
|
||||
|
||||
@Override
|
||||
public void execute() { doLoseControl(c, hostCard, bTapOnLose, kws, newController); } // execute()
|
||||
public void execute() { doLoseControl(c, hostCard, bTapOnLose, kws, tStamp); }
|
||||
};
|
||||
|
||||
return loseControl;
|
||||
|
||||
@@ -86,7 +86,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
||||
copy = CardFactory.getCard(CardDb.getCard(c), sa.getActivatingPlayer());
|
||||
|
||||
// when copying something stolen:
|
||||
copy.addController(controller);
|
||||
copy.setController(controller, 0);
|
||||
|
||||
copy.setToken(true);
|
||||
copy.setCopiedToken(true);
|
||||
@@ -97,7 +97,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
||||
copy.setImageKey(c.getImageKey());
|
||||
|
||||
copy.setOwner(controller);
|
||||
copy.addController(controller);
|
||||
copy.setController(controller, 0);
|
||||
|
||||
copy.setManaCost(c.getManaCost());
|
||||
copy.setColor(c.getColor());
|
||||
|
||||
@@ -149,11 +149,11 @@ public class CounterEffect extends SpellAbilityEffect {
|
||||
if (tgtSA instanceof SpellPermanent) {
|
||||
Card c = tgtSA.getSourceCard();
|
||||
System.out.println(c + " is SpellPermanent");
|
||||
c.addController(srcSA.getActivatingPlayer());
|
||||
c.setController(srcSA.getActivatingPlayer(), 0);
|
||||
Singletons.getModel().getGame().getAction().moveToPlay(c, srcSA.getActivatingPlayer());
|
||||
} else {
|
||||
Card c = Singletons.getModel().getGame().getAction().moveToPlay(tgtSA.getSourceCard(), srcSA.getActivatingPlayer());
|
||||
c.addController(srcSA.getActivatingPlayer());
|
||||
c.setController(srcSA.getActivatingPlayer(), 0);
|
||||
}
|
||||
} else if (destination.equals("BottomOfLibrary")) {
|
||||
Singletons.getModel().getGame().getAction().moveToBottomOfLibrary(tgtSA.getSourceCard());
|
||||
|
||||
@@ -131,7 +131,7 @@ public class DigUntilEffect extends SpellAbilityEffect {
|
||||
while (itr.hasNext()) {
|
||||
final Card c = itr.next();
|
||||
if (sa.hasParam("GainControl") && foundDest.equals(ZoneType.Battlefield)) {
|
||||
c.addController(sa.getSourceCard());
|
||||
c.setController(sa.getActivatingPlayer(), Singletons.getModel().getGame().getNextTimestamp());
|
||||
Singletons.getModel().getGame().getAction().moveTo(c.getController().getZone(foundDest), c);
|
||||
} else if (sa.hasParam("NoMoveFound") && foundDest.equals(ZoneType.Library)) {
|
||||
//Don't do anything
|
||||
|
||||
@@ -1,26 +1,18 @@
|
||||
package forge.card.ability.effects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
public class DiscardEffect extends RevealEffectBase {
|
||||
@Override
|
||||
@@ -87,44 +79,6 @@ public class DiscardEffect extends RevealEffectBase {
|
||||
return sb.toString();
|
||||
} // discardStackDescription()
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param sa
|
||||
* @param opponentHand
|
||||
* @param list
|
||||
*/
|
||||
private Card chooseCardToDiscardFromOpponent(SpellAbility sa, List<Card> opponentHand) {
|
||||
List<Card> goodChoices = CardLists.filter(opponentHand, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
if (!c.getSVar("DiscardMeByOpp").equals("") || !c.getSVar("DiscardMe").equals("")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (goodChoices.isEmpty()) {
|
||||
goodChoices = opponentHand;
|
||||
}
|
||||
final List<Card> dChoices = new ArrayList<Card>();
|
||||
if (sa.hasParam("DiscardValid")) {
|
||||
final String validString = sa.getParam("DiscardValid");
|
||||
if (validString.contains("Creature") && !validString.contains("nonCreature")) {
|
||||
final Card c = ComputerUtilCard.getBestCreatureAI(goodChoices);
|
||||
if (c != null) {
|
||||
dChoices.add(ComputerUtilCard.getBestCreatureAI(goodChoices));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(goodChoices, CardLists.TextLenComparator);
|
||||
|
||||
CardLists.sortByCmcDesc(goodChoices);
|
||||
dChoices.add(goodChoices.get(0));
|
||||
|
||||
return Aggregates.random(goodChoices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
final Card source = sa.getSourceCard();
|
||||
@@ -194,11 +148,7 @@ public class DiscardEffect extends RevealEffectBase {
|
||||
// Reveal
|
||||
final List<Card> dPHand = p.getCardsIn(ZoneType.Hand);
|
||||
|
||||
if (p.isHuman()) {
|
||||
// "reveal to computer" for information gathering
|
||||
} else {
|
||||
GuiChoose.oneOrNone("Revealed computer hand", dPHand);
|
||||
}
|
||||
p.getOpponent().getController().reveal("Reveal " + p + " hand" , dPHand, ZoneType.Hand, p);
|
||||
|
||||
String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
||||
|
||||
@@ -215,7 +165,7 @@ public class DiscardEffect extends RevealEffectBase {
|
||||
} else if (mode.equals("RevealYouChoose") || mode.equals("RevealOppChoose") || mode.equals("TgtChoose")) {
|
||||
// Is Reveal you choose right? I think the wrong player is
|
||||
// being used?
|
||||
List<Card> dPHand = new ArrayList<Card>(p.getCardsIn(ZoneType.Hand));
|
||||
List<Card> dPHand = p.getCardsIn(ZoneType.Hand);
|
||||
if (dPHand.isEmpty())
|
||||
continue; // for loop over players
|
||||
|
||||
@@ -224,11 +174,9 @@ public class DiscardEffect extends RevealEffectBase {
|
||||
int amount = StringUtils.isNumeric(amountString) ? Integer.parseInt(amountString) : CardFactoryUtil.xCount(source, source.getSVar(amountString));
|
||||
dPHand = getRevealedList(p, dPHand, amount, false);
|
||||
}
|
||||
List<Card> dPChHand = new ArrayList<Card>(dPHand);
|
||||
final String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
||||
String[] dValid = ArrayUtils.EMPTY_STRING_ARRAY;
|
||||
dValid = valid.split(",");
|
||||
dPChHand = CardLists.getValidCards(dPHand, dValid, source.getController(), source);
|
||||
String[] dValid = valid.split(",");
|
||||
List<Card> validCards = CardLists.getValidCards(dPHand, dValid, source.getController(), source);
|
||||
|
||||
Player chooser = p;
|
||||
if (mode.equals("RevealYouChoose")) {
|
||||
@@ -237,60 +185,16 @@ public class DiscardEffect extends RevealEffectBase {
|
||||
chooser = source.getController().getOpponent();
|
||||
}
|
||||
|
||||
List<Card> toBeDiscarded = new ArrayList<Card>();
|
||||
if (chooser.isComputer()) {
|
||||
List<Card> dPChHand1 = new ArrayList<Card>(p.getCardsIn(ZoneType.Hand));
|
||||
dPChHand1 = CardLists.getValidCards(dPChHand1, dValid, source.getController(), source);
|
||||
|
||||
int max = Math.min(dPChHand1.size(), numCards);
|
||||
List<Card> list = new ArrayList<Card>();
|
||||
|
||||
if (!p.isOpponentOf(chooser) && p instanceof AIPlayer) { // discard AI cards
|
||||
toBeDiscarded = ((AIPlayer) p).getAi().getCardsToDiscard(max, dValid, sa);
|
||||
} else {
|
||||
// discard hostile or human opponent
|
||||
for (int i = 0; i < max; i++) {
|
||||
Card dC = chooseCardToDiscardFromOpponent(sa, dPChHand1);
|
||||
dPChHand1.remove(dC);
|
||||
toBeDiscarded.add(dC);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode.startsWith("Reveal")) {
|
||||
GuiChoose.oneOrNone("Computer has chosen", list);
|
||||
}
|
||||
if (mode.startsWith("Reveal") && p != chooser)
|
||||
chooser.getController().reveal("Revealed " + p + " hand", dPHand, ZoneType.Hand, p);
|
||||
|
||||
int minDiscardAmount = sa.hasParam("AnyNumber") || sa.hasParam("Optional") ? 0 : numCards;
|
||||
int max = Math.min(validCards.size(), minDiscardAmount);
|
||||
|
||||
} else {
|
||||
// human
|
||||
if (mode.startsWith("Reveal")) {
|
||||
GuiChoose.oneOrNone("Revealed " + p + " hand", dPHand);
|
||||
}
|
||||
List<Card> toBeDiscarded = validCards.isEmpty() ? CardLists.emptyList : chooser.getController().chooseCardsToDiscardFrom(p, sa, validCards, max);
|
||||
|
||||
if (sa.hasParam("AnyNumber")) {
|
||||
List<Card> chosen = getDiscardedList(p, dPChHand);
|
||||
|
||||
for (Card c : chosen) {
|
||||
dPChHand.remove(c);
|
||||
toBeDiscarded.add(c);
|
||||
}
|
||||
} else
|
||||
for (int i = 0; i < numCards; i++) {
|
||||
if (dPChHand.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
Card dC = null;
|
||||
if (sa.hasParam("Optional")) {
|
||||
dC = GuiChoose.oneOrNone("Choose a card to be discarded", dPChHand);
|
||||
} else {
|
||||
dC = GuiChoose.one("Choose a card to be discarded", dPChHand);
|
||||
}
|
||||
|
||||
if (dC != null) {
|
||||
dPChHand.remove(dC);
|
||||
toBeDiscarded.add(dC);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
if (mode.startsWith("Reveal") ) {
|
||||
p.getController().reveal(chooser + " has chosen", toBeDiscarded, ZoneType.Hand, p);
|
||||
}
|
||||
|
||||
if (toBeDiscarded != null) {
|
||||
@@ -311,34 +215,4 @@ public class DiscardEffect extends RevealEffectBase {
|
||||
}
|
||||
|
||||
} // discardResolve()
|
||||
|
||||
public static List<Card> getDiscardedList(final Player player, final List<Card> valid) {
|
||||
final List<Card> chosen = new ArrayList<Card>();
|
||||
final int validamount = Math.min(valid.size(), valid.size());
|
||||
|
||||
if (player.isHuman() && validamount > 0) {
|
||||
final List<Card> selection = GuiChoose.order("Choose Which Cards to Discard", "Discarded", -1, valid, null, null);
|
||||
for (final Object o : selection) {
|
||||
if (o != null && o instanceof Card) {
|
||||
chosen.add((Card) o);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < validamount; i++) {
|
||||
if (player.isHuman()) {
|
||||
final Card o = GuiChoose.one("Choose card(s) to discard", valid);
|
||||
if (o != null) {
|
||||
chosen.add(o);
|
||||
valid.remove(o);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else { // Computer
|
||||
chosen.add(valid.get(0));
|
||||
valid.remove(valid.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
return chosen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class PermanentCreatureEfect extends SpellAbilityEffect {
|
||||
*/
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
sa.getSourceCard().addController(sa.getActivatingPlayer());
|
||||
sa.getSourceCard().setController(sa.getActivatingPlayer(), 0);
|
||||
final Card c = Singletons.getModel().getGame().getAction().moveTo(sa.getActivatingPlayer().getZone(ZoneType.Battlefield), sa.getSourceCard());
|
||||
sa.setSourceCard(c);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class PermanentNoncreatureEffect extends SpellAbilityEffect {
|
||||
*/
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
sa.getSourceCard().addController(sa.getActivatingPlayer());
|
||||
sa.getSourceCard().setController(sa.getActivatingPlayer(), 0);
|
||||
final Card c = Singletons.getModel().getGame().getAction().moveTo(sa.getActivatingPlayer().getZone(ZoneType.Battlefield), sa.getSourceCard());
|
||||
sa.setSourceCard(c);
|
||||
}
|
||||
|
||||
@@ -462,22 +462,13 @@ public class CardFactorySorceries {
|
||||
}
|
||||
|
||||
private static final void balanceHands(Spell card) {
|
||||
|
||||
List<List<Card>> hands = new ArrayList<List<Card>>();
|
||||
for (Player p : Singletons.getModel().getGame().getPlayers()) {
|
||||
|
||||
hands.add(p.getCardsIn(ZoneType.Hand));
|
||||
}
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (List<Card> h : hands) {
|
||||
int s = h.size();
|
||||
min = Math.min(min, s);
|
||||
}
|
||||
Iterator<List<Card>> hh = hands.iterator();
|
||||
for (Player p : Singletons.getModel().getGame().getPlayers()) {
|
||||
min = Math.min(min, p.getZone(ZoneType.Hand).size());
|
||||
}
|
||||
|
||||
List<Card> h = hh.next();
|
||||
int sac = h.size() - min;
|
||||
for (Player p : Singletons.getModel().getGame().getPlayers()) {
|
||||
int sac = p.getCardsIn(ZoneType.Hand).size() - min;
|
||||
if (sac == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ public class SpellPermanent extends Spell {
|
||||
@Override
|
||||
public void resolve() {
|
||||
Card c = this.getSourceCard();
|
||||
c.addController(this.getActivatingPlayer());
|
||||
c.setController(this.getActivatingPlayer(), 0);
|
||||
Singletons.getModel().getGame().getAction().moveTo(ZoneType.Battlefield, c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,10 @@ public class StaticAbility {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.params.containsKey("GainControl")) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (this.params.containsKey("AddType") || this.params.containsKey("RemoveType")
|
||||
|| this.params.containsKey("RemoveCardType") || this.params.containsKey("RemoveSubType")
|
||||
|| this.params.containsKey("RemoveSuperType")) {
|
||||
|
||||
@@ -317,6 +317,11 @@ public class StaticAbilityContinuous {
|
||||
// start modifying the cards
|
||||
for (int i = 0; i < affectedCards.size(); i++) {
|
||||
final Card affectedCard = affectedCards.get(i);
|
||||
|
||||
// Gain control
|
||||
if (params.containsKey("GainControl")) {
|
||||
affectedCard.addTempController(hostCard.getController(), hostCard.getTimestamp());
|
||||
}
|
||||
|
||||
// set P/T
|
||||
if (params.containsKey("CharacteristicDefining")) {
|
||||
|
||||
@@ -977,9 +977,18 @@ public class GameAction {
|
||||
|
||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||
game.getTriggerHandler().runTrigger(TriggerType.Always, runParams, false);
|
||||
|
||||
for (Player p : game.getPlayers()) {
|
||||
for (Card c : p.getCardsIn(ZoneType.Battlefield)) {
|
||||
if (!c.getController().equals(p)) {
|
||||
controllerChangeZoneCorrection(c);
|
||||
c.runChangeControllerCommands();
|
||||
checkAgain = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
||||
|
||||
if (c.isEquipped()) {
|
||||
final List<Card> equipments = new ArrayList<Card>(c.getEquippedBy());
|
||||
for (final Card equipment : equipments) {
|
||||
@@ -990,7 +999,6 @@ public class GameAction {
|
||||
}
|
||||
} // if isEquipped()
|
||||
|
||||
|
||||
if (c.isEquipping()) {
|
||||
final Card equippedCreature = c.getEquipping().get(0);
|
||||
if (!equippedCreature.isCreature() || !equippedCreature.isInPlay()) {
|
||||
@@ -1091,7 +1099,7 @@ public class GameAction {
|
||||
checkAgain = true;
|
||||
}
|
||||
|
||||
} // while it.hasNext()
|
||||
}
|
||||
|
||||
if (game.getTriggerHandler().runWaitingTriggers(true)) {
|
||||
checkAgain = true;
|
||||
|
||||
@@ -47,6 +47,7 @@ import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.Expressions;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -524,16 +525,21 @@ public class AiController {
|
||||
*/
|
||||
public List<Card> getCardsToDiscard(final int numDiscard, final String[] uTypes, final SpellAbility sa) {
|
||||
List<Card> hand = new ArrayList<Card>(player.getCardsIn(ZoneType.Hand));
|
||||
Card sourceCard = null;
|
||||
|
||||
|
||||
if ((uTypes != null) && (sa != null)) {
|
||||
hand = CardLists.getValidCards(hand, uTypes, sa.getActivatingPlayer(), sa.getSourceCard());
|
||||
}
|
||||
return getCardsToDiscard(numDiscard, hand, sa);
|
||||
}
|
||||
|
||||
if (hand.size() < numDiscard) {
|
||||
public List<Card> getCardsToDiscard(final int numDiscard, final List<Card> validCards, final SpellAbility sa) {
|
||||
|
||||
if (validCards.size() < numDiscard) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Card sourceCard = null;
|
||||
final List<Card> discardList = new ArrayList<Card>();
|
||||
int count = 0;
|
||||
if (sa != null) {
|
||||
@@ -544,7 +550,7 @@ public class AiController {
|
||||
while (count < numDiscard) {
|
||||
Card prefCard = null;
|
||||
if (sa != null && sa.getActivatingPlayer() != null && sa.getActivatingPlayer().isOpponentOf(player)) {
|
||||
for (Card c : hand) {
|
||||
for (Card c : validCards) {
|
||||
if (c.hasKeyword("If a spell or ability an opponent controls causes you to discard CARDNAME,"
|
||||
+ " put it onto the battlefield instead of putting it into your graveyard.")) {
|
||||
prefCard = c;
|
||||
@@ -553,11 +559,11 @@ public class AiController {
|
||||
}
|
||||
}
|
||||
if (prefCard == null) {
|
||||
prefCard = ComputerUtil.getCardPreference(player, sourceCard, "DiscardCost", hand);
|
||||
prefCard = ComputerUtil.getCardPreference(player, sourceCard, "DiscardCost", validCards);
|
||||
}
|
||||
if (prefCard != null) {
|
||||
discardList.add(prefCard);
|
||||
hand.remove(prefCard);
|
||||
validCards.remove(prefCard);
|
||||
count++;
|
||||
} else {
|
||||
break;
|
||||
@@ -568,11 +574,11 @@ public class AiController {
|
||||
|
||||
// choose rest
|
||||
for (int i = 0; i < discardsLeft; i++) {
|
||||
if (hand.isEmpty()) {
|
||||
if (validCards.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
final int numLandsInPlay = Iterables.size(Iterables.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.LANDS));
|
||||
final List<Card> landsInHand = CardLists.filter(hand, CardPredicates.Presets.LANDS);
|
||||
final List<Card> landsInHand = CardLists.filter(validCards, CardPredicates.Presets.LANDS);
|
||||
final int numLandsInHand = landsInHand.size();
|
||||
|
||||
// Discard a land
|
||||
@@ -581,21 +587,21 @@ public class AiController {
|
||||
|
||||
if (canDiscardLands) {
|
||||
discardList.add(landsInHand.get(0));
|
||||
hand.remove(landsInHand.get(0));
|
||||
validCards.remove(landsInHand.get(0));
|
||||
} else { // Discard other stuff
|
||||
CardLists.sortByCmcDesc(hand);
|
||||
CardLists.sortByCmcDesc(validCards);
|
||||
int numLandsAvailable = numLandsInPlay;
|
||||
if (numLandsInHand > 0) {
|
||||
numLandsAvailable++;
|
||||
}
|
||||
//Discard unplayable card
|
||||
if (hand.get(0).getCMC() > numLandsAvailable) {
|
||||
discardList.add(hand.get(0));
|
||||
hand.remove(hand.get(0));
|
||||
if (validCards.get(0).getCMC() > numLandsAvailable) {
|
||||
discardList.add(validCards.get(0));
|
||||
validCards.remove(validCards.get(0));
|
||||
} else { //Discard worst card
|
||||
Card worst = ComputerUtilCard.getWorstAI(hand);
|
||||
Card worst = ComputerUtilCard.getWorstAI(validCards);
|
||||
discardList.add(worst);
|
||||
hand.remove(worst);
|
||||
validCards.remove(worst);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -700,5 +706,18 @@ public class AiController {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* AI decides if he wants to use dredge ability and which one if many available
|
||||
* @param dredgers - contains at least single element
|
||||
* @return
|
||||
*/
|
||||
public Card chooseCardToDredge(List<Card> dredgers) {
|
||||
// use dredge if there are more than one of them in your graveyard
|
||||
if (dredgers.size() > 1 || MyRandom.getRandom().nextBoolean()) {
|
||||
return Aggregates.random(dredgers);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,8 +87,12 @@ public class AiInputCommon extends Input {
|
||||
final int size = player.getCardsIn(ZoneType.Hand).size();
|
||||
|
||||
if (!player.isUnlimitedHandSize()) {
|
||||
final int numDiscards = size - player.getMaxHandSize();
|
||||
player.discard(numDiscards, null);
|
||||
|
||||
int max = Math.min(player.getZone(ZoneType.Hand).size(), size - player.getMaxHandSize());
|
||||
final List<Card> toDiscard = player.getAi().getCardsToDiscard(max, (String[])null, null);
|
||||
for (int i = 0; i < toDiscard.size(); i++) {
|
||||
player.discard(toDiscard.get(i), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1000,21 +1000,7 @@ public class ComputerUtil {
|
||||
|
||||
for (final Card c : all) {
|
||||
for (final SpellAbility sa : c.getSpellAbility()) {
|
||||
|
||||
if (sa.getApi() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/// ????
|
||||
// if ( sa.isAbility() || sa.isSpell() && sa.getApi() != ApiType.Pump ) continue
|
||||
if (sa.hasParam("AB") && !sa.getParam("AB").equals("Pump")) {
|
||||
continue;
|
||||
}
|
||||
if (sa.hasParam("SP") && !sa.getParam("SP").equals("Pump")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sa.hasParam("KW") && sa.getParam("KW").contains("Haste")) {
|
||||
if (sa.getApi() == ApiType.Pump && sa.hasParam("KW") && sa.getParam("KW").contains("Haste")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1238,4 +1224,62 @@ public class ComputerUtil {
|
||||
}
|
||||
return bottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param chooser
|
||||
* @param discarder
|
||||
* @param sa
|
||||
* @param validCards
|
||||
* @param min
|
||||
* @return
|
||||
*/
|
||||
public static List<Card> getCardsToDiscardFromOpponent(AIPlayer chooser, Player discarder, SpellAbility sa, List<Card> validCards, int min) {
|
||||
List<Card> goodChoices = CardLists.filter(validCards, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
if (!c.getSVar("DiscardMeByOpp").equals("") || !c.getSVar("DiscardMe").equals("")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (goodChoices.isEmpty()) {
|
||||
goodChoices = validCards;
|
||||
}
|
||||
final List<Card> dChoices = new ArrayList<Card>();
|
||||
if (sa.hasParam("DiscardValid")) {
|
||||
final String validString = sa.getParam("DiscardValid");
|
||||
if (validString.contains("Creature") && !validString.contains("nonCreature")) {
|
||||
final Card c = ComputerUtilCard.getBestCreatureAI(goodChoices);
|
||||
if (c != null) {
|
||||
dChoices.add(ComputerUtilCard.getBestCreatureAI(goodChoices));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(goodChoices, CardLists.TextLenComparator);
|
||||
|
||||
CardLists.sortByCmcDesc(goodChoices);
|
||||
dChoices.add(goodChoices.get(0));
|
||||
|
||||
return Aggregates.random(goodChoices, min);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param aiChoser
|
||||
* @param p
|
||||
* @param sa
|
||||
* @param validCards
|
||||
* @param min
|
||||
* @return
|
||||
*/
|
||||
public static List<Card> getCardsToDiscardFromFriend(AIPlayer aiChooser, Player p, SpellAbility sa, List<Card> validCards, int min) {
|
||||
if (p instanceof AIPlayer) { // ask that ai player what he would like to discard
|
||||
return ((AIPlayer) p).getAi().getCardsToDiscard(min, validCards, sa);
|
||||
}
|
||||
// no special options for human or remote friends
|
||||
return getCardsToDiscardFromOpponent(aiChooser, p, sa, validCards, min);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,8 +550,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
if (game.getType() == GameType.Planechase) {
|
||||
Card p = game.getActivePlane();
|
||||
if (p != null) {
|
||||
p.clearControllers();
|
||||
p.addController(next);
|
||||
p.setController(next, 0);
|
||||
game.getAction().controllerChangeZoneCorrection(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
package forge.game.player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
@@ -27,10 +25,8 @@ import forge.CardPredicates;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.AiController;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -63,43 +59,6 @@ public class AIPlayer extends Player {
|
||||
|
||||
|
||||
|
||||
// //////////////////////////////
|
||||
// /
|
||||
// / replaces Singletons.getModel().getGameAction().draw* methods
|
||||
// /
|
||||
// //////////////////////////////
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* dredge.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
@Override
|
||||
public final boolean dredge() {
|
||||
final List<Card> dredgers = this.getDredge();
|
||||
final Random random = MyRandom.getRandom();
|
||||
|
||||
// use dredge if there are more than one of them in your graveyard
|
||||
if ((dredgers.size() > 1) || ((dredgers.size() == 1) && random.nextBoolean())) {
|
||||
CardLists.shuffle(dredgers);
|
||||
final Card c = dredgers.get(0);
|
||||
// rule 702.49a
|
||||
if (this.getDredgeNumber(c) <= this.getCardsIn(ZoneType.Library).size()) {
|
||||
// dredge library, put card in hand
|
||||
game.getAction().moveToHand(c);
|
||||
// put dredge number in graveyard
|
||||
for (int i = 0; i < this.getDredgeNumber(c); i++) {
|
||||
final Card c2 = this.getCardsIn(ZoneType.Library).get(0);
|
||||
game.getAction().moveToGraveyard(c2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// //////////////////////////////
|
||||
// /
|
||||
// / replaces Singletons.getModel().getGameAction().discard* methods
|
||||
@@ -111,7 +70,7 @@ public class AIPlayer extends Player {
|
||||
public final void discard(final int num, final SpellAbility sa) {
|
||||
int max = this.getCardsIn(ZoneType.Hand).size();
|
||||
max = Math.min(max, num);
|
||||
final List<Card> toDiscard = this.getAi().getCardsToDiscard(max, null, sa);
|
||||
final List<Card> toDiscard = this.getAi().getCardsToDiscard(max, (String[])null, sa);
|
||||
for (int i = 0; i < toDiscard.size(); i++) {
|
||||
this.doDiscard(toDiscard.get(i), sa);
|
||||
}
|
||||
@@ -125,8 +84,7 @@ public class AIPlayer extends Player {
|
||||
|
||||
if (tHand.size() > 0) {
|
||||
Card toDiscard = Aggregates.itemWithMin(tHand, CardPredicates.Accessors.fnGetCmc);
|
||||
toDiscard.getController().discard(toDiscard, sa); // this got changed
|
||||
// to doDiscard basically
|
||||
discard(toDiscard, sa); // this got changed to doDiscard basically
|
||||
return;
|
||||
}
|
||||
this.discard(num, sa);
|
||||
@@ -134,16 +92,6 @@ public class AIPlayer extends Player {
|
||||
|
||||
// /////////////////////////
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void sacrificePermanent(final String prompt, final List<Card> choices) {
|
||||
if (choices.size() > 0) {
|
||||
// TODO - this could probably use better AI
|
||||
final Card c = ComputerUtilCard.getWorstPermanentAI(choices, false, false, false, false);
|
||||
game.getAction().sacrificeDestroy(c);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.game.player.Player#getType()
|
||||
*/
|
||||
|
||||
@@ -17,74 +17,19 @@
|
||||
*/
|
||||
package forge.game.player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import forge.Card;
|
||||
import forge.Singletons;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.gui.GuiDialog;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* HumanPlayer class.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
public class HumanPlayer extends Player {
|
||||
private PlayerControllerHuman controller;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for HumanPlayer.
|
||||
* </p>
|
||||
*
|
||||
* @param myName
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
public HumanPlayer(final LobbyPlayer player, GameState game) {
|
||||
super(player, game);
|
||||
|
||||
controller = new PlayerControllerHuman(game, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* dredge.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
@Override
|
||||
public final boolean dredge() {
|
||||
boolean dredged = false;
|
||||
final boolean wantDredge = GuiDialog.confirm(null, "Do you want to dredge?");
|
||||
if (wantDredge) {
|
||||
final Card c = GuiChoose.one("Select card to dredge", this.getDredge());
|
||||
// rule 702.49a
|
||||
if (this.getDredgeNumber(c) <= getZone(ZoneType.Library).size()) {
|
||||
|
||||
// might have to make this more sophisticated
|
||||
// dredge library, put card in hand
|
||||
game.getAction().moveToHand(c);
|
||||
|
||||
for (int i = 0; i < this.getDredgeNumber(c); i++) {
|
||||
final Card c2 = getZone(ZoneType.Library).get(0);
|
||||
game.getAction().moveToGraveyard(c2);
|
||||
}
|
||||
dredged = true;
|
||||
} else {
|
||||
dredged = false;
|
||||
}
|
||||
}
|
||||
return dredged;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void discard(final int num, final SpellAbility sa) {
|
||||
@@ -99,26 +44,12 @@ public class HumanPlayer extends Player {
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void sacrificePermanent(final String prompt, final List<Card> choices) {
|
||||
final Input in = PlayerUtil.inputSacrificePermanent(choices, prompt);
|
||||
Singletons.getModel().getMatch().getInput().setInput(in);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.game.player.Player#getType()
|
||||
*/
|
||||
@Override
|
||||
public PlayerType getType() {
|
||||
return PlayerType.HUMAN;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.game.player.Player#getController()
|
||||
*/
|
||||
@Override
|
||||
public PlayerController getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
} // end HumanPlayer class
|
||||
|
||||
@@ -1233,16 +1233,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
return this.drawCards(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* dredge.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public abstract boolean dredge();
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO Write javadoc for this method.
|
||||
@@ -1287,8 +1277,17 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
for (int i = 0; i < n; i++) {
|
||||
|
||||
// TODO: multiple replacements need to be selected by the controller
|
||||
if (!this.getDredge().isEmpty()) {
|
||||
if (this.dredge()) {
|
||||
List<Card> dredgers = this.getDredge();
|
||||
if (!dredgers.isEmpty()) {
|
||||
Card toDredge = getController().chooseCardToDredge(dredgers);
|
||||
int dredgeNumber = toDredge == null ? Integer.MAX_VALUE : getDredgeNumber(toDredge);
|
||||
if ( dredgeNumber <= getZone(ZoneType.Library).size()) {
|
||||
game.getAction().moveToHand(toDredge);
|
||||
|
||||
for (int iD = 0; iD < dredgeNumber; iD++) {
|
||||
final Card c2 = getZone(ZoneType.Library).get(0);
|
||||
game.getAction().moveToGraveyard(c2);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1687,18 +1686,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* discardRandom.
|
||||
* </p>
|
||||
*
|
||||
* @param sa
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
* @return a List<Card> of cards discarded
|
||||
*/
|
||||
public final List<Card> discardRandom(final SpellAbility sa) {
|
||||
return this.discardRandom(1, sa);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -1862,7 +1849,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
*/
|
||||
public final void playLand(final Card land) {
|
||||
if (this.canPlayLand(land)) {
|
||||
land.addController(this);
|
||||
land.setController(this, 0);
|
||||
game.getAction().moveTo(this.getZone(ZoneType.Battlefield), land);
|
||||
CardFactoryUtil.playLandEffects(land);
|
||||
this.numLandsPlayed++;
|
||||
@@ -1910,9 +1897,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
|
||||
// Dev Mode
|
||||
if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.DEV_UNLIMITED_LAND)
|
||||
&& this.isHuman()
|
||||
&& Preferences.DEV_MODE) {
|
||||
if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.DEV_UNLIMITED_LAND) && this.getType() == PlayerType.HUMAN && Preferences.DEV_MODE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2140,19 +2125,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
this.attackersDeclaredThisTurn = 0;
|
||||
}
|
||||
|
||||
// //////////////////////////////
|
||||
/**
|
||||
* <p>
|
||||
* sacrificePermanent.
|
||||
* </p>
|
||||
*
|
||||
* @param prompt
|
||||
* a {@link java.lang.String} object.
|
||||
* @param choices
|
||||
* a {@link forge.CardList} object.
|
||||
*/
|
||||
public abstract void sacrificePermanent(String prompt, List<Card> choices);
|
||||
|
||||
// Game win/loss
|
||||
|
||||
/**
|
||||
|
||||
@@ -108,4 +108,8 @@ public abstract class PlayerController {
|
||||
public abstract void reveal(String string, List<Card> cards, ZoneType zone, Player owner);
|
||||
public abstract ImmutablePair<List<Card>, List<Card>> arrangeForScry(List<Card> topN);
|
||||
public abstract boolean willPutCardOnTop(Card c);
|
||||
|
||||
/** p = target player, validCards - possible discards, min cards to discard */
|
||||
public abstract List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min);
|
||||
public abstract Card chooseCardToDredge(List<Card> dredgers);
|
||||
}
|
||||
|
||||
@@ -255,4 +255,18 @@ public class PlayerControllerAi extends PlayerController {
|
||||
return true; // AI does not know what will happen next (another clash or that would become his topdeck)
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min) {
|
||||
boolean isTargetFriendly = !p.isOpponentOf(getPlayer());
|
||||
|
||||
return isTargetFriendly
|
||||
? ComputerUtil.getCardsToDiscardFromFriend(player, p, sa, validCards, min)
|
||||
: ComputerUtil.getCardsToDiscardFromOpponent(player, p, sa, validCards, min);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Card chooseCardToDredge(List<Card> dredgers) {
|
||||
return brains.chooseCardToDredge(dredgers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -318,4 +318,23 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
public boolean willPutCardOnTop(Card c) {
|
||||
return GuiDialog.confirm(c, "Where will you put " + c.getName() + " in your library", new String[]{"Top", "Bottom"} );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.game.player.PlayerController#chooseCardsToDiscardFrom(forge.game.player.Player, java.util.List, int)
|
||||
*/
|
||||
@Override
|
||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> valid, int minDiscard) {
|
||||
return GuiChoose.order("Choose cards to Discard", "Discarded", minDiscard == 0 ? -1 : minDiscard, valid, null, null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.game.player.PlayerController#chooseCardToDredge(java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public Card chooseCardToDredge(List<Card> dredgers) {
|
||||
if (GuiDialog.confirm(null, "Do you want to dredge?", false)) {
|
||||
return GuiChoose.oneOrNone("Select card to dredge", dredgers);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,7 @@ package forge.game.player;
|
||||
* @author jendave
|
||||
*/
|
||||
public enum PlayerType {
|
||||
|
||||
/** The HUMAN. */
|
||||
HUMAN,
|
||||
|
||||
/** The COMPUTER. */
|
||||
COMPUTER
|
||||
COMPUTER,
|
||||
REMOTE
|
||||
}
|
||||
|
||||
@@ -153,22 +153,6 @@ public final class PlayerUtil {
|
||||
return target;
|
||||
} // input_discard()
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* input_sacrificePermanent.
|
||||
* </p>
|
||||
*
|
||||
* @param choices
|
||||
* a {@link forge.CardList} object.
|
||||
* @param message
|
||||
* a {@link java.lang.String} object.
|
||||
* @return a {@link forge.control.input.Input} object.
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static Input inputSacrificePermanent(final List<Card> choices, final String message) {
|
||||
return PlayerUtil.inputSacrificePermanentsFromList(1, choices, message);
|
||||
} // input_sacrifice()
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* input_sacrificePermanents.
|
||||
|
||||
@@ -29,6 +29,7 @@ import forge.CardPredicates;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.spellability.Ability;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
@@ -142,30 +143,17 @@ public class PlayerZoneBattlefield extends PlayerZone {
|
||||
|
||||
}
|
||||
|
||||
final List<Card> les = c.getOwner().getOpponent().getCardsIn(ZoneType.Battlefield, "Land Equilibrium");
|
||||
final Card lesLand = c;
|
||||
if (les.size() > 0) {
|
||||
final Card source = les.get(0);
|
||||
final SpellAbility ability = new Ability(source, ManaCost.NO_COST) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
final List<Card> lands = lesLand.getOwner().getLandsInPlay();
|
||||
lesLand.getOwner().sacrificePermanent(source.getName() + " - Select a land to sacrifice",
|
||||
lands);
|
||||
|
||||
for( Player opp : c.getOwner().getOpponents())
|
||||
for( Card le : opp.getCardsIn(ZoneType.Battlefield, "Land Equilibrium") ) {
|
||||
final List<Card> pLands = c.getOwner().getLandsInPlay();
|
||||
final List<Card> oLands = opp.getLandsInPlay();
|
||||
|
||||
if (oLands.size() <= (pLands.size() - 1)) {
|
||||
SpellAbility abSac = AbilityFactory.getAbility(le.getSVar("SacLand"), le);
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(abSac);
|
||||
}
|
||||
};
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(source).append(" - ");
|
||||
sb.append(tisLand.getController()).append(" sacrifices a land.");
|
||||
ability.setStackDescription(sb.toString());
|
||||
final List<Card> pLands = lesLand.getOwner().getLandsInPlay();
|
||||
final List<Card> oLands = lesLand.getOwner().getOpponent().getLandsInPlay();
|
||||
// (pLands - 1) because this land is in play, and the
|
||||
// ability is before it is in play
|
||||
if (oLands.size() <= (pLands.size() - 1)) {
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
}
|
||||
}
|
||||
} // isLand()
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import forge.deck.Deck;
|
||||
import forge.game.GameFormat;
|
||||
import forge.game.event.Event;
|
||||
import forge.game.event.MulliganEvent;
|
||||
import forge.game.player.PlayerType;
|
||||
import forge.item.CardPrinted;
|
||||
import forge.item.PreconDeck;
|
||||
import forge.properties.NewConstants;
|
||||
@@ -445,7 +444,8 @@ public class QuestController {
|
||||
if ( ev instanceof MulliganEvent ) {
|
||||
MulliganEvent mev = (MulliganEvent)ev;
|
||||
// First mulligan is free
|
||||
if (mev.player.getType() == PlayerType.HUMAN && getAssets().hasItem(QuestItemType.SLEIGHT) && mev.player.getStats().getMulliganCount() == 0) {
|
||||
if (mev.player.getLobbyPlayer() == Singletons.getControl().getLobby().getQuestPlayer()
|
||||
&& getAssets().hasItem(QuestItemType.SLEIGHT) && mev.player.getStats().getMulliganCount() == 0) {
|
||||
mev.player.drawCard();
|
||||
}
|
||||
}
|
||||
|
||||
136
src/main/java/forge/quest/QuestRewardCard.java
Normal file
136
src/main/java/forge/quest/QuestRewardCard.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package forge.quest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.CardRules;
|
||||
import forge.item.CardPrinted;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.InventoryItem;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public abstract class QuestRewardCard implements InventoryItem, IQuestRewardCard {
|
||||
|
||||
protected String buildDescription(final String [] input) {
|
||||
final String defaultDescription = "a card";
|
||||
if (input == null || input.length < 1) {
|
||||
return defaultDescription;
|
||||
}
|
||||
|
||||
String buildDesc = null;
|
||||
|
||||
for (String s : input) {
|
||||
if (s.startsWith("desc:") || s.startsWith("Desc:")) {
|
||||
String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
buildDesc = new String(tmp[1]);
|
||||
} else {
|
||||
buildDesc = new String();
|
||||
}
|
||||
} else if (buildDesc != null) {
|
||||
if (s.contains(":")) {
|
||||
return buildDesc;
|
||||
} else {
|
||||
buildDesc = buildDesc + " " + s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buildDesc != null) {
|
||||
return buildDesc;
|
||||
}
|
||||
return defaultDescription;
|
||||
}
|
||||
|
||||
protected Predicate<CardPrinted> buildPredicates(final String [] input) {
|
||||
if (input == null || input.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Predicate<CardPrinted> filters = Singletons.getModel().getQuest().getFormat().getFilterPrinted();
|
||||
Predicate<CardRules> filterRules = null;
|
||||
Predicate<CardPrinted> filterRarity = null;
|
||||
|
||||
for (String s : input) {
|
||||
if (s.startsWith("sets:") || s.startsWith("Sets:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] setcodes = tmp[1].split(",");
|
||||
if (setcodes.length > 0) {
|
||||
List<String> sets = new ArrayList<String>();
|
||||
for (String code : setcodes) {
|
||||
if (Singletons.getModel().getEditions().contains(code)) {
|
||||
// System.out.println("Set " + code + " was found!");
|
||||
sets.add(code);
|
||||
}
|
||||
// else { System.out.println("Unknown set code " + code); }
|
||||
}
|
||||
if (sets.size() > 0) {
|
||||
filters = IPaperCard.Predicates.printedInSets(sets, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (s.startsWith("rules:") || s.startsWith("Rules:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] ruleCodes = tmp[1].split(",");
|
||||
if (ruleCodes.length > 0) {
|
||||
for (String rule : ruleCodes) {
|
||||
final Predicate<CardRules> newRule = BoosterUtils.parseRulesLimitation(rule);
|
||||
if (newRule != null) {
|
||||
filterRules = (filterRules == null ? newRule : Predicates.and(filterRules, newRule));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (s.startsWith("rarity:") || s.startsWith("Rarity:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] rarityCodes = tmp[1].split(",");
|
||||
if (rarityCodes.length > 0) {
|
||||
for (String rarity : rarityCodes) {
|
||||
if (rarity.startsWith("C") || rarity.startsWith("c")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_COMMON : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_COMMON));
|
||||
} else if (rarity.startsWith("U") || rarity.startsWith("u")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_UNCOMMON : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_UNCOMMON));
|
||||
} else if (rarity.startsWith("R") || rarity.startsWith("r")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_RARE : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_RARE));
|
||||
} else if (rarity.startsWith("M") || rarity.startsWith("m")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_MYTHIC_RARE : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_MYTHIC_RARE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (filterRules != null) {
|
||||
final Predicate<CardPrinted> rulesPrinted = Predicates.compose(filterRules, CardPrinted.FN_GET_RULES);
|
||||
filters = Predicates.and(filters, rulesPrinted);
|
||||
}
|
||||
if (filterRarity != null) {
|
||||
filters = Predicates.and(filters, filterRarity);
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* A QuestRewardCardChooser ought to always be resolved to an actual card, hence no images.
|
||||
*
|
||||
* @return an empty string
|
||||
*/
|
||||
@Override
|
||||
public String getImageKey() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public abstract List<CardPrinted> getChoices();
|
||||
|
||||
}
|
||||
@@ -6,14 +6,11 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.CardRules;
|
||||
import forge.item.CardDb;
|
||||
import forge.item.CardPrinted;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.item.ItemPool;
|
||||
|
||||
@@ -22,7 +19,7 @@ import forge.item.ItemPool;
|
||||
* The initial version includes "duplicate", other type may be added later.
|
||||
*
|
||||
*/
|
||||
public class QuestRewardCardChooser implements InventoryItem {
|
||||
public class QuestRewardCardChooser extends QuestRewardCard implements InventoryItem {
|
||||
|
||||
/**
|
||||
* Possible types for this object.
|
||||
@@ -55,110 +52,6 @@ public class QuestRewardCardChooser implements InventoryItem {
|
||||
}
|
||||
}
|
||||
|
||||
private String buildDescription(final String [] input) {
|
||||
final String defaultDescription = "a card";
|
||||
if (input == null || input.length < 1) {
|
||||
return defaultDescription;
|
||||
}
|
||||
|
||||
String buildDesc = null;
|
||||
|
||||
for (String s : input) {
|
||||
if (s.startsWith("desc:") || s.startsWith("Desc:")) {
|
||||
String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
buildDesc = new String(tmp[1]);
|
||||
} else {
|
||||
buildDesc = new String();
|
||||
}
|
||||
} else if (buildDesc != null) {
|
||||
if (s.contains(":")) {
|
||||
return buildDesc;
|
||||
} else {
|
||||
buildDesc = buildDesc + " " + s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buildDesc != null) {
|
||||
return buildDesc;
|
||||
}
|
||||
return defaultDescription;
|
||||
}
|
||||
|
||||
|
||||
private Predicate<CardPrinted> buildPredicates(final String [] input) {
|
||||
if (input == null || input.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Predicate<CardPrinted> filters = Singletons.getModel().getQuest().getFormat().getFilterPrinted();
|
||||
Predicate<CardRules> filterRules = null;
|
||||
Predicate<CardPrinted> filterRarity = null;
|
||||
|
||||
for (String s : input) {
|
||||
if (s.startsWith("sets:") || s.startsWith("Sets:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] setcodes = tmp[1].split(",");
|
||||
if (setcodes.length > 0) {
|
||||
List<String> sets = new ArrayList<String>();
|
||||
for (String code : setcodes) {
|
||||
if (Singletons.getModel().getEditions().contains(code)) {
|
||||
// System.out.println("Set " + code + " was found!");
|
||||
sets.add(code);
|
||||
}
|
||||
// else { System.out.println("Unknown set code " + code); }
|
||||
}
|
||||
if (sets.size() > 0) {
|
||||
filters = IPaperCard.Predicates.printedInSets(sets, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (s.startsWith("rules:") || s.startsWith("Rules:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] ruleCodes = tmp[1].split(",");
|
||||
if (ruleCodes.length > 0) {
|
||||
for (String rule : ruleCodes) {
|
||||
final Predicate<CardRules> newRule = BoosterUtils.parseRulesLimitation(rule);
|
||||
if (newRule != null) {
|
||||
filterRules = (filterRules == null ? newRule : Predicates.and(filterRules, newRule));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (s.startsWith("rarity:") || s.startsWith("Rarity:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] rarityCodes = tmp[1].split(",");
|
||||
if (rarityCodes.length > 0) {
|
||||
for (String rarity : rarityCodes) {
|
||||
if (rarity.startsWith("C") || rarity.startsWith("c")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_COMMON : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_COMMON));
|
||||
} else if (rarity.startsWith("U") || rarity.startsWith("u")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_UNCOMMON : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_UNCOMMON));
|
||||
} else if (rarity.startsWith("R") || rarity.startsWith("r")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_RARE : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_RARE));
|
||||
} else if (rarity.startsWith("M") || rarity.startsWith("m")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_MYTHIC_RARE : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_MYTHIC_RARE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (filterRules != null) {
|
||||
final Predicate<CardPrinted> rulesPrinted = Predicates.compose(filterRules, CardPrinted.FN_GET_RULES);
|
||||
filters = Predicates.and(filters, rulesPrinted);
|
||||
}
|
||||
if (filterRarity != null) {
|
||||
filters = Predicates.and(filters, filterRarity);
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name.
|
||||
*
|
||||
@@ -169,16 +62,6 @@ public class QuestRewardCardChooser implements InventoryItem {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* A QuestRewardCardChooser ought to always be resolved to an actual card, hence no images.
|
||||
*
|
||||
* @return an empty string
|
||||
*/
|
||||
@Override
|
||||
public String getImageKey() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* The item type.
|
||||
*
|
||||
@@ -207,6 +90,7 @@ public class QuestRewardCardChooser implements InventoryItem {
|
||||
*
|
||||
* @return a List<CardPrinted> or null if could not create a list.
|
||||
*/
|
||||
@Override
|
||||
public final List<CardPrinted> getChoices() {
|
||||
if (type == poolType.playerCards) {
|
||||
final ItemPool<CardPrinted> playerCards = Singletons.getModel().getQuest().getAssets().getCardPool();
|
||||
|
||||
@@ -5,20 +5,16 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.CardRules;
|
||||
import forge.item.CardDb;
|
||||
import forge.item.CardPrinted;
|
||||
import forge.item.IPaperCard;
|
||||
|
||||
/**
|
||||
* Allows the player to choose a card from a predicate-filtered list of cards.
|
||||
*
|
||||
*/
|
||||
public class QuestRewardCardFiltered implements IQuestRewardCard {
|
||||
public class QuestRewardCardFiltered extends QuestRewardCard implements IQuestRewardCard {
|
||||
|
||||
private final String description;
|
||||
private final Predicate<CardPrinted> predicates;
|
||||
@@ -33,109 +29,7 @@ public class QuestRewardCardFiltered implements IQuestRewardCard {
|
||||
|
||||
}
|
||||
|
||||
private String buildDescription(final String [] input) {
|
||||
final String defaultDescription = "a card";
|
||||
if (input == null || input.length < 1) {
|
||||
return defaultDescription;
|
||||
}
|
||||
|
||||
String buildDesc = null;
|
||||
|
||||
for (String s : input) {
|
||||
if (s.startsWith("desc:") || s.startsWith("Desc:")) {
|
||||
String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
buildDesc = new String(tmp[1]);
|
||||
} else {
|
||||
buildDesc = new String();
|
||||
}
|
||||
} else if (buildDesc != null) {
|
||||
if (s.contains(":")) {
|
||||
return buildDesc;
|
||||
} else {
|
||||
buildDesc = buildDesc + " " + s;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buildDesc != null) {
|
||||
return buildDesc;
|
||||
}
|
||||
return defaultDescription;
|
||||
}
|
||||
|
||||
private Predicate<CardPrinted> buildPredicates(final String [] input) {
|
||||
if (input == null || input.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Predicate<CardPrinted> filters = Singletons.getModel().getQuest().getFormat().getFilterPrinted();
|
||||
Predicate<CardRules> filterRules = null;
|
||||
Predicate<CardPrinted> filterRarity = null;
|
||||
|
||||
for (String s : input) {
|
||||
if (s.startsWith("sets:") || s.startsWith("Sets:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] setcodes = tmp[1].split(",");
|
||||
if (setcodes.length > 0) {
|
||||
List<String> sets = new ArrayList<String>();
|
||||
for (String code : setcodes) {
|
||||
if (Singletons.getModel().getEditions().contains(code)) {
|
||||
// System.out.println("Set " + code + " was found!");
|
||||
sets.add(code);
|
||||
}
|
||||
// else { System.out.println("Unknown set code " + code); }
|
||||
}
|
||||
if (sets.size() > 0) {
|
||||
filters = IPaperCard.Predicates.printedInSets(sets, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (s.startsWith("rules:") || s.startsWith("Rules:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] ruleCodes = tmp[1].split(",");
|
||||
if (ruleCodes.length > 0) {
|
||||
for (String rule : ruleCodes) {
|
||||
final Predicate<CardRules> newRule = BoosterUtils.parseRulesLimitation(rule);
|
||||
if (newRule != null) {
|
||||
filterRules = (filterRules == null ? newRule : Predicates.and(filterRules, newRule));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (s.startsWith("rarity:") || s.startsWith("Rarity:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] rarityCodes = tmp[1].split(",");
|
||||
if (rarityCodes.length > 0) {
|
||||
for (String rarity : rarityCodes) {
|
||||
if (rarity.startsWith("C") || rarity.startsWith("c")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_COMMON : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_COMMON));
|
||||
} else if (rarity.startsWith("U") || rarity.startsWith("u")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_UNCOMMON : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_UNCOMMON));
|
||||
} else if (rarity.startsWith("R") || rarity.startsWith("r")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_RARE : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_RARE));
|
||||
} else if (rarity.startsWith("M") || rarity.startsWith("m")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_MYTHIC_RARE : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_MYTHIC_RARE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (filterRules != null) {
|
||||
final Predicate<CardPrinted> rulesPrinted = Predicates.compose(filterRules, CardPrinted.FN_GET_RULES);
|
||||
filters = Predicates.and(filters, rulesPrinted);
|
||||
}
|
||||
if (filterRarity != null) {
|
||||
filters = Predicates.and(filters, filterRarity);
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* The name.
|
||||
*
|
||||
* @return the name
|
||||
@@ -145,15 +39,6 @@ public class QuestRewardCardFiltered implements IQuestRewardCard {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a dynamic list of cards, hence no images.
|
||||
*
|
||||
* @return an empty string
|
||||
*/
|
||||
@Override
|
||||
public String getImageKey() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* The item type.
|
||||
@@ -170,6 +55,7 @@ public class QuestRewardCardFiltered implements IQuestRewardCard {
|
||||
*
|
||||
* @return a List<CardPrinted> or null if could not create a list.
|
||||
*/
|
||||
@Override
|
||||
public final List<CardPrinted> getChoices() {
|
||||
List<CardPrinted> cardChoices = new ArrayList<CardPrinted>();
|
||||
for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllCards(), predicates)) {
|
||||
|
||||
Reference in New Issue
Block a user