[CMR] fixed Rakshasa Debaser - class cast exception in filter on usage;

This commit is contained in:
Oleg Agafonov 2020-12-18 15:54:59 +04:00
parent d39575c24e
commit c13d07b73d
8 changed files with 62 additions and 88 deletions

View file

@ -111,73 +111,6 @@ public class ComputerPlayerMCTS extends ComputerPlayer implements Player {
calculateActions(game, nextAction); calculateActions(game, nextAction);
} }
// @Override
// public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
//
// @Override
// public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map<String, Serializable> options) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
//
// @Override
// public boolean choose(Outcome outcome, Cards cards, TargetCard target, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
//
// @Override
// public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
//
// @Override
// public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
//
// @Override
// public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
//
// @Override
// public boolean chooseMulligan(Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
//
// @Override
// public boolean chooseUse(Outcome outcome, String message, Game game) {
// getNextAction(game, NextAction.CHOOSE_USE);
// return root.get
// }
//
// @Override
// public boolean choose(Outcome outcome, Choice choice, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
// @Override
// public boolean playMana(ManaCost unpaid, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
// @Override
// public int chooseEffect(List<ReplacementEffect> rEffects, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
//
// @Override
// public TriggeredAbility chooseTriggeredAbility(TriggeredAbilities abilities, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
//
// @Override
// public Mode chooseMode(Modes modes, Ability source, Game game) {
// throw new UnsupportedOperationException("Not supported yet.");
// }
@Override @Override
public void selectAttackers(Game game, UUID attackingPlayerId) { public void selectAttackers(Game game, UUID attackingPlayerId) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.copy; package org.mage.test.cards.copy;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
@ -7,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class CopyEnchantmentTest extends CardTestPlayerBase { public class CopyEnchantmentTest extends CardTestPlayerBase {
@ -32,9 +30,9 @@ public class CopyEnchantmentTest extends CardTestPlayerBase {
assertLife(playerA, 20); assertLife(playerA, 20);
assertLife(playerB, 20); assertLife(playerB, 20);
assertGraveyardCount(playerA, "Copy Enchantment",0); assertGraveyardCount(playerA, "Copy Enchantment", 0);
assertPermanentCount(playerA, "Crucible of Fire", 1); assertPermanentCount(playerA, "Crucible of Fire", 1);
assertPowerToughness(playerA, "Furnace Whelp", 5,5); assertPowerToughness(playerA, "Furnace Whelp", 5, 5);
} }
@Test @Test
@ -52,17 +50,22 @@ public class CopyEnchantmentTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Inferno Fist", "Geist of the Moors"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Inferno Fist", "Geist of the Moors");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Copy Enchantment"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Copy Enchantment");
setChoice(playerB, "Yes"); // copy
setChoice(playerB, "Inferno Fist"); // copied
setChoice(playerB, "Silvercoat Lion"); // target for copy
setStrictChooseMode(true);
setStopAt(2, PhaseStep.BEGIN_COMBAT); setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute(); execute();
assertAllCommandsUsed();
assertLife(playerA, 20); assertLife(playerA, 20);
assertLife(playerB, 20); assertLife(playerB, 20);
assertHandCount(playerA, "Inferno Fist", 0); assertHandCount(playerA, "Inferno Fist", 0);
assertGraveyardCount(playerB, "Copy Enchantment",0); assertGraveyardCount(playerB, "Copy Enchantment", 0);
assertPermanentCount(playerA, "Inferno Fist", 1); assertPermanentCount(playerA, "Inferno Fist", 1);
assertPermanentCount(playerB, "Inferno Fist", 1); assertPermanentCount(playerB, "Inferno Fist", 1);
assertPowerToughness(playerA, "Geist of the Moors", 5,1); assertPowerToughness(playerA, "Geist of the Moors", 5, 1);
assertPowerToughness(playerB, "Silvercoat Lion", 4,2); assertPowerToughness(playerB, "Silvercoat Lion", 4, 2);
} }
} }

View file

@ -0,0 +1,31 @@
package org.mage.test.cards.single.cmr;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author JayDi85
*/
public class RakshasaDebaserTest extends CardTestPlayerBase {
@Test
public void test_Playable() {
// Whenever Rakshasa Debaser attacks, put target creature card from defending player's graveyard onto the battlefield under your control.
addCard(Zone.BATTLEFIELD, playerA, "Rakshasa Debaser", 1);
addCard(Zone.GRAVEYARD, playerB, "Balduvian Bears", 1);
// attack and trigger
attack(1, playerA, "Rakshasa Debaser", playerB);
addTarget(playerA, "Balduvian Bears");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Balduvian Bears", 1); // from trigger
}
}

