Fix Tezzeret, Betrayer of Flesh

This commit is contained in:
tool4EvEr
2022-05-15 23:36:19 +02:00
parent 24b2186e0d
commit 5a1d740243
9 changed files with 30 additions and 23 deletions

View File

@@ -1773,7 +1773,7 @@ public class AiController {
} }
return toExile; return toExile;
} }
public boolean doTrigger(SpellAbility spell, boolean mandatory) { public boolean doTrigger(SpellAbility spell, boolean mandatory) {
if (spell instanceof WrappedAbility) if (spell instanceof WrappedAbility)
return doTrigger(((WrappedAbility)spell).getWrappedAbility(), mandatory); return doTrigger(((WrappedAbility)spell).getWrappedAbility(), mandatory);
@@ -1785,7 +1785,7 @@ public class AiController {
} }
return false; return false;
} }
/** /**
* Ai should run. * Ai should run.
* *
@@ -1840,12 +1840,11 @@ public class AiController {
} else if (effect.hasParam("AICheckDredge")) { } else if (effect.hasParam("AICheckDredge")) {
return player.getCardsIn(ZoneType.Library).size() > 8 || player.isCardInPlay("Laboratory Maniac"); return player.getCardsIn(ZoneType.Library).size() > 8 || player.isCardInPlay("Laboratory Maniac");
} else return sa != null && doTrigger(sa, false); } else return sa != null && doTrigger(sa, false);
} }
public List<SpellAbility> chooseSaToActivateFromOpeningHand(List<SpellAbility> usableFromOpeningHand) { public List<SpellAbility> chooseSaToActivateFromOpeningHand(List<SpellAbility> usableFromOpeningHand) {
// AI would play everything. But limits to one copy of (Leyline of Singularity) and (Gemstone Caverns) // AI would play everything. But limits to one copy of (Leyline of Singularity) and (Gemstone Caverns)
List<SpellAbility> result = Lists.newArrayList(); List<SpellAbility> result = Lists.newArrayList();
for (SpellAbility sa : usableFromOpeningHand) { for (SpellAbility sa : usableFromOpeningHand) {
// Is there a better way for the AI to decide this? // Is there a better way for the AI to decide this?
@@ -1853,7 +1852,7 @@ public class AiController {
result.add(sa); result.add(sa);
} }
} }
boolean hasLeyline1 = false; boolean hasLeyline1 = false;
SpellAbility saGemstones = null; SpellAbility saGemstones = null;
@@ -1879,7 +1878,7 @@ public class AiController {
result.remove(saGemstones); result.remove(saGemstones);
result.add(saGemstones); result.add(saGemstones);
} }
return result; return result;
} }

View File

@@ -273,8 +273,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
} }
} }
//Ninjutsu if (sa.isNinjutsu()) {
if (sa.hasParam("Ninjutsu")) {
if (!source.ignoreLegendRule() && ai.isCardInPlay(source.getName())) { if (!source.ignoreLegendRule() && ai.isCardInPlay(source.getName())) {
return false; return false;
} }

View File

@@ -54,7 +54,6 @@ public class PermanentAi extends SpellAbilityAi {
// check on legendary // check on legendary
if (!card.ignoreLegendRule() && ai.isCardInPlay(card.getName())) { if (!card.ignoreLegendRule() && ai.isCardInPlay(card.getName())) {
// TODO check the risk we'd lose the effect with bad timing // TODO check the risk we'd lose the effect with bad timing
// TODO check for keyword
if (!card.hasSVar("AILegendaryException")) { if (!card.hasSVar("AILegendaryException")) {
// AiPlayDecision.WouldDestroyLegend // AiPlayDecision.WouldDestroyLegend
return false; return false;

View File

@@ -144,7 +144,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
sa.getParam("ChangeNum"), sa) : 1; sa.getParam("ChangeNum"), sa) : 1;
boolean tapped = sa.hasParam("Tapped"); boolean tapped = sa.hasParam("Tapped");
boolean attacking = sa.hasParam("Attacking"); boolean attacking = sa.hasParam("Attacking");
if (sa.hasParam("Ninjutsu")) { if (sa.isNinjutsu()) {
tapped = true; tapped = true;
attacking = true; attacking = true;
} }
@@ -455,7 +455,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
return; return;
} }
if (sa.isHidden() && !sa.hasParam("Ninjutsu")) { if (sa.isHidden() && !sa.isNinjutsu()) {
changeHiddenOriginResolve(sa); changeHiddenOriginResolve(sa);
} else { } else {
//else if (isKnown(origin) || sa.containsKey("Ninjutsu")) { //else if (isKnown(origin) || sa.containsKey("Ninjutsu")) {
@@ -599,7 +599,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
movedCard = game.getAction().moveToLibrary(gameCard, libraryPosition, sa); movedCard = game.getAction().moveToLibrary(gameCard, libraryPosition, sa);
} else { } else {
if (destination.equals(ZoneType.Battlefield)) { if (destination.equals(ZoneType.Battlefield)) {
if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) { if (sa.hasParam("Tapped") || sa.isNinjutsu()) {
gameCard.setTapped(true); gameCard.setTapped(true);
} }
if (sa.hasParam("Untapped")) { if (sa.hasParam("Untapped")) {
@@ -713,7 +713,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (addToCombat(movedCard, movedCard.getController(), sa, "Attacking", "Blocking")) { if (addToCombat(movedCard, movedCard.getController(), sa, "Attacking", "Blocking")) {
combatChanged = true; combatChanged = true;
} }
if (sa.hasParam("Ninjutsu")) { if (sa.isNinjutsu()) {
// Ninjutsu need to get the Defender of the Returned Creature // Ninjutsu need to get the Defender of the Returned Creature
final Card returned = sa.getPaidList("Returned").getFirst(); final Card returned = sa.getPaidList("Returned").getFirst();
final GameEntity defender = game.getCombat().getDefenderByAttacker(returned); final GameEntity defender = game.getCombat().getDefenderByAttacker(returned);

View File

@@ -245,8 +245,6 @@ public class ManaEffect extends SpellAbilityEffect {
// Only clear express choice after mana has been produced // Only clear express choice after mana has been produced
abMana.clearExpressChoice(); abMana.clearExpressChoice();
//resolveDrawback(sa);
} }
/** /**

View File

@@ -433,8 +433,8 @@ public class CostAdjustment {
if (!st.matchesValidParam("Activator", activator)) { if (!st.matchesValidParam("Activator", activator)) {
return false; return false;
} }
if (st.hasParam("NonActivatorTurn") && ((activator == null) if (st.hasParam("NonActivatorTurn") && (activator == null
|| hostCard.getGame().getPhaseHandler().isPlayerTurn(activator))) { || game.getPhaseHandler().isPlayerTurn(activator))) {
return false; return false;
} }
@@ -469,6 +469,18 @@ public class CostAdjustment {
if (!sa.isActivatedAbility() || sa.isReplacementAbility()) { if (!sa.isActivatedAbility() || sa.isReplacementAbility()) {
return false; return false;
} }
if (st.hasParam("OnlyFirstActivation")) {
int times = 0;
for (IndividualCostPaymentInstance i : game.costPaymentStack) {
SpellAbility paymentSa = i.getPayment().getAbility();
if (paymentSa.isActivatedAbility() && st.matchesValidParam("ValidCard", paymentSa.getHostCard())) {
times++;
if (times > 1) {
return false;
}
}
}
}
} else if (type.equals("NonManaAbility")) { } else if (type.equals("NonManaAbility")) {
if (!sa.isActivatedAbility() || sa.isManaAbility() || sa.isReplacementAbility()) { if (!sa.isActivatedAbility() || sa.isManaAbility() || sa.isReplacementAbility()) {
return false; return false;
@@ -488,7 +500,7 @@ public class CostAdjustment {
} }
if (st.hasParam("AffectedZone")) { if (st.hasParam("AffectedZone")) {
List<ZoneType> zones = ZoneType.listValueOf(st.getParam("AffectedZone")); List<ZoneType> zones = ZoneType.listValueOf(st.getParam("AffectedZone"));
if (sa.isSpell() && sa.getHostCard().wasCast()) { if (sa.isSpell() && card.wasCast()) {
if (!zones.contains(card.getCastFrom().getZoneType())) { if (!zones.contains(card.getCastFrom().getZoneType())) {
return false; return false;
} }
@@ -508,7 +520,7 @@ public class CostAdjustment {
continue; continue;
} }
for (GameObject target : curSa.getTargets()) { for (GameObject target : curSa.getTargets()) {
if (target.isValid(st.getParam("ValidTarget").split(","), hostCard.getController(), hostCard, curSa)) { if (target.isValid(st.getParam("ValidTarget").split(","), controller, hostCard, curSa)) {
targetValid = true; targetValid = true;
break outer; break outer;
} }
@@ -533,7 +545,7 @@ public class CostAdjustment {
} }
for (SpellAbility target : curSa.getTargets().getTargetSpells()) { for (SpellAbility target : curSa.getTargets().getTargetSpells()) {
Card targetCard = target.getHostCard(); Card targetCard = target.getHostCard();
if (targetCard.isValid(st.getParam("ValidSpellTarget").split(","), hostCard.getController(), hostCard, curSa)) { if (targetCard.isValid(st.getParam("ValidSpellTarget").split(","), controller, hostCard, curSa)) {
targetValid = true; targetValid = true;
break outer; break outer;
} }

View File

@@ -2,6 +2,6 @@ Name:Hematite Talisman
ManaCost:2 ManaCost:2
Types:Artifact Types:Artifact
T:Mode$ SpellCast | ValidCard$ Card.Red | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever a player casts a red spell, you may pay {3}. If you do, untap target permanent. T:Mode$ SpellCast | ValidCard$ Card.Red | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever a player casts a red spell, you may pay {3}. If you do, untap target permanent.
SVar:TrigUntap:AB$Untap | Cost$ 3 | ValidTgts$ Permanent | TgtPrompt$ Select target permanent SVar:TrigUntap:AB$ Untap | Cost$ 3 | ValidTgts$ Permanent | TgtPrompt$ Select target permanent
AI:RemoveDeck:Random AI:RemoveDeck:Random
Oracle:Whenever a player casts a red spell, you may pay {3}. If you do, untap target permanent. Oracle:Whenever a player casts a red spell, you may pay {3}. If you do, untap target permanent.

View File

@@ -1,7 +1,7 @@
Name:Shreds of Sanity Name:Shreds of Sanity
ManaCost:2 R ManaCost:2 R
Types:Sorcery Types:Sorcery
A:SP$ ChangeZone | Cost$ 2 R | Origin$ Graveyard | Destination$ Hand | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Choose target instant card in your graveyard | ValidTgts$ Instant.YouCtrl | SpellDescription$ Return up to two target creature cards from your graveyard to your hand, then discard a card. | SubAbility$ DBReturn A:SP$ ChangeZone | Cost$ 2 R | Origin$ Graveyard | Destination$ Hand | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Choose target instant card in your graveyard | ValidTgts$ Instant.YouCtrl | SpellDescription$ Return up to one target instant card and up to one target sorcery card from your graveyard to your hand, then discard a card. Exile CARDNAME. | SubAbility$ DBReturn
SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Sorcery.YouCtrl | TgtPrompt$ Select target sorcery card in your graveyard | SubAbility$ DBDiscard SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Sorcery.YouCtrl | TgtPrompt$ Select target sorcery card in your graveyard | SubAbility$ DBDiscard
SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose | SubAbility$ DBExile SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose | SubAbility$ DBExile
SVar:DBExile:DB$ ChangeZone | Origin$ Stack | Destination$ Exile SVar:DBExile:DB$ ChangeZone | Origin$ Stack | Destination$ Exile

View File

@@ -7,7 +7,7 @@ SVar:TrigStore:DB$ Pump | NoteNumber$ 1
SVar:ArtAct:Count$NotedNumber SVar:ArtAct:Count$NotedNumber
T:Mode$ TurnBegin | Execute$ TrigReset | Static$ True T:Mode$ TurnBegin | Execute$ TrigReset | Static$ True
SVar:TrigReset:DB$ Pump | NoteNumber$ 0 SVar:TrigReset:DB$ Pump | NoteNumber$ 0
S:Mode$ ReduceCost | ValidCard$ Artifact.YouCtrl | Type$ Ability | Amount$ 2 | CheckSVar$ ArtAct | SVarCompare$ NE1 | AffectedZone$ Battlefield | Description$ The first activated ability of an artifact you activate each turn costs {2} less to activate. S:Mode$ ReduceCost | ValidCard$ Artifact.YouCtrl | Type$ Ability | Amount$ 2 | CheckSVar$ ArtAct | SVarCompare$ NE1 | OnlyFirstActivation$ True | AffectedZone$ Battlefield | Description$ The first activated ability of an artifact you activate each turn costs {2} less to activate.
A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | NumCards$ 2 | SpellDescription$ Draw two cards. Then discard two cards unless you discard an artifact card. | SubAbility$ DBDiscard A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | NumCards$ 2 | SpellDescription$ Draw two cards. Then discard two cards unless you discard an artifact card. | SubAbility$ DBDiscard
SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 2 | Mode$ TgtChoose | UnlessType$ Artifact SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 2 | Mode$ TgtChoose | UnlessType$ Artifact
A:AB$ Animate | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | ValidTgts$ Artifact | Types$ Creature,Artifact | TgtPrompt$ Select target artifact | SubAbility$ NonVehicle | Duration$ Permanent | SpellDescription$ Target artifact becomes an artifact creature. If it isn't a vehicle, it has base power and toughness 4/4. A:AB$ Animate | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | ValidTgts$ Artifact | Types$ Creature,Artifact | TgtPrompt$ Select target artifact | SubAbility$ NonVehicle | Duration$ Permanent | SpellDescription$ Target artifact becomes an artifact creature. If it isn't a vehicle, it has base power and toughness 4/4.