forked from External/mage
215 lines
7.8 KiB
Java
215 lines
7.8 KiB
Java
|
|
package mage.cards.d;
|
|
|
|
import mage.MageObject;
|
|
import mage.abilities.Ability;
|
|
import mage.abilities.effects.PreventionEffectImpl;
|
|
import mage.cards.Card;
|
|
import mage.cards.CardImpl;
|
|
import mage.cards.CardSetInfo;
|
|
import mage.constants.CardType;
|
|
import mage.constants.Duration;
|
|
import mage.constants.Outcome;
|
|
import mage.filter.FilterSource;
|
|
import mage.game.Game;
|
|
import mage.game.events.DamageEvent;
|
|
import mage.game.events.GameEvent;
|
|
import mage.game.permanent.Permanent;
|
|
import mage.game.stack.StackObject;
|
|
import mage.players.Player;
|
|
import mage.target.TargetSource;
|
|
import mage.util.CardUtil;
|
|
|
|
import java.util.HashSet;
|
|
import java.util.Objects;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* @author L_J
|
|
*/
|
|
public final class DesperateGambit extends CardImpl {
|
|
|
|
public DesperateGambit(UUID ownerId, CardSetInfo setInfo) {
|
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
|
|
|
|
// Choose a source you control and flip a coin. If you win the flip, the next time that source would deal damage this turn, it deals double that damage instead. If you lose the flip, the next time it would deal damage this turn, prevent that damage.
|
|
this.getSpellAbility().addEffect(new DesperateGambitEffect());
|
|
}
|
|
|
|
private DesperateGambit(final DesperateGambit card) {
|
|
super(card);
|
|
}
|
|
|
|
@Override
|
|
public DesperateGambit copy() {
|
|
return new DesperateGambit(this);
|
|
}
|
|
}
|
|
|
|
class DesperateGambitEffect extends PreventionEffectImpl {
|
|
|
|
private final TargetSource target;
|
|
private boolean wonFlip;
|
|
|
|
public DesperateGambitEffect() {
|
|
super(Duration.EndOfTurn, Integer.MAX_VALUE, false);
|
|
staticText = "Choose a source you control and flip a coin. If you win the flip, the next time that source would deal damage this turn, it deals double that damage instead. If you lose the flip, the next time it would deal damage this turn, prevent that damage";
|
|
this.target = new TargetControlledSource();
|
|
}
|
|
|
|
private DesperateGambitEffect(final DesperateGambitEffect effect) {
|
|
super(effect);
|
|
this.target = effect.target.copy();
|
|
}
|
|
|
|
@Override
|
|
public void init(Ability source, Game game) {
|
|
super.init(source, game);
|
|
|
|
Player you = game.getPlayer(source.getControllerId());
|
|
if (you == null) {
|
|
discard();
|
|
return;
|
|
}
|
|
|
|
this.target.choose(Outcome.Benefit, source.getControllerId(), source.getSourceId(), source, game);
|
|
this.wonFlip = you.flipCoin(source, game, true);
|
|
}
|
|
|
|
@Override
|
|
public DesperateGambitEffect copy() {
|
|
return new DesperateGambitEffect(this);
|
|
}
|
|
|
|
@Override
|
|
public boolean checksEventType(GameEvent event, Game game) {
|
|
return event.getType() == GameEvent.EventType.DAMAGE_PERMANENT ||
|
|
event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
|
|
}
|
|
|
|
@Override
|
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
|
if (event.getSourceId().equals(target.getFirstTarget())) {
|
|
// check source
|
|
MageObject object = game.getObject(event.getSourceId());
|
|
if (object == null) {
|
|
game.informPlayers("Couldn't find source of damage");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
|
MageObject object = game.getObject(event.getSourceId());
|
|
Player controller = game.getPlayer(source.getControllerId());
|
|
if (controller != null && object != null) {
|
|
if (super.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) {
|
|
if (wonFlip) {
|
|
event.setAmount(CardUtil.overflowMultiply(event.getAmount(), 2));
|
|
this.discard();
|
|
} else {
|
|
preventDamageAction(event, source, game);
|
|
this.discard();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* TODO: should not be needed with the proper {@link FilterSource}.
|
|
* make sure it works properly with 108.4a if you do
|
|
*/
|
|
class TargetControlledSource extends TargetSource {
|
|
|
|
public TargetControlledSource() {
|
|
super(1, 1, new FilterSource("source you control"));
|
|
}
|
|
|
|
private TargetControlledSource(final TargetControlledSource target) {
|
|
super(target);
|
|
}
|
|
|
|
@Override
|
|
public boolean canChoose(UUID sourceControllerId, Game game) {
|
|
int count = 0;
|
|
for (StackObject stackObject : game.getStack()) {
|
|
if (game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getControllerId())
|
|
&& Objects.equals(stackObject.getControllerId(), sourceControllerId)) {
|
|
count++;
|
|
if (count >= this.minNumberOfTargets) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(sourceControllerId, game)) {
|
|
if (Objects.equals(permanent.getControllerId(), sourceControllerId)) {
|
|
count++;
|
|
if (count >= this.minNumberOfTargets) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
for (Player player : game.getPlayers().values()) {
|
|
if (Objects.equals(player, game.getPlayer(sourceControllerId))) {
|
|
for (Card card : player.getGraveyard().getCards(game)) {
|
|
count++;
|
|
if (count >= this.minNumberOfTargets) {
|
|
return true;
|
|
}
|
|
}
|
|
// 108.4a If anything asks for the controller of a card that doesn't have one (because it's not a permanent or spell), use its owner instead.
|
|
for (Card card : game.getExile().getAllCards(game)) {
|
|
if (Objects.equals(card.getOwnerId(), sourceControllerId)) {
|
|
count++;
|
|
if (count >= this.minNumberOfTargets) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) {
|
|
Set<UUID> possibleTargets = new HashSet<>();
|
|
for (StackObject stackObject : game.getStack()) {
|
|
if (game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getControllerId())
|
|
&& Objects.equals(stackObject.getControllerId(), sourceControllerId)) {
|
|
possibleTargets.add(stackObject.getId());
|
|
}
|
|
}
|
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(sourceControllerId, game)) {
|
|
if (Objects.equals(permanent.getControllerId(), sourceControllerId)) {
|
|
possibleTargets.add(permanent.getId());
|
|
}
|
|
}
|
|
for (Player player : game.getPlayers().values()) {
|
|
if (Objects.equals(player, game.getPlayer(sourceControllerId))) {
|
|
for (Card card : player.getGraveyard().getCards(game)) {
|
|
possibleTargets.add(card.getId());
|
|
}
|
|
// 108.4a If anything asks for the controller of a card that doesn't have one (because it's not a permanent or spell), use its owner instead.
|
|
for (Card card : game.getExile().getAllCards(game)) {
|
|
if (Objects.equals(card.getOwnerId(), sourceControllerId)) {
|
|
possibleTargets.add(card.getId());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return possibleTargets;
|
|
}
|
|
|
|
@Override
|
|
public TargetControlledSource copy() {
|
|
return new TargetControlledSource(this);
|
|
}
|
|
}
|