Started reworking handling prevention effects.

This commit is contained in:
LevelX2 2014-04-20 09:49:29 +02:00
parent 465da61626
commit c40fa87674
8 changed files with 93 additions and 75 deletions

View file

@ -47,7 +47,7 @@ public class PreventAllNonCombatDamageToEffect extends PreventionEffectImpl<Prev
protected FilterInPlay filter;
public PreventAllNonCombatDamageToEffect(Duration duration, FilterInPlay filter) {
super(duration);
super(duration, Integer.MAX_VALUE);
this.filter = filter;
staticText = "Prevent all non combat damage that would be dealt to " + filter.getMessage() + " " + duration.toString();
}
@ -62,35 +62,21 @@ public class PreventAllNonCombatDamageToEffect extends PreventionEffectImpl<Prev
return new PreventAllNonCombatDamageToEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
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(), false);
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)
&& !((DamageEvent) event).isCombatDamage()) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) {
if (filter.match(permanent, source.getSourceId(), source.getControllerId(), game))
if (filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) {
return true;
}
}
else {
Player player = game.getPlayer(event.getTargetId());
if (player != null && filter.match(player, source.getSourceId(), source.getControllerId(), game))
if (player != null && filter.match(player, source.getSourceId(), source.getControllerId(), game)) {
return true;
}
}
}
return false;

View file

