Treat replaceAbilityText bandaids

This commit is contained in:
tool4EvEr
2023-05-25 22:04:17 +02:00
parent ea4cfaf9b7
commit d4030e0f1d
6 changed files with 23 additions and 24 deletions

View File

@@ -120,7 +120,7 @@ public class PlayAi extends SpellAbilityAi {
if ("ReplaySpell".equals(sa.getParam("AILogic"))) { if ("ReplaySpell".equals(sa.getParam("AILogic"))) {
return ComputerUtil.targetPlayableSpellCard(ai, getPlayableCards(sa, ai), sa, sa.hasParam("WithoutManaCost"), mandatory); return ComputerUtil.targetPlayableSpellCard(ai, getPlayableCards(sa, ai), sa, sa.hasParam("WithoutManaCost"), mandatory);
} }
return checkApiLogic(ai, sa); return checkApiLogic(ai, sa);
} }

View File

@@ -5,6 +5,7 @@ import java.util.Map;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import forge.ai.ComputerUtil; import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilAbility; import forge.ai.ComputerUtilAbility;
@@ -307,11 +308,18 @@ public class UntapAi extends SpellAbilityAi {
return true; return true;
} }
@Override @Override
public Card chooseSingleCard(Player ai, SpellAbility sa, Iterable<Card> list, boolean isOptional, Player targetedPlayer, Map<String, Object> params) { public Card chooseSingleCard(Player ai, SpellAbility sa, Iterable<Card> list, boolean isOptional, Player targetedPlayer, Map<String, Object> params) {
PlayerCollection pl = ai.getYourTeam(); CardCollection pref = CardLists.filterControlledBy(list, ai.getYourTeam());
return ComputerUtilCard.getBestAI(CardLists.filterControlledBy(list, pl)); if (Iterables.isEmpty(pref)) {
if (isOptional) {
return null;
}
} else {
list = pref;
}
return ComputerUtilCard.getBestAI(list);
} }
private static Card detectPriorityUntapTargets(final List<Card> untapList) { private static Card detectPriorityUntapTargets(final List<Card> untapList) {

View File

@@ -55,7 +55,6 @@ public class CharmEffect extends SpellAbilityEffect {
public static String makeFormatedDescription(SpellAbility sa) { public static String makeFormatedDescription(SpellAbility sa) {
return makeFormatedDescription(sa, true); return makeFormatedDescription(sa, true);
} }
public static String makeFormatedDescription(SpellAbility sa, boolean includeChosen) { public static String makeFormatedDescription(SpellAbility sa, boolean includeChosen) {
Card source = sa.getHostCard(); Card source = sa.getHostCard();

View File

@@ -158,7 +158,6 @@ public abstract class Trigger extends TriggerReplacementBase {
public final String replaceAbilityText(final String desc, SpellAbility sa) { public final String replaceAbilityText(final String desc, SpellAbility sa) {
return replaceAbilityText(desc, sa, false); return replaceAbilityText(desc, sa, false);
} }
public final String replaceAbilityText(final String desc, SpellAbility sa, boolean forStack) { public final String replaceAbilityText(final String desc, SpellAbility sa, boolean forStack) {
String result = desc; String result = desc;
@@ -184,29 +183,22 @@ public abstract class Trigger extends TriggerReplacementBase {
} }
} }
if (digMore) { // if ABILITY is used, there is probably Charm somewhere if (digMore) { // if ABILITY is used, there is probably Charm somewhere
while (sa != null) { SpellAbility trigSA = sa;
ApiType api = sa.getApi(); while (trigSA != null) {
ApiType api = trigSA.getApi();
if (ApiType.Charm.equals(api)) { if (ApiType.Charm.equals(api)) {
saDesc = CharmEffect.makeFormatedDescription(sa, !forStack); saDesc = CharmEffect.makeFormatedDescription(trigSA, !forStack);
break; break;
} }
if (ApiType.ImmediateTrigger.equals(api) || ApiType.DelayedTrigger.equals(api)) { if (ApiType.ImmediateTrigger.equals(api) || ApiType.DelayedTrigger.equals(api)) {
SpellAbility trigSA = sa.getAdditionalAbility("Execute"); trigSA = sa.getAdditionalAbility("Execute");
while (trigSA != null) { } else {
if (ApiType.Charm.equals(trigSA.getApi())) { trigSA = sa.getSubAbility();
saDesc = CharmEffect.makeFormatedDescription(trigSA, !forStack);
break;
}
trigSA = trigSA.getSubAbility();
}
break;
} }
sa = sa.getSubAbility();
} }
} }
if (saDesc.equals("")) { // in case we haven't found anything better if (saDesc.equals("")) { // in case we haven't found anything better
if (sa != null) saDesc = sa.toString();
saDesc = sa.toString();
} }
// string might have leading whitespace // string might have leading whitespace
saDesc = saDesc.trim(); saDesc = saDesc.trim();
@@ -223,7 +215,7 @@ public abstract class Trigger extends TriggerReplacementBase {
} }
result = TextUtil.fastReplace(result, "ABILITY", saDesc); result = TextUtil.fastReplace(result, "ABILITY", saDesc);
String currentName = sa == null ? "" : sa.getHostCard().getName(); String currentName = sa.getHostCard().getName();
result = CardTranslation.translateMultipleDescriptionText(result, currentName); result = CardTranslation.translateMultipleDescriptionText(result, currentName);
result = TextUtil.fastReplace(result,"CARDNAME", CardTranslation.getTranslatedName(currentName)); result = TextUtil.fastReplace(result,"CARDNAME", CardTranslation.getTranslatedName(currentName));
result = TextUtil.fastReplace(result,"NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName))); result = TextUtil.fastReplace(result,"NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));

View File

@@ -7,7 +7,7 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S
SVar:TrigDig:DB$ DigUntil | Defined$ Player | Valid$ Card.nonLand | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | SubAbility$ DBPlay SVar:TrigDig:DB$ DigUntil | Defined$ Player | Valid$ Card.nonLand | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | SubAbility$ DBPlay
SVar:DBPlay:DB$ Play | Controller$ You | Defined$ Remembered | WithoutManaCost$ True | ValidSA$ Spell | Optional$ True | Amount$ All | SubAbility$ DBCleanup SVar:DBPlay:DB$ Play | Controller$ You | Defined$ Remembered | WithoutManaCost$ True | ValidSA$ Spell | Optional$ True | Amount$ All | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
A:AB$ SetState | Cost$ 9 GP | Defined$ Self | Mode$ Transform | SorcerySpeed$ True | AILogic$ Always | SpellDescription$ Transform CARDNAME. Activate only as a sorcery. A:AB$ SetState | Cost$ 9 GP | Defined$ Self | Mode$ Transform | SorcerySpeed$ True | AILogic$ Always | SpellDescription$ Transform NICKNAME. Activate only as a sorcery.
AlternateMode:DoubleFaced AlternateMode:DoubleFaced
Oracle:Trample\nWhen Etali, Primal Conqueror enters the battlefield, each player exiles cards from the top of their library until they exile a nonland card. You may cast any number of spells from among the nonland cards exiled this way without paying their mana costs.\n{9}{G/P}: Transform Etali. Activate only as a sorcery. Oracle:Trample\nWhen Etali, Primal Conqueror enters the battlefield, each player exiles cards from the top of their library until they exile a nonland card. You may cast any number of spells from among the nonland cards exiled this way without paying their mana costs.\n{9}{G/P}: Transform Etali. Activate only as a sorcery.

View File

@@ -4,7 +4,7 @@ Types:Legendary Creature Merfolk Rogue
PT:4/4 PT:4/4
K:Flash K:Flash
A:AB$ ChangeZone | Cost$ 2 U B Return<1/Rogue.unblocked+attacking+YouCtrl/unblocked attacking Rogue you control> | ActivationZone$ Hand | Defined$ Self | Origin$ Hand | Destination$ Battlefield | Tapped$ True | Attacking$ True | SpellDescription$ Put CARDNAME from your hand onto the battlefield tapped and attacking. A:AB$ ChangeZone | Cost$ 2 U B Return<1/Rogue.unblocked+attacking+YouCtrl/unblocked attacking Rogue you control> | ActivationZone$ Hand | Defined$ Self | Origin$ Hand | Destination$ Battlefield | Tapped$ True | Attacking$ True | SpellDescription$ Put CARDNAME from your hand onto the battlefield tapped and attacking.
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigGainControl | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may put target permanent card from that player's graveyard onto the battlefield under your control. T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigGainControl | OptionalDecider$ You | TriggerDescription$ Whenever NICKNAME deals combat damage to a player, you may put target permanent card from that player's graveyard onto the battlefield under your control.
SVar:TrigGainControl:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | ValidTgts$ Permanent | TargetsWithDefinedController$ TriggeredTarget | TgtPrompt$ Select target permanent in opponent's graveyard SVar:TrigGainControl:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | ValidTgts$ Permanent | TargetsWithDefinedController$ TriggeredTarget | TgtPrompt$ Select target permanent in opponent's graveyard
DeckHints:Type$Rogue DeckHints:Type$Rogue
Oracle:Flash\n{2}{U}{B}, Return an unblocked attacking Rogue you control to its owner's hand: Put Zareth San, the Trickster from your hand onto the battlefield tapped and attacking.\nWhenever Zareth San deals combat damage to a player, you may put target permanent card from that player's graveyard onto the battlefield under your control. Oracle:Flash\n{2}{U}{B}, Return an unblocked attacking Rogue you control to its owner's hand: Put Zareth San, the Trickster from your hand onto the battlefield tapped and attacking.\nWhenever Zareth San deals combat damage to a player, you may put target permanent card from that player's graveyard onto the battlefield under your control.