fixed issue 44 and made triggered abilities extendable

This commit is contained in:
BetaSteward 2010-12-08 04:27:28 +00:00
parent 139faeb7a5
commit 7efd24464c
54 changed files with 115 additions and 80 deletions

View file

@ -48,8 +48,10 @@ import mage.game.events.GameEvent;
Iterator<DelayedTriggeredAbility> it = this.iterator();
while (it.hasNext()) {
DelayedTriggeredAbility ability = it.next();
if (ability.checkTrigger(event, game))
if (ability.checkTrigger(event, game)) {
ability.trigger(game, ability.controllerId);
it.remove();
}
}
}

View file

@ -52,7 +52,6 @@ public class AttacksTriggeredAbility extends TriggeredAbilityImpl<AttacksTrigger
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == EventType.ATTACKER_DECLARED && event.getSourceId().equals(this.getSourceId()) ) {
trigger(game, this.controllerId);
return true;
}
return false;

View file

@ -52,7 +52,6 @@ public class BlocksTriggeredAbility extends TriggeredAbilityImpl<BlocksTriggered
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == EventType.BLOCKER_DECLARED && event.getSourceId().equals(this.getSourceId()) ) {
trigger(game, this.controllerId);
return true;
}
return false;

View file

@ -60,7 +60,6 @@ public class DealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility
if (event.getType() == EventType.DAMAGED_PLAYER && event.getSourceId().equals(this.sourceId)) {
this.addTarget(new TargetPlayer());
this.targets.get(0).add(event.getPlayerId(), game);
trigger(game, this.controllerId);
return true;
}
return false;

View file

@ -57,7 +57,6 @@ public class LandfallAbility extends TriggeredAbilityImpl<LandfallAbility> {
if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone() == Zone.BATTLEFIELD) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && permanent.getCardType().contains(CardType.LAND) && permanent.getControllerId().equals(this.controllerId)) {
trigger(game, this.controllerId);
return true;
}
}

View file

@ -75,7 +75,6 @@ public class OnEventTriggeredAbility extends TriggeredAbilityImpl<OnEventTrigger
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == eventType) {
if (allPlayers || event.getPlayerId().equals(this.controllerId) ) {
trigger(game, this.controllerId);
return true;
}
}

View file

@ -56,7 +56,6 @@ public class SimpleTriggeredAbility extends TriggeredAbilityImpl<SimpleTriggered
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == eventType) {
trigger(game, this.controllerId);
return true;
}
return false;

View file

@ -72,7 +72,6 @@ public class ZoneChangeTriggeredAbility<T extends ZoneChangeTriggeredAbility<T>>
if (event.getType() == EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
if ((fromZone == null || zEvent.getFromZone() == fromZone) && (toZone == null || zEvent.getToZone() == toZone)) {
trigger(game, this.controllerId);
return true;
}
}

View file

@ -45,6 +45,7 @@ public interface ContinuousEffect<T extends ContinuousEffect<T>> extends Effect<
public Duration getDuration();
public Date getTimestamp();
public void setTimestamp();
public void newId();
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game);
public boolean hasLayer(Layer layer);
public void init(Ability source, Game game);

View file

@ -104,6 +104,11 @@ public abstract class ContinuousEffectImpl<T extends ContinuousEffectImpl<T>> ex
this.timestamp = new Date();
}
@Override
public void newId() {
this.id = UUID.randomUUID();
}
@Override
public boolean hasLayer(Layer layer) {
return this.layer == layer;

View file

@ -384,26 +384,30 @@ public class ContinuousEffects implements Serializable {
case REPLACEMENT:
ReplacementEffect newReplacementEffect = (ReplacementEffect)effect.copy();
newReplacementEffect.setTimestamp();
newReplacementEffect.newId();
replacementEffects.add(newReplacementEffect);
abilityMap.put(newReplacementEffect.getId(), source);
abilityMap.put(newReplacementEffect.getId(), source.copy());
break;
case PREVENTION:
PreventionEffect newPreventionEffect = (PreventionEffect)effect.copy();
newPreventionEffect.setTimestamp();
newPreventionEffect.newId();
preventionEffects.add(newPreventionEffect);
abilityMap.put(newPreventionEffect.getId(), source);
abilityMap.put(newPreventionEffect.getId(), source.copy());
break;
case ASTHOUGH:
AsThoughEffect newAsThoughEffect = (AsThoughEffect)effect.copy();
newAsThoughEffect.setTimestamp();
newAsThoughEffect.newId();
asThoughEffects.add(newAsThoughEffect);
abilityMap.put(newAsThoughEffect.getId(), source);
abilityMap.put(newAsThoughEffect.getId(), source.copy());
break;
default:
ContinuousEffect newEffect = (ContinuousEffect)effect.copy();
newEffect.setTimestamp();
newEffect.newId();
layeredEffects.add(newEffect);
abilityMap.put(newEffect.getId(), source);
abilityMap.put(newEffect.getId(), source.copy());
break;
}
}

View file

@ -39,7 +39,7 @@ import mage.abilities.Ability;
*/
public abstract class EffectImpl<T extends Effect<T>> implements Effect<T> {
protected final UUID id;
protected UUID id;
protected final Outcome outcome;
protected EffectType effectType;

View file

@ -63,7 +63,6 @@ public class CascadeAbility extends TriggeredAbilityImpl<CascadeAbility> {
if (event.getType() == EventType.SPELL_CAST) {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && spell.getSourceId().equals(this.getSourceId())) {
trigger(game, this.controllerId);
return true;
}
}

View file

@ -63,7 +63,6 @@ public class ExaltedAbility extends TriggeredAbilityImpl<ExaltedAbility> {
TargetCreaturePermanent target = new TargetCreaturePermanent();
this.addTarget(target);
this.getTargets().get(0).add(game.getCombat().getAttackers().get(0),game);
trigger(game, controllerId);
return true;
}
}

View file

@ -101,7 +101,6 @@ class UnearthDelayedTriggeredAbility extends DelayedTriggeredAbility<UnearthDela
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == EventType.END_TURN_STEP_PRE && event.getPlayerId().equals(this.controllerId)) {
trigger(game, this.controllerId);
return true;
}
return false;

View file

@ -171,7 +171,9 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
@Override
public void checkTriggers(Zone zone, GameEvent event, Game game) {
for (TriggeredAbility ability: abilities.getTriggeredAbilities(zone)) {
ability.checkTrigger(event, game);
if (ability.checkTrigger(event, game)) {
ability.trigger(game, ownerId);
}
}
}

View file

@ -73,6 +73,13 @@ public class Battlefield implements Serializable {
field.clear();
}
/**
* Returns a count of all {@link Permanent} that match the filter.
* This method ignores the range of influence.
*
* @param filter
* @return count
*/
public int countAll(FilterPermanent filter) {
int count = 0;
for (Permanent permanent: field.values()) {
@ -83,6 +90,14 @@ public class Battlefield implements Serializable {
return count;
}
/**
* Returns a count of all {@link Permanent} that match the filter and are controlled by controllerId.
* This method ignores the range of influence.
*
* @param filter
* @param controllerId
* @return count
*/
public int countAll(FilterPermanent filter, UUID controllerId) {
int count = 0;
for (Permanent permanent: field.values()) {
@ -93,7 +108,15 @@ public class Battlefield implements Serializable {
return count;
}
/**
* Returns a count of all {@link Permanent} that are within the range of influence of the specified player id
* and that match the supplied filter.
*
* @param filter
* @param sourcePlayerId
* @param game
* @return count
*/
public int count(FilterPermanent filter, UUID sourcePlayerId, Game game) {
int count = 0;
if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) {
@ -171,11 +194,11 @@ public class Battlefield implements Serializable {
}
/**
* Returns all Permanents on the battlefield that are controlled by the specified
* Returns all {@link Permanent} on the battlefield that are controlled by the specified
* player id. The method ignores the range of influence.
*
* @param controllerId
* @return a list of Permanent
* @return a list of {@link Permanent}
* @see Permanent
*/
public List<Permanent> getAllActivePermanents(UUID controllerId) {
@ -188,11 +211,11 @@ public class Battlefield implements Serializable {
}
/**
* Returns all Permanents on the battlefield that match the specified CardType.
* Returns all {@link Permanent} on the battlefield that match the specified {@link CardType}.
* This method ignores the range of influence.
*
* @param type
* @return a list of Permanent
* @return a list of {@link Permanent}
* @see Permanent
*/
public List<Permanent> getAllActivePermanents(CardType type) {
@ -205,11 +228,11 @@ public class Battlefield implements Serializable {
}
/**
* Returns all Permanents on the battlefield that match the supplied filter.
* Returns all {@link Permanent} on the battlefield that match the supplied filter.
* This method ignores the range of influence.
*
* @param filter
* @return a list of Permanent
* @return a list of {@link Permanent}
* @see Permanent
*/
public List<Permanent> getAllActivePermanents(FilterPermanent filter) {
@ -222,12 +245,12 @@ public class Battlefield implements Serializable {
}
/**
* Returns all Permanents that match the filter and are controlled by controllerId.
* Returns all {@link Permanent} that match the filter and are controlled by controllerId.
* This method ignores the range of influence.
*
* @param filter
* @param controllerId
* @return a list of Permanent
* @return a list of {@link Permanent}
* @see Permanent
*/
public List<Permanent> getAllActivePermanents(FilterPermanent filter, UUID controllerId) {
@ -240,13 +263,13 @@ public class Battlefield implements Serializable {
}
/**
* Returns all Permanents that are within the range of influence of the specified player id
* Returns all {@link Permanent} that are within the range of influence of the specified player id
* and that match the supplied filter.
*
* @param filter
* @param sourcePlayerId
* @param game
* @return a list of Permanent
* @return a list of {@link Permanent}
* @see Permanent
*/
public List<Permanent> getActivePermanents(FilterPermanent filter, UUID sourcePlayerId, Game game) {
@ -268,11 +291,11 @@ public class Battlefield implements Serializable {
}
/**
* Returns all Permanents that are within the range of influence of the specified player id.
* Returns all {@link Permanent} that are within the range of influence of the specified player id.
*
* @param sourcePlayerId
* @param game
* @return a list of Permanent
* @return a list of {@link Permanent}
* @see Permanent
*/
public List<Permanent> getActivePermanents(UUID sourcePlayerId, Game game) {

View file

@ -121,18 +121,25 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
// card abilities will get triggered later when the card hits the new zone
Card card = game.getCard(objectId).copy();
for (TriggeredAbility ability: abilities.getTriggeredAbilities(event.getFromZone())) {
if (!card.getAbilities().containsKey(ability.getId()))
ability.checkTrigger(event, game);
else if (ability instanceof ZoneChangeTriggeredAbility && event.getFromZone() == Zone.BATTLEFIELD) {
if (!card.getAbilities().containsKey(ability.getId())) {
if (ability.checkTrigger(event, game)) {
ability.trigger(game, controllerId);
}
} else if (ability instanceof ZoneChangeTriggeredAbility && event.getFromZone() == Zone.BATTLEFIELD) {
ZoneChangeTriggeredAbility zcAbility = (ZoneChangeTriggeredAbility)ability;
if (zcAbility.getToZone() == null) {
ability.checkTrigger(event, game);
if (ability.checkTrigger(event, game)) {
ability.trigger(game, controllerId);
}
}
}
}
for (TriggeredAbility ability: abilities.getTriggeredAbilities(event.getToZone())) {
if (!card.getAbilities().containsKey(ability.getId()))
ability.checkTrigger(event, game);
if (!card.getAbilities().containsKey(ability.getId())) {
if (ability.checkTrigger(event, game)) {
ability.trigger(game, controllerId);
}
}
}
}

View file

@ -180,7 +180,9 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
if (event.getType() == EventType.BEGINNING_PHASE_PRE && game.getActivePlayerId().equals(controllerId))
this.controlledFromStartOfTurn = true;
for (TriggeredAbility ability: abilities.getTriggeredAbilities(Zone.BATTLEFIELD)) {
ability.checkTrigger(event, game);
if (ability.checkTrigger(event, game)) {
ability.trigger(game, controllerId);
}
}
}