fix for issue 22 + fix for planeswalker damage redirection

This commit is contained in:
BetaSteward 2010-11-28 04:31:48 +00:00
parent c90193a4eb
commit 9c3ff863e8
49 changed files with 636 additions and 182 deletions

View file

@ -31,7 +31,6 @@ package mage.view;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID; import java.util.UUID;
import mage.game.Game; import mage.game.Game;
import mage.game.GameState;
import mage.game.combat.CombatGroup; import mage.game.combat.CombatGroup;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
@ -44,7 +43,7 @@ public class CombatGroupView implements Serializable {
private CardsView attackers = new CardsView(); private CardsView attackers = new CardsView();
private CardsView blockers = new CardsView(); private CardsView blockers = new CardsView();
private String defenderName; private String defenderName = "";
public CombatGroupView(CombatGroup combatGroup, Game game) { public CombatGroupView(CombatGroup combatGroup, Game game) {
Player player = game.getPlayer(combatGroup.getDefenderId()); Player player = game.getPlayer(combatGroup.getDefenderId());
@ -53,6 +52,7 @@ public class CombatGroupView implements Serializable {
} }
else { else {
Permanent perm = game.getPermanent(combatGroup.getDefenderId()); Permanent perm = game.getPermanent(combatGroup.getDefenderId());
if (perm != null)
this.defenderName = perm.getName(); this.defenderName = perm.getName();
} }
for (UUID id: combatGroup.getAttackers()) { for (UUID id: combatGroup.getAttackers()) {

View file

@ -720,7 +720,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
public void assignDamage(int damage, List<UUID> targets, UUID sourceId, Game game) { public void assignDamage(int damage, List<UUID> targets, UUID sourceId, Game game) {
logger.fine("assignDamage"); logger.fine("assignDamage");
//TODO: improve this //TODO: improve this
game.getPermanent(targets.get(0)).damage(damage, sourceId, game, true); game.getPermanent(targets.get(0)).damage(damage, sourceId, game, true, false);
} }
@Override @Override

View file

@ -440,7 +440,7 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
int damageAmount = getAmount(0, remainingDamage, "Select amount", game); int damageAmount = getAmount(0, remainingDamage, "Select amount", game);
Permanent permanent = game.getPermanent(target.getFirstTarget()); Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) { if (permanent != null) {
permanent.damage(damageAmount, sourceId, game, true); permanent.damage(damageAmount, sourceId, game, true, false);
remainingDamage -= damageAmount; remainingDamage -= damageAmount;
} }
else { else {

View file

@ -103,7 +103,7 @@ class VengefulRebirthEffect extends OneShotEffect<VengefulRebirthEffect> {
if (!card.getCardType().contains(CardType.LAND)) { if (!card.getCardType().contains(CardType.LAND)) {
Permanent permanent = game.getPermanent(source.getTargets().get(1).getTargets().get(0)); Permanent permanent = game.getPermanent(source.getTargets().get(1).getTargets().get(0));
if (permanent != null) { if (permanent != null) {
permanent.damage(damage, source.getSourceId(), game, true); permanent.damage(damage, source.getSourceId(), game, true, false);
return true; return true;
} }
Player targetPlayer = game.getPlayer(source.getTargets().get(1).getTargets().get(0)); Player targetPlayer = game.getPlayer(source.getTargets().get(1).getTargets().get(0));

View file

@ -96,7 +96,7 @@ class EarthquakeEffect extends OneShotEffect<EarthquakeEffect> {
int amount = source.getManaCosts().getVariableCosts().get(0).getAmount(); int amount = source.getManaCosts().getVariableCosts().get(0).getAmount();
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
permanent.damage(amount, source.getId(), game, true); permanent.damage(amount, source.getId(), game, true, false);
} }
for (UUID playerId: game.getPlayer(source.getControllerId()).getInRange()) { for (UUID playerId: game.getPlayer(source.getControllerId()).getInRange()) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);

View file

@ -98,7 +98,7 @@ class FireballEffect extends OneShotEffect<FireballEffect> {
for (UUID targetId: source.getTargets().get(0).getTargets()) { for (UUID targetId: source.getTargets().get(0).getTargets()) {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);
if (permanent != null) { if (permanent != null) {
permanent.damage(damagePer, source.getSourceId(), game, true); permanent.damage(damagePer, source.getSourceId(), game, true, false);
} }
else { else {
Player player = game.getPlayer(targetId); Player player = game.getPlayer(targetId);

View file

@ -119,7 +119,7 @@ class MasterOfTheWildHuntEffect extends OneShotEffect<MasterOfTheWildHuntEffect>
if (target != null && game.getBattlefield().countAll(filter, source.getControllerId()) > 0) { if (target != null && game.getBattlefield().countAll(filter, source.getControllerId()) > 0) {
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId())) { for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId())) {
permanent.tap(game); permanent.tap(game);
target.damage(permanent.getToughness().getValue(), permanent.getId(), game, true); target.damage(permanent.getToughness().getValue(), permanent.getId(), game, true, false);
wolves.add(permanent.getId()); wolves.add(permanent.getId());
} }
Player player = game.getPlayer(target.getControllerId()); Player player = game.getPlayer(target.getControllerId());

View file

@ -39,9 +39,7 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.BoostControlledEffect; import mage.abilities.effects.common.BoostControlledEffect;
import mage.abilities.effects.common.GainAbilityControlledEffect;
import mage.abilities.effects.common.GainAbilityTargetEffect; import mage.abilities.effects.common.GainAbilityTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.UnblockableAbility; import mage.abilities.keyword.UnblockableAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;

View file

@ -86,7 +86,7 @@ class ChandrasOutrageEffect extends OneShotEffect<ChandrasOutrageEffect> {
if (permanent != null) { if (permanent != null) {
Player player = game.getPlayer(permanent.getControllerId()); Player player = game.getPlayer(permanent.getControllerId());
if (player != null) { if (player != null) {
permanent.damage(4, source.getSourceId(), game, true); permanent.damage(4, source.getSourceId(), game, true, false);
player.damage(2, source.getSourceId(), game, false, true); player.damage(2, source.getSourceId(), game, false, true);
return true; return true;
} }

View file

@ -41,6 +41,7 @@ import mage.abilities.effects.common.BoostSourceEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.game.Game; import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
@ -90,10 +91,13 @@ class ChandrasSpitfireAbility extends TriggeredAbilityImpl<ChandrasSpitfireAbili
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == EventType.NONCOMBAT_DAMAGED_PLAYER && game.getOpponents(controllerId).contains(event.getTargetId()) && game.getTurn().getStepType() != PhaseStep.COMBAT_DAMAGE) { if (event instanceof DamagedPlayerEvent) {
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event;
if (!damageEvent.isCombatDamage() && game.getOpponents(controllerId).contains(event.getTargetId())) {
trigger(game, this.controllerId); trigger(game, this.controllerId);
return true; return true;
} }
}
return false; return false;
} }

View file

@ -98,7 +98,7 @@ class CorruptEffect extends OneShotEffect<CorruptEffect> {
int damageDealt = amount; int damageDealt = amount;
Permanent permanent = game.getPermanent(source.getFirstTarget()); Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) { if (permanent != null) {
damageDealt = permanent.damage(amount, source.getSourceId(), game, true); damageDealt = permanent.damage(amount, source.getSourceId(), game, true, false);
} }
else { else {
Player player = game.getPlayer(source.getFirstTarget()); Player player = game.getPlayer(source.getFirstTarget());

View file

@ -107,8 +107,8 @@ class CyclopsGladiatorEffect extends OneShotEffect<CyclopsGladiatorEffect> {
Permanent permanent = game.getPermanent(target.getFirstTarget()); Permanent permanent = game.getPermanent(target.getFirstTarget());
Permanent cyclops = game.getPermanent(source.getSourceId()); Permanent cyclops = game.getPermanent(source.getSourceId());
if (permanent != null && cyclops != null) { if (permanent != null && cyclops != null) {
permanent.damage(cyclops.getPower().getValue(), cyclops.getId(), game, true); permanent.damage(cyclops.getPower().getValue(), cyclops.getId(), game, true, false);
cyclops.damage(permanent.getPower().getValue(), permanent.getId(), game, true); cyclops.damage(permanent.getPower().getValue(), permanent.getId(), game, true, false);
return true; return true;
} }
} }

View file

@ -95,7 +95,7 @@ class FlingEffect extends OneShotEffect<FlingEffect> {
if (amount > 0) { if (amount > 0) {
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.getSourceId(), game, true, false);
return true; return true;
} }
Player player = game.getPlayer(source.getFirstTarget()); Player player = game.getPlayer(source.getFirstTarget());

View file

@ -101,6 +101,7 @@ class VengefulArchonEffect extends PreventionEffectImpl<VengefulArchonEffect> {
@Override @Override
public void init(Ability source, Game game) { public void init(Ability source, Game game) {
super.init(source, game);
if (source.getManaCosts().getVariableCosts().size() > 0) if (source.getManaCosts().getVariableCosts().size() > 0)
amount = source.getManaCosts().getVariableCosts().get(0).getAmount(); amount = source.getManaCosts().getVariableCosts().get(0).getAmount();
} }

View file

@ -132,7 +132,7 @@ class SearingBlazeEffect extends OneShotEffect<SearingBlazeEffect> {
player.damage(3, source.getId(), game, false, true); player.damage(3, source.getId(), game, false, true);
} }
if (creature != null) { if (creature != null) {
creature.damage(3, source.getId(), game, true); creature.damage(3, source.getId(), game, true, false);
} }
} }
else { else {
@ -140,7 +140,7 @@ class SearingBlazeEffect extends OneShotEffect<SearingBlazeEffect> {
player.damage(1, source.getId(), game, false, true); player.damage(1, source.getId(), game, false, true);
} }
if (creature != null) { if (creature != null) {
creature.damage(1, source.getId(), game, true); creature.damage(1, source.getId(), game, true, false);
} }
} }
return true; return true;

View file

@ -28,13 +28,17 @@
package mage.abilities.effects; package mage.abilities.effects;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.UUID;
import mage.Constants.Duration; import mage.Constants.Duration;
import mage.Constants.EffectType; import mage.Constants.EffectType;
import mage.Constants.Layer; import mage.Constants.Layer;
import mage.Constants.Outcome; import mage.Constants.Outcome;
import mage.Constants.SubLayer; import mage.Constants.SubLayer;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.game.Game; import mage.game.Game;
/** /**
@ -48,6 +52,8 @@ public abstract class ContinuousEffectImpl<T extends ContinuousEffectImpl<T>> ex
protected SubLayer sublayer; protected SubLayer sublayer;
protected Date timestamp; protected Date timestamp;
protected boolean used = false; protected boolean used = false;
protected boolean affectedObjectsSet = false;
protected List<UUID> objects = new ArrayList<UUID>();
public ContinuousEffectImpl(Duration duration, Outcome outcome) { public ContinuousEffectImpl(Duration duration, Outcome outcome) {
super(outcome); super(outcome);
@ -62,13 +68,17 @@ public abstract class ContinuousEffectImpl<T extends ContinuousEffectImpl<T>> ex
this.sublayer = sublayer; this.sublayer = sublayer;
} }
public ContinuousEffectImpl(final ContinuousEffectImpl effect) { public ContinuousEffectImpl(final ContinuousEffectImpl<T> effect) {
super(effect); super(effect);
this.duration = effect.duration; this.duration = effect.duration;
this.layer = effect.layer; this.layer = effect.layer;
this.sublayer = effect.sublayer; this.sublayer = effect.sublayer;
this.timestamp = new Date(effect.timestamp.getTime()); this.timestamp = new Date(effect.timestamp.getTime());
this.used = effect.used; this.used = effect.used;
this.affectedObjectsSet = effect.affectedObjectsSet;
for (UUID objectId: effect.objects) {
this.objects.add(objectId);
}
} }
@Override @Override
@ -105,6 +115,20 @@ public abstract class ContinuousEffectImpl<T extends ContinuousEffectImpl<T>> ex
} }
@Override @Override
public void init(Ability source, Game game) {} public void init(Ability source, Game game) {
//20100716 - 611.2c
if (source instanceof ActivatedAbility) {
switch (layer) {
case CopyEffects_1:
case ControlChangingEffects_2:
case TextChangingEffects_3:
case TypeChangingEffects_4:
case ColorChangingEffects_5:
case AbilityAddingRemovingEffects_6:
case PTChangingEffects_7:
this.affectedObjectsSet = true;
}
}
}
} }

View file

@ -34,6 +34,7 @@ import mage.Constants.Outcome;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.filter.common.FilterPlaneswalkerPermanent; import mage.filter.common.FilterPlaneswalkerPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -65,8 +66,9 @@ public class PlaneswalkerRedirectionEffect extends RedirectionEffect<Planeswalke
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.DAMAGE_PLAYER) { if (event.getType() == EventType.DAMAGE_PLAYER) {
DamageEvent damageEvent = (DamageEvent)event;
UUID playerId = getSourceControllerId(event.getSourceId(), game); UUID playerId = getSourceControllerId(event.getSourceId(), game);
if (game.getOpponents(event.getTargetId()).contains(playerId)) { if (!damageEvent.isCombatDamage() && game.getOpponents(event.getTargetId()).contains(playerId)) {
Player target = game.getPlayer(event.getTargetId()); Player target = game.getPlayer(event.getTargetId());
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (target != null) { if (target != null) {

View file

@ -34,6 +34,7 @@ import mage.Constants.EffectType;
import mage.Constants.Outcome; import mage.Constants.Outcome;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.game.Game; import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
@ -67,15 +68,16 @@ public abstract class RedirectionEffect<T extends RedirectionEffect<T>> extends
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
DamageEvent damageEvent = (DamageEvent)event;
Permanent permanent = game.getPermanent(redirectTarget.getFirstTarget()); Permanent permanent = game.getPermanent(redirectTarget.getFirstTarget());
Ability damageSource = getSource(event.getSourceId(), game); Ability damageSource = getSource(damageEvent.getSourceId(), game);
if (permanent != null) { if (permanent != null) {
permanent.damage(event.getAmount(), damageSource.getId(), game, event.getFlag()); permanent.damage(damageEvent.getAmount(), damageSource.getId(), game, damageEvent.isPreventable(), damageEvent.isCombatDamage());
return true; return true;
} }
Player player = game.getPlayer(redirectTarget.getFirstTarget()); Player player = game.getPlayer(redirectTarget.getFirstTarget());
if (player != null) { if (player != null) {
player.damage(event.getAmount(), damageSource.getId(), game, false, event.getFlag()); player.damage(damageEvent.getAmount(), damageSource.getId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable());
return true; return true;
} }
return false; return false;

View file

@ -78,14 +78,28 @@ public class BoostControlledEffect extends ContinuousEffectImpl<BoostControlledE
return new BoostControlledEffect(this); return new BoostControlledEffect(this);
} }
@Override
public void init(Ability source, Game game) {
super.init(source, game);
if (this.affectedObjectsSet) {
for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId())) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
objects.add(perm.getId());
}
}
}
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId())) { for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId())) {
if (!this.affectedObjectsSet || objects.contains(perm.getId())) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) { if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
perm.addPower(power); perm.addPower(power);
perm.addToughness(toughness); perm.addToughness(toughness);
} }
} }
}
return true; return true;
} }

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.getId(), game, true); permanent.damage(amount, source.getId(), game, true, false);
} }
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.getId(), game, true); permanent.damage(amount, source.getId(), game, true, false);
} }
return true; return true;
} }

View file

@ -63,7 +63,7 @@ public class DamageEverythingEffect extends OneShotEffect<DamageEverythingEffect
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) {
permanent.damage(amount, source.getId(), game, true); permanent.damage(amount, source.getId(), game, true, false);
} }
for (UUID playerId: game.getPlayer(source.getControllerId()).getInRange()) { for (UUID playerId: game.getPlayer(source.getControllerId()).getInRange()) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);

View file

@ -70,7 +70,7 @@ 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.getId(), game, true); permanent.damage(multiTarget.getTargetAmount(target), source.getId(), game, true, false);
} }
else { else {
Player player = game.getPlayer(target); Player player = game.getPlayer(target);

View file

@ -73,7 +73,7 @@ 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.getId(), game, preventable); permanent.damage(amount, source.getId(), game, preventable, false);
return true; return true;
} }
Player player = game.getPlayer(source.getFirstTarget()); Player player = game.getPlayer(source.getFirstTarget());

View file

@ -59,7 +59,7 @@ public class DamageXTargetEffect extends OneShotEffect<DamageXTargetEffect> {
int amount = source.getManaCosts().getVariableCosts().get(0).getAmount(); int amount = source.getManaCosts().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.getId(), game, true); permanent.damage(amount, source.getId(), game, true, false);
return true; return true;
} }
Player player = game.getPlayer(source.getFirstTarget()); Player player = game.getPlayer(source.getFirstTarget());

View file

@ -66,8 +66,7 @@ public class GainAbilityAttachedEffect extends ContinuousEffectImpl<GainAbilityA
if (equipment != null && equipment.getAttachedTo() != null) { if (equipment != null && equipment.getAttachedTo() != null) {
Permanent creature = game.getPermanent(equipment.getAttachedTo()); Permanent creature = game.getPermanent(equipment.getAttachedTo());
if (creature != null) if (creature != null)
creature.addAbility(ability); creature.addAbility(ability.copy());
//TODO: should copy ability before adding
} }
return true; return true;
} }

View file

@ -1,33 +1,36 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.abilities.effects.common; package mage.abilities.effects.common;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.Constants.Duration; import mage.Constants.Duration;
import mage.Constants.Layer; import mage.Constants.Layer;
import mage.Constants.Outcome; import mage.Constants.Outcome;
@ -46,7 +49,7 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl<GainAbilit
protected Ability ability; protected Ability ability;
protected boolean excludeSource; protected boolean excludeSource;
protected FilterPermanent permanentFilter; protected FilterPermanent filter;
public GainAbilityControlledEffect(Ability ability, Duration duration) { public GainAbilityControlledEffect(Ability ability, Duration duration) {
this(ability, duration, new FilterPermanent()); this(ability, duration, new FilterPermanent());
@ -59,17 +62,29 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl<GainAbilit
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.filter = 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.filter = effect.filter.copy();
this.excludeSource = effect.excludeSource; this.excludeSource = effect.excludeSource;
} }
@Override
public void init(Ability source, Game game) {
super.init(source, game);
if (this.affectedObjectsSet) {
for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId())) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
objects.add(perm.getId());
}
}
}
}
@Override @Override
public GainAbilityControlledEffect copy() { public GainAbilityControlledEffect copy() {
return new GainAbilityControlledEffect(this); return new GainAbilityControlledEffect(this);
@ -77,11 +92,13 @@ 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(filter, source.getControllerId())) {
if (!this.affectedObjectsSet || objects.contains(perm.getId())) {
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;
} }
@ -90,7 +107,7 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl<GainAbilit
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(filter.getMessage()).append(" you control gain ").append(ability.getRule());
sb.append(" ").append(duration.toString()); sb.append(" ").append(duration.toString());
return sb.toString(); return sb.toString();
} }

View file

@ -64,8 +64,7 @@ public class GainAbilitySourceEffect extends ContinuousEffectImpl<GainAbilitySou
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.addAbility(ability); permanent.addAbility(ability.copy());
//TODO: should copy ability before adding
return true; return true;
} }
return false; return false;

View file

@ -64,8 +64,7 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
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.addAbility(ability); permanent.addAbility(ability.copy());
//TODO: should copy ability before adding
return true; return true;
} }
return false; return false;

View file

@ -35,6 +35,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.abilities.keyword.VigilanceAbility; import mage.abilities.keyword.VigilanceAbility;
import mage.filter.common.FilterPlaneswalkerPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -49,6 +50,8 @@ import mage.util.Copyable;
*/ */
public class Combat implements Serializable, Copyable<Combat> { public class Combat implements Serializable, Copyable<Combat> {
private static FilterPlaneswalkerPermanent filterPlaneswalker = new FilterPlaneswalkerPermanent();
protected List<CombatGroup> groups = new ArrayList<CombatGroup>(); protected List<CombatGroup> groups = new ArrayList<CombatGroup>();
protected Set<UUID> defenders = new HashSet<UUID>(); protected Set<UUID> defenders = new HashSet<UUID>();
protected UUID attackerId; protected UUID attackerId;
@ -118,15 +121,12 @@ public class Combat implements Serializable, Copyable<Combat> {
public void selectBlockers(Game game) { public void selectBlockers(Game game) {
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_BLOCKERS, attackerId, attackerId))) { if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_BLOCKERS, attackerId, attackerId))) {
for (UUID defenderId: defenders) { for (UUID defenderId: getPlayerDefenders(game)) {
//check if defender is being attacked
if (isAttacked(defenderId, game)) {
game.getPlayer(defenderId).selectBlockers(game); game.getPlayer(defenderId).selectBlockers(game);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId));
} }
} }
} }
}
public void setDefenders(Game game) { public void setDefenders(Game game) {
Set<UUID> opponents = game.getOpponents(attackerId); Set<UUID> opponents = game.getOpponents(attackerId);
@ -137,7 +137,7 @@ public class Combat implements Serializable, Copyable<Combat> {
while (true) { while (true) {
Player opponent = players.getNext(game); Player opponent = players.getNext(game);
if (opponents.contains(opponent.getId())) { if (opponents.contains(opponent.getId())) {
defenders.add(opponent.getId()); addDefender(opponent.getId(), game);
break; break;
} }
} }
@ -147,17 +147,26 @@ public class Combat implements Serializable, Copyable<Combat> {
while (true) { while (true) {
Player opponent = players.getPrevious(game); Player opponent = players.getPrevious(game);
if (opponents.contains(opponent.getId())) { if (opponents.contains(opponent.getId())) {
defenders.add(opponent.getId()); addDefender(opponent.getId(), game);
break; break;
} }
} }
break; break;
case MULITPLE: case MULITPLE:
defenders.addAll(game.getOpponents(attackerId)); for (UUID opponentId: game.getOpponents(attackerId)) {
addDefender(opponentId, game);
}
break; break;
} }
} }
private void addDefender(UUID defenderId, Game game) {
defenders.add(defenderId);
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filterPlaneswalker, defenderId)) {
defenders.add(permanent.getId());
}
}
public void declareAttacker(UUID attackerId, UUID defenderId, Game game) { public void declareAttacker(UUID attackerId, UUID defenderId, Game game) {
if (!defenders.contains(defenderId)) if (!defenders.contains(defenderId))
return; return;
@ -252,6 +261,21 @@ public class Combat implements Serializable, Copyable<Combat> {
return false; return false;
} }
private Set<UUID> getPlayerDefenders(Game game) {
Set<UUID> playerDefenders = new HashSet<UUID>();
for (CombatGroup group: groups) {
if (group.defenderIsPlaneswalker) {
Permanent permanent = game.getPermanent(group.getDefenderId());
if (permanent != null)
playerDefenders.add(permanent.getControllerId());
}
else {
playerDefenders.add(group.getDefenderId());
}
}
return playerDefenders;
}
public void damageAssignmentOrder(Game game) { public void damageAssignmentOrder(Game game) {
//TODO: set damage assignment order //TODO: set damage assignment order
} }

View file

@ -171,23 +171,23 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
if (hasTrample(attacker)) { if (hasTrample(attacker)) {
int lethalDamage = blocker.getToughness().getValue() - blocker.getDamage(); int lethalDamage = blocker.getToughness().getValue() - blocker.getDamage();
if (lethalDamage >= damage) { if (lethalDamage >= damage) {
blocker.damage(damage, attacker.getId(), game, true); blocker.damage(damage, attacker.getId(), game, true, true);
} }
else { else {
Player player = game.getPlayer(attacker.getControllerId()); Player player = game.getPlayer(attacker.getControllerId());
int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game); int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game);
blocker.damage(damageAssigned, attacker.getId(), game, true); blocker.damage(damageAssigned, attacker.getId(), game, true, true);
damage -= damageAssigned; damage -= damageAssigned;
if (damage > 0) if (damage > 0)
defenderDamage(attacker, damage, game); defenderDamage(attacker, damage, game);
} }
} }
else { else {
blocker.damage(damage, attacker.getId(), game, true); blocker.damage(damage, attacker.getId(), game, true, true);
} }
} }
if (canDamage(blocker, first)) { if (canDamage(blocker, first)) {
attacker.damage(blocker.getPower().getValue(), blocker.getId(), game, true); attacker.damage(blocker.getPower().getValue(), blocker.getId(), game, true, true);
} }
} }
} }
@ -202,12 +202,12 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
Permanent blocker = game.getPermanent(blockerId); Permanent blocker = game.getPermanent(blockerId);
int lethalDamage = blocker.getToughness().getValue() - blocker.getDamage(); int lethalDamage = blocker.getToughness().getValue() - blocker.getDamage();
if (lethalDamage >= damage) { if (lethalDamage >= damage) {
blocker.damage(damage, attacker.getId(), game, true); blocker.damage(damage, attacker.getId(), game, true, true);
damage = 0; damage = 0;
break; break;
} }
int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game); int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game);
blocker.damage(damageAssigned, attacker.getId(), game, true); blocker.damage(damageAssigned, attacker.getId(), game, true, true);
damage -= damageAssigned; damage -= damageAssigned;
} }
if (damage > 0 && hasTrample(attacker)) { if (damage > 0 && hasTrample(attacker)) {
@ -216,7 +216,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
for (UUID blockerId: blockerOrder) { for (UUID blockerId: blockerOrder) {
Permanent blocker = game.getPermanent(blockerId); Permanent blocker = game.getPermanent(blockerId);
if (canDamage(blocker, first)) { if (canDamage(blocker, first)) {
attacker.damage(blocker.getPower().getValue(), blocker.getId(), game, true); attacker.damage(blocker.getPower().getValue(), blocker.getId(), game, true, true);
} }
} }
} }
@ -226,7 +226,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
if (this.defenderIsPlaneswalker) { if (this.defenderIsPlaneswalker) {
Permanent defender = game.getPermanent(defenderId); Permanent defender = game.getPermanent(defenderId);
if (defender != null) { if (defender != null) {
defender.damage(amount, attacker.getId(), game, true); defender.damage(amount, attacker.getId(), game, true, true);
} }
} }
else { else {

View file

@ -0,0 +1,43 @@
/*
* 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.game.events;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DamageCreatureEvent extends DamageEvent {
public DamageCreatureEvent(UUID targetId, UUID sourceId, UUID playerId, int amount, boolean preventable, boolean combat) {
super(EventType.DAMAGE_CREATURE, targetId, sourceId, playerId, amount, preventable, combat);
}
}

View file

@ -0,0 +1,54 @@
/*
* 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.game.events;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public abstract class DamageEvent extends GameEvent {
protected boolean combat;
public DamageEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId, int amount, boolean preventable, boolean combat) {
super(type, targetId, sourceId, playerId, amount, preventable);
this.combat = combat;
}
public boolean isCombatDamage() {
return combat;
}
public boolean isPreventable() {
return flag;
}
}

View file

@ -0,0 +1,43 @@
/*
* 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.game.events;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DamagePlaneswalkerEvent extends DamageEvent {
public DamagePlaneswalkerEvent(UUID targetId, UUID sourceId, UUID playerId, int amount, boolean preventable, boolean combat) {
super(EventType.DAMAGE_PLANESWALKER, targetId, sourceId, playerId, amount, preventable, combat);
}
}

View file

@ -0,0 +1,43 @@
/*
* 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.game.events;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DamagePlayerEvent extends DamageEvent {
public DamagePlayerEvent(UUID targetId, UUID sourceId, UUID playerId, int amount, boolean preventable, boolean combat) {
super(EventType.DAMAGE_PLAYER, targetId, sourceId, playerId, amount, preventable, combat);
}
}

View file

@ -0,0 +1,43 @@
/*
* 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.game.events;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DamagedCreatureEvent extends DamagedEvent {
public DamagedCreatureEvent(UUID targetId, UUID sourceId, UUID playerId, int amount, boolean combat) {
super(EventType.DAMAGED_CREATURE, targetId, sourceId, playerId, amount, combat);
}
}

View file

@ -0,0 +1,54 @@
/*
* 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.game.events;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public abstract class DamagedEvent extends GameEvent {
protected boolean combat;
public DamagedEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId, int amount, boolean combat) {
super(type, targetId, sourceId, playerId, amount, false);
this.combat = combat;
}
public boolean isCombatDamage() {
return combat;
}
public boolean isPreventable() {
return flag;
}
}

View file

@ -0,0 +1,43 @@
/*
* 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.game.events;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DamagedPlaneswalkerEvent extends DamagedEvent {
public DamagedPlaneswalkerEvent(UUID targetId, UUID sourceId, UUID playerId, int amount, boolean combat) {
super(EventType.DAMAGED_PLANESWALKER, targetId, sourceId, playerId, amount, combat);
}
}

View file

@ -0,0 +1,43 @@
/*
* 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.game.events;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DamagedPlayerEvent extends DamagedEvent {
public DamagedPlayerEvent(UUID targetId, UUID sourceId, UUID playerId, int amount, boolean combat) {
super(EventType.DAMAGED_PLAYER, targetId, sourceId, playerId, amount, combat);
}
}

View file

@ -36,13 +36,13 @@ import java.util.UUID;
*/ */
public class GameEvent { public class GameEvent {
private EventType type; protected EventType type;
private UUID targetId; protected UUID targetId;
private UUID sourceId; protected UUID sourceId;
private UUID playerId; protected UUID playerId;
private int amount; protected int amount;
private boolean flag; protected boolean flag;
private String data; protected String data;
public enum EventType { public enum EventType {
@ -79,8 +79,6 @@ public class GameEvent {
DISCARDED_CARD, DISCARDED_CARD,
CYCLE_CARD, CYCLED_CARD, CYCLE_CARD, CYCLED_CARD,
DAMAGE_PLAYER, DAMAGED_PLAYER, DAMAGE_PLAYER, DAMAGED_PLAYER,
COMBAT_DAMAGE_PLAYER, COMBAT_DAMAGED_PLAYER,
NONCOMBAT_DAMAGE_PLAYER, NONCOMBAT_DAMAGED_PLAYER,
PLAYER_LIFE_CHANGE, PLAYER_LIFE_CHANGE,
GAIN_LIFE, GAINED_LIFE, GAIN_LIFE, GAINED_LIFE,
LOSE_LIFE, LOST_LIFE, LOSE_LIFE, LOST_LIFE,

View file

@ -70,7 +70,7 @@ public interface Permanent extends Card {
public boolean hasProtectionFrom(MageObject source); public boolean hasProtectionFrom(MageObject source);
public boolean hasSummoningSickness(); public boolean hasSummoningSickness();
public int getDamage(); public int getDamage();
public int damage(int damage, UUID sourceId, Game game, boolean preventable); public int damage(int damage, UUID sourceId, Game game, boolean preventable, boolean combat);
public void removeAllDamage(Game game); public void removeAllDamage(Game game);
public Counters getCounters(); public Counters getCounters();
public void addCounters(String name, int amount); public void addCounters(String name, int amount);

View file

@ -48,6 +48,10 @@ import mage.cards.CardImpl;
import mage.counters.Counter; import mage.counters.Counter;
import mage.counters.Counters; import mage.counters.Counters;
import mage.game.Game; import mage.game.Game;
import mage.game.events.DamageCreatureEvent;
import mage.game.events.DamagePlaneswalkerEvent;
import mage.game.events.DamagedCreatureEvent;
import mage.game.events.DamagedPlaneswalkerEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.players.Player; import mage.players.Player;
@ -408,14 +412,14 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
} }
@Override @Override
public int damage(int damageAmount, UUID sourceId, Game game, boolean preventable) { public int damage(int damageAmount, UUID sourceId, Game game, boolean preventable, boolean combat) {
int damageDone = 0; int damageDone = 0;
if (damageAmount > 0 && canDamage(game.getObject(sourceId))) { if (damageAmount > 0 && canDamage(game.getObject(sourceId))) {
if (cardType.contains(CardType.PLANESWALKER)) { if (cardType.contains(CardType.PLANESWALKER)) {
damageDone = damagePlaneswalker(damageAmount, sourceId, game, preventable); damageDone = damagePlaneswalker(damageAmount, sourceId, game, preventable, combat);
} }
else { else {
damageDone = damageCreature(damageAmount, sourceId, game, preventable); damageDone = damageCreature(damageAmount, sourceId, game, preventable, combat);
} }
if (damageDone > 0) { if (damageDone > 0) {
Permanent source = game.getPermanent(sourceId); Permanent source = game.getPermanent(sourceId);
@ -436,8 +440,8 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
damage = 0; damage = 0;
} }
protected int damagePlaneswalker(int damage, UUID sourceId, Game game, boolean preventable) { protected int damagePlaneswalker(int damage, UUID sourceId, Game game, boolean preventable, boolean combat) {
GameEvent event = new GameEvent(GameEvent.EventType.DAMAGE_PLANESWALKER, objectId, sourceId, controllerId, damage, preventable); GameEvent event = new DamagePlaneswalkerEvent(objectId, sourceId, controllerId, damage, preventable, combat);
if (!game.replaceEvent(event)) { if (!game.replaceEvent(event)) {
int actualDamage = event.getAmount(); int actualDamage = event.getAmount();
if (actualDamage > 0) { if (actualDamage > 0) {
@ -445,15 +449,15 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
actualDamage = this.loyalty.getValue(); actualDamage = this.loyalty.getValue();
} }
this.loyalty.boostValue(-actualDamage); this.loyalty.boostValue(-actualDamage);
game.fireEvent(GameEvent.getEvent(EventType.DAMAGED_PLANESWALKER, objectId, sourceId, controllerId, actualDamage)); game.fireEvent(new DamagedPlaneswalkerEvent(objectId, sourceId, controllerId, actualDamage, combat));
return actualDamage; return actualDamage;
} }
} }
return 0; return 0;
} }
protected int damageCreature(int damage, UUID sourceId, Game game, boolean preventable) { protected int damageCreature(int damage, UUID sourceId, Game game, boolean preventable, boolean combat) {
GameEvent event = new GameEvent(GameEvent.EventType.DAMAGE_CREATURE, objectId, sourceId, controllerId, damage, preventable); GameEvent event = new DamageCreatureEvent(objectId, sourceId, controllerId, damage, preventable, combat);
if (!game.replaceEvent(event)) { if (!game.replaceEvent(event)) {
int actualDamage = event.getAmount(); int actualDamage = event.getAmount();
if (actualDamage > 0) { if (actualDamage > 0) {
@ -461,7 +465,7 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
actualDamage = this.toughness.getValue() - this.damage; actualDamage = this.toughness.getValue() - this.damage;
} }
this.damage += actualDamage; this.damage += actualDamage;
game.fireEvent(GameEvent.getEvent(EventType.DAMAGED_CREATURE, objectId, sourceId, controllerId, actualDamage)); game.fireEvent(new DamagedCreatureEvent(objectId, sourceId, controllerId, actualDamage, combat));
return actualDamage; return actualDamage;
} }
} }

View file

@ -68,6 +68,8 @@ import mage.filter.common.FilterCreatureForAttack;
import mage.filter.common.FilterCreatureForCombat; import mage.filter.common.FilterCreatureForCombat;
import mage.game.Game; import mage.game.Game;
import mage.game.combat.CombatGroup; import mage.game.combat.CombatGroup;
import mage.game.events.DamagePlayerEvent;
import mage.game.events.DamagedPlayerEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.stack.StackAbility; import mage.game.stack.StackAbility;
@ -616,7 +618,7 @@ 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, preventable); GameEvent event = new DamagePlayerEvent(playerId, sourceId, playerId, damage, preventable, combatDamage);
if (!game.replaceEvent(event)) { if (!game.replaceEvent(event)) {
int actualDamage = event.getAmount(); int actualDamage = event.getAmount();
if (actualDamage > 0) { if (actualDamage > 0) {
@ -626,11 +628,12 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
player.gainLife(actualDamage, game); player.gainLife(actualDamage, game);
} }
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DAMAGED_PLAYER, playerId, sourceId, playerId, actualDamage)); game.fireEvent(new DamagedPlayerEvent(playerId, sourceId, playerId, actualDamage, combatDamage));
if (combatDamage) // game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DAMAGED_PLAYER, playerId, sourceId, playerId, actualDamage));
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COMBAT_DAMAGED_PLAYER, playerId, sourceId, playerId, actualDamage)); // if (combatDamage)
else // game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COMBAT_DAMAGED_PLAYER, playerId, sourceId, playerId, actualDamage));
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.NONCOMBAT_DAMAGED_PLAYER, playerId, sourceId, playerId, actualDamage)); // else
// game.fireEvent(GameEvent.getEvent(GameEvent.EventType.NONCOMBAT_DAMAGED_PLAYER, playerId, sourceId, playerId, actualDamage));
return actualDamage; return actualDamage;
} }
} }