Some fixes (#8779)

This commit is contained in:
tool4ever
2025-09-26 08:48:22 +02:00
committed by GitHub
parent 9599d01d2c
commit c10b5706f1
9 changed files with 113 additions and 119 deletions

View File

@@ -3104,41 +3104,38 @@ public class ComputerUtil {
public static CardCollection filterAITgts(SpellAbility sa, Player ai, CardCollection srcList, boolean alwaysStrict) { public static CardCollection filterAITgts(SpellAbility sa, Player ai, CardCollection srcList, boolean alwaysStrict) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
if (source == null) { return srcList; } if (source == null || !sa.hasParam("AITgts")) {
return srcList;
if (sa.hasParam("AITgts")) {
CardCollection list;
String aiTgts = sa.getParam("AITgts");
if (aiTgts.startsWith("BetterThan")) {
int value = 0;
if (aiTgts.endsWith("Source")) {
value = ComputerUtilCard.evaluateCreature(source);
if (source.isEnchanted()) {
for (Card enc : source.getEnchantedBy()) {
if (enc.getController().equals(ai)) {
value += 100; // is 100 per AI's own aura enough?
}
}
}
} else if (aiTgts.contains("EvalRating.")) {
value = AbilityUtils.calculateAmount(source, aiTgts.substring(aiTgts.indexOf(".") + 1), sa);
} else {
System.err.println("Warning: Unspecified AI target evaluation rating for SA " + sa);
value = ComputerUtilCard.evaluateCreature(source);
}
final int totalValue = value;
list = CardLists.filter(srcList, c -> ComputerUtilCard.evaluateCreature(c) > totalValue + 30);
} else {
list = CardLists.getValidCards(srcList, sa.getParam("AITgts"), sa.getActivatingPlayer(), source, sa);
}
if (!list.isEmpty() || sa.hasParam("AITgtsStrict") || alwaysStrict) {
return list;
} else {
return srcList;
}
} }
CardCollection list;
String aiTgts = sa.getParam("AITgts");
if (aiTgts.startsWith("BetterThan")) {
int value = 0;
if (aiTgts.endsWith("Source")) {
value = ComputerUtilCard.evaluateCreature(source);
if (source.isEnchanted()) {
for (Card enc : source.getEnchantedBy()) {
if (enc.getController().equals(ai)) {
value += 100; // is 100 per AI's own aura enough?
}
}
}
} else if (aiTgts.contains("EvalRating.")) {
value = AbilityUtils.calculateAmount(source, aiTgts.substring(aiTgts.indexOf(".") + 1), sa);
} else {
System.err.println("Warning: Unspecified AI target evaluation rating for SA " + sa);
value = ComputerUtilCard.evaluateCreature(source);
}
final int totalValue = value;
list = CardLists.filter(srcList, c -> ComputerUtilCard.evaluateCreature(c) > totalValue + 30);
} else {
list = CardLists.getValidCards(srcList, sa.getParam("AITgts"), sa.getActivatingPlayer(), source, sa);
}
if (!list.isEmpty() || sa.hasParam("AITgtsStrict") || alwaysStrict) {
return list;
}
return srcList; return srcList;
} }

View File

@@ -815,7 +815,7 @@ public class ComputerUtilMana {
String manaProduced = predictManafromSpellAbility(saPayment, ai, toPay); String manaProduced = predictManafromSpellAbility(saPayment, ai, toPay);
payMultipleMana(cost, manaProduced, ai); payMultipleMana(cost, manaProduced, ai);
// remove from available lists // remove to prevent re-usage since resources don't get consumed
sourcesForShards.values().removeIf(CardTraitPredicates.isHostCard(saPayment.getHostCard())); sourcesForShards.values().removeIf(CardTraitPredicates.isHostCard(saPayment.getHostCard()));
} else { } else {
final CostPayment pay = new CostPayment(saPayment.getPayCosts(), saPayment); final CostPayment pay = new CostPayment(saPayment.getPayCosts(), saPayment);
@@ -828,8 +828,10 @@ public class ComputerUtilMana {
// subtract mana from mana pool // subtract mana from mana pool
manapool.payManaFromAbility(sa, cost, saPayment); manapool.payManaFromAbility(sa, cost, saPayment);
// no need to remove abilities from resource map, // need to consider if another use is now prevented
// once their costs are paid and consume resources, they can not be used again if (!cost.isPaid() && saPayment.isActivatedAbility() && !saPayment.getRestrictions().canPlay(saPayment.getHostCard(), saPayment)) {
sourcesForShards.values().removeIf(s -> s == saPayment);
}
if (hasConverge) { if (hasConverge) {
// hack to prevent converge re-using sources // hack to prevent converge re-using sources
@@ -1662,7 +1664,6 @@ public class ComputerUtilMana {
if (replaced.contains("C")) { if (replaced.contains("C")) {
manaMap.put(ManaAtom.COLORLESS, m); manaMap.put(ManaAtom.COLORLESS, m);
} }
} }
} }
} }

