diff --git a/.gitattributes b/.gitattributes index 239ad66645e..0663a45dfc7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13534,6 +13534,7 @@ forge-gui/res/cardsfolder/s/simoon.txt svneol=native#text/plain forge-gui/res/cardsfolder/s/simplify.txt svneol=native#text/plain forge-gui/res/cardsfolder/s/simulacrum.txt -text forge-gui/res/cardsfolder/s/sin_collector.txt -text +forge-gui/res/cardsfolder/s/sin_prodder.txt -text forge-gui/res/cardsfolder/s/sindbad.txt -text forge-gui/res/cardsfolder/s/sinew_sliver.txt svneol=native#text/plain forge-gui/res/cardsfolder/s/singe.txt svneol=native#text/plain diff --git a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java index cbd6734705a..aa20dd933c8 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java @@ -1,7 +1,11 @@ package forge.ai.ability; +import forge.ai.ComputerUtilCombat; import forge.ai.ComputerUtilCost; import forge.ai.SpellAbilityAi; +import forge.game.card.Card; +import forge.game.combat.Combat; +import forge.game.combat.CombatUtil; import forge.game.cost.Cost; import forge.game.player.Player; import forge.game.spellability.SpellAbility; @@ -38,6 +42,7 @@ public class ChooseGenericEffectAi extends SpellAbilityAi { @Override public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells) { + Card host = sa.getHostCard(); final String logic = sa.getParam("AILogic"); if ("Random".equals(logic)) { return Aggregates.random(spells); @@ -68,6 +73,55 @@ public class ChooseGenericEffectAi extends SpellAbilityAi { return sp; } } + } else if ("Fatespinner".equals(logic)) { + SpellAbility skipDraw = null, skipMain = null, skipCombat = null; + for (final SpellAbility sp : spells) { + if (sp.getDescription().equals("FatespinnerSkipDraw")) { + skipDraw = sp; + } else if (sp.getDescription().equals("FatespinnerSkipDraw")) { + skipMain = sp; + } else { + skipCombat = sp; + } + } + // FatespinnerSkipDraw,FatespinnerSkipMain,FatespinnerSkipCombat + if (player.hasKeyword("Skip your draw step.")) { + return skipDraw; + } + if (player.hasKeyword("Skip your next combat phase.")) { + return skipCombat; + } + + // TODO If combat is poor, Skip Combat + // Todo if hand is empty or mostly empty, skip main phase + // Todo if hand has gas, skip draw + return Aggregates.random(spells); + + } else if ("SinProdder".equals(logic)) { + SpellAbility allow = null, deny = null; + for (final SpellAbility sp : spells) { + if (sp.getDescription().equals("Allow")) { + allow = sp; + } else { + deny = sp; + } + } + + Card imprinted = host.getImprintedCards().getFirst(); + int dmg = imprinted.getCMC(); + if (dmg == 0) { + // If CMC = 0, mill it! + return deny; + } else if (dmg + 3 > player.getLife()) { + // if low on life, do nothing. + return allow; + } else if (player.getLife() - dmg > 15) { + // TODO Check "danger" level of card + // If lots of life, and card might be dangerous? Mill it! + return deny; + } + // if unsure, random? + return Aggregates.random(spells); } return spells.get(0); // return first choice if no logic found } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index a3b9d1f77e4..247442972ee 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -782,6 +782,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect { final String totalcmc = sa.getParam("WithTotalCMC"); int totcmc = AbilityUtils.calculateAmount(source, totalcmc, sa); + fetchList.sort(); + CardCollection chosenCards = new CardCollection(); for (int i = 0; i < changeNum && destination != null; i++) { if (sa.hasParam("DifferentNames")) { diff --git a/forge-gui/res/cardsfolder/s/sin_prodder.txt b/forge-gui/res/cardsfolder/s/sin_prodder.txt new file mode 100644 index 00000000000..c9abc71b005 --- /dev/null +++ b/forge-gui/res/cardsfolder/s/sin_prodder.txt @@ -0,0 +1,17 @@ +Name:Sin Prodder +ManaCost:2 R +Types:Creature Devil +PT:3/2 +K:Menace +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPeek | TriggerDescription$ At the beginning of your upkeep, reveal the top card of your library. Any opponent may have you put that card into your graveyard. If a player does, Sin Prodder deals damage to that player equal to that card's converted mana cost. Otherwise, put that card into your hand. +SVar:TrigPeek:DB$ PeekAndReveal | PeekAmount$ 1 | RevealValid$ Card | ImprintRevealed$ True | SubAbility$ DBRepeat +SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ Opponent | RepeatSubAbility$ DBProd | SubAbility$ DBPutIntoHand +SVar:DBProd:DB$ GenericChoice | Defined$ Remembered | Choices$ DBMillAndDamage,DoNothing | ConditionDefined$ Imprinted | ConditionPresent$ Card | ConditionCompare$ EQ1 | AILogic$ SinProdder +SVar:DoNothing:DB$ Cleanup | SpellDescription$ Allow +SVar:DBMillAndDamage:DB$ Mill | Defined$ You | NumCards$ 1 | SubAbility$ DBDamage | SpellDescription$ Deny +SVar:DBDamage:DB$ DealDamage | Defined$ Remembered | NumDmg$ X | References$ X | SubAbility$ DBCleanup +SVar:X:Imprinted$CardManaCost +SVar:DBPutIntoHand:DB$ Dig | DigNum$ 1 | ChangeNum$ All | ChangeValid$ Card | DestinationZone$ Hand | SubAbility$ DBCleanup | ConditionDefined$ Imprinted | ConditionPresent$ Card | ConditionCompare$ EQ1 +SVar:DBCleanup:DB$Cleanup | ClearRemembered$ True | ClearImprinted$ True +SVar:Picture:http://www.wizards.com/global/images/magic/general/sin_prodder.jpg +Oracle:Menace\nAt the beginning of your upkeep, reveal the top card of your library. Any opponent may have you put that card into your graveyard. If a player does, Sin Prodder deals damage to that player equal to that card's converted mana cost. Otherwise, put that card into your hand. \ No newline at end of file