@ -39,16 +39,42 @@ import mage.game.events.GameEvent;
/**
*
* @author BetaSteward_at_googlemail.com
* @param <T>
*/
public abstract class PreventionEffectImpl<T extends PreventionEffectImpl<T>> extends ReplacementEffectImpl<T> implements PreventionEffect<T> {
private Integer amountToPrevent;
public PreventionEffectImpl(Duration duration) {
this(duration, Integer.MAX_VALUE);
}
public PreventionEffectImpl(Duration duration, int amountToPrevent) {
super(duration, Outcome.PreventDamage);
this.effectType = EffectType.PREVENTION;
this.amountToPrevent = amountToPrevent;
}
public PreventionEffectImpl(final PreventionEffectImpl effect) {
super(effect);
this.amountToPrevent = effect.amountToPrevent;
}
@Override
public boolean apply(Game game, Ability source) {
// not used for prevention effect
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
game.preventDamage(event, source, game, amountToPrevent);
if (amountToPrevent == 0) {
this.used = true;
}
// damage amount is reduced or set to 0 so replace of damage event is never neccessary
return false;
}
@Override

View file

@ -28,6 +28,7 @@
package mage.abilities.effects.common;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectImpl;
import mage.constants.Duration;
@ -68,17 +69,6 @@ public class PreventAllDamageByAttachedEffect extends PreventionEffectImpl<Preve
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), damage));
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {

View file

@ -27,6 +27,7 @@
*/
package mage.abilities.effects.common;
import mage.MageObject;
import mage.constants.Duration;
import mage.abilities.Ability;
import mage.abilities.Mode;
@ -44,7 +45,7 @@ import mage.game.permanent.Permanent;
public class PreventAllDamageEffect extends PreventionEffectImpl<PreventAllDamageEffect> {
private FilterPermanent filter;
private boolean onlyCombat;
private final boolean onlyCombat;
public PreventAllDamageEffect(FilterPermanent filter, Duration duration, boolean onlyCombat) {
super(duration);
@ -52,7 +53,7 @@ public class PreventAllDamageEffect extends PreventionEffectImpl<PreventAllDamag
this.onlyCombat = onlyCombat;
}
public PreventAllDamageEffect(Duration duration, boolean onlyCombat) {
public PreventAllDamageEffect(Duration duration, boolean onlyCombat) {
super(duration);
this.onlyCombat = onlyCombat;
}
@ -75,29 +76,6 @@ public class PreventAllDamageEffect extends PreventionEffectImpl<PreventAllDamag
return new PreventAllDamageEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
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(), false);
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
Permanent permanent = game.getPermanent(event.getSourceId());
StringBuilder sourceName = new StringBuilder();
if (permanent != null) {
sourceName.append(" from ").append(permanent.getName());
}
sourceName.insert(0, "Damage").append(" has been prevented: ").append(damage);
event.setAmount(0);
game.informPlayers(sourceName.toString());
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) {

View file

@ -28,9 +28,9 @@
package mage.abilities.effects.common;
import mage.constants.Duration;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectImpl;
import mage.constants.Duration;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -41,7 +41,7 @@ import mage.game.events.GameEvent;
public class PreventAllDamageSourceEffect extends PreventionEffectImpl<PreventAllDamageSourceEffect> {
public PreventAllDamageSourceEffect(Duration duration) {
super(duration);
super(duration, Integer.MAX_VALUE);
staticText = "Prevent all damage that would be dealt to {this} " + duration.toString();
}
@ -54,22 +54,6 @@ public class PreventAllDamageSourceEffect extends PreventionEffectImpl<PreventAl
return new PreventAllDamageSourceEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
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(), false);
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {

View file

@ -55,7 +55,7 @@ public enum CardRepository {
private static final String JDBC_URL = "jdbc:sqlite:db/cards.db";
private static final String VERSION_ENTITY_NAME = "card";
private static final long CARD_DB_VERSION = 27;
private static final long CARD_DB_VERSION = 28;
private final Random random = new Random();
private Dao<CardInfo, Object> cardDao;

View file

@ -181,6 +181,27 @@ public interface Game extends MageItem, Serializable {
void addSimultaneousEvent(GameEvent event);
boolean replaceEvent(GameEvent event);
/**
* Creates and fires an damage prevention event
*
* @param damageEvent damage event that will be replaced (instanceof check will be done)
* @param source ability that's the source of the prevention effect
* @param game
* @param amountToPrevent
* @return true prevention was successfull / false prevention was replaced
*/
boolean preventDamage(GameEvent damageEvent, Ability source, Game game, Integer amountToPrevent);
/**
* Creates and fires an damage prevention event
*
* @param event damage event that will be replaced (instanceof check will be done)
* @param source ability that's the source of the prevention effect
* @param game
* @param preventAllDamage true if there is no limit to the damage that can be prevented
* @return true prevention was successfull / false prevention was replaced
*/
boolean preventDamage(GameEvent event, Ability source, Game game, boolean preventAllDamage);
//game play methods
void start(UUID choosingPlayerId);
void start(UUID choosingPlayerId, GameOptions options);

View file

@ -88,6 +88,7 @@ import mage.game.combat.Combat;
import mage.game.command.CommandObject;
import mage.game.command.Commander;
import mage.game.command.Emblem;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.Listener;
import mage.game.events.PlayerQueryEvent;
@ -1818,6 +1819,38 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
return state.replaceEvent(event, this);
}
@Override
public boolean preventDamage(GameEvent event, Ability source, Game game, boolean preventAllDamage) {
return preventDamage(event, source, game, Integer.MAX_VALUE);
}
@Override
public boolean preventDamage(GameEvent event, Ability source, Game game, Integer amountToPrevent) {
if (!(event instanceof DamageEvent)) {
return false;
}
DamageEvent damageEvent = (DamageEvent) event;
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, damageEvent.getTargetId(), damageEvent.getSourceId(), source.getControllerId(), damageEvent.getAmount(), false);
if (!game.replaceEvent(preventEvent)) {
int preventedDamage = damageEvent.getAmount();
MageObject damageSource = game.getObject(damageEvent.getSourceId());
MageObject preventionSource = game.getObject(source.getSourceId());
if (damageSource != null && preventionSource != null) {
StringBuilder message = new StringBuilder(Integer.toString(preventedDamage)).append(" damage from ");
message.append(damageSource.getName()).append(" prevented ");
message.append("(").append(preventionSource).append(")");
game.informPlayers(message.toString());
}
damageEvent.setAmount(0);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, damageEvent.getTargetId(), source.getSourceId(), source.getControllerId(), preventedDamage));
return true;
}
return false;
}
protected void removeCreaturesFromCombat() {
//20091005 - 511.3
getCombat().endCombat(this);
@ -1831,7 +1864,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
//initialize transient objects during deserialization
in.defaultReadObject();
savedStates = new Stack<Integer>();
savedStates = new Stack<>();
tableEventSource = new TableEventSource();
playerQueryEventSource = new PlayerQueryEventSource();
gameStates = new GameStates();