Card fixes (#2389)

* Fix AI check

* Fix cards

* Clean up

---------

Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.59>
This commit is contained in:
tool4ever
2023-02-04 05:43:12 +01:00
committed by GitHub
parent de5c6f1fef
commit f8761d2349
7 changed files with 35 additions and 20 deletions

View File

@@ -3161,4 +3161,14 @@ public class ComputerUtil {
return remainingLife;
}
public static boolean isETBprevented(Card c) {
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(c);
// don't need to bother with real LKI since this is a passive check and the card isn't going anywhere
repParams.put(AbilityKey.CardLKI, c);
repParams.put(AbilityKey.Origin, c.getZone().getZoneType());
repParams.put(AbilityKey.Destination, ZoneType.Battlefield);
List<ReplacementEffect> list = c.getGame().getReplacementHandler().getReplacementList(ReplacementType.Moved, repParams, ReplacementLayer.CantHappen);
return !list.isEmpty();
}
}

View File

@@ -673,10 +673,8 @@ public class ChangeZoneAi extends SpellAbilityAi {
return false;
}
// if (origin.equals("Graveyard")) {
// return this card from graveyard: cards like Hammer of Bogardan
// in general this is cool, but we should add some type of
// restrictions
// in general this is cool, but we should add some type of restrictions
// return this card from battlefield: cards like Blinking Spirit
// in general this should only be used to protect from Imminent Harm
@@ -713,6 +711,10 @@ public class ChangeZoneAi extends SpellAbilityAi {
}
if (destination == ZoneType.Battlefield) {
if (ComputerUtil.isETBprevented(retrieval.get(0))) {
return false;
}
// predict whether something may put a ETBing creature below zero toughness
// (e.g. Reassembing Skeleton + Elesh Norn, Grand Cenobite)
for (final Card c : retrieval) {

View File

@@ -1,6 +1,5 @@
package forge.ai.ability;
import java.util.List;
import java.util.Map;
import com.google.common.base.Predicate;
@@ -11,7 +10,6 @@ import forge.ai.ComputerUtilCard;
import forge.ai.ComputerUtilCost;
import forge.ai.SpellAbilityAi;
import forge.game.Game;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardCollectionView;
@@ -21,9 +19,6 @@ import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.replacement.ReplacementEffect;
import forge.game.replacement.ReplacementLayer;
import forge.game.replacement.ReplacementType;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.MyRandom;
@@ -90,19 +85,13 @@ public class ManifestAi extends SpellAbilityAi {
}
static boolean shouldManyfest(final Card card, final Player ai, final SpellAbility sa) {
final Game game = ai.getGame();
// check to ensure that there are no replacement effects that prevent creatures ETBing from library
// (e.g. Grafdigger's Cage)
Card topCopy = CardUtil.getLKICopy(card);
topCopy.turnFaceDownNoUpdate();
topCopy.setManifested(true);
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(topCopy);
repParams.put(AbilityKey.Origin, card.getZone().getZoneType());
repParams.put(AbilityKey.Destination, ZoneType.Battlefield);
repParams.put(AbilityKey.Source, sa.getHostCard());
List<ReplacementEffect> list = game.getReplacementHandler().getReplacementList(ReplacementType.Moved, repParams, ReplacementLayer.CantHappen);
if (!list.isEmpty()) {
if (ComputerUtil.isETBprevented(topCopy)) {
return false;
}

View File

@@ -194,6 +194,20 @@ public class PlayerProperty {
if (source.isRemembered(player)) {
return false;
}
} else if (property.equals("IsTriggerRemembered")) {
boolean found = false;
for (Object o : spellAbility.getTriggerRemembered()) {
if (o instanceof Player) {
Player trigRem = (Player) o;
if (trigRem.equals(player)) {
found = true;
break;
}
}
}
if (!found) {
return false;
}
} else if (property.equals("EnchantedBy")) {
if (!player.isEnchantedBy(source)) {
return false;

View File

@@ -3,7 +3,7 @@ ManaCost:4 G G
Types:Creature Plant Elemental
PT:7/2
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ DelTrig | TriggerDescription$ When CARDNAME dies, return it to the battlefield tapped under its owner's control at the beginning of their next upkeep.
SVar:DelTrig:DB$ DelayedTrigger | DelayedTriggerDefinedPlayer$ TriggeredCardOwner | Mode$ Phase | Phase$ Upkeep | Execute$ TrigChange | RememberObjects$ TriggeredNewCardLKICopy | TriggerDescription$ Return CARDNAME to the battlefield tapped under its owner's control at the beginning of their next upkeep.
SVar:DelTrig:DB$ DelayedTrigger | ValidPlayer$ Player.IsTriggerRemembered | Mode$ Phase | Phase$ Upkeep | Execute$ TrigChange | RememberObjects$ TriggeredNewCardLKICopy,TriggeredCardOwner | TriggerDescription$ Return CARDNAME to the battlefield tapped under its owner's control at the beginning of their next upkeep.
SVar:TrigChange:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ DelayTriggerRememberedLKI | Tapped$ True
SVar:SacMe:1
Oracle:When Phytotitan dies, return it to the battlefield tapped under its owner's control at the beginning of their next upkeep.

View File

@@ -5,7 +5,7 @@ PT:6/5
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ SacAllOthers | TriggerDescription$ At the beginning of your end step, sacrifice each other creature you control.
SVar:SacAllOthers:DB$ SacrificeAll | ValidCards$ Creature.Other+YouCtrl
A:AB$ Pump | Cost$ Discard<2/Card> Sac<1/CARDNAME> | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | RememberTargets$ True | SubAbility$ DBDelayTrig | StackDescription$ Return CARDNAME to the battlefield under {p:Targeted}'s control at the beginning of their next upkeep. | SpellDescription$ Choose target opponent. Return CARDNAME to the battlefield under that player's control at the beginning of their next upkeep.
SVar:DBDelayTrig:DB$ DelayedTrigger | TriggerZones$ Graveyard | Mode$ Phase | Phase$ Upkeep | DelayedTriggerDefinedPlayer$ Remembered | RememberObjects$ Remembered,SacrificedCards | Execute$ DBChange | StackDescription$ None | TriggerDescription$ Return CARDNAME to the battlefield under that player's control at the beginning of their next upkeep.
SVar:DBDelayTrig:DB$ DelayedTrigger | TriggerZones$ Graveyard | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player.IsTriggerRemembered | RememberObjects$ Remembered,SacrificedCards | Execute$ DBChange | StackDescription$ None | TriggerDescription$ Return CARDNAME to the battlefield under that player's control at the beginning of their next upkeep.
SVar:DBChange:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Graveyard | Destination$ Battlefield | GainControl$ DelayTriggerRemembered
AI:RemoveDeck:All
DeckHas:Ability$Discard|Sacrifice

View File

@@ -2,10 +2,10 @@ Name:Uro, Titan of Nature's Wrath
ManaCost:1 G U
Types:Legendary Creature Elder Giant
PT:6/6
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless it escaped.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When NICKNAME enters the battlefield, sacrifice it unless it escaped.
SVar:TrigSac:DB$ Sacrifice | SacValid$ Self | ConditionNotPresent$ Card.Self+escaped
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME enters the battlefield or attacks, you gain 3 life and draw a card, then you may put a land card from your hand onto the battlefield.
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerZones$ Battlefield | OptionalDecider$ You | Secondary$ True | TriggerDescription$ When CARDNAME enters the battlefield or attacks, you gain 3 life and draw a card, then you may put a land card from your hand onto the battlefield.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When NICKNAME enters the battlefield or attacks, you gain 3 life and draw a card, then you may put a land card from your hand onto the battlefield.
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerZones$ Battlefield | OptionalDecider$ You | Secondary$ True | TriggerDescription$ When NICKNAME enters the battlefield or attacks, you gain 3 life and draw a card, then you may put a land card from your hand onto the battlefield.
SVar:TrigGainLife:DB$ GainLife | LifeAmount$ 3 | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | Defined$ You | SubAbility$ DBLand
SVar:DBLand:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Land | ChangeNum$ 1 | OptionalDecider$ You