added missing Planeswalker damage redirection effect + some fixes

This commit is contained in:
BetaSteward 2010-11-21 03:35:04 +00:00
parent 120de78d97
commit 06b7e63843
37 changed files with 347 additions and 75 deletions

View file

@ -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);

View file

@ -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.";
}
} }

View file

@ -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) {

View file

@ -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

View file

@ -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),

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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;
} }

View 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;
}
}

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;

View file

@ -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);
} }
} }
} }

View file

@ -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;

View file

@ -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;

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;

View file

@ -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;
} }

View file

@ -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;

View file

@ -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;

View file

@ -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());

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -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;
/** /**

View file

@ -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;

View file

@ -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;
} }

View file

@ -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) {

View file

@ -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;
} }

View file

@ -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;
}
} }

View file

@ -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)) {

View file

@ -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()) {

View file

@ -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;
} }
} }

View file

@ -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;
} }

View file

@ -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);