diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index cd890ca1cfb..3011e56ba06 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -1115,7 +1115,9 @@ public class ComputerUtilMana { final String xSvar = card.getSVar("X").startsWith("Count$xPaid") ? "PayX" : "X"; if (!sa.getSVar(xSvar).isEmpty() || card.hasSVar(xSvar)) { if (xSvar.equals("PayX") && card.hasSVar(xSvar)) { - manaToAdd = Integer.parseInt(card.getSVar(xSvar)) * cost.getXcounter(); // X + // X SVar may end up being an empty string when copying a spell with no cost (e.g. Jhoira Avatar) + String xValue = card.getSVar(xSvar); + manaToAdd = xValue.isEmpty() ? 0 : Integer.parseInt(card.getSVar(xSvar)) * cost.getXcounter(); // X } else { manaToAdd = AbilityUtils.calculateAmount(card, xSvar, sa) * cost.getXcounter(); } diff --git a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java index 0ea94e90725..26912848459 100644 --- a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java +++ b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java @@ -25,6 +25,7 @@ import forge.card.ColorSet; import forge.card.MagicColor; import forge.card.mana.ManaCost; import forge.game.Game; +import forge.game.GameType; import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; @@ -43,6 +44,7 @@ import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; import forge.game.zone.ZoneType; import forge.util.Aggregates; +import forge.util.MyRandom; import forge.util.TextUtil; import forge.util.maps.LinkedHashMapToAmount; import forge.util.maps.MapToAmount; @@ -778,6 +780,14 @@ public class SpecialCardAi { if (source.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN1)) { return false; } + + // In MoJhoSto, prefer Jhoira sorcery ability from time to time + if (source.getGame().getRules().hasAppliedVariant(GameType.MoJhoSto) + && CardLists.filter(ai.getLandsInPlay(), CardPredicates.Presets.UNTAPPED).size() >= 3 + && MyRandom.percentTrue(50)) { + return false; + } + // Set PayX here to maximum value. int tokenSize = ComputerUtilMana.determineLeftoverMana(sa, ai); diff --git a/forge-ai/src/main/java/forge/ai/ability/PlayAi.java b/forge-ai/src/main/java/forge/ai/ability/PlayAi.java index 5d9876bd759..90896e6f1e5 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PlayAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PlayAi.java @@ -5,6 +5,7 @@ import forge.ai.*; import forge.card.CardStateName; import forge.card.CardTypeView; import forge.game.Game; +import forge.game.GameType; import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.card.CardCollection; @@ -16,6 +17,7 @@ import forge.game.spellability.Spell; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.game.zone.ZoneType; +import forge.util.MyRandom; import java.util.List; @@ -51,7 +53,15 @@ public class PlayAi extends SpellAbilityAi { return false; } } - + + if (game.getRules().hasAppliedVariant(GameType.MoJhoSto) && source.getName().equals("Jhoira of the Ghitu Avatar")) { + // Some additional logic for MoJhoSto: don't spam activate the Instant copying ability all the time + // Can probably be improved, but as random as MoJhoSto already is, probably not a huge deal for now + if ("Instant".equals(sa.getParam("AnySupportedCard")) && MyRandom.percentTrue(80)) { + return false; + } + } + if ("ReplaySpell".equals(logic)) { return ComputerUtil.targetPlayableSpellCard(ai, cards, sa, sa.hasParam("WithoutManaCost")); }