mirror of
https://github.com/magefree/mage.git
synced 2026-01-24 04:09:54 -08:00
fixed issue 44 and made triggered abilities extendable
This commit is contained in:
parent
139faeb7a5
commit
7efd24464c
54 changed files with 115 additions and 80 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue