Added using RuleModification effect and setting targetAbility for triggered abilities

This commit is contained in:
magenoxx 2014-08-18 19:42:29 +04:00
parent 265b85cb9e
commit ffa987755b
7 changed files with 45 additions and 67 deletions

View file

@ -31,22 +31,18 @@ package mage.player.ai;
import mage.MageObject;
import mage.Mana;
import mage.abilities.*;
import mage.abilities.costs.VariableCost;
import mage.abilities.costs.mana.*;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.continious.BecomesCreatureSourceEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.*;
import mage.abilities.mana.ManaAbility;
import mage.abilities.mana.ManaOptions;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.decks.Deck;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.cards.repository.*;
import mage.choices.Choice;
import mage.constants.*;
import mage.filter.FilterPermanent;
@ -77,15 +73,8 @@ import org.apache.log4j.Logger;
import java.io.IOException;
import java.io.Serializable;
import java.lang.String;
import java.util.*;
import java.util.HashSet;
import java.util.Map.Entry;
import mage.abilities.costs.VariableCost;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FlashAbility;
import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository;
/**
@ -835,7 +824,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
Set<Card> lands = new LinkedHashSet<>();
for (Card landCard: hand.getCards(new FilterLandCard(), game)) {
// remove lands that can not be played
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, landCard.getId(), landCard.getId(), playerId), game, true)) {
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, landCard.getId(), landCard.getId(), playerId), null, game, true)) {
break;
}
lands.add(landCard);
@ -903,7 +892,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (mana.enough(avail)) {
SpellAbility ability = card.getSpellAbility();
if (ability != null && ability.canActivate(playerId, game) &&
game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getSourceId(), ability.getSourceId(), playerId), game, true)) {
game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
if (card.getCardType().contains(CardType.INSTANT)
|| card.hasAbility(FlashAbility.getInstance().getId(), game)) {
playableInstant.add(card);

View file

@ -28,19 +28,16 @@
package mage.abilities;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.keyword.FlashAbility;
import mage.cards.SplitCard;
import mage.constants.AbilityType;
import mage.constants.AsThoughEffectType;
import mage.constants.SpellAbilityType;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
@ -101,7 +98,7 @@ public class SpellAbility extends ActivatedAbilityImpl {
// Check if rule modifying events prevent to cast the spell in check playable mode
if (this.isCheckPlayableMode()) {
if (game.getContinuousEffects().preventedByRuleModification(
GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, this.getId(), this.getSourceId(), playerId), game, true)) {
GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, this.getId(), this.getSourceId(), playerId), this, game, true)) {
return false;
}
}

View file

@ -62,22 +62,26 @@ public class TriggeredAbilities extends HashMap<String, TriggeredAbility> {
for (TriggeredAbility ability: this.values()) {
// for effects like when leaves battlefield use ShortLKI to check if permanent was in the correct zone before (e.g. Oblivion Ring)
if (ability.isInUseableZone(game, null, event.getType().equals(GameEvent.EventType.ZONE_CHANGE))) {
MageObject object = null;
if (!ability.getZone().equals(Zone.COMMAND) && !game.getState().getZone(ability.getSourceId()).equals(ability.getZone())) {
object = game.getShortLivingLKI(ability.getSourceId(), ability.getZone());
}
if (object == null) {
object = getMageObject(event, game, ability);
}
if (object != null) {
if (checkAbilityStillExists(ability, event, object)) {
if (object instanceof Permanent) {
ability.setControllerId(((Permanent) object).getControllerId());
}
ability.setSourceObject(object);
if (ability.checkTrigger(event, game)) {
UUID controllerId = ability.getControllerId();
ability.trigger(game, controllerId);
if (!game.getContinuousEffects().preventedByRuleModification(event, ability, game, false)) {
MageObject object = null;
if (!ability.getZone().equals(Zone.COMMAND) && !game.getState().getZone(ability.getSourceId()).equals(ability.getZone())) {
object = game.getShortLivingLKI(ability.getSourceId(), ability.getZone());
}
if (object == null) {
object = getMageObject(event, game, ability);
}
if (object != null) {
if (checkAbilityStillExists(ability, event, object)) {
if (object instanceof Permanent) {
ability.setControllerId(((Permanent) object).getControllerId());
}
ability.setSourceObject(object);
if (ability.checkTrigger(event, game)) {
UUID controllerId = ability.getControllerId();
ability.trigger(game, controllerId);
}
}
}
}

View file

@ -596,21 +596,23 @@ public class ContinuousEffects implements Serializable {
}
/**
* Checks if an event wont't happen because of an rule modifying effect
* Checks if an event won't happen because of an rule modifying effect
*
* @param event
* @param targetAbility ability the event is attached to. can be null.
* @param game
* @param checkPlayableMode true if the event does not really happen but it#s checked if the event would be replaced
* @return
*/
public boolean preventedByRuleModification(GameEvent event, Game game, boolean checkPlayableMode) {
public boolean preventedByRuleModification(GameEvent event, Ability targetAbility, Game game, boolean checkPlayableMode) {
for (ContinuousRuleModifiyingEffect effect: continuousRuleModifyingEffects) {
for (Ability ability : continuousRuleModifyingEffects.getAbility(effect.getId())) {
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, false)) {
for (Ability sourceAbility : continuousRuleModifyingEffects.getAbility(effect.getId())) {
if (!(sourceAbility instanceof StaticAbility) || sourceAbility.isInUseableZone(game, null, false)) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
if (effect.applies(event, ability, game)) {
effect.setValue("targetAbility", targetAbility);
if (effect.applies(event, sourceAbility, game)) {
if (!checkPlayableMode) {
String message = effect.getInfoMessage(ability, event, game);
String message = effect.getInfoMessage(sourceAbility, event, game);
if (message != null && !message.isEmpty()) {
if (effect.sendMessageToUser()) {
Player player = game.getPlayer(event.getPlayerId());

View file

@ -28,25 +28,8 @@
package mage.game;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Abilities;
import mage.abilities.AbilitiesImpl;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.DelayedTriggeredAbilities;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.Mode;
import mage.abilities.SpecialActions;
import mage.abilities.StaticAbility;
import mage.abilities.TriggeredAbilities;
import mage.abilities.TriggeredAbility;
import mage.abilities.*;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffects;
import mage.abilities.effects.Effect;
@ -73,6 +56,9 @@ import mage.util.Copyable;
import mage.watchers.Watcher;
import mage.watchers.Watchers;
import java.io.Serializable;
import java.util.*;
/**
*
* @author BetaSteward_at_googlemail.com
@ -537,7 +523,7 @@ public class GameState implements Serializable, Copyable<GameState> {
}
public boolean replaceEvent(GameEvent event, Game game) {
if (effects.preventedByRuleModification(event, game, false)) {
if (effects.preventedByRuleModification(event, null, game, false)) {
return true;
}
return effects.replaceEvent(event, game);

View file

@ -753,7 +753,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
}
// needed to get the correct possible targets if target rule modification effects are active
// e.g. Fiendslayer Paladin tried to target with Ultimate Price
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(EventType.TARGET, this.getId(), source.getId(), sourceControllerId), game, true)) {
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(EventType.TARGET, this.getId(), source.getId(), sourceControllerId), null, game, true)) {
return false;
}
}

View file

@ -1929,7 +1929,7 @@ public abstract class PlayerImpl implements Player, Serializable {
for (Card card : hand.getUniqueCards(game)) {
for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) {
if (ability instanceof PlayLandAbility) {
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), game, true)) {
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
break;
}
}
@ -2029,7 +2029,7 @@ public abstract class PlayerImpl implements Player, Serializable {
for (Card card : hand.getCards(game)) {
for (ActivatedAbility ability : card.getAbilities().getPlayableAbilities(Zone.HAND)) {
if (ability instanceof PlayLandAbility) {
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), game, true)) {
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
break;
}
}