This commit is contained in:
tool4ever
2023-06-09 13:47:59 +02:00
committed by GitHub
parent 85eb8fd5b4
commit ba1d3fbe43
17 changed files with 26 additions and 71 deletions

View File

@@ -1293,7 +1293,6 @@ public class ComputerUtil {
&& !sa.hasParam("ActivationPhases");
}
//returns true if it's better to wait until blockers are declared).
public static boolean castSpellInMain1(final Player ai, final SpellAbility sa) {
final Card source = sa.getHostCard();
final SpellAbility sub = sa.getSubAbility();
@@ -1315,6 +1314,7 @@ public class ComputerUtil {
return true;
}
}
final CardCollectionView buffed = ai.getCardsIn(ZoneType.Battlefield);
boolean checkThreshold = sa.isSpell() && !ai.hasThreshold() && !source.isInZone(ZoneType.Graveyard);
for (Card buffedCard : buffed) {
@@ -2716,12 +2716,11 @@ public class ComputerUtil {
return ComputerUtilCard.getBestCreatureAI(killables);
}
public static int predictDamageFromSpell(final SpellAbility sa, final Player targetPlayer) {
public static int predictDamageFromSpell(SpellAbility ab, final Player targetPlayer) {
int damage = -1; // returns -1 if the spell does not deal damage
final Card card = sa.getHostCard();
final Card card = ab.getHostCard();
SpellAbility ab = sa;
while (ab != null) {
while (ab != null && targetPlayer.canLoseLife()) {
if (ab.getApi() == ApiType.DealDamage) {
if (damage == -1) { damage = 0; } // found a damage-dealing spell
if (!ab.hasParam("NumDmg")) {

View File

@@ -823,7 +823,7 @@ public class ComputerUtilCard {
}
// Changeling are all creature types, they are not interesting for
// counting creature types
if (c.hasStartOfKeyword(Keyword.CHANGELING.toString())) {
if (c.getType().hasAllCreatureTypes()) {
continue;
}
// ignore cards that does enter the battlefield as clones

View File

@@ -1197,7 +1197,7 @@ public class AbilityUtils {
}
else if (defined.startsWith("Non")) {
players.addAll(game.getPlayersInTurnOrder());
players.removeAll((FCollectionView<Player>)getDefinedPlayers(card, defined.substring(3), sa));
players.removeAll(getDefinedPlayers(card, defined.substring(3), sa));
}
else if (defined.equals("EnchantedPlayer")) {
final Object o = sa.getHostCard().getEntityAttachedTo();
@@ -2699,8 +2699,7 @@ public class AbilityUtils {
}
if (sq[0].startsWith("OppTypesInGrave")) {
final PlayerCollection opponents = player.getOpponents();
CardCollection oppCards = new CardCollection();
oppCards.addAll(opponents.getCardsIn(ZoneType.Graveyard));
CardCollection oppCards = opponents.getCardsIn(ZoneType.Graveyard);
return doXMath(getCardTypesFromList(oppCards), expr, c, ctb);
}
@@ -3053,7 +3052,7 @@ public class AbilityUtils {
newWord = "<strike>" + originalWord + "</strike> " + newWord;
}
// use word boundaries and keep negations
return text.replaceAll((isDescriptive ? "(?<!>)" : "") + "\\b(non)?" + originalWord, "$1" + newWord);
return text.replaceAll((isDescriptive ? "(?<!>)" : "") + "(?<!named.*)\\b(non)?" + originalWord, "$1" + newWord);
}
public static final String getSVar(final CardTraitBase ability, final String sVarName) {
@@ -3783,34 +3782,6 @@ public class AbilityUtils {
}
}
// Count$InEnchantedHand (targeted player's cards in hand)
if (sq[0].contains("InEnchantedHand")) {
GameEntity o = c.getEntityAttachedTo();
Player controller = null;
if (o instanceof Card) {
controller = ((Card) o).getController();
}
else {
controller = (Player) o;
}
if (controller != null) {
someCards.addAll(controller.getCardsIn(ZoneType.Hand));
}
}
if (sq[0].contains("InEnchantedYard")) {
GameEntity o = c.getEntityAttachedTo();
Player controller = null;
if (o instanceof Card) {
controller = ((Card) o).getController();
}
else {
controller = (Player) o;
}
if (controller != null) {
someCards.addAll(controller.getCardsIn(ZoneType.Graveyard));
}
}
// filter lists based on the specified quality
// "Clerics you control" - Count$TypeYouCtrl.Cleric

View File

@@ -351,7 +351,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
// Enumeration for CMC request types
public enum SplitCMCMode {
CurrentSideCMC,
CombinedCMC,
LeftSplitCMC,
RightSplitCMC
}
@@ -2419,7 +2418,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return CardTranslation.translateMultipleDescriptionText(sb.toString(), getName());
}
private String kickerDesc (String keyword, String remText) {
private String kickerDesc(String keyword, String remText) {
final StringBuilder sbx = new StringBuilder();
final String[] n = keyword.split(":");
final Cost cost = new Cost(n[1], false);
@@ -2467,7 +2466,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public String getAbilityText() {
return getAbilityText(currentState);
}
public String getAbilityText(final CardState state) {
final String linebreak = "\r\n\r\n";
boolean useGrayTag = true;
@@ -2574,7 +2572,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
boolean hasMeldEffect = hasSVar("Meld")
|| Iterables.any(state.getNonManaAbilities(), SpellAbilityPredicates.isApi(ApiType.Meld));
String meld = this.getRules().getMeldWith();
if (meld != "" && (!hasMeldEffect)) {
if (meld != "" && !hasMeldEffect) {
sb.append("\r\n");
sb.append("(Melds with ").append(meld).append(".)");
sb.append("\r\n");
@@ -2694,8 +2692,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
final Card host = stAb.getHostCard();
String currentName = host.getName();
String desc1 = TextUtil.fastReplace(stAb.toString(), "CARDNAME", currentName);
String desc = TextUtil.fastReplace(desc1, "NICKNAME", currentName.split(" ")[0].replace(",", ""));
String desc = TextUtil.fastReplace(stAb.toString(), "CARDNAME", currentName);
desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(currentName));
if (host.getEffectSource() != null) {
desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", host.getEffectSource().getName());
}
@@ -5916,7 +5914,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public final SpellAbility getTokenSpawningAbility() {
return tokenSpawningAbility;
}
public void setTokenSpawningAbility(SpellAbility sa) {
tokenSpawningAbility = sa;
}
@@ -6606,7 +6603,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
if (isSplitCard()) {
switch(mode) {
case CurrentSideCMC:
// TODO: test if this returns combined CMC for the full face (then get rid of CombinedCMC mode?)
requestedCMC = getManaCost().getCMC() + xPaid;
break;
case LeftSplitCMC:
@@ -6615,11 +6611,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
case RightSplitCMC:
requestedCMC = getState(CardStateName.RightSplit).getManaCost().getCMC() + xPaid;
break;
case CombinedCMC:
requestedCMC += getState(CardStateName.LeftSplit).getManaCost().getCMC();
requestedCMC += getState(CardStateName.RightSplit).getManaCost().getCMC();
requestedCMC += xPaid;
break;
default:
System.out.println(TextUtil.concatWithSpace("Illegal Split Card CMC mode", mode.toString(),"passed to getCMC!"));
break;

View File

@@ -781,6 +781,7 @@ public class CardFactory {
if (sa.hasParam("KeepName")) {
state.setName(originalState.getName());
} else if (newName != null) {
// convert NICKNAME descriptions?
state.setName(newName);
}

View File

@@ -575,11 +575,8 @@ public class TriggerHandler {
regtrig.triggerRun();
if (regtrig.hasParam("OneOff")) {
if (regtrig.getHostCard().isImmutable()) {
Player p = regtrig.getHostCard().getController();
p.getZone(ZoneType.Command).remove(regtrig.getHostCard());
}
if (regtrig.hasParam("OneOff") && host.isImmutable()) {
host.getController().getZone(ZoneType.Command).remove(host);
}
}

View File

@@ -1785,8 +1785,6 @@ public class GameSimulationTest extends SimulationTest {
AssertJUnit.assertEquals(clonedOutLaw.getName(), hillGiantName);
AssertJUnit.assertTrue(clonedOutLaw.isTransformable());
score = sim.simulateSpellAbility(moonmistSA).value;
AssertJUnit.assertTrue(score > 0);

View File

@@ -3,7 +3,7 @@ ManaCost:4 R
Types:Legendary Creature Elf Shaman
PT:2/5
K:Choose a Background
S:Mode$ Continuous | Affected$ Creature.powerLTY+OppCtrl | Goad$ True | Description$ Creatures your opponents control with power less than CARDNAME power are goaded. (They attack each combat if able and attack a player other than you if able.)
S:Mode$ Continuous | Affected$ Creature.powerLTY+OppCtrl | Goad$ True | Description$ Creatures your opponents control with power less than NICKNAME's power are goaded. (They attack each combat if able and attack a player other than you if able.)
SVar:Y:Count$CardPower
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.attacking+IsGoaded,Creature.blocking+IsGoaded | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever a goaded attacking or blocking creature dies, you create a Treasure token. (It's an artifact with "{T}, Sacrifice this artifact: Add one mana of any color.")
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_treasure_sac | TokenOwner$ You

View File

@@ -4,5 +4,5 @@ Types:Enchantment Aura
K:Enchant creature
A:SP$ Attach | Cost$ B | ValidTgts$ Creature | AILogic$ Curse
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ -X | AddToughness$ -X | Description$ Enchanted creature gets -X/-X, where X is the number of creature cards in its controller's graveyard.
SVar:X:Count$TypeInEnchantedYard.Creature
SVar:X:Count$ValidGraveyard Creature.OwnedBy EnchantedController
Oracle:Enchant creature\nEnchanted creature gets -X/-X, where X is the number of creature cards in its controller's graveyard.

View File

@@ -2,13 +2,12 @@ Name:Gideon, the Oathsworn
ManaCost:4 W W
Types:Legendary Planeswalker Gideon
Loyalty:4
T:Mode$ AttackersDeclared | Execute$ TrigCounter | CheckSVar$ NonGideonAttackers | SVarCompare$ GE2 | NoResolvingCheck$ True | TriggerZones$ Battlefield | AttackingPlayer$ You | TriggerDescription$ Whenever you attack with two or more non-Gideon creatures, put a +1/+1 counter on each of those creatures.
T:Mode$ AttackersDeclared | Execute$ TrigCounter | IsPresent$ Creature.nonGideon+YouCtrl+attacking | PresentCompare$ GE2 | NoResolvingCheck$ True | TriggerZones$ Battlefield | AttackingPlayer$ You | TriggerDescription$ Whenever you attack with two or more non-Gideon creatures, put a +1/+1 counter on each of those creatures.
SVar:TrigCounter:DB$ PutCounterAll | ValidCards$ Creature.nonGideon+YouCtrl+attacking | CounterType$ P1P1 | CounterNum$ 1
A:AB$ Animate | Cost$ AddCounter<2/LOYALTY> | Defined$ Self | Power$ 5 | Toughness$ 5 | Types$ Creature,Soldier | SubAbility$ GideonPrevent | Planeswalker$ True | SpellDescription$ Until end of turn, CARDNAME becomes a 5/5 white Soldier creature that's still a planeswalker. Prevent all damage that would be dealt to him this turn.
SVar:GideonPrevent:DB$ Effect | ReplacementEffects$ RPrevent | Duration$ UntilHostLeavesPlayOrEOT
SVar:RPrevent:Event$ DamageDone | Prevent$ True | ActiveZones$ Command | ValidTarget$ Card.EffectSource | Description$ Prevent all damage that would be dealt to EFFECTSOURCE.
A:AB$ ChangeZone | Cost$ SubCounter<9/LOYALTY> | Planeswalker$ True | Ultimate$ True | Defined$ Self | Origin$ Battlefield | Destination$ Exile | SubAbility$ ExileOppCreatures | SpellDescription$ Exile CARDNAME and each creature your opponents control.
SVar:ExileOppCreatures:DB$ ChangeZoneAll | Origin$ Battlefield | Destination$ Exile | ChangeType$ Creature.OppCtrl
SVar:NonGideonAttackers:Count$Valid Creature.nonGideon+YouCtrl+attacking
DeckHas:Ability$Counters
Oracle:Whenever you attack with two or more non-Gideon creatures, put a +1/+1 counter on each of those creatures.\n[+2]: Until end of turn, Gideon, the Oathsworn becomes a 5/5 white Soldier creature that's still a planeswalker. Prevent all damage that would be dealt to him this turn. (He can't attack if he was cast this turn.)\n[-9]: Exile Gideon, the Oathsworn and each creature your opponents control.

View File

@@ -4,7 +4,7 @@ Types:Creature Zombie Wizard
PT:4/4
A:AB$ Effect | Name$ Havengul Lich Delayed Trigger | Cost$ 1 | ValidTgts$ Creature | TgtZone$ Graveyard | TgtPrompt$ Select target creature card | StaticAbilities$ STPlay | Triggers$ DTCast | RememberObjects$ Targeted | ExileOnMoved$ Graveyard | SpellDescription$ You may cast target creature card in a graveyard this turn. When you cast it this turn, CARDNAME gains all activated abilities of that card until end of turn.
SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Graveyard | Description$ Until end of turn, you may cast a creature card in a graveyard.
SVar:DTCast:Mode$ SpellCast | ValidCard$ Card.IsRemembered | Execute$ StealAbs | TriggerDescription$ When you cast that card this turn, Havengul Lich gains all activated abilities of that card until end of turn.
SVar:DTCast:Mode$ SpellCast | ValidCard$ Card.IsRemembered+nonLand | Execute$ StealAbs | TriggerDescription$ When you cast that card this turn, Havengul Lich gains all activated abilities of that card until end of turn.
SVar:StealAbs:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ STSteal | Duration$ UntilHostLeavesPlayOrEOT
SVar:STSteal:Mode$ Continuous | Affected$ Card.EffectSource | EffectZone$ Command | GainsAbilitiesOfDefined$ RememberedLKI | Description$ Havengul Lich gains all activated abilities of that card until end of turn.
AI:RemoveDeck:All

View File

@@ -4,7 +4,7 @@ Types:Creature Ogre Warrior
PT:3/2
K:Haste
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ Whenever CARDNAME attacks, look at the top six cards of your library. You may reveal a Dragon card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
SVar:TrigDig:DB$ Dig | DigNum$ 6 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Card.Dragon | RestRandomOrder$ True
SVar:TrigDig:DB$ Dig | DigNum$ 6 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Card.Dragon | RestRandomOrder$ True | ForceRevealToController$ True
DeckNeeds:Type$Dragon
SVar:HasAttackEffect:TRUE
Oracle:Whenever Kolaghan Warmonger attacks, look at the top six cards of your library. You may reveal a Dragon card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.

View File

@@ -4,7 +4,7 @@ Types:Enchantment Aura
K:Enchant creature
A:SP$ Attach | Cost$ 3 W U | ValidTgts$ Creature | AILogic$ Pump
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ X | AddToughness$ X | Description$ Enchanted creature gets +1/+1 for each card in its controller's hand.
SVar:X:Count$InEnchantedHand
SVar:X:Count$ValidHand Card.OwnedBy EnchantedController
T:Mode$ Phase | Phase$ Draw | ValidPlayer$ Player.EnchantedController | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ At the beginning of the draw step of enchanted creature's controller, that player draws an additional card.
SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ TriggeredPlayer
Oracle:Enchant creature\nEnchanted creature gets +1/+1 for each card in its controller's hand.\nAt the beginning of the draw step of enchanted creature's controller, that player draws an additional card.

View File

@@ -3,7 +3,7 @@ ManaCost:3 B B
Types:Creature Vampire
PT:3/3
K:Flying
T:Mode$ ChangesZoneAll | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.Other | TriggerZones$ Battlefield | ActivationLimit$ 1 | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more other creatures die, put a +1/+1 counter on CARDNAME. This ability triggers only once each turn.
T:Mode$ ChangesZoneAll | Origin$ Battlefield | Destination$ Graveyard | ValidCards$ Creature.Other | TriggerZones$ Battlefield | ActivationLimit$ 1 | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more other creatures die, put a +1/+1 counter on CARDNAME. This ability triggers only once each turn.
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
DeckHas:Ability$Counters
Oracle:Flying\nWhenever one or more other creatures die, put a +1/+1 counter on Sengir Connoisseur. This ability triggers only once each turn.

View File

@@ -3,5 +3,5 @@ ManaCost:no cost
Types:Creature Cleric
Colors:white,black
PT:1/1
A:AB$ ChangeZone | Cost$ 3 W B B T Sac<1/CARDNAME> | ChangeType$ Card.namedDeathpact Angel+YouOwn | ChangeNum$ 1 | Origin$ Graveyard | Destination$ Battlefield | Hidden$ True | SpellDescription$ Return a card named Deathpact Angel from your graveyard to the battlefield.
A:AB$ ChangeZone | Cost$ 3 W B B T Sac<1/CARDNAME> | ChangeType$ Card.namedDeathpact Angel+YouOwn | Mandatory$ True | ChangeNum$ 1 | Origin$ Graveyard | Destination$ Battlefield | Hidden$ True | SpellDescription$ Return a card named Deathpact Angel from your graveyard to the battlefield.
Oracle:{3}{W}{B}{B}, {T}, Sacrifice this creature: Return a card named Deathpact Angel from your graveyard to the battlefield.

View File

@@ -90,7 +90,7 @@ public class BoosterDraftAI {
out[i] = new BoosterDeckBuilder(this.decks.get(i), this.playerColors.get(i)).buildDeck();
}
return out;
} // getDecks()
}
public BoosterDraftAI() {
// Initialize deck array and playerColors list
@@ -98,7 +98,7 @@ public class BoosterDraftAI {
this.decks.add(new ArrayList<>());
this.playerColors.add(new DeckColors());
}
} // BoosterDraftAI()
}
public IBoosterDraft getBd() {
return this.bd;
@@ -107,4 +107,4 @@ public class BoosterDraftAI {
this.bd = bd0;
}
} // BoosterDraftAI()
}

View File

@@ -15,7 +15,6 @@ public class LimitedPlayerAI extends LimitedPlayer {
public LimitedPlayerAI(int seatingOrder) {
super(seatingOrder);
deckCols = new DeckColors();
}
@Override