View File

@@ -891,9 +891,6 @@ public class ChangeZoneAi extends SpellAbilityAi {
CardCollection list = CardLists.getTargetableCards(game.getCardsIn(origin), sa); CardCollection list = CardLists.getTargetableCards(game.getCardsIn(origin), sa);
list = ComputerUtil.filterAITgts(sa, ai, list, true); list = ComputerUtil.filterAITgts(sa, ai, list, true);
if (sa.hasParam("AITgtsOnlyBetterThanSelf")) {
list = CardLists.filter(list, card -> ComputerUtilCard.evaluateCreature(card) > ComputerUtilCard.evaluateCreature(source) + 30);
}
if (source.isInZone(ZoneType.Hand)) { if (source.isInZone(ZoneType.Hand)) {
list = CardLists.filter(list, CardPredicates.nameNotEquals(source.getName())); // Don't get the same card back. list = CardLists.filter(list, CardPredicates.nameNotEquals(source.getName())); // Don't get the same card back.

View File

@@ -75,9 +75,8 @@ public class RestartGameEffect extends SpellAbilityEffect {
p.clearController(); p.clearController();
CardCollection newLibrary = new CardCollection(p.getCardsIn(restartZones, false)); CardCollection newLibrary = new CardCollection(p.getCardsIn(restartZones, false));
List<Card> filteredCards = null;
if (leaveZone != null) { if (leaveZone != null) {
filteredCards = CardLists.getValidCards(p.getCardsIn(leaveZone), leaveRestriction, p, sa.getHostCard(), sa); List<Card> filteredCards = CardLists.getValidCards(p.getCardsIn(leaveZone), leaveRestriction, p, sa.getHostCard(), sa);
newLibrary.addAll(filteredCards); newLibrary.addAll(filteredCards);
} }

View File

@@ -466,29 +466,29 @@ public class CardFactory {
return new WrappedAbility(sa.getTrigger(), sa.getWrappedAbility().copy(newHost, controller, false), sa.getDecider()); return new WrappedAbility(sa.getTrigger(), sa.getWrappedAbility().copy(newHost, controller, false), sa.getDecider());
} }
public static CardCloneStates getCloneStates(final Card in, final Card out, final CardTraitBase sa) { public static CardCloneStates getCloneStates(final Card in, final Card out, final CardTraitBase cause) {
final Card host = sa.getHostCard(); final Card host = cause.getHostCard();
final Map<String,String> origSVars = host.getSVars(); final Map<String,String> origSVars = host.getSVars();
final List<String> types = Lists.newArrayList(); final List<String> types = Lists.newArrayList();
final List<String> keywords = Lists.newArrayList(); final List<String> keywords = Lists.newArrayList();
boolean KWifNew = false; boolean KWifNew = false;
final List<String> removeKeywords = Lists.newArrayList(); final List<String> removeKeywords = Lists.newArrayList();
List<String> creatureTypes = null; List<String> creatureTypes = null;
final CardCloneStates result = new CardCloneStates(in, sa); final CardCloneStates result = new CardCloneStates(in, cause);
final String newName = sa.getParam("NewName"); final String newName = cause.getParam("NewName");
ColorSet colors = null; ColorSet colors = null;
if (sa.hasParam("AddTypes")) { if (cause.hasParam("AddTypes")) {
types.addAll(Arrays.asList(sa.getParam("AddTypes").split(" & "))); types.addAll(Arrays.asList(cause.getParam("AddTypes").split(" & ")));
} }
if (sa.hasParam("SetCreatureTypes")) { if (cause.hasParam("SetCreatureTypes")) {
creatureTypes = ImmutableList.copyOf(sa.getParam("SetCreatureTypes").split(" ")); creatureTypes = ImmutableList.copyOf(cause.getParam("SetCreatureTypes").split(" "));
} }
if (sa.hasParam("AddKeywords")) { if (cause.hasParam("AddKeywords")) {
String kwString = sa.getParam("AddKeywords"); String kwString = cause.getParam("AddKeywords");
if (kwString.startsWith("IfNew ")) { if (kwString.startsWith("IfNew ")) {
KWifNew = true; KWifNew = true;
kwString = kwString.substring(6); kwString = kwString.substring(6);
@@ -496,21 +496,21 @@ public class CardFactory {
keywords.addAll(Arrays.asList(kwString.split(" & "))); keywords.addAll(Arrays.asList(kwString.split(" & ")));
} }
if (sa.hasParam("RemoveKeywords")) { if (cause.hasParam("RemoveKeywords")) {
removeKeywords.addAll(Arrays.asList(sa.getParam("RemoveKeywords").split(" & "))); removeKeywords.addAll(Arrays.asList(cause.getParam("RemoveKeywords").split(" & ")));
} }
if (sa.hasParam("AddColors")) { if (cause.hasParam("AddColors")) {
colors = ColorSet.fromNames(sa.getParam("AddColors").split(",")); colors = ColorSet.fromNames(cause.getParam("AddColors").split(","));
} }
if (sa.hasParam("SetColor")) { if (cause.hasParam("SetColor")) {
colors = ColorSet.fromNames(sa.getParam("SetColor").split(",")); colors = ColorSet.fromNames(cause.getParam("SetColor").split(","));
} }
if (sa.hasParam("SetColorByManaCost")) { if (cause.hasParam("SetColorByManaCost")) {
if (sa.hasParam("SetManaCost")) { if (cause.hasParam("SetManaCost")) {
colors = ColorSet.fromManaCost(new ManaCost(new ManaCostParser(sa.getParam("SetManaCost")))); colors = ColorSet.fromManaCost(new ManaCost(new ManaCostParser(cause.getParam("SetManaCost"))));
} else { } else {
colors = ColorSet.fromManaCost(host.getManaCost()); colors = ColorSet.fromManaCost(host.getManaCost());
} }
@@ -522,56 +522,55 @@ public class CardFactory {
// if something is cloning a facedown card, it only clones the // if something is cloning a facedown card, it only clones the
// facedown state into original // facedown state into original
final CardState ret = new CardState(out, CardStateName.Original); final CardState ret = new CardState(out, CardStateName.Original);
ret.copyFrom(in.getFaceDownState(), false, sa); ret.copyFrom(in.getFaceDownState(), false, cause);
result.put(CardStateName.Original, ret); result.put(CardStateName.Original, ret);
} else if (in.isFlipCard()) { } else if (in.isFlipCard()) {
// if something is cloning a flip card, copy both original and // if something is cloning a flip card, copy both original and
// flipped state // flipped state
final CardState ret1 = new CardState(out, CardStateName.Original); final CardState ret1 = new CardState(out, CardStateName.Original);
ret1.copyFrom(in.getState(CardStateName.Original), false, sa); ret1.copyFrom(in.getState(CardStateName.Original), false, cause);
result.put(CardStateName.Original, ret1); result.put(CardStateName.Original, ret1);
final CardState ret2 = new CardState(out, CardStateName.Flipped); final CardState ret2 = new CardState(out, CardStateName.Flipped);
ret2.copyFrom(in.getState(CardStateName.Flipped), false, sa); ret2.copyFrom(in.getState(CardStateName.Flipped), false, cause);
result.put(CardStateName.Flipped, ret2); result.put(CardStateName.Flipped, ret2);
} else if (in.hasState(CardStateName.Secondary)) { } else if (in.hasState(CardStateName.Secondary)) {
final CardState ret1 = new CardState(out, CardStateName.Original); final CardState ret1 = new CardState(out, CardStateName.Original);
ret1.copyFrom(in.getState(CardStateName.Original), false, sa); ret1.copyFrom(in.getState(CardStateName.Original), false, cause);
result.put(CardStateName.Original, ret1); result.put(CardStateName.Original, ret1);
final CardState ret2 = new CardState(out, CardStateName.Secondary); final CardState ret2 = new CardState(out, CardStateName.Secondary);
ret2.copyFrom(in.getState(CardStateName.Secondary), false, sa); ret2.copyFrom(in.getState(CardStateName.Secondary), false, cause);
result.put(CardStateName.Secondary, ret2); result.put(CardStateName.Secondary, ret2);
} else if (in.isTransformable() && sa instanceof SpellAbility && ( } else if (in.isTransformable() && cause instanceof SpellAbility sa && (
ApiType.CopyPermanent.equals(((SpellAbility)sa).getApi()) || ApiType.CopyPermanent.equals(sa.getApi()) ||
ApiType.CopySpellAbility.equals(((SpellAbility)sa).getApi()) || ApiType.CopySpellAbility.equals(sa.getApi()) ||
ApiType.ReplaceToken.equals(((SpellAbility)sa).getApi()) ApiType.ReplaceToken.equals(sa.getApi()))) {
)) {
// CopyPermanent can copy token // CopyPermanent can copy token
final CardState ret1 = new CardState(out, CardStateName.Original); final CardState ret1 = new CardState(out, CardStateName.Original);
ret1.copyFrom(in.getState(CardStateName.Original), false, sa); ret1.copyFrom(in.getState(CardStateName.Original), false, cause);
result.put(CardStateName.Original, ret1); result.put(CardStateName.Original, ret1);
final CardState ret2 = new CardState(out, CardStateName.Backside); final CardState ret2 = new CardState(out, CardStateName.Backside);
ret2.copyFrom(in.getState(CardStateName.Backside), false, sa); ret2.copyFrom(in.getState(CardStateName.Backside), false, cause);
result.put(CardStateName.Backside, ret2); result.put(CardStateName.Backside, ret2);
} else if (in.isSplitCard()) { } else if (in.isSplitCard()) {
// for split cards, copy all three states // for split cards, copy all three states
final CardState ret1 = new CardState(out, CardStateName.Original); final CardState ret1 = new CardState(out, CardStateName.Original);
ret1.copyFrom(in.getState(CardStateName.Original), false, sa); ret1.copyFrom(in.getState(CardStateName.Original), false, cause);
result.put(CardStateName.Original, ret1); result.put(CardStateName.Original, ret1);
final CardState ret2 = new CardState(out, CardStateName.LeftSplit); final CardState ret2 = new CardState(out, CardStateName.LeftSplit);
ret2.copyFrom(in.getState(CardStateName.LeftSplit), false, sa); ret2.copyFrom(in.getState(CardStateName.LeftSplit), false, cause);
result.put(CardStateName.LeftSplit, ret2); result.put(CardStateName.LeftSplit, ret2);
final CardState ret3 = new CardState(out, CardStateName.RightSplit); final CardState ret3 = new CardState(out, CardStateName.RightSplit);
ret3.copyFrom(in.getState(CardStateName.RightSplit), false, sa); ret3.copyFrom(in.getState(CardStateName.RightSplit), false, cause);
result.put(CardStateName.RightSplit, ret3); result.put(CardStateName.RightSplit, ret3);
} else { } else {
// in all other cases just copy the current state to original // in all other cases just copy the current state to original
final CardState ret = new CardState(out, CardStateName.Original); final CardState ret = new CardState(out, CardStateName.Original);
ret.copyFrom(in.getState(in.getCurrentStateName()), false, sa); ret.copyFrom(in.getState(in.getCurrentStateName()), false, cause);
result.put(CardStateName.Original, ret); result.put(CardStateName.Original, ret);
} }
@@ -581,32 +580,32 @@ public class CardFactory {
final CardState state = e.getValue(); final CardState state = e.getValue();
// has Embalm Condition for extra changes of Vizier of Many Faces // has Embalm Condition for extra changes of Vizier of Many Faces
if (sa.hasParam("Embalm") && !out.isEmbalmed()) { if (cause.hasParam("Embalm") && !out.isEmbalmed()) {
continue; continue;
} }
// update the names for the states // update the names for the states
if (sa.hasParam("KeepName")) { if (cause.hasParam("KeepName")) {
state.setName(originalState.getName()); state.setName(originalState.getName());
} else if (newName != null) { } else if (newName != null) {
// convert NICKNAME descriptions? // convert NICKNAME descriptions?
state.setName(newName); state.setName(newName);
} }
if (sa.hasParam("AddColors")) { if (cause.hasParam("AddColors")) {
state.addColor(colors.getColor()); state.addColor(colors.getColor());
} }
if (sa.hasParam("SetColor") || sa.hasParam("SetColorByManaCost")) { if (cause.hasParam("SetColor") || cause.hasParam("SetColorByManaCost")) {
state.setColor(colors.getColor()); state.setColor(colors.getColor());
} }
if (sa.hasParam("NonLegendary")) { if (cause.hasParam("NonLegendary")) {
state.removeType(CardType.Supertype.Legendary); state.removeType(CardType.Supertype.Legendary);
} }
if (sa.hasParam("RemoveCardTypes")) { if (cause.hasParam("RemoveCardTypes")) {
state.removeCardTypes(sa.hasParam("RemoveSubTypes")); state.removeCardTypes(cause.hasParam("RemoveSubTypes"));
} }
state.addType(types); state.addType(types);
@@ -638,31 +637,31 @@ public class CardFactory {
// CR 208.3 A noncreature object not on the battlefield has power or toughness only if it has a power and toughness printed on it. // CR 208.3 A noncreature object not on the battlefield has power or toughness only if it has a power and toughness printed on it.
// currently only LKI can be trusted? // currently only LKI can be trusted?
if ((sa.hasParam("SetPower") || sa.hasParam("SetToughness")) && if ((cause.hasParam("SetPower") || cause.hasParam("SetToughness")) &&
(state.getType().isCreature() || (originalState != null && in.getOriginalState(originalState.getStateName()).getBasePowerString() != null))) { (state.getType().isCreature() || (originalState != null && in.getOriginalState(originalState.getStateName()).getBasePowerString() != null))) {
if (sa.hasParam("SetPower")) { if (cause.hasParam("SetPower")) {
state.setBasePower(AbilityUtils.calculateAmount(host, sa.getParam("SetPower"), sa)); state.setBasePower(AbilityUtils.calculateAmount(host, cause.getParam("SetPower"), cause));
} }
if (sa.hasParam("SetToughness")) { if (cause.hasParam("SetToughness")) {
state.setBaseToughness(AbilityUtils.calculateAmount(host, sa.getParam("SetToughness"), sa)); state.setBaseToughness(AbilityUtils.calculateAmount(host, cause.getParam("SetToughness"), cause));
} }
} }
if (state.getType().isPlaneswalker() && sa.hasParam("SetLoyalty")) { if (state.getType().isPlaneswalker() && cause.hasParam("SetLoyalty")) {
state.setBaseLoyalty(String.valueOf(AbilityUtils.calculateAmount(host, sa.getParam("SetLoyalty"), sa))); state.setBaseLoyalty(String.valueOf(AbilityUtils.calculateAmount(host, cause.getParam("SetLoyalty"), cause)));
} }
if (sa.hasParam("RemoveCost")) { if (cause.hasParam("RemoveCost")) {
state.setManaCost(ManaCost.NO_COST); state.setManaCost(ManaCost.NO_COST);
} }
if (sa.hasParam("SetManaCost")) { if (cause.hasParam("SetManaCost")) {
state.setManaCost(new ManaCost(new ManaCostParser(sa.getParam("SetManaCost")))); state.setManaCost(new ManaCost(new ManaCostParser(cause.getParam("SetManaCost"))));
} }
// SVars to add to clone // SVars to add to clone
if (sa.hasParam("AddSVars") || sa.hasParam("GainTextSVars")) { if (cause.hasParam("AddSVars") || cause.hasParam("GainTextSVars")) {
final String str = sa.getParamOrDefault("GainTextSVars", sa.getParam("AddSVars")); final String str = cause.getParamOrDefault("GainTextSVars", cause.getParam("AddSVars"));
for (final String s : str.split(",")) { for (final String s : str.split(",")) {
if (origSVars.containsKey(s)) { if (origSVars.containsKey(s)) {
final String actualsVar = origSVars.get(s); final String actualsVar = origSVars.get(s);
@@ -672,8 +671,8 @@ public class CardFactory {
} }
// triggers to add to clone // triggers to add to clone
if (sa.hasParam("AddTriggers")) { if (cause.hasParam("AddTriggers")) {
for (final String s : sa.getParam("AddTriggers").split(",")) { for (final String s : cause.getParam("AddTriggers").split(",")) {
if (origSVars.containsKey(s)) { if (origSVars.containsKey(s)) {
final String actualTrigger = origSVars.get(s); final String actualTrigger = origSVars.get(s);
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, out, true, state); final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, out, true, state);
@@ -683,8 +682,8 @@ public class CardFactory {
} }
// abilities to add to clone // abilities to add to clone
if (sa.hasParam("AddAbilities") || sa.hasParam("GainTextAbilities")) { if (cause.hasParam("AddAbilities") || cause.hasParam("GainTextAbilities")) {
final String str = sa.getParamOrDefault("GainTextAbilities", sa.getParam("AddAbilities")); final String str = cause.getParamOrDefault("GainTextAbilities", cause.getParam("AddAbilities"));
for (final String s : str.split(",")) { for (final String s : str.split(",")) {
if (origSVars.containsKey(s)) { if (origSVars.containsKey(s)) {
final String actualAbility = origSVars.get(s); final String actualAbility = origSVars.get(s);
@@ -696,18 +695,18 @@ public class CardFactory {
} }
// static abilities to add to clone // static abilities to add to clone
if (sa.hasParam("AddStaticAbilities")) { if (cause.hasParam("AddStaticAbilities")) {
final String str = sa.getParam("AddStaticAbilities"); final String str = cause.getParam("AddStaticAbilities");
for (final String s : str.split(",")) { for (final String s : str.split(",")) {
if (origSVars.containsKey(s)) { if (origSVars.containsKey(s)) {
final String actualStatic = origSVars.get(s); final String actualStatic = origSVars.get(s);
state.addStaticAbility(StaticAbility.create(actualStatic, out, sa.getCardState(), true)); state.addStaticAbility(StaticAbility.create(actualStatic, out, cause.getCardState(), true));
} }
} }
} }
if (sa.hasParam("GainThisAbility") && sa instanceof SpellAbility) { if (cause.hasParam("GainThisAbility") && cause instanceof SpellAbility sa) {
SpellAbility root = ((SpellAbility) sa).getRootAbility(); SpellAbility root = sa.getRootAbility();
// Aurora Shifter // Aurora Shifter
if (root.isTrigger() && root.getTrigger().getSpawningAbility() != null) { if (root.isTrigger() && root.getTrigger().getSpawningAbility() != null) {
@@ -724,35 +723,35 @@ public class CardFactory {
} }
// Special Rules for Embalm and Eternalize // Special Rules for Embalm and Eternalize
if (sa.isEmbalm() && sa.isIntrinsic()) { if (cause.isEmbalm() && cause.isIntrinsic()) {
String name = "embalm_" + TextUtil.fastReplace( String name = "embalm_" + TextUtil.fastReplace(
TextUtil.fastReplace(host.getName(), ",", ""), TextUtil.fastReplace(host.getName(), ",", ""),
" ", "_").toLowerCase(); " ", "_").toLowerCase();
state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode())); state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode()));
} }
if (sa.isEternalize() && sa.isIntrinsic()) { if (cause.isEternalize() && cause.isIntrinsic()) {
String name = "eternalize_" + TextUtil.fastReplace( String name = "eternalize_" + TextUtil.fastReplace(
TextUtil.fastReplace(host.getName(), ",", ""), TextUtil.fastReplace(host.getName(), ",", ""),
" ", "_").toLowerCase(); " ", "_").toLowerCase();
state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode())); state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode()));
} }
if (sa.isKeyword(Keyword.OFFSPRING) && sa.isIntrinsic()) { if (cause.isKeyword(Keyword.OFFSPRING) && cause.isIntrinsic()) {
String name = "offspring_" + TextUtil.fastReplace( String name = "offspring_" + TextUtil.fastReplace(
TextUtil.fastReplace(host.getName(), ",", ""), TextUtil.fastReplace(host.getName(), ",", ""),
" ", "_").toLowerCase(); " ", "_").toLowerCase();
state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode())); state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode()));
} }
if (sa.isKeyword(Keyword.SQUAD) && sa.isIntrinsic()) { if (cause.isKeyword(Keyword.SQUAD) && cause.isIntrinsic()) {
String name = "squad_" + TextUtil.fastReplace( String name = "squad_" + TextUtil.fastReplace(
TextUtil.fastReplace(host.getName(), ",", ""), TextUtil.fastReplace(host.getName(), ",", ""),
" ", "_").toLowerCase(); " ", "_").toLowerCase();
state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode())); state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode()));
} }
if (sa.hasParam("GainTextOf") && originalState != null) { if (cause.hasParam("GainTextOf") && originalState != null) {
state.setSetCode(originalState.getSetCode()); state.setSetCode(originalState.getSetCode());
state.setRarity(originalState.getRarity()); state.setRarity(originalState.getRarity());
state.setImageKey(originalState.getImageKey()); state.setImageKey(originalState.getImageKey());
@@ -764,27 +763,27 @@ public class CardFactory {
continue; continue;
} }
if (sa.hasParam("SetPower") && sta.hasParam("SetPower")) if (cause.hasParam("SetPower") && sta.hasParam("SetPower"))
state.removeStaticAbility(sta); state.removeStaticAbility(sta);
if (sa.hasParam("SetToughness") && sta.hasParam("SetToughness")) if (cause.hasParam("SetToughness") && sta.hasParam("SetToughness"))
state.removeStaticAbility(sta); state.removeStaticAbility(sta);
// currently only Changeling and similar should be affected by that // currently only Changeling and similar should be affected by that
// other cards using AddType$ ChosenType should not // other cards using AddType$ ChosenType should not
if (sa.hasParam("SetCreatureTypes") && sta.hasParam("AddAllCreatureTypes")) { if (cause.hasParam("SetCreatureTypes") && sta.hasParam("AddAllCreatureTypes")) {
state.removeStaticAbility(sta); state.removeStaticAbility(sta);
} }
if ((sa.hasParam("SetColor") || sa.hasParam("SetColorByManaCost")) && sta.hasParam("SetColor")) { if ((cause.hasParam("SetColor") || cause.hasParam("SetColorByManaCost")) && sta.hasParam("SetColor")) {
state.removeStaticAbility(sta); state.removeStaticAbility(sta);
} }
} }
// remove some keywords // remove some keywords
if (sa.hasParam("SetCreatureTypes")) { if (cause.hasParam("SetCreatureTypes")) {
state.removeIntrinsicKeyword(Keyword.CHANGELING); state.removeIntrinsicKeyword(Keyword.CHANGELING);
} }
if (sa.hasParam("SetColor") || sa.hasParam("SetColorByManaCost")) { if (cause.hasParam("SetColor") || cause.hasParam("SetColorByManaCost")) {
state.removeIntrinsicKeyword(Keyword.DEVOID); state.removeIntrinsicKeyword(Keyword.DEVOID);
} }
} }

View File

@@ -92,7 +92,7 @@ public abstract class AbilityActivated extends SpellAbility implements Cloneable
return false; return false;
} }
if (!(this.getRestrictions().canPlay(c, this))) { if (!getRestrictions().canPlay(c, this)) {
return false; return false;
} }

View File

@@ -2,5 +2,5 @@ Name:Kami of Twisted Reflection
ManaCost:1 U U ManaCost:1 U U
Types:Creature Spirit Types:Creature Spirit
PT:2/2 PT:2/2
A:AB$ ChangeZone | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature.YouCtrl | AITgts$ Creature.Other+YouCtrl | AITgtsOnlyBetterThanSelf$ True | TgtPrompt$ Select target creature you control | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target creature you control to its owner's hand. A:AB$ ChangeZone | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature.YouCtrl | AITgts$ BetterThanSource | TgtPrompt$ Select target creature you control | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target creature you control to its owner's hand.
Oracle:Sacrifice Kami of Twisted Reflection: Return target creature you control to its owner's hand. Oracle:Sacrifice Kami of Twisted Reflection: Return target creature you control to its owner's hand.

View File

@@ -8,4 +8,5 @@ SVar:DBLoseLife:DB$ LoseLife | Defined$ Player.IsRemembered | LifeAmount$ X
SVar:DBChangeZoneAll:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Library | Destination$ Hand | SubAbility$ DBCleanup SVar:DBChangeZoneAll:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Library | Destination$ Hand | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Count$ValidLibrary Card.IsRemembered+!RememberedPlayerOwn$CardManaCost SVar:X:Count$ValidLibrary Card.IsRemembered+!RememberedPlayerOwn$CardManaCost
AI:RemoveDeck:All
Oracle:At the beginning of your end step, two target players each reveal the top card of their library. They each lose life equal to the mana value of the card revealed by the other player. Then they each put the card they revealed into their hand. Oracle:At the beginning of your end step, two target players each reveal the top card of their library. They each lose life equal to the mana value of the card revealed by the other player. Then they each put the card they revealed into their hand.

View File

@@ -6,7 +6,7 @@ K:Double Strike
K:Vigilance K:Vigilance
S:Mode$ CantBeCast | ValidCard$ Card.Self | EffectZone$ All | Caster$ Player.Active | CheckSVar$ Z | SVarCompare$ LE3 | Description$ You can't cast CARDNAME during your first, second, or third turns of the game. S:Mode$ CantBeCast | ValidCard$ Card.Self | EffectZone$ All | Caster$ Player.Active | CheckSVar$ Z | SVarCompare$ LE3 | Description$ You can't cast CARDNAME during your first, second, or third turns of the game.
SVar:Z:Count$YourTurns SVar:Z:Count$YourTurns
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | CheckSVar$ Y | SVarCompare$ EQ1 | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ At the beginning of your end step, if you've played a land or cast a spell this turn from anywhere other than your hand, CARDNAME deals damage equal to his power to any target. T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | CheckSVar$ Y | SVarCompare$ GE1 | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ At the beginning of your end step, if you've played a land or cast a spell this turn from anywhere other than your hand, CARDNAME deals damage equal to his power to any target.
SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ X | AILogic$ PowerDmg SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ X | AILogic$ PowerDmg
SVar:X:Count$CardPower SVar:X:Count$CardPower
T:Mode$ LandPlayed | Origin$ Exile,Library,Graveyard | ValidCard$ Land.YouCtrl | Execute$ StoreVar | Static$ True T:Mode$ LandPlayed | Origin$ Exile,Library,Graveyard | ValidCard$ Land.YouCtrl | Execute$ StoreVar | Static$ True