mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
[CMR] fixed Rakshasa Debaser - class cast exception in filter on usage;
This commit is contained in:
parent
d39575c24e
commit
c13d07b73d
8 changed files with 62 additions and 88 deletions
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
@ -52,9 +50,14 @@ 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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue