mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-14 01:38:13 +00:00
Merge branch 'miscfix' into 'master'
ControlGain Lose fix See merge request core-developers/forge!6379
This commit is contained in:
@@ -890,7 +890,7 @@ public class AiBlockController {
|
||||
|
||||
CardCollection pwsWithChumpBlocks = new CardCollection();
|
||||
CardCollection chosenChumpBlockers = new CardCollection();
|
||||
CardCollection chumpPWDefenders = CardLists.filter(new CardCollection(this.blockersLeft), new Predicate<Card>() {
|
||||
CardCollection chumpPWDefenders = CardLists.filter(this.blockersLeft, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(Card card) {
|
||||
return ComputerUtilCard.evaluateCreature(card) <= (card.isToken() ? evalThresholdToken
|
||||
|
||||
@@ -1187,7 +1187,7 @@ public class AiController {
|
||||
if ("DiscardUncastableAndExcess".equals(sa.getParam("AILogic"))) {
|
||||
CardCollection discards = new CardCollection();
|
||||
final CardCollectionView inHand = player.getCardsIn(ZoneType.Hand);
|
||||
final int numLandsOTB = CardLists.count(player.getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS);
|
||||
final int numLandsOTB = CardLists.count(inHand, CardPredicates.Presets.LANDS);
|
||||
int numOppInHand = 0;
|
||||
for (Player p : player.getGame().getPlayers()) {
|
||||
if (p.getCardsIn(ZoneType.Hand).size() > numOppInHand) {
|
||||
|
||||
@@ -106,8 +106,7 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
||||
}
|
||||
return false;
|
||||
} else if ("ManifestCreatsFromGraveyard".equals(sa.getParam("AILogic"))) {
|
||||
PlayerCollection players = new PlayerCollection();
|
||||
players.addAll(ai.getOpponents());
|
||||
PlayerCollection players = ai.getOpponents();
|
||||
players.add(ai);
|
||||
int maxSize = 1;
|
||||
for (Player player : players) {
|
||||
|
||||
@@ -142,6 +142,10 @@ public class ControlGainAi extends SpellAbilityAi {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (c.canBeControlledBy(ai)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// do not take perm control on something that leaves the play end of turn
|
||||
if (!lose.contains("EOT") && c.hasSVar("EndOfTurnLeavePlay")) {
|
||||
return false;
|
||||
|
||||
@@ -747,7 +747,7 @@ public class CountersPutAi extends CountersAi {
|
||||
|
||||
if (!sa.usesTargeting()) {
|
||||
// No target. So must be defined
|
||||
list = new CardCollection(AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa));
|
||||
list = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
|
||||
|
||||
if (amountStr.equals("X")
|
||||
&& root.getXManaCostPaid() != null /* SubAbility on something that already had set PayX, e.g. Endless One ETB counters */
|
||||
@@ -988,6 +988,9 @@ public class CountersPutAi extends CountersAi {
|
||||
if (!negative.isEmpty()) {
|
||||
return ComputerUtilCard.getBestAI(negative);
|
||||
}
|
||||
if (!isOptional) {
|
||||
return ComputerUtilCard.getBestAI(opponents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,12 @@ public class RearrangeTopOfLibraryAi extends SpellAbilityAi {
|
||||
PlayerCollection pc = sa.usesTargeting() ? new PlayerCollection(sa.getTargets().getTargetPlayers())
|
||||
: AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Defined"), sa);
|
||||
|
||||
Player p = pc.getFirst(); // currently always a single target spell
|
||||
Card top = p.getCardsIn(ZoneType.Library).isEmpty() ? null : p.getCardsIn(ZoneType.Library).getFirst();
|
||||
if (top == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int uncastableCMCThreshold = 2;
|
||||
int minLandsToScryLandsAway = 4;
|
||||
if (player.getController().isAI()) {
|
||||
@@ -107,8 +113,6 @@ public class RearrangeTopOfLibraryAi extends SpellAbilityAi {
|
||||
uncastableCMCThreshold = aic.getIntProperty(AiProps.SCRY_IMMEDIATELY_UNCASTABLE_CMC_DIFF);
|
||||
}
|
||||
|
||||
Player p = pc.getFirst(); // currently always a single target spell
|
||||
Card top = p.getCardsIn(ZoneType.Library).getFirst();
|
||||
int landsOTB = CardLists.count(p.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.LANDS_PRODUCING_MANA);
|
||||
int cmc = top.isSplitCard() ? Math.min(top.getCMC(Card.SplitCMCMode.LeftSplitCMC), top.getCMC(Card.SplitCMCMode.RightSplitCMC))
|
||||
: top.getCMC();
|
||||
|
||||
@@ -1519,7 +1519,7 @@ public class GameAction {
|
||||
}
|
||||
|
||||
if (c.hasCardAttachments()) {
|
||||
for (final Card attach : Lists.newArrayList(c.getAttachedCards())) {
|
||||
for (final Card attach : c.getAttachedCards()) {
|
||||
if (!attach.isInPlay()) {
|
||||
unAttachList.add(attach);
|
||||
checkAgain = true;
|
||||
|
||||
@@ -33,6 +33,9 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
&& !source.isInPlay()) {
|
||||
return;
|
||||
}
|
||||
if ("UntilLoseControlOfHost".equals(sa.getParam("Duration")) && source.getController() != sa.getActivatingPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remember Objects
|
||||
if (sa.hasParam("RememberObjects")) {
|
||||
|
||||
@@ -574,13 +574,15 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
gameCard.addEtbCounter(cType, cAmount, player);
|
||||
}
|
||||
if (sa.hasParam("GainControl")) {
|
||||
Player newController = player;
|
||||
if (sa.hasParam("NewController")) {
|
||||
final Player p = Iterables.getFirst(AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("NewController"), sa), null);
|
||||
if (p != null) {
|
||||
gameCard.setController(p, game.getNextTimestamp());
|
||||
newController = Iterables.getFirst(AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("NewController"), sa), null);
|
||||
}
|
||||
if (newController != null) {
|
||||
if (newController != gameCard.getController()) {
|
||||
gameCard.runChangeControllerCommands();
|
||||
}
|
||||
} else {
|
||||
gameCard.setController(player, game.getNextTimestamp());
|
||||
gameCard.setController(newController, game.getNextTimestamp());
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("AttachedTo")) {
|
||||
@@ -959,7 +961,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
boolean shuffleMandatory = true;
|
||||
boolean searchedLibrary = false;
|
||||
if (defined) {
|
||||
fetchList = new CardCollection(AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa));
|
||||
fetchList = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
|
||||
if (!sa.hasParam("ChangeNum")) {
|
||||
changeNum = fetchList.size();
|
||||
}
|
||||
@@ -1239,6 +1241,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("NewController")) {
|
||||
newController = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("NewController"), sa).get(0);
|
||||
}
|
||||
if (newController != c.getController()) {
|
||||
c.runChangeControllerCommands();
|
||||
}
|
||||
c.setController(newController, game.getNextTimestamp());
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,9 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
if (lose != null && lose.contains("LeavesPlay") && !source.isInPlay()) {
|
||||
return;
|
||||
}
|
||||
if (lose != null && lose.contains("LoseControl") && source.getController() != sa.getActivatingPlayer()) {
|
||||
return;
|
||||
}
|
||||
if (lose != null && lose.contains("Untap") && !source.isTapped()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,15 @@ public class EffectEffect extends SpellAbilityEffect {
|
||||
String noteCounterDefined = null;
|
||||
List<Player> effectOwner = null;
|
||||
boolean imprintOnHost = false;
|
||||
final String duration = sa.getParam("Duration");
|
||||
|
||||
if (("UntilHostLeavesPlay".equals(duration) || "UntilLoseControlOfHost".equals(duration))
|
||||
&& !hostCard.isInPlay()) {
|
||||
return;
|
||||
}
|
||||
if ("UntilLoseControlOfHost".equals(duration) && hostCard.getController() != sa.getActivatingPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sa.hasParam("Abilities")) {
|
||||
effectAbilities = sa.getParam("Abilities").split(",");
|
||||
@@ -275,7 +284,6 @@ public class EffectEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
// Duration
|
||||
final String duration = sa.getParam("Duration");
|
||||
if (duration == null || !duration.equals("Permanent")) {
|
||||
final GameCommand endEffect = new GameCommand() {
|
||||
private static final long serialVersionUID = -5861759814760561373L;
|
||||
|
||||
@@ -69,7 +69,7 @@ public class MultiplePilesEffect extends SpellAbilityEffect {
|
||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||
CardCollection pool;
|
||||
if (sa.hasParam("DefinedCards")) {
|
||||
pool = new CardCollection(AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa));
|
||||
pool = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa);
|
||||
} else {
|
||||
pool = new CardCollection(p.getCardsIn(zone));
|
||||
}
|
||||
|
||||
@@ -43,6 +43,9 @@ public class PumpEffect extends SpellAbilityEffect {
|
||||
&& !(host.isInPlay() || host.isInZone(ZoneType.Stack))) {
|
||||
return;
|
||||
}
|
||||
if ("UntilLoseControlOfHost".equals(sa.getParam("Duration")) && host.getController() != sa.getActivatingPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// do Game Check there in case of LKI
|
||||
final Card gameCard = game.getCardState(applyTo, null);
|
||||
|
||||
@@ -19,5 +19,4 @@ Types:Legendary Creature Spirit
|
||||
PT:4/3
|
||||
K:Trample
|
||||
A:AB$ Pump | Cost$ SubCounter<1/KI> | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 2 | NumDef$ 2 | SpellDescription$ Target creature gets +2/+2 until end of turn.
|
||||
# This link may be a temporary solution and could change in the near future.
|
||||
Oracle:Trample\nRemove a ki counter from Ichiga, Who Topples Oaks: Target creature gets +2/+2 until end of turn.
|
||||
|
||||
@@ -18,5 +18,4 @@ Colors:blue
|
||||
Types:Legendary Creature Spirit
|
||||
PT:3/4
|
||||
A:AB$ Counter | Cost$ SubCounter<1/KI> | TargetType$ Spell | ValidTgts$ Card | TgtPrompt$ Select target spell. | Destination$ Graveyard | UnlessCost$ 2 | UnlessPayer$ TargetedController | SpellDescription$ Counter target spell unless its controller pays 2.
|
||||
# This link may be a temporary solution and could change in the near future.
|
||||
Oracle:Remove a ki counter from Jaraku the Interloper: Counter target spell unless its controller pays {2}.
|
||||
|
||||
@@ -18,5 +18,4 @@ Colors:red
|
||||
Types:Legendary Creature Spirit
|
||||
PT:5/2
|
||||
A:AB$ GainControl | Cost$ SubCounter<1/KI> | ValidTgts$ Creature | TgtPrompt$ Select target creature | LoseControl$ EOT | SpellDescription$ Gain control of target creature until end of turn.
|
||||
# This link may be a temporary solution and could change in the near future.
|
||||
Oracle:Remove a ki counter from Azamuki, Treachery Incarnate: Gain control of target creature until end of turn.
|
||||
|
||||
@@ -16,5 +16,4 @@ ManaCost:1 U
|
||||
Types:Legendary Enchantment
|
||||
T:Mode$ SpellCast | ValidActivatingPlayer$ Player.Opponent | ActivatorThisTurnCast$ EQ1 | NoResolvingCheck$ True | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent casts their first spell each turn, counter that spell.
|
||||
SVar:TrigCounter:DB$ Counter | Defined$ TriggeredSpellAbility | Destination$ Graveyard
|
||||
# This link may be a temporary solution and could change in the near future.
|
||||
Oracle:Whenever an opponent casts their first spell each turn, counter that spell.
|
||||
|
||||
@@ -19,5 +19,4 @@ Types:Legendary Creature Spirit
|
||||
PT:3/4
|
||||
K:Flying
|
||||
A:AB$ Pump | Cost$ SubCounter<1/KI> | KW$ Prevent all damage that would be dealt to CARDNAME. | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Prevent all damage that would be dealt to target creature this turn.
|
||||
# This link may be a temporary solution and could change in the near future.
|
||||
Oracle:Flying\nRemove a ki counter from Kaiso, Memory of Loyalty: Prevent all damage that would be dealt to target creature this turn.
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Gather Specimens
|
||||
ManaCost:3 U U U
|
||||
Types:Instant
|
||||
A:SP$ Effect | Cost$ 3 U U U | Name$ Gather Specimens Effect | ReplacementEffects$ OppCreatEnters | SpellDescription$ If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead.
|
||||
SVar:OppCreatEnters:Event$ Moved | Destination$ Battlefield | ValidCard$ Creature.OppCtrl | ReplaceWith$ ETBYourCtrl | Description$ If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead.
|
||||
SVar:OppCreatEnters:Event$ Moved | Destination$ Battlefield | ValidCard$ Creature.OppCtrl | ReplaceWith$ ETBYourCtrl | Layer$ Control | Description$ If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead.
|
||||
SVar:ETBYourCtrl:DB$ ChangeZone | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard | GainControl$ True
|
||||
AI:RemoveDeck:All
|
||||
Oracle:If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead.
|
||||
|
||||
@@ -2,9 +2,9 @@ Name:Haphazard Bombardment
|
||||
ManaCost:5 R
|
||||
Types:Enchantment
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBPutCounter | TriggerDescription$ When CARDNAME enters the battlefield, choose four nonenchantment permanents you don't control and put an aim counter on each of them.
|
||||
SVar:DBPutCounter:DB$ PutCounter | Choices$ Permanent.YouDontCtrl+nonEnchantment | ChoiceAmount$ 4 | Defined$ ChosenCard | CounterType$ AIM | CounterNum$ 1
|
||||
SVar:DBPutCounter:DB$ PutCounter | Choices$ Permanent.YouDontCtrl+nonEnchantment | ChoiceAmount$ 4 | Defined$ ChosenCard | CounterType$ AIM | CounterNum$ 1 | IsCurse$ True
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Permanent.YouDontCtrl+counters_GE1_AIM | PresentCompare$ GE2 | Execute$ TrigDestroy | TriggerDescription$ At the beginning of your end step, if two or more permanents you don't control have an aim counter on them, destroy one of those permanents at random.
|
||||
SVar:TrigDestroy:DB$ ChooseCard | Amount$ 1 | AtRandom$ True | Choices$ Permanent.YouDontCtrl+counters_GE1_AIM | SubAbility$ DBDestroy
|
||||
SVar:TrigDestroy:DB$ ChooseCard | Amount$ 1 | AtRandom$ True | Choices$ Permanent.YouDontCtrl+counters_GE1_AIM+withoutIndestructible | SubAbility$ DBDestroy
|
||||
SVar:DBDestroy:DB$ Destroy | Defined$ ChosenCard | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True
|
||||
Oracle:When Haphazard Bombardment enters the battlefield, choose four nonenchantment permanents you don't control and put an aim counter on each of them.\nAt the beginning of your end step, if two or more permanents you don't control have an aim counter on them, destroy one of those permanents at random.
|
||||
|
||||
@@ -18,5 +18,4 @@ Colors:black
|
||||
Types:Legendary Creature Spirit
|
||||
PT:4/4
|
||||
A:AB$ Pump | Cost$ SubCounter<1/KI> | KW$ Fear | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Target creature gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.)
|
||||
# This link may be a temporary solution and could change in the near future.
|
||||
Oracle:Remove a ki counter from Scarmaker: Target creature gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.)
|
||||
|
||||
@@ -16,5 +16,4 @@ Colors:black
|
||||
Types:Legendary Enchantment
|
||||
T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of each player's upkeep, that player sacrifices a creature.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ TriggeredPlayer | SacValid$ Creature
|
||||
# This link may be a temporary solution and could change in the near future.
|
||||
Oracle:At the beginning of each player's upkeep, that player sacrifices a creature.
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:2 U U
|
||||
Types:Creature Human Rogue
|
||||
PT:2/2
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters the battlefield, gain control of target artifact for as long as you control CARDNAME.
|
||||
SVar:TrigChange:DB$ GainControl | TgtPrompt$ Choose target artifact | ValidTgts$ Artifact | LoseControl$ LeavesPlay, LoseControl | SpellDescription$ Gain control of target artifact for as long as you control CARDNAME.
|
||||
SVar:TrigChange:DB$ GainControl | TgtPrompt$ Choose target artifact | ValidTgts$ Artifact | LoseControl$ LeavesPlay,LoseControl | SpellDescription$ Gain control of target artifact for as long as you control CARDNAME.
|
||||
SVar:PlayMain1:TRUE
|
||||
Oracle:When Master Thief enters the battlefield, gain control of target artifact for as long as you control Master Thief.
|
||||
|
||||
@@ -13,5 +13,4 @@ Name:Rune-Tail's Essence
|
||||
ManaCost:2 W
|
||||
Types:Legendary Enchantment
|
||||
R:Event$ DamageDone | Prevent$ True | ValidTarget$ Creature.YouCtrl | Description$ Prevent all damage that would be dealt to creatures you control.
|
||||
# This link may be a temporary solution and could change in the near future.
|
||||
Oracle:Prevent all damage that would be dealt to creatures you control.
|
||||
|
||||
@@ -8,6 +8,6 @@ R:Event$ AddCounter | ActiveZones$ Battlefield | ValidSource$ You | ValidObject$
|
||||
SVar:DoubleCounters:DB$ ReplaceCounter | ValidSource$ You | Amount$ X
|
||||
SVar:X:ReplaceCount$CounterNum/Twice
|
||||
R:Event$ AddCounter | ActiveZones$ Battlefield | ValidSource$ Opponent | ValidObject$ Permanent.inZoneBattlefield,Player | ReplaceWith$ HalfCounters | Description$ If an opponent would put one or more counters on a permanent or player, they put half that many of each of those kinds of counters on that permanent or player instead, rounded down.
|
||||
SVar:HalfCounters:DB$ ReplaceCounter | ValidSource$ Opponent | Amount$ DB$ Y
|
||||
SVar:HalfCounters:DB$ ReplaceCounter | ValidSource$ Opponent | Amount$ Y
|
||||
SVar:Y:ReplaceCount$CounterNum/HalfDown
|
||||
Oracle:Trample, haste\nIf you would put one or more counters on a permanent or player, put twice that many of each of those kinds of counters on that permanent or player instead.\nIf an opponent would put one or more counters on a permanent or player, they put half that many of each of those kinds of counters on that permanent or player instead, rounded down.
|
||||
|
||||
Reference in New Issue
Block a user