Some fixes (#5219)

Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.60>
This commit is contained in:
tool4ever
2024-05-08 21:06:04 +02:00
committed by GitHub
parent a2deb08337
commit f60718b7b5
11 changed files with 60 additions and 84 deletions

View File

@@ -1352,7 +1352,7 @@ public class ComputerUtilMana {
CostAdjustment.adjust(cost, sa, null, test);
int timesMultikicked = card.getKickerMagnitude();
if (timesMultikicked > 0 && sa.hasParam("Announce") && sa.getParam("Announce").startsWith("Multikicker")) {
if (timesMultikicked > 0 && sa.isAnnouncing("Multikicker")) {
ManaCost mkCost = sa.getMultiKickerManaCost();
for (int i = 0; i < timesMultikicked; i++) {
cost.addManaCost(mkCost);

View File

@@ -153,8 +153,7 @@ public class PermanentAi extends SpellAbilityAi {
return false;
}
if (sa.hasParam("Announce") && sa.getParam("Announce").startsWith("Multikicker")) {
// String announce = sa.getParam("Announce");
if (sa.isAnnouncing("Multikicker")) {
ManaCost mkCost = sa.getMultiKickerManaCost();
ManaCost mCost = sa.getPayCosts().getTotalMana();
boolean isZeroCost = mCost.isZero();

View File

@@ -13,23 +13,17 @@ public class BranchEffect extends SpellAbilityEffect {
// TODO Reuse SpellAbilityCondition and areMet() here instead of repeating each
int value = 0;
if (sa.hasParam("BranchCondition")) {
if (sa.getParam("BranchCondition").equals("ChosenCard")) {
value = host.getChosenCards().size();
}
} else {
value = AbilityUtils.calculateAmount(host, sa.getParam("BranchConditionSVar"), sa);
}
String branchSVar = sa.getParam("BranchConditionSVar");
String branchCompare = sa.getParamOrDefault("BranchConditionSVarCompare", "GE1");
String operator = branchCompare.substring(0, 2);
String operand = branchCompare.substring(2);
final int svarValue = AbilityUtils.calculateAmount(host, branchSVar, sa);
final int operandValue = AbilityUtils.calculateAmount(host, operand, sa);
SpellAbility sub = null;
if (Expressions.compare(value, operator, operandValue)) {
if (Expressions.compare(svarValue, operator, operandValue)) {
sub = sa.getAdditionalAbility("TrueSubAbility");
} else {
sub = sa.getAdditionalAbility("FalseSubAbility");

View File

@@ -35,8 +35,11 @@ public class TapOrUntapEffect extends SpellAbilityEffect {
@Override
public void resolve(SpellAbility sa) {
Player activator = sa.getActivatingPlayer();
PlayerController pc = activator.getController();
Player tapper = sa.getActivatingPlayer();
if (sa.hasParam("Tapper")) {
tapper = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Tapper"), sa).getFirst();
}
PlayerController pc = tapper.getController();
CardCollection tapped = new CardCollection();
final Map<Player, CardCollection> untapMap = Maps.newHashMap();
@@ -50,12 +53,8 @@ public class TapOrUntapEffect extends SpellAbilityEffect {
// If the effected card is controlled by the same controller of the SA, default to untap.
boolean tap = pc.chooseBinary(sa, Localizer.getInstance().getMessage("lblTapOrUntapTarget", CardTranslation.getTranslatedName(tgtC.getName())), PlayerController.BinaryChoiceType.TapOrUntap,
!tgtC.getController().equals(activator) );
!tgtC.getController().equals(tapper) );
Player tapper = activator;
if (sa.hasParam("Tapper")) {
tapper = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Tapper"), sa).getFirst();
}
if (tap) {
if (tgtC.tap(true, sa, tapper)) tapped.add(tgtC);
} else if (tgtC.untap(true)) {
@@ -65,12 +64,12 @@ public class TapOrUntapEffect extends SpellAbilityEffect {
if (!untapMap.isEmpty()) {
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
runParams.put(AbilityKey.Map, untapMap);
activator.getGame().getTriggerHandler().runTrigger(TriggerType.UntapAll, runParams, false);
tapper.getGame().getTriggerHandler().runTrigger(TriggerType.UntapAll, runParams, false);
}
if (!tapped.isEmpty()) {
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
runParams.put(AbilityKey.Cards, tapped);
activator.getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
tapper.getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
}
}

View File

@@ -2290,12 +2290,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
? ", or " : n + 2 == costs.length ? " or " : ", ");
}
} else if (keyword.startsWith("Multikicker")) {
if (!keyword.endsWith("Generic")) {
final String[] n = keyword.split(":");
final Cost cost = new Cost(n[1], false);
sbLong.append("Multikicker ").append(cost.toSimpleString());
sbLong.append(" (").append(inst.getReminderText()).append(")").append("\r\n");
}
final String[] n = keyword.split(":");
final Cost cost = new Cost(n[1], false);
sbLong.append("Multikicker ").append(cost.toSimpleString());
sbLong.append(" (").append(inst.getReminderText()).append(")").append("\r\n");
} else if (keyword.startsWith("Kicker")) {
sbLong.append(kickerDesc(keyword, inst.getReminderText())).append("\r\n");
} else if (keyword.startsWith("Trample:")) {
@@ -2583,41 +2581,34 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
final Cost cost = new Cost(n[1], false);
final String costStr = cost.toSimpleString();
final boolean manaOnly = cost.isOnlyManaCost();
if (!keyword.endsWith("Generic")) {
sbx.append("Kicker").append(manaOnly ? " " + costStr : "" + costStr + ".");
if (Lists.newArrayList(n).size() > 2) {
sbx.append(" and/or ");
final Cost cost2 = new Cost(n[2], false);
sbx.append(cost2.toSimpleString());
}
if (!manaOnly) {
if (cost.hasNoManaCost()) {
remText = remText.replaceFirst(" pay an additional", "");
remText = remText.replace(remText.charAt(8), Character.toLowerCase(remText.charAt(8)));
} else {
remText = remText.replaceFirst(" an additional", "");
char c = remText.charAt(remText.indexOf(",") + 2);
remText = remText.replace(c, Character.toLowerCase(c));
remText = remText.replaceFirst(", ", " and ");
}
remText = remText.replaceFirst("as", "in addition to any other costs as");
if (remText.contains(" tap ")) {
if (remText.contains("tap a")) {
String noun = remText.substring(remText.indexOf("untapped") + 9, remText.indexOf(" in "));
remText = remText.replace(remText.substring(12, remText.indexOf(" in ")),
Lang.nounWithNumeralExceptOne(1, noun) + " ");
} else {
remText = remText.replaceFirst(" untapped ", "");
}
}
}
sbx.append(" (").append(remText).append(")\r\n");
} else {
sbx.append("As an additional cost to cast this spell, you may ");
String costS = StringUtils.uncapitalize(costStr);
sbx.append(cost.hasManaCost() ? "pay " + costS : costS);
sbx.append(".").append("\r\n");
sbx.append("Kicker").append(manaOnly ? " " + costStr : "" + costStr + ".");
if (Lists.newArrayList(n).size() > 2) {
sbx.append(" and/or ");
final Cost cost2 = new Cost(n[2], false);
sbx.append(cost2.toSimpleString());
}
if (!manaOnly) {
if (cost.hasNoManaCost()) {
remText = remText.replaceFirst(" pay an additional", "");
remText = remText.replace(remText.charAt(8), Character.toLowerCase(remText.charAt(8)));
} else {
remText = remText.replaceFirst(" an additional", "");
char c = remText.charAt(remText.indexOf(",") + 2);
remText = remText.replace(c, Character.toLowerCase(c));
remText = remText.replaceFirst(", ", " and ");
}
remText = remText.replaceFirst("as", "in addition to any other costs as");
if (remText.contains(" tap ")) {
if (remText.contains("tap a")) {
String noun = remText.substring(remText.indexOf("untapped") + 9, remText.indexOf(" in "));
remText = remText.replace(remText.substring(12, remText.indexOf(" in ")),
Lang.nounWithNumeralExceptOne(1, noun) + " ");
} else {
remText = remText.replaceFirst(" untapped ", "");
}
}
}
sbx.append(" (").append(remText).append(")\r\n");
return sbx.toString();
}
@@ -3028,11 +3019,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
sbBefore.append(sbCost).append(" (").append(inst.getReminderText()).append(")");
sbBefore.append("\r\n");
} else if (keyword.startsWith("Multikicker")) {
if (!keyword.endsWith("Generic")) {
final String[] n = keyword.split(":");
final Cost cost = new Cost(n[1], false);
sbBefore.append("Multikicker ").append(cost.toSimpleString()).append(" (").append(inst.getReminderText()).append(")").append("\r\n");
}
final String[] n = keyword.split(":");
final Cost cost = new Cost(n[1], false);
sbBefore.append("Multikicker ").append(cost.toSimpleString()).append(" (").append(inst.getReminderText()).append(")").append("\r\n");
} else if (keyword.startsWith("Kicker")) {
sbBefore.append(kickerDesc(keyword, inst.getReminderText())).append("\r\n");
} else if (keyword.startsWith("AlternateAdditionalCost")) {
@@ -4622,7 +4611,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
}
private int multiKickerMagnitude = 0;
public final void addMultiKickerMagnitude(final int n) { multiKickerMagnitude += n; }
public final void setKickerMagnitude(final int n) { multiKickerMagnitude = n; }
public final int getKickerMagnitude() {
if (multiKickerMagnitude > 0) {
@@ -4673,7 +4661,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public final boolean isUntapped() {
return !tapped;
}
public final boolean isTapped() {
return tapped;
}

View File

@@ -74,9 +74,6 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
return false;
}
// Save the original cost and the face down info for a later check since the LKI copy will overwrite them
ManaCost origCost = card.getState(card.isFaceDown() ? CardStateName.Original : card.getCurrentStateName()).getManaCost();
Player activator = this.getActivatingPlayer();
if (activator == null) {
activator = card.getController();
@@ -90,6 +87,9 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
return false;
}
// Save the original cost and the face down info for a later check since the LKI copy will overwrite them
ManaCost origCost = card.getState(card.isFaceDown() ? CardStateName.Original : card.getCurrentStateName()).getManaCost();
// do performanceMode only for cases where the activator is different than controller
if (!Spell.performanceMode && !card.getController().equals(activator)) {
// always make a lki copy in this case?
@@ -105,10 +105,8 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
// for uncastables like lotus bloom, check if manaCost is blank (except for morph spells)
// but ignore if it comes from PlayEffect
if (!isCastFaceDown()
&& !isCastFromPlayEffect()
&& isBasicSpell()
&& origCost.isNoCost()) {
if (!isCastFaceDown() && !isCastFromPlayEffect()
&& isBasicSpell() && origCost.isNoCost()) {
return false;
}
@@ -117,7 +115,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
}
return true;
} // canPlay()
}
/** {@inheritDoc} */
@Override

View File

@@ -753,10 +753,8 @@ public final class StaticAbilityContinuous {
Iterables.removeIf(newKeywords, new Predicate<String>() {
@Override
public boolean apply(String input) {
if (input.contains("CardManaCost")) {
if (affectedCard.getManaCost().isNoCost()) {
return true;
}
if (input.contains("CardManaCost") && affectedCard.getManaCost().isNoCost()) {
return true;
}
// replace one Keyword with list of keywords
if (input.startsWith("Protection") && input.contains("CardColors")) {
@@ -897,7 +895,7 @@ public final class StaticAbilityContinuous {
}
}
if (!addedAbilities.isEmpty() || addReplacements != null || addTriggers != null || addStatics != null
if (!addedAbilities.isEmpty() || !addedTrigger.isEmpty() || addReplacements != null || addStatics != null
|| removeAllAbilities) {
affectedCard.addChangedCardTraits(
addedAbilities, null, addedTrigger, addedReplacementEffects, addedStaticAbility, removeAllAbilities, removeNonMana,

View File

@@ -3,7 +3,7 @@ ManaCost:3 B
Types:Sorcery
A:SP$ RevealHand | ValidTgts$ Opponent | RememberRevealed$ True | SubAbility$ DBChoose | SpellDescription$ Target opponent reveals their hand.
SVar:DBChoose:DB$ ChooseCard | ChoiceZone$ Hand | Amount$ 1 | Choices$ Card.nonLand+IsRemembered | ChoiceDesc$ nonland | FromDesc$ it | SubAbility$ DBBranch | ChoiceTitle$ You may choose a nonland card | SpellDescription$ You may choose a nonland card from it.
SVar:DBBranch:DB$ Branch | BranchCondition$ ChosenCard | TrueSubAbility$ DBDiscard | FalseSubAbility$ DBDiscard2 | StackDescription$ If they do, {p:Targeted} discards that card. If they don't, {p:Targeted} discards two cards. | SpellDescription$ If you do, that player discards that card. If you don't, that player discards two cards.
SVar:DBBranch:DB$ Branch | BranchConditionSVar$ Count$ChosenSize | TrueSubAbility$ DBDiscard | FalseSubAbility$ DBDiscard2 | StackDescription$ If they do, {p:Targeted} discards that card. If they don't, {p:Targeted} discards two cards. | SpellDescription$ If you do, that player discards that card. If you don't, that player discards two cards.
SVar:DBDiscard:DB$ Discard | DefinedCards$ ChosenCard | Defined$ Targeted | Mode$ Defined | SubAbility$ DBCleanup
SVar:DBDiscard2:DB$ Discard | Defined$ Targeted | NumCards$ 2 | Mode$ TgtChoose | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True

View File

@@ -3,7 +3,7 @@ ManaCost:2 B
Types:Sorcery
A:SP$ RevealHand | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | RememberRevealed$ True | SubAbility$ DBChoose | SpellDescription$ Target opponent reveals their hand.
SVar:DBChoose:DB$ ChooseCard | ChoiceZone$ Hand | Amount$ 1 | Choices$ Card.nonLand+IsRemembered | ChoiceDesc$ nonland | FromDesc$ it | SubAbility$ DBBranch | ChoiceTitle$ You may choose a nonland card | SpellDescription$ You may choose a nonland card from it.
SVar:DBBranch:DB$ Branch | BranchCondition$ ChosenCard | TrueSubAbility$ DBDiscard | FalseSubAbility$ DBPutCounter | StackDescription$ If they do, {p:Targeted} discards that card. If they don't, they put two +1/+1 counters on a creature or Vehicle they control. | SpellDescription$ If you do, that player discards that card. If you don't, put two +1/+1 counters on a creature or Vehicle you control.
SVar:DBBranch:DB$ Branch | BranchConditionSVar$ Count$ChosenSize | TrueSubAbility$ DBDiscard | FalseSubAbility$ DBPutCounter | StackDescription$ If they do, {p:Targeted} discards that card. If they don't, they put two +1/+1 counters on a creature or Vehicle they control. | SpellDescription$ If you do, that player discards that card. If you don't, put two +1/+1 counters on a creature or Vehicle you control.
SVar:DBDiscard:DB$ Discard | DefinedCards$ ChosenCard | Defined$ Targeted | Mode$ Defined | SubAbility$ DBCleanup
SVar:DBPutCounter:DB$ PutCounter | Choices$ Creature.YouCtrl,Vehicle.YouCtrl | ChoiceTitle$ Choose a creature or Vehicle you control | CounterType$ P1P1 | CounterNum$ 2 | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True

View File

@@ -3,7 +3,7 @@ ManaCost:U B
Types:Instant
A:SP$ Dig | ValidTgts$ Opponent | DigNum$ 2 | ChangeNum$ 1 | DestinationZone$ Exile | DestinationZone2$ Library | ExileFaceDown$ True | ChangeValid$ Card | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Look at the top two cards of target opponent's library. Exile one of them face down and put the other on the bottom of that library. You may look at and play the exiled card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell.
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup | StackDescription$ Exile one of them face down and put the other on the bottom of that library. You may look at and play the exiled card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell.
SVar:STPlay:Mode$ Continuous | MayLookAt$ You | MayPlay$ True | MayPlayIgnoreType$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Secondary$ True | Description$ You may look at and play the exiled card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell.
SVar:STPlay:Mode$ Continuous | MayLookAt$ You | MayPlay$ True | MayPlayIgnoreColor$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Secondary$ True | Description$ You may look at and play the exiled card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
K:Flashback:1 U B
DeckHas:Ability$Graveyard

View File

@@ -385,6 +385,7 @@ Guff
Huatli
Inzerva
Jace
Jared
Jaya
Jeska
Kaito