View file

@ -195,7 +195,7 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
* Return real affected max modes in current game. Use null params for default max modes value. * Return real affected max modes in current game. Use null params for default max modes value.
* *
* @param game * @param game
* @param source * @param source can be null for rules generation
* @return * @return
*/ */
public int getMaxModes(Game game, Ability source) { public int getMaxModes(Game game, Ability source) {

View file

@ -1,19 +1,19 @@
package mage.filter.predicate.permanent; package mage.filter.predicate.permanent;
import mage.cards.Card; import mage.cards.Card;
import mage.filter.predicate.ObjectSourcePlayer; import mage.filter.predicate.ObjectPlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.filter.predicate.ObjectPlayerPredicate;
import mage.game.Game; import mage.game.Game;
/** /**
* @author TheElk801 * @author TheElk801
*/ */
public enum DefendingPlayerOwnsCardPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<Card>> { public enum DefendingPlayerOwnsCardPredicate implements ObjectPlayerPredicate<ObjectPlayer<Card>> {
instance; instance;
@Override @Override
public boolean apply(ObjectSourcePlayer<Card> input, Game game) { public boolean apply(ObjectPlayer<Card> input, Game game) {
return input.getObject().isOwnedBy(game.getCombat().getDefendingPlayerId(input.getSourceId(), game)); return game.getCombat().getPlayerDefenders(game, false).contains(input.getObject().getOwnerId());
} }
@Override @Override

View file

@ -50,6 +50,12 @@ public interface Target extends Serializable {
boolean canTarget(UUID id, Game game); boolean canTarget(UUID id, Game game);
/**
* @param id
* @param source WARNING, it can be null for AI or other calls from events (TODO: introduce normal source in AI ComputerPlayer)
* @param game
* @return
*/
boolean canTarget(UUID id, Ability source, Game game); boolean canTarget(UUID id, Ability source, Game game);
boolean stillLegalTarget(UUID id, Ability source, Game game); boolean stillLegalTarget(UUID id, Ability source, Game game);

View file

@ -41,6 +41,7 @@ public class TargetActivatedAbility extends TargetObject {
@Override @Override
public boolean canTarget(UUID id, Ability source, Game game) { public boolean canTarget(UUID id, Ability source, Game game) {
// 114.4. A spell or ability on the stack is an illegal target for itself.
if (source != null && source.getSourceId().equals(id)) { if (source != null && source.getSourceId().equals(id)) {
return false; return false;
} }
@ -80,7 +81,7 @@ public class TargetActivatedAbility extends TargetObject {
for (StackObject stackObject : game.getStack()) { for (StackObject stackObject : game.getStack()) {
if (stackObject.getStackAbility().getAbilityType() == AbilityType.ACTIVATED if (stackObject.getStackAbility().getAbilityType() == AbilityType.ACTIVATED
&& game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getStackAbility().getControllerId()) && game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getStackAbility().getControllerId())
&& filter.match(((StackAbility) stackObject), game)) { && filter.match(stackObject, game)) {
possibleTargets.add(stackObject.getStackAbility().getId()); possibleTargets.add(stackObject.getStackAbility().getId());
} }
} }

View file

@ -1,9 +1,5 @@
package mage.target.common; package mage.target.common;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbility;
import mage.constants.Zone; import mage.constants.Zone;
@ -13,8 +9,11 @@ import mage.game.Game;
import mage.game.stack.StackObject; import mage.game.stack.StackObject;
import mage.target.TargetObject; import mage.target.TargetObject;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/** /**
*
* @author Styxo * @author Styxo
*/ */
public class TargetTriggeredAbility extends TargetObject { public class TargetTriggeredAbility extends TargetObject {
@ -32,6 +31,7 @@ public class TargetTriggeredAbility extends TargetObject {
@Override @Override
public boolean canTarget(UUID id, Ability source, Game game) { public boolean canTarget(UUID id, Ability source, Game game) {
// 114.4. A spell or ability on the stack is an illegal target for itself.
if (source != null && source.getSourceId().equals(id)) { if (source != null && source.getSourceId().equals(id)) {
return false; return false;
} }