mirror of
https://github.com/magefree/mage.git
synced 2025-12-23 03:51:58 -08:00
added missing Planeswalker damage redirection effect + some fixes
This commit is contained in:
parent
120de78d97
commit
06b7e63843
37 changed files with 347 additions and 75 deletions
|
|
@ -137,7 +137,7 @@ public class ProteanHydra extends CardImpl<ProteanHydra> {
|
||||||
@Override
|
@Override
|
||||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
boolean retValue = false;
|
boolean retValue = false;
|
||||||
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount());
|
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount(), false);
|
||||||
int damage = event.getAmount();
|
int damage = event.getAmount();
|
||||||
if (!game.replaceEvent(preventEvent)) {
|
if (!game.replaceEvent(preventEvent)) {
|
||||||
event.setAmount(0);
|
event.setAmount(0);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ import mage.Constants.Zone;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.OnEventTriggeredAbility;
|
import mage.abilities.common.OnEventTriggeredAbility;
|
||||||
|
import mage.abilities.common.PutIntoGraveFromBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.effects.ContinuousEffectImpl;
|
import mage.abilities.effects.ContinuousEffectImpl;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
|
@ -117,7 +118,7 @@ class NecroticPlagueEffect extends ContinuousEffectImpl<NecroticPlagueEffect> {
|
||||||
case AbilityAddingRemovingEffects_6:
|
case AbilityAddingRemovingEffects_6:
|
||||||
if (sublayer == SubLayer.NA) {
|
if (sublayer == SubLayer.NA) {
|
||||||
creature.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new SacrificeSourceEffect()));
|
creature.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new SacrificeSourceEffect()));
|
||||||
creature.addAbility(new LeavesBattlefieldTriggeredAbility(new NecroticPlagueEffect2(source.getSourceId()), false));
|
creature.addAbility(new PutIntoGraveFromBattlefieldTriggeredAbility(new NecroticPlagueEffect2(source.getSourceId()), false));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -187,4 +188,9 @@ class NecroticPlagueEffect2 extends OneShotEffect<NecroticPlagueEffect2> {
|
||||||
return new NecroticPlagueEffect2(this);
|
return new NecroticPlagueEffect2(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText(Ability source) {
|
||||||
|
return "its controller chooses target creature one of his or her opponents controls. Return Necrotic Plague from its owner's graveyard to the battlefield attached to that creature.";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +112,7 @@ class VengefulArchonEffect extends PreventionEffectImpl<VengefulArchonEffect> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getControllerId(), source.getId(), source.getControllerId(), event.getAmount());
|
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getControllerId(), source.getId(), source.getControllerId(), event.getAmount(), false);
|
||||||
if (!game.replaceEvent(preventEvent)) {
|
if (!game.replaceEvent(preventEvent)) {
|
||||||
Player player = game.getPlayer(source.getFirstTarget());
|
Player player = game.getPlayer(source.getFirstTarget());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
|
|
|
||||||
|
|
@ -74,20 +74,23 @@ public class BraveTheElements extends CardImpl<BraveTheElements> {
|
||||||
|
|
||||||
class BraveTheElementsEffect extends GainAbilityControlledEffect {
|
class BraveTheElementsEffect extends GainAbilityControlledEffect {
|
||||||
|
|
||||||
FilterCreaturePermanent filter1 = new FilterCreaturePermanent();
|
private static FilterCreaturePermanent filter1 = new FilterCreaturePermanent();
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter1.setUseColor(true);
|
||||||
|
filter1.getColor().setWhite(true);
|
||||||
|
}
|
||||||
|
|
||||||
FilterCard filter2;
|
FilterCard filter2;
|
||||||
|
|
||||||
public BraveTheElementsEffect() {
|
public BraveTheElementsEffect() {
|
||||||
super(new ProtectionAbility(new FilterCard()), Duration.EndOfTurn);
|
super(new ProtectionAbility(new FilterCard()), Duration.EndOfTurn, filter1);
|
||||||
filter1.setUseColor(true);
|
|
||||||
filter1.getColor().setWhite(true);
|
|
||||||
filter2 = (FilterCard)((ProtectionAbility)ability).getFilter();
|
filter2 = (FilterCard)((ProtectionAbility)ability).getFilter();
|
||||||
filter2.setUseColor(true);
|
filter2.setUseColor(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BraveTheElementsEffect(final BraveTheElementsEffect effect) {
|
public BraveTheElementsEffect(final BraveTheElementsEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
this.filter1 = effect.filter1.copy();
|
|
||||||
this.filter2 = effect.filter2.copy();
|
this.filter2 = effect.filter2.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,10 +104,8 @@ class BraveTheElementsEffect extends GainAbilityControlledEffect {
|
||||||
ChoiceColor choice = (ChoiceColor) source.getChoices().get(0);
|
ChoiceColor choice = (ChoiceColor) source.getChoices().get(0);
|
||||||
filter2.setColor(choice.getColor());
|
filter2.setColor(choice.getColor());
|
||||||
filter2.setMessage(choice.getChoice());
|
filter2.setMessage(choice.getChoice());
|
||||||
for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter1, source.getControllerId())) {
|
ability = new ProtectionAbility(new FilterCard(filter2));
|
||||||
perm.addAbility(ability);
|
return super.apply(game, source);
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -281,6 +281,7 @@ public final class Constants {
|
||||||
PutManaInPool(true),
|
PutManaInPool(true),
|
||||||
Regenerate(true),
|
Regenerate(true),
|
||||||
PreventDamage(true),
|
PreventDamage(true),
|
||||||
|
RedirectDamage(true),
|
||||||
Tap(false),
|
Tap(false),
|
||||||
Untap(true),
|
Untap(true),
|
||||||
Win(true),
|
Win(true),
|
||||||
|
|
|
||||||
|
|
@ -59,13 +59,16 @@ public class ContinuousEffects implements Serializable {
|
||||||
private final Map<PreventionEffect, Ability> preventionEffects = new HashMap<PreventionEffect, Ability>();
|
private final Map<PreventionEffect, Ability> preventionEffects = new HashMap<PreventionEffect, Ability>();
|
||||||
private final Map<AsThoughEffect, Ability> asThoughEffects = new HashMap<AsThoughEffect, Ability>();
|
private final Map<AsThoughEffect, Ability> asThoughEffects = new HashMap<AsThoughEffect, Ability>();
|
||||||
private final ApplyCountersEffect applyCounters;
|
private final ApplyCountersEffect applyCounters;
|
||||||
|
private final PlaneswalkerRedirectionEffect planeswalkerRedirectionEffect;
|
||||||
|
|
||||||
public ContinuousEffects() {
|
public ContinuousEffects() {
|
||||||
applyCounters = new ApplyCountersEffect();
|
applyCounters = new ApplyCountersEffect();
|
||||||
|
planeswalkerRedirectionEffect = new PlaneswalkerRedirectionEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContinuousEffects(final ContinuousEffects effect) {
|
public ContinuousEffects(final ContinuousEffects effect) {
|
||||||
this.applyCounters = effect.applyCounters.copy();
|
this.applyCounters = effect.applyCounters.copy();
|
||||||
|
this.planeswalkerRedirectionEffect = effect.planeswalkerRedirectionEffect.copy();
|
||||||
for (Entry<ContinuousEffect, Ability> entry: effect.layeredEffects.entrySet()) {
|
for (Entry<ContinuousEffect, Ability> entry: effect.layeredEffects.entrySet()) {
|
||||||
layeredEffects.put((ContinuousEffect)entry.getKey().copy(), entry.getValue().copy());
|
layeredEffects.put((ContinuousEffect)entry.getKey().copy(), entry.getValue().copy());
|
||||||
}
|
}
|
||||||
|
|
@ -158,10 +161,12 @@ public class ContinuousEffects implements Serializable {
|
||||||
|
|
||||||
private List<ReplacementEffect> getApplicableReplacementEffects(GameEvent event, Game game) {
|
private List<ReplacementEffect> getApplicableReplacementEffects(GameEvent event, Game game) {
|
||||||
List<ReplacementEffect> replaceEffects = new ArrayList<ReplacementEffect>();
|
List<ReplacementEffect> replaceEffects = new ArrayList<ReplacementEffect>();
|
||||||
|
if (planeswalkerRedirectionEffect.applies(event, null, game))
|
||||||
|
replaceEffects.add(planeswalkerRedirectionEffect);
|
||||||
for (ReplacementEffect effect: replacementEffects.keySet()) {
|
for (ReplacementEffect effect: replacementEffects.keySet()) {
|
||||||
if (effect.applies(event, replacementEffects.get(effect), game)) {
|
if (effect.applies(event, replacementEffects.get(effect), game)) {
|
||||||
if (effect.getDuration() != Duration.OneUse || !effect.isUsed())
|
if (effect.getDuration() != Duration.OneUse || !effect.isUsed())
|
||||||
replaceEffects.add((ReplacementEffect)effect);
|
replaceEffects.add(effect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return replaceEffects;
|
return replaceEffects;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.abilities.effects;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Outcome;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.filter.common.FilterPlaneswalkerPermanent;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.events.GameEvent.EventType;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class PlaneswalkerRedirectionEffect extends RedirectionEffect<PlaneswalkerRedirectionEffect> {
|
||||||
|
|
||||||
|
private static FilterPlaneswalkerPermanent filter = new FilterPlaneswalkerPermanent();
|
||||||
|
|
||||||
|
public PlaneswalkerRedirectionEffect() {
|
||||||
|
super(Duration.EndOfGame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaneswalkerRedirectionEffect(final PlaneswalkerRedirectionEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlaneswalkerRedirectionEffect copy() {
|
||||||
|
return new PlaneswalkerRedirectionEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
|
if (event.getType() == EventType.DAMAGE_PLAYER) {
|
||||||
|
UUID playerId = getSourceControllerId(event.getSourceId(), game);
|
||||||
|
if (game.getOpponents(event.getTargetId()).contains(playerId)) {
|
||||||
|
Player target = game.getPlayer(event.getTargetId());
|
||||||
|
Player player = game.getPlayer(playerId);
|
||||||
|
if (target != null) {
|
||||||
|
int numPlaneswalkers = game.getBattlefield().countAll(filter, target.getId());
|
||||||
|
if (numPlaneswalkers > 0 && player.chooseUse(outcome, "Redirect damage to planeswalker?", game)) {
|
||||||
|
redirectTarget = new TargetPermanent(filter);
|
||||||
|
if (numPlaneswalkers == 1) {
|
||||||
|
redirectTarget.add(game.getBattlefield().getAllActivePermanents(filter, target.getId()).get(0).getId(), game);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
player.choose(Outcome.Damage, redirectTarget, game);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UUID getSourceControllerId(UUID sourceId, Game game) {
|
||||||
|
StackObject source = game.getStack().getStackObject(sourceId);
|
||||||
|
if (source != null)
|
||||||
|
return source.getControllerId();
|
||||||
|
Permanent permanent = game.getBattlefield().getPermanent(sourceId);
|
||||||
|
if (permanent != null)
|
||||||
|
return permanent.getControllerId();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -55,7 +55,7 @@ public abstract class PreventionEffectImpl<T extends PreventionEffectImpl<T>> ex
|
||||||
case DAMAGE_CREATURE:
|
case DAMAGE_CREATURE:
|
||||||
case DAMAGE_PLAYER:
|
case DAMAGE_PLAYER:
|
||||||
case DAMAGE_PLANESWALKER:
|
case DAMAGE_PLANESWALKER:
|
||||||
return true;
|
return event.getFlag();
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
93
Mage/src/mage/abilities/effects/RedirectionEffect.java
Normal file
93
Mage/src/mage/abilities/effects/RedirectionEffect.java
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.abilities.effects;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Outcome;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.game.stack.Spell;
|
||||||
|
import mage.game.stack.StackAbility;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public abstract class RedirectionEffect<T extends RedirectionEffect<T>> extends ReplacementEffectImpl<T> {
|
||||||
|
|
||||||
|
protected TargetPermanent redirectTarget;
|
||||||
|
|
||||||
|
public RedirectionEffect(Duration duration) {
|
||||||
|
super(duration, Outcome.RedirectDamage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RedirectionEffect(final RedirectionEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
this.redirectTarget = effect.redirectTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
|
Permanent permanent = game.getPermanent(redirectTarget.getFirstTarget());
|
||||||
|
Ability damageSource = getSource(event.getSourceId(), game);
|
||||||
|
if (permanent != null) {
|
||||||
|
permanent.damage(event.getAmount(), damageSource.getId(), game, event.getFlag());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Player player = game.getPlayer(redirectTarget.getFirstTarget());
|
||||||
|
if (player != null) {
|
||||||
|
player.damage(event.getAmount(), damageSource.getId(), game, false, event.getFlag());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Ability getSource(UUID sourceId, Game game) {
|
||||||
|
StackObject source = game.getStack().getStackObject(sourceId);
|
||||||
|
if (source != null) {
|
||||||
|
if (source instanceof StackAbility)
|
||||||
|
return (StackAbility)source;
|
||||||
|
if (source instanceof Spell)
|
||||||
|
return ((Spell)source).getSpellAbility();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ public class DamageAllControlledTargetEffect extends OneShotEffect<DamageAllCont
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget())) {
|
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget())) {
|
||||||
permanent.damage(amount, source.getSourceId(), game, true);
|
permanent.damage(amount, source.getId(), game, true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ public class DamageAllEffect extends OneShotEffect<DamageAllEffect> {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
|
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
|
||||||
permanent.damage(amount, source.getSourceId(), game, true);
|
permanent.damage(amount, source.getId(), game, true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ public class DamageControllerEffect extends OneShotEffect<DamageControllerEffect
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.damage(amount, source.getSourceId(), game, false, preventable);
|
player.damage(amount, source.getId(), game, false, preventable);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -70,12 +70,12 @@ public class DamageMultiEffect extends OneShotEffect<DamageMultiEffect> {
|
||||||
for (UUID target: multiTarget.getTargets()) {
|
for (UUID target: multiTarget.getTargets()) {
|
||||||
Permanent permanent = game.getPermanent(target);
|
Permanent permanent = game.getPermanent(target);
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
permanent.damage(multiTarget.getTargetAmount(target), source.getSourceId(), game, true);
|
permanent.damage(multiTarget.getTargetAmount(target), source.getId(), game, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Player player = game.getPlayer(target);
|
Player player = game.getPlayer(target);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.damage(multiTarget.getTargetAmount(target), source.getSourceId(), game, false, true);
|
player.damage(multiTarget.getTargetAmount(target), source.getId(), game, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,12 @@ public class DamageTargetEffect extends OneShotEffect<DamageTargetEffect> {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
permanent.damage(amount, source.getSourceId(), game, preventable);
|
permanent.damage(amount, source.getId(), game, preventable);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Player player = game.getPlayer(source.getFirstTarget());
|
Player player = game.getPlayer(source.getFirstTarget());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.damage(amount, source.getSourceId(), game, false, preventable);
|
player.damage(amount, source.getId(), game, false, preventable);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,12 @@ public class DamageXTargetEffect extends OneShotEffect<DamageXTargetEffect> {
|
||||||
int amount = source.getCosts().getVariableCosts().get(0).getAmount();
|
int amount = source.getCosts().getVariableCosts().get(0).getAmount();
|
||||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
permanent.damage(amount, source.getSourceId(), game, true);
|
permanent.damage(amount, source.getId(), game, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Player player = game.getPlayer(source.getFirstTarget());
|
Player player = game.getPlayer(source.getFirstTarget());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.damage(amount, source.getSourceId(), game, false, true);
|
player.damage(amount, source.getId(), game, false, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public class DestroyAllControlledTargetEffect extends OneShotEffect<DestroyAllCo
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget())) {
|
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget())) {
|
||||||
permanent.destroy(source.getSourceId(), game, false);
|
permanent.destroy(source.getId(), game, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public class DestroyAllEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
|
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
|
||||||
permanent.destroy(source.getSourceId(), game, false);
|
permanent.destroy(source.getId(), game, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public class DestroyAllNamedPermanentsEffect extends OneShotEffect<DestroyAllNam
|
||||||
permanent.destroy(source.getSourceId(), game, false);
|
permanent.destroy(source.getSourceId(), game, false);
|
||||||
for (Permanent perm: game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
for (Permanent perm: game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
||||||
if (perm.getName().equals(name))
|
if (perm.getName().equals(name))
|
||||||
perm.destroy(source.getSourceId(), game, false);
|
perm.destroy(source.getId(), game, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ public class DestroyNoRegenTargetEffect extends OneShotEffect<DestroyNoRegenTarg
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||||
permanent.destroy(source.getSourceId(), game, true);
|
permanent.destroy(source.getId(), game, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ public class DestroySourceEffect extends OneShotEffect<DestroySourceEffect> {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
permanent.destroy(source.getSourceId(), game, noRegen);
|
permanent.destroy(source.getId(), game, noRegen);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ public class DestroyTargetEffect extends OneShotEffect<DestroyTargetEffect> {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
permanent.destroy(source.getSourceId(), game, noRegen);
|
permanent.destroy(source.getId(), game, noRegen);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ import mage.game.permanent.Permanent;
|
||||||
public class GainAbilityControlledEffect extends ContinuousEffectImpl<GainAbilityControlledEffect> {
|
public class GainAbilityControlledEffect extends ContinuousEffectImpl<GainAbilityControlledEffect> {
|
||||||
|
|
||||||
protected Ability ability;
|
protected Ability ability;
|
||||||
protected boolean excludeSource;
|
protected boolean excludeSource;
|
||||||
protected FilterPermanent permanentFilter;
|
protected FilterPermanent permanentFilter;
|
||||||
|
|
||||||
public GainAbilityControlledEffect(Ability ability, Duration duration) {
|
public GainAbilityControlledEffect(Ability ability, Duration duration) {
|
||||||
|
|
@ -56,18 +56,18 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl<GainAbilit
|
||||||
this(ability, duration, filter, false);
|
this(ability, duration, filter, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GainAbilityControlledEffect(Ability ability, Duration duration, FilterPermanent filter, boolean excludeSource) {
|
public GainAbilityControlledEffect(Ability ability, Duration duration, FilterPermanent filter, boolean excludeSource) {
|
||||||
super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
||||||
this.ability = ability;
|
this.ability = ability;
|
||||||
this.permanentFilter = filter;
|
this.permanentFilter = filter;
|
||||||
this.excludeSource = excludeSource;
|
this.excludeSource = excludeSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GainAbilityControlledEffect(final GainAbilityControlledEffect effect) {
|
public GainAbilityControlledEffect(final GainAbilityControlledEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
this.ability = effect.ability.copy();
|
this.ability = effect.ability.copy();
|
||||||
this.permanentFilter = effect.permanentFilter.copy();
|
this.permanentFilter = effect.permanentFilter.copy();
|
||||||
this.excludeSource = effect.excludeSource;
|
this.excludeSource = effect.excludeSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -78,9 +78,9 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl<GainAbilit
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (Permanent perm: game.getBattlefield().getAllActivePermanents(permanentFilter, source.getControllerId())) {
|
for (Permanent perm: game.getBattlefield().getAllActivePermanents(permanentFilter, source.getControllerId())) {
|
||||||
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
|
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
|
||||||
perm.addAbility(ability.copy());
|
perm.addAbility(ability.copy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +88,7 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl<GainAbilit
|
||||||
@Override
|
@Override
|
||||||
public String getText(Ability source) {
|
public String getText(Ability source) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (excludeSource)
|
if (excludeSource)
|
||||||
sb.append("Other ");
|
sb.append("Other ");
|
||||||
sb.append(permanentFilter.getMessage()).append(" you control gain ").append(ability.getRule());
|
sb.append(permanentFilter.getMessage()).append(" you control gain ").append(ability.getRule());
|
||||||
sb.append(" ").append(duration.toString());
|
sb.append(" ").append(duration.toString());
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public class PreventAllCombatDamageEffect extends PreventionEffectImpl<PreventAl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount());
|
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount(), false);
|
||||||
if (!game.replaceEvent(preventEvent)) {
|
if (!game.replaceEvent(preventEvent)) {
|
||||||
int damage = event.getAmount();
|
int damage = event.getAmount();
|
||||||
event.setAmount(0);
|
event.setAmount(0);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public class PreventAllDamageSourceEffect extends PreventionEffectImpl<PreventAl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount());
|
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount(), false);
|
||||||
if (!game.replaceEvent(preventEvent)) {
|
if (!game.replaceEvent(preventEvent)) {
|
||||||
int damage = event.getAmount();
|
int damage = event.getAmount();
|
||||||
event.setAmount(0);
|
event.setAmount(0);
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ public class PreventAllDamageToEffect extends PreventionEffectImpl<PreventAllDam
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount());
|
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount(), false);
|
||||||
if (!game.replaceEvent(preventEvent)) {
|
if (!game.replaceEvent(preventEvent)) {
|
||||||
int damage = event.getAmount();
|
int damage = event.getAmount();
|
||||||
event.setAmount(0);
|
event.setAmount(0);
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ public class PreventDamageTargetEffect extends PreventionEffectImpl<PreventDamag
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount());
|
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount(), false);
|
||||||
if (!game.replaceEvent(preventEvent)) {
|
if (!game.replaceEvent(preventEvent)) {
|
||||||
if (event.getAmount() >= this.amount) {
|
if (event.getAmount() >= this.amount) {
|
||||||
int damage = event.getAmount();
|
int damage = event.getAmount();
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,10 @@ import mage.Constants.Outcome;
|
||||||
import mage.Constants.TargetController;
|
import mage.Constants.TargetController;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.filter.FilterPermanent;
|
|
||||||
import mage.filter.common.FilterControlledPermanent;
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.TargetPermanent;
|
|
||||||
import mage.target.common.TargetControlledPermanent;
|
import mage.target.common.TargetControlledPermanent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ class CascadeEffect extends OneShotEffect<CascadeEffect> {
|
||||||
if (card == null)
|
if (card == null)
|
||||||
break;
|
break;
|
||||||
card.moveToExile(exile.getId(), exile.getName(), game);
|
card.moveToExile(exile.getId(), exile.getName(), game);
|
||||||
// exile.add(card);
|
|
||||||
} while (card.getCardType().contains(CardType.LAND) || card.getManaCost().convertedManaCost() >= sourceCost);
|
} while (card.getCardType().contains(CardType.LAND) || card.getManaCost().convertedManaCost() >= sourceCost);
|
||||||
|
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
|
|
@ -111,7 +110,6 @@ class CascadeEffect extends OneShotEffect<CascadeEffect> {
|
||||||
card = exile.getRandom(game);
|
card = exile.getRandom(game);
|
||||||
exile.remove(card.getId());
|
exile.remove(card.getId());
|
||||||
card.moveToZone(Zone.LIBRARY, game, false);
|
card.moveToZone(Zone.LIBRARY, game, false);
|
||||||
// player.getLibrary().putOnBottom(card, game);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
|
||||||
|
|
||||||
public boolean moveToZone(Zone toZone, UUID controllerId, Game game, boolean flag) {
|
public boolean moveToZone(Zone toZone, UUID controllerId, Game game, boolean flag) {
|
||||||
Zone fromZone = zone;
|
Zone fromZone = zone;
|
||||||
ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), controllerId, fromZone, toZone);
|
ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, controllerId, fromZone, toZone);
|
||||||
if (!game.replaceEvent(event)) {
|
if (!game.replaceEvent(event)) {
|
||||||
switch (event.getToZone()) {
|
switch (event.getToZone()) {
|
||||||
case GRAVEYARD:
|
case GRAVEYARD:
|
||||||
|
|
@ -226,7 +226,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
|
||||||
@Override
|
@Override
|
||||||
public boolean moveToExile(UUID exileId, String name, Game game) {
|
public boolean moveToExile(UUID exileId, String name, Game game) {
|
||||||
Zone fromZone = zone;
|
Zone fromZone = zone;
|
||||||
ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), ownerId, fromZone, Zone.EXILED);
|
ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, ownerId, fromZone, Zone.EXILED);
|
||||||
if (!game.replaceEvent(event)) {
|
if (!game.replaceEvent(event)) {
|
||||||
if (exileId == null) {
|
if (exileId == null) {
|
||||||
game.getExile().getPermanentExile().add(this);
|
game.getExile().getPermanentExile().add(this);
|
||||||
|
|
@ -235,7 +235,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
|
||||||
game.getExile().createZone(exileId, name).add(this);
|
game.getExile().createZone(exileId, name).add(this);
|
||||||
}
|
}
|
||||||
zone = event.getToZone();
|
zone = event.getToZone();
|
||||||
game.fireEvent(new ZoneChangeEvent(this.getId(), ownerId, fromZone, Zone.EXILED));
|
game.fireEvent(new ZoneChangeEvent(this.objectId, ownerId, fromZone, Zone.EXILED));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -248,7 +248,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
|
||||||
zone = Zone.BATTLEFIELD;
|
zone = Zone.BATTLEFIELD;
|
||||||
permanent.entersBattlefield(game);
|
permanent.entersBattlefield(game);
|
||||||
game.applyEffects();
|
game.applyEffects();
|
||||||
game.fireEvent(new ZoneChangeEvent(permanent.getId(), controllerId, fromZone, Zone.BATTLEFIELD));
|
game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ import mage.abilities.TriggeredAbilities;
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
import mage.abilities.effects.ContinuousEffects;
|
import mage.abilities.effects.ContinuousEffects;
|
||||||
import mage.game.combat.Combat;
|
import mage.game.combat.Combat;
|
||||||
|
import mage.game.events.GameEvent.EventType;
|
||||||
|
import mage.game.events.ZoneChangeEvent;
|
||||||
import mage.game.permanent.Battlefield;
|
import mage.game.permanent.Battlefield;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.stack.StackObject;
|
import mage.game.stack.StackObject;
|
||||||
|
|
@ -295,14 +297,20 @@ public class GameState implements Serializable, Copyable<GameState> {
|
||||||
public void handleEvent(GameEvent event, Game game) {
|
public void handleEvent(GameEvent event, Game game) {
|
||||||
watchers.watch(event, game);
|
watchers.watch(event, game);
|
||||||
if (!replaceEvent(event, game)) {
|
if (!replaceEvent(event, game)) {
|
||||||
|
if (event.getType() == EventType.ZONE_CHANGE) {
|
||||||
|
ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
|
||||||
|
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
||||||
|
zEvent.getTarget().checkTriggers(zEvent.getToZone(), event, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (Player player: players.values()) {
|
for (Player player: players.values()) {
|
||||||
player.checkTriggers(event, game);
|
player.checkTriggers(event, game);
|
||||||
}
|
}
|
||||||
|
battlefield.checkTriggers(event, game);
|
||||||
|
stack.checkTriggers(event, game);
|
||||||
|
delayed.checkTriggers(event, game);
|
||||||
|
exile.checkTriggers(event, game);
|
||||||
}
|
}
|
||||||
battlefield.checkTriggers(event, game);
|
|
||||||
stack.checkTriggers(event, game);
|
|
||||||
delayed.checkTriggers(event, game);
|
|
||||||
exile.checkTriggers(event, game);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean replaceEvent(GameEvent event, Game game) {
|
public boolean replaceEvent(GameEvent event, Game game) {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ public class GameEvent {
|
||||||
private UUID sourceId;
|
private UUID sourceId;
|
||||||
private UUID playerId;
|
private UUID playerId;
|
||||||
private int amount;
|
private int amount;
|
||||||
|
private boolean flag;
|
||||||
private String data;
|
private String data;
|
||||||
|
|
||||||
public enum EventType {
|
public enum EventType {
|
||||||
|
|
@ -119,19 +120,20 @@ public class GameEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId) {
|
public GameEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId) {
|
||||||
this(type, targetId, sourceId, playerId, 0);
|
this(type, targetId, sourceId, playerId, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId, int amount) {
|
public GameEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.targetId = targetId;
|
this.targetId = targetId;
|
||||||
this.sourceId = sourceId;
|
this.sourceId = sourceId;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.playerId = playerId;
|
this.playerId = playerId;
|
||||||
|
this.flag = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameEvent getEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId, int amount) {
|
public static GameEvent getEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId, int amount) {
|
||||||
return new GameEvent(type, targetId, sourceId, playerId, amount);
|
return new GameEvent(type, targetId, sourceId, playerId, amount, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameEvent getEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId) {
|
public static GameEvent getEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId) {
|
||||||
|
|
@ -162,6 +164,10 @@ public class GameEvent {
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getFlag() {
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
public void setAmount(int amount) {
|
public void setAmount(int amount) {
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ package mage.game.events;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.Constants.Zone;
|
import mage.Constants.Zone;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -39,6 +40,14 @@ public class ZoneChangeEvent extends GameEvent {
|
||||||
|
|
||||||
private Zone fromZone;
|
private Zone fromZone;
|
||||||
private Zone toZone;
|
private Zone toZone;
|
||||||
|
private Permanent target;
|
||||||
|
|
||||||
|
public ZoneChangeEvent(Permanent target, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) {
|
||||||
|
super(EventType.ZONE_CHANGE, target.getId(), sourceId, playerId);
|
||||||
|
this.fromZone = fromZone;
|
||||||
|
this.toZone = toZone;
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
public ZoneChangeEvent(UUID targetId, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) {
|
public ZoneChangeEvent(UUID targetId, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) {
|
||||||
super(EventType.ZONE_CHANGE, targetId, sourceId, playerId);
|
super(EventType.ZONE_CHANGE, targetId, sourceId, playerId);
|
||||||
|
|
@ -46,6 +55,10 @@ public class ZoneChangeEvent extends GameEvent {
|
||||||
this.toZone = toZone;
|
this.toZone = toZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ZoneChangeEvent(Permanent target, UUID playerId, Zone fromZone, Zone toZone) {
|
||||||
|
this(target, null, playerId, fromZone, toZone);
|
||||||
|
}
|
||||||
|
|
||||||
public ZoneChangeEvent(UUID targetId, UUID playerId, Zone fromZone, Zone toZone) {
|
public ZoneChangeEvent(UUID targetId, UUID playerId, Zone fromZone, Zone toZone) {
|
||||||
this(targetId, null, playerId, fromZone, toZone);
|
this(targetId, null, playerId, fromZone, toZone);
|
||||||
}
|
}
|
||||||
|
|
@ -61,4 +74,8 @@ public class ZoneChangeEvent extends GameEvent {
|
||||||
public void setToZone(Zone toZone) {
|
public void setToZone(Zone toZone) {
|
||||||
this.toZone = toZone;
|
this.toZone = toZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Permanent getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,10 @@ import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.keyword.LevelAbility;
|
import mage.abilities.keyword.LevelAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
|
||||||
import mage.cards.LevelerCard;
|
import mage.cards.LevelerCard;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.ZoneChangeEvent;
|
import mage.game.events.ZoneChangeEvent;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -112,18 +112,58 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
|
||||||
this.cardNumber = card.getCardNumber();
|
this.cardNumber = card.getCardNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public boolean moveToZone(Zone zone, Game game, boolean flag) {
|
||||||
|
// ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone);
|
||||||
|
// if (!game.replaceEvent(event)) {
|
||||||
|
// if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
|
||||||
|
// CardImpl card = (CardImpl) game.getCard(objectId);
|
||||||
|
// return card.moveToZone(event.getToZone(), controllerId, game, flag);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean moveToZone(Zone zone, Game game, boolean flag) {
|
public boolean moveToZone(Zone toZone, Game game, boolean flag) {
|
||||||
ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone);
|
Zone fromZone = zone;
|
||||||
|
ZoneChangeEvent event = new ZoneChangeEvent(this, controllerId, fromZone, toZone);
|
||||||
if (!game.replaceEvent(event)) {
|
if (!game.replaceEvent(event)) {
|
||||||
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
|
Player controller = game.getPlayer(controllerId);
|
||||||
CardImpl card = (CardImpl) game.getCard(objectId);
|
if (controller != null && controller.removeFromBattlefield(this, game)) {
|
||||||
return card.moveToZone(event.getToZone(), controllerId, game, flag);
|
Card card = game.getCard(objectId);
|
||||||
|
Player owner = game.getPlayer(ownerId);
|
||||||
|
if (owner != null) {
|
||||||
|
switch (event.getToZone()) {
|
||||||
|
case GRAVEYARD:
|
||||||
|
owner.putInGraveyard(card, game, !flag);
|
||||||
|
break;
|
||||||
|
case HAND:
|
||||||
|
owner.getHand().add(card);
|
||||||
|
break;
|
||||||
|
case EXILED:
|
||||||
|
game.getExile().getPermanentExile().add(card);
|
||||||
|
break;
|
||||||
|
case LIBRARY:
|
||||||
|
if (flag)
|
||||||
|
owner.getLibrary().putOnTop(card, game);
|
||||||
|
else
|
||||||
|
owner.getLibrary().putOnBottom(card, game);
|
||||||
|
break;
|
||||||
|
case BATTLEFIELD:
|
||||||
|
//should never happen
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
zone = event.getToZone();
|
||||||
|
game.fireEvent(event);
|
||||||
|
return zone == toZone;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean moveToExile(UUID exileId, String name, Game game) {
|
public boolean moveToExile(UUID exileId, String name, Game game) {
|
||||||
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
|
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
|
||||||
|
|
|
||||||
|
|
@ -438,8 +438,8 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int damagePlaneswalker(int damage, UUID sourceId, Game game, boolean preventable) {
|
protected int damagePlaneswalker(int damage, UUID sourceId, Game game, boolean preventable) {
|
||||||
GameEvent event = new GameEvent(GameEvent.EventType.DAMAGE_PLANESWALKER, objectId, sourceId, controllerId, damage);
|
GameEvent event = new GameEvent(GameEvent.EventType.DAMAGE_PLANESWALKER, objectId, sourceId, controllerId, damage, preventable);
|
||||||
if (!preventable || !game.replaceEvent(event)) {
|
if (!game.replaceEvent(event)) {
|
||||||
int actualDamage = event.getAmount();
|
int actualDamage = event.getAmount();
|
||||||
if (actualDamage > 0) {
|
if (actualDamage > 0) {
|
||||||
if (event.getAmount() > this.loyalty.getValue()) {
|
if (event.getAmount() > this.loyalty.getValue()) {
|
||||||
|
|
@ -454,8 +454,8 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int damageCreature(int damage, UUID sourceId, Game game, boolean preventable) {
|
protected int damageCreature(int damage, UUID sourceId, Game game, boolean preventable) {
|
||||||
GameEvent event = new GameEvent(GameEvent.EventType.DAMAGE_CREATURE, objectId, sourceId, controllerId, damage);
|
GameEvent event = new GameEvent(GameEvent.EventType.DAMAGE_CREATURE, objectId, sourceId, controllerId, damage, preventable);
|
||||||
if (!preventable || !game.replaceEvent(event)) {
|
if (!game.replaceEvent(event)) {
|
||||||
int actualDamage = event.getAmount();
|
int actualDamage = event.getAmount();
|
||||||
if (actualDamage > 0) {
|
if (actualDamage > 0) {
|
||||||
if (this.damage + event.getAmount() > this.toughness.getValue()) {
|
if (this.damage + event.getAmount() > this.toughness.getValue()) {
|
||||||
|
|
|
||||||
|
|
@ -76,9 +76,9 @@ public class PermanentToken extends PermanentImpl<PermanentToken> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean moveToZone(Zone zone, Game game, boolean flag) {
|
public boolean moveToZone(Zone zone, Game game, boolean flag) {
|
||||||
if (!game.replaceEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone))) {
|
if (!game.replaceEvent(new ZoneChangeEvent(this, this.getControllerId(), Zone.BATTLEFIELD, zone))) {
|
||||||
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
|
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
|
||||||
game.fireEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone));
|
game.fireEvent(new ZoneChangeEvent(this, this.getControllerId(), Zone.BATTLEFIELD, zone));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -87,9 +87,9 @@ public class PermanentToken extends PermanentImpl<PermanentToken> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean moveToExile(UUID exileId, String name, Game game) {
|
public boolean moveToExile(UUID exileId, String name, Game game) {
|
||||||
if (!game.replaceEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, Zone.EXILED))) {
|
if (!game.replaceEvent(new ZoneChangeEvent(this, this.getControllerId(), Zone.BATTLEFIELD, Zone.EXILED))) {
|
||||||
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
|
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
|
||||||
game.fireEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, Zone.EXILED));
|
game.fireEvent(new ZoneChangeEvent(this, this.getControllerId(), Zone.BATTLEFIELD, Zone.EXILED));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ public class Token extends MageObjectImpl<Token> {
|
||||||
game.getBattlefield().addPermanent(permanent);
|
game.getBattlefield().addPermanent(permanent);
|
||||||
permanent.entersBattlefield(game);
|
permanent.entersBattlefield(game);
|
||||||
game.applyEffects();
|
game.applyEffects();
|
||||||
game.fireEvent(new ZoneChangeEvent(permanent.getId(), controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD));
|
game.fireEvent(new ZoneChangeEvent(permanent, controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -593,7 +593,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int loseLife(int amount, Game game) {
|
public int loseLife(int amount, Game game) {
|
||||||
GameEvent event = new GameEvent(GameEvent.EventType.LOSE_LIFE, playerId, playerId, playerId, amount);
|
GameEvent event = new GameEvent(GameEvent.EventType.LOSE_LIFE, playerId, playerId, playerId, amount, false);
|
||||||
if (!game.replaceEvent(event)) {
|
if (!game.replaceEvent(event)) {
|
||||||
setLife(this.life - amount, game);
|
setLife(this.life - amount, game);
|
||||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LOST_LIFE, playerId, playerId, playerId, amount));
|
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LOST_LIFE, playerId, playerId, playerId, amount));
|
||||||
|
|
@ -604,7 +604,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void gainLife(int amount, Game game) {
|
public void gainLife(int amount, Game game) {
|
||||||
GameEvent event = new GameEvent(GameEvent.EventType.GAIN_LIFE, playerId, playerId, playerId, amount);
|
GameEvent event = new GameEvent(GameEvent.EventType.GAIN_LIFE, playerId, playerId, playerId, amount, false);
|
||||||
if (!game.replaceEvent(event)) {
|
if (!game.replaceEvent(event)) {
|
||||||
setLife(this.life + amount, game);
|
setLife(this.life + amount, game);
|
||||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.GAINED_LIFE, playerId, playerId, playerId, amount));
|
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.GAINED_LIFE, playerId, playerId, playerId, amount));
|
||||||
|
|
@ -614,8 +614,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
||||||
@Override
|
@Override
|
||||||
public int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable) {
|
public int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable) {
|
||||||
if (damage > 0 && canDamage(game.getObject(sourceId))) {
|
if (damage > 0 && canDamage(game.getObject(sourceId))) {
|
||||||
GameEvent event = new GameEvent(GameEvent.EventType.DAMAGE_PLAYER, playerId, sourceId, playerId, damage);
|
GameEvent event = new GameEvent(GameEvent.EventType.DAMAGE_PLAYER, playerId, sourceId, playerId, damage, preventable);
|
||||||
if (!preventable || !game.replaceEvent(event)) {
|
if (!game.replaceEvent(event)) {
|
||||||
int actualDamage = event.getAmount();
|
int actualDamage = event.getAmount();
|
||||||
if (actualDamage > 0) {
|
if (actualDamage > 0) {
|
||||||
actualDamage = this.loseLife(actualDamage, game);
|
actualDamage = this.loseLife(actualDamage, game);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue