mirror of
https://github.com/correl/mage.git
synced 2025-04-11 17:00:08 -09:00
fixes + optimizations + allow games to be paused and resumed
This commit is contained in:
parent
8fd03a5bb5
commit
7c69bc6f30
44 changed files with 430 additions and 331 deletions
Mage.Server.Plugins
Mage.Player.AI.MA/src/mage/player/ai
Mage.Player.AI/src/main/java/mage/player/ai
Mage.Player.AIMinimax/src/mage/player/ai
Mage.Server/plugins
Mage.Sets/src/mage/sets
Mage/src/mage
MageObjectImpl.java
abilities
cards
choices
filter
game
players
target
|
@ -95,15 +95,9 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
this.currentScore = player.currentScore;
|
||||
if (player.combat != null)
|
||||
this.combat = player.combat.copy();
|
||||
for (Ability ability: player.actions) {
|
||||
actions.add(ability);
|
||||
}
|
||||
for (UUID targetId: player.targets) {
|
||||
targets.add(targetId);
|
||||
}
|
||||
for (String choice: player.choices) {
|
||||
choices.add(choice);
|
||||
}
|
||||
this.actions.addAll(player.actions);
|
||||
this.targets.addAll(player.targets);
|
||||
this.choices.addAll(player.choices);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -773,7 +767,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
Game sim = game.copy();
|
||||
|
||||
for (Player copyPlayer: sim.getState().getPlayers().values()) {
|
||||
Player origPlayer = game.getState().getPlayers().get(copyPlayer.getId());
|
||||
Player origPlayer = game.getState().getPlayers().get(copyPlayer.getId()).copy();
|
||||
SimulatedPlayer2 newPlayer = new SimulatedPlayer2(copyPlayer.getId(), copyPlayer.getId().equals(playerId), suggested);
|
||||
newPlayer.restore(origPlayer);
|
||||
sim.getState().getPlayers().put(copyPlayer.getId(), newPlayer);
|
||||
|
|
|
@ -180,7 +180,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
|||
}
|
||||
if (target instanceof TargetControlledPermanent) {
|
||||
List<Permanent> targets;
|
||||
targets = threats(playerId, ((TargetControlledPermanent)target).getFilter(), game);
|
||||
targets = threats(playerId, ((TargetControlledPermanent)target).getFilter(), game, target.getTargets());
|
||||
if (!outcome.isGood())
|
||||
Collections.reverse(targets);
|
||||
for (Permanent permanent: targets) {
|
||||
|
@ -193,10 +193,10 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
|||
if (target instanceof TargetPermanent) {
|
||||
List<Permanent> targets;
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(playerId, ((TargetPermanent)target).getFilter(), game);
|
||||
targets = threats(playerId, ((TargetPermanent)target).getFilter(), game, target.getTargets());
|
||||
}
|
||||
else {
|
||||
targets = threats(opponentId, ((TargetPermanent)target).getFilter(), game);
|
||||
targets = threats(opponentId, ((TargetPermanent)target).getFilter(), game, target.getTargets());
|
||||
}
|
||||
for (Permanent permanent: targets) {
|
||||
if (((TargetPermanent)target).canTarget(playerId, permanent.getId(), null, game) && !target.getTargets().contains(permanent.getId())) {
|
||||
|
@ -268,7 +268,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
|||
}
|
||||
if (target instanceof TargetControlledPermanent) {
|
||||
List<Permanent> targets;
|
||||
targets = threats(playerId, ((TargetControlledPermanent)target).getFilter(), game);
|
||||
targets = threats(playerId, ((TargetControlledPermanent)target).getFilter(), game, target.getTargets());
|
||||
if (!outcome.isGood())
|
||||
Collections.reverse(targets);
|
||||
for (Permanent permanent: targets) {
|
||||
|
@ -282,10 +282,10 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
|||
if (target instanceof TargetPermanent) {
|
||||
List<Permanent> targets;
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(playerId, ((TargetPermanent)target).getFilter(), game);
|
||||
targets = threats(playerId, ((TargetPermanent)target).getFilter(), game, target.getTargets());
|
||||
}
|
||||
else {
|
||||
targets = threats(opponentId, ((TargetPermanent)target).getFilter(), game);
|
||||
targets = threats(opponentId, ((TargetPermanent)target).getFilter(), game, target.getTargets());
|
||||
}
|
||||
for (Permanent permanent: targets) {
|
||||
if (((TargetPermanent)target).canTarget(playerId, permanent.getId(), source, game)) {
|
||||
|
@ -299,10 +299,10 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
|||
List<Permanent> targets;
|
||||
TargetCreatureOrPlayer t = ((TargetCreatureOrPlayer)target);
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(playerId, ((FilterCreatureOrPlayer)t.getFilter()).getCreatureFilter(), game);
|
||||
targets = threats(playerId, ((FilterCreatureOrPlayer)t.getFilter()).getCreatureFilter(), game, target.getTargets());
|
||||
}
|
||||
else {
|
||||
targets = threats(opponentId, ((FilterCreatureOrPlayer)t.getFilter()).getCreatureFilter(), game);
|
||||
targets = threats(opponentId, ((FilterCreatureOrPlayer)t.getFilter()).getCreatureFilter(), game, target.getTargets());
|
||||
}
|
||||
for (Permanent permanent: targets) {
|
||||
List<UUID> alreadyTargetted = target.getTargets();
|
||||
|
@ -395,10 +395,10 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
|||
}
|
||||
List<Permanent> targets;
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(playerId, new FilterCreaturePermanent(), game);
|
||||
targets = threats(playerId, new FilterCreaturePermanent(), game, target.getTargets());
|
||||
}
|
||||
else {
|
||||
targets = threats(opponentId, new FilterCreaturePermanent(), game);
|
||||
targets = threats(opponentId, new FilterCreaturePermanent(), game, target.getTargets());
|
||||
}
|
||||
for (Permanent permanent: targets) {
|
||||
if (target.canTarget(permanent.getId(), source, game)) {
|
||||
|
@ -1301,8 +1301,14 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
|||
return worst;
|
||||
}
|
||||
|
||||
protected List<Permanent> threats(UUID playerId, FilterPermanent filter, Game game) {
|
||||
protected List<Permanent> threats(UUID playerId, FilterPermanent filter, Game game, List<UUID> targets) {
|
||||
List<Permanent> threats = game.getBattlefield().getAllActivePermanents(filter, playerId);
|
||||
Iterator<Permanent> it = threats.iterator();
|
||||
while (it.hasNext()) { // remove permanents already targetted
|
||||
Permanent test = it.next();
|
||||
if (targets.contains(test.getId()))
|
||||
it.remove();
|
||||
}
|
||||
Collections.sort(threats, new PermanentComparator(game));
|
||||
return threats;
|
||||
}
|
||||
|
|
|
@ -120,15 +120,9 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
this.currentScore = player.currentScore;
|
||||
if (player.combat != null)
|
||||
this.combat = player.combat.copy();
|
||||
for (Ability ability: player.actions) {
|
||||
actions.add(ability);
|
||||
}
|
||||
for (UUID targetId: player.targets) {
|
||||
targets.add(targetId);
|
||||
}
|
||||
for (String choice: player.choices) {
|
||||
choices.add(choice);
|
||||
}
|
||||
this.actions.addAll(player.actions);
|
||||
this.targets.addAll(player.targets);
|
||||
this.choices.addAll(player.choices);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -731,7 +725,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
Game sim = game.copy();
|
||||
|
||||
for (Player copyPlayer: sim.getState().getPlayers().values()) {
|
||||
Player origPlayer = game.getState().getPlayers().get(copyPlayer.getId());
|
||||
Player origPlayer = game.getState().getPlayers().get(copyPlayer.getId()).copy();
|
||||
SimulatedPlayer newPlayer = new SimulatedPlayer(copyPlayer.getId(), copyPlayer.getId().equals(playerId), maxDepth);
|
||||
newPlayer.restore(origPlayer);
|
||||
sim.getState().getPlayers().put(copyPlayer.getId(), newPlayer);
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -113,8 +113,8 @@ public class Sets extends HashMap<String, ExpansionSet> {
|
|||
|
||||
private void addSet(ExpansionSet set) {
|
||||
this.put(set.getCode(), set);
|
||||
cards.addAll(set.getCards());
|
||||
for (Card card: set.getCards()) {
|
||||
cards.add(card);
|
||||
names.add(card.getName());
|
||||
if (card.getCardType().contains(CardType.CREATURE)) {
|
||||
for (String type : card.getSubtype()) {
|
||||
|
|
|
@ -82,15 +82,9 @@ public abstract class MageObjectImpl<T extends MageObjectImpl<T>> implements Mag
|
|||
power = object.power.copy();
|
||||
toughness = object.toughness.copy();
|
||||
abilities = object.abilities.copy();
|
||||
for (CardType cType: object.cardType) {
|
||||
cardType.add(cType);
|
||||
}
|
||||
for (String subType: object.subtype) {
|
||||
this.subtype.add(subType);
|
||||
}
|
||||
for (String superType: object.supertype) {
|
||||
this.supertype.add(superType);
|
||||
}
|
||||
this.cardType.addAll(object.cardType);
|
||||
this.subtype.addAll(object.subtype);
|
||||
this.supertype.addAll(object.supertype);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,6 +34,7 @@ import mage.Constants.TimingRule;
|
|||
import mage.Constants.Zone;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.PhyrexianManaCost;
|
||||
|
@ -100,8 +101,8 @@ public abstract class ActivatedAbilityImpl<T extends ActivatedAbilityImpl<T>> ex
|
|||
if (cost != null) {
|
||||
if (cost instanceof PhyrexianManaCost) {
|
||||
this.addManaCost((PhyrexianManaCost)cost);
|
||||
} else if (cost instanceof ManaCostsImpl) {
|
||||
this.addManaCost((ManaCostsImpl) cost);
|
||||
} else if (cost instanceof ManaCost) {
|
||||
this.addManaCost((ManaCost) cost);
|
||||
} else {
|
||||
this.addCost(cost);
|
||||
}
|
||||
|
@ -164,7 +165,7 @@ public abstract class ActivatedAbilityImpl<T extends ActivatedAbilityImpl<T>> ex
|
|||
return true;
|
||||
else {
|
||||
Card card = (Card)game.getObject(this.sourceId);
|
||||
if (card != null && game.getZone(this.sourceId) != Zone.BATTLEFIELD)
|
||||
if (card != null && game.getState().getZone(this.sourceId) != Zone.BATTLEFIELD)
|
||||
return card.getOwnerId().equals(playerId);
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -53,7 +53,7 @@ public class FlashbackCost extends AlternativeCostImpl<FlashbackCost> {
|
|||
|
||||
@Override
|
||||
public boolean isAvailable(Game game, Ability source) {
|
||||
Constants.Zone zone = game.getZone(source.getSourceId());
|
||||
Constants.Zone zone = game.getState().getZone(source.getSourceId());
|
||||
if (zone != null) {
|
||||
return zone.equals(Constants.Zone.GRAVEYARD);
|
||||
}
|
||||
|
|
|
@ -77,9 +77,7 @@ public abstract class ContinuousEffectImpl<T extends ContinuousEffectImpl<T>> ex
|
|||
this.timestamp = new Date(effect.timestamp.getTime());
|
||||
this.used = effect.used;
|
||||
this.affectedObjectsSet = effect.affectedObjectsSet;
|
||||
for (UUID objectId: effect.objects) {
|
||||
this.objects.add(objectId);
|
||||
}
|
||||
this.objects.addAll(effect.objects);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -60,13 +60,13 @@ import mage.players.Player;
|
|||
public class ContinuousEffects implements Serializable {
|
||||
|
||||
//transient Continuous effects
|
||||
private final List<ContinuousEffect> layeredEffects = new ArrayList<ContinuousEffect>();
|
||||
private final List<ReplacementEffect> replacementEffects = new ArrayList<ReplacementEffect>();
|
||||
private final List<PreventionEffect> preventionEffects = new ArrayList<PreventionEffect>();
|
||||
private final List<RequirementEffect> requirementEffects = new ArrayList<RequirementEffect>();
|
||||
private final List<RestrictionEffect> restrictionEffects = new ArrayList<RestrictionEffect>();
|
||||
private final List<AsThoughEffect> asThoughEffects = new ArrayList<AsThoughEffect>();
|
||||
private final List<CostModificationEffect> costModificationEffects = new ArrayList<CostModificationEffect>();
|
||||
private final ArrayList<ContinuousEffect> layeredEffects = new ArrayList<ContinuousEffect>();
|
||||
private final ArrayList<ReplacementEffect> replacementEffects = new ArrayList<ReplacementEffect>();
|
||||
private final ArrayList<PreventionEffect> preventionEffects = new ArrayList<PreventionEffect>();
|
||||
private final ArrayList<RequirementEffect> requirementEffects = new ArrayList<RequirementEffect>();
|
||||
private final ArrayList<RestrictionEffect> restrictionEffects = new ArrayList<RestrictionEffect>();
|
||||
private final ArrayList<AsThoughEffect> asThoughEffects = new ArrayList<AsThoughEffect>();
|
||||
private final ArrayList<CostModificationEffect> costModificationEffects = new ArrayList<CostModificationEffect>();
|
||||
|
||||
//map Abilities to Continuous effects
|
||||
private final Map<UUID, Ability> abilityMap = new HashMap<UUID, Ability>();
|
||||
|
@ -82,24 +82,31 @@ public class ContinuousEffects implements Serializable {
|
|||
public ContinuousEffects(final ContinuousEffects effect) {
|
||||
this.applyCounters = effect.applyCounters.copy();
|
||||
this.planeswalkerRedirectionEffect = effect.planeswalkerRedirectionEffect.copy();
|
||||
layeredEffects.ensureCapacity(effect.layeredEffects.size());
|
||||
for (ContinuousEffect entry: effect.layeredEffects) {
|
||||
layeredEffects.add((ContinuousEffect) entry.copy());
|
||||
}
|
||||
replacementEffects.ensureCapacity(effect.replacementEffects.size());
|
||||
for (ReplacementEffect entry: effect.replacementEffects) {
|
||||
replacementEffects.add((ReplacementEffect)entry.copy());
|
||||
}
|
||||
preventionEffects.ensureCapacity(effect.preventionEffects.size());
|
||||
for (PreventionEffect entry: effect.preventionEffects) {
|
||||
preventionEffects.add((PreventionEffect)entry.copy());
|
||||
}
|
||||
requirementEffects.ensureCapacity(effect.requirementEffects.size());
|
||||
for (RequirementEffect entry: effect.requirementEffects) {
|
||||
requirementEffects.add((RequirementEffect)entry.copy());
|
||||
}
|
||||
restrictionEffects.ensureCapacity(effect.restrictionEffects.size());
|
||||
for (RestrictionEffect entry: effect.restrictionEffects) {
|
||||
restrictionEffects.add((RestrictionEffect)entry.copy());
|
||||
}
|
||||
asThoughEffects.ensureCapacity(effect.asThoughEffects.size());
|
||||
for (AsThoughEffect entry: effect.asThoughEffects) {
|
||||
asThoughEffects.add((AsThoughEffect)entry.copy());
|
||||
}
|
||||
costModificationEffects.ensureCapacity(effect.costModificationEffects.size());
|
||||
for ( CostModificationEffect entry : effect.costModificationEffects ) {
|
||||
costModificationEffects.add(entry);
|
||||
}
|
||||
|
@ -209,7 +216,7 @@ public class ContinuousEffects implements Serializable {
|
|||
private List<ContinuousEffect> getLayeredEffects(Game game) {
|
||||
List<ContinuousEffect> layerEffects = new ArrayList<ContinuousEffect>(layeredEffects);
|
||||
for (Card card: game.getCards()) {
|
||||
Zone zone = game.getZone(card.getId());
|
||||
Zone zone = game.getState().getZone(card.getId());
|
||||
if (zone == Zone.HAND || zone == Zone.GRAVEYARD) {
|
||||
for (Entry<Effect, Ability> entry: card.getAbilities().getEffects(zone, EffectType.CONTINUOUS).entrySet()) {
|
||||
layerEffects.add((ContinuousEffect)entry.getKey());
|
||||
|
@ -284,7 +291,7 @@ public class ContinuousEffects implements Serializable {
|
|||
replaceEffects.add(planeswalkerRedirectionEffect);
|
||||
//get all applicable Replacement effects in each players hand and graveyard
|
||||
for (Card card: game.getCards()) {
|
||||
Zone zone = game.getZone(card.getId());
|
||||
Zone zone = game.getState().getZone(card.getId());
|
||||
if (zone == Zone.HAND || zone == Zone.GRAVEYARD) {
|
||||
for (Entry<ReplacementEffect, Ability> entry: card.getAbilities().getReplacementEffects(zone).entrySet()) {
|
||||
if (entry.getKey().applies(event, entry.getValue(), game)) {
|
||||
|
|
|
@ -66,7 +66,7 @@ public class PutOnLibraryTargetEffect extends OneShotEffect<PutOnLibraryTargetEf
|
|||
public boolean apply(Game game, Ability source) {
|
||||
boolean result = false;
|
||||
for (UUID targetId : targetPointer.getTargets(source)) {
|
||||
switch (game.getZone(targetId)) {
|
||||
switch (game.getState().getZone(targetId)) {
|
||||
case BATTLEFIELD:
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
|
|
|
@ -59,7 +59,7 @@ public class ReturnToHandSourceEffect extends OneShotEffect<ReturnToHandSourceEf
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
switch (game.getZone(card.getId())) {
|
||||
switch (game.getState().getZone(card.getId())) {
|
||||
case BATTLEFIELD:
|
||||
Permanent p = game.getPermanent(source.getSourceId());
|
||||
if (p != null) {
|
||||
|
|
|
@ -61,7 +61,7 @@ public class ReturnToHandTargetEffect extends OneShotEffect<ReturnToHandTargetEf
|
|||
public boolean apply(Game game, Ability source) {
|
||||
boolean result = false;
|
||||
for (UUID id : targetPointer.getTargets(source)) {
|
||||
switch (game.getZone(id)) {
|
||||
switch (game.getState().getZone(id)) {
|
||||
case BATTLEFIELD:
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
if (permanent != null) {
|
||||
|
|
|
@ -38,6 +38,7 @@ import mage.Constants.CardType;
|
|||
import mage.Constants.Outcome;
|
||||
import mage.Constants.Rarity;
|
||||
import mage.Constants.Zone;
|
||||
import mage.MageException;
|
||||
import mage.MageObjectImpl;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -46,6 +47,7 @@ import mage.abilities.SpellAbility;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.mana.ManaAbility;
|
||||
import mage.game.Game;
|
||||
import mage.game.GameException;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
|
@ -226,7 +228,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
|
|||
|
||||
@Override
|
||||
public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) {
|
||||
Zone fromZone = game.getZone(objectId);
|
||||
Zone fromZone = game.getState().getZone(objectId);
|
||||
ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, sourceId, ownerId, fromZone, toZone);
|
||||
if (!game.replaceEvent(event)) {
|
||||
if (event.getFromZone() != null) {
|
||||
|
@ -243,8 +245,11 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
|
|||
case EXILED:
|
||||
game.getExile().removeCard(this, game);
|
||||
break;
|
||||
case STACK:
|
||||
break;
|
||||
default:
|
||||
//logger.warning("moveToZone, not fully implemented: from="+event.getFromZone() + ", to="+event.getToZone());
|
||||
logger.fatal("invalid zone for card - " + fromZone);
|
||||
return false;
|
||||
}
|
||||
game.rememberLKI(objectId, event.getFromZone(), this);
|
||||
}
|
||||
|
@ -278,7 +283,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
|
|||
}
|
||||
game.setZone(objectId, event.getToZone());
|
||||
game.fireEvent(event);
|
||||
return game.getZone(objectId) == toZone;
|
||||
return game.getState().getZone(objectId) == toZone;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -309,14 +314,14 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
|
|||
game.getStack().push(new Spell(this, ability.copy(), controllerId));
|
||||
game.setZone(objectId, event.getToZone());
|
||||
game.fireEvent(event);
|
||||
return game.getZone(objectId) == Zone.STACK;
|
||||
return game.getState().getZone(objectId) == Zone.STACK;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game) {
|
||||
Zone fromZone = game.getZone(objectId);
|
||||
Zone fromZone = game.getState().getZone(objectId);
|
||||
ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, sourceId, ownerId, fromZone, Zone.EXILED);
|
||||
if (!game.replaceEvent(event)) {
|
||||
if (fromZone != null) {
|
||||
|
|
|
@ -61,14 +61,12 @@ public class CardsImpl extends LinkedHashSet<UUID> implements Cards, Serializabl
|
|||
public CardsImpl(Zone zone, List<Card> cards) {
|
||||
this(zone);
|
||||
for (Card card: cards) {
|
||||
add(card);
|
||||
this.add(card.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public CardsImpl(final CardsImpl cards) {
|
||||
for (UUID cardId: cards) {
|
||||
this.add(cardId);
|
||||
}
|
||||
this.addAll(cards);
|
||||
this.ownerId = cards.ownerId;
|
||||
this.zone = cards.zone;
|
||||
}
|
||||
|
@ -163,7 +161,7 @@ public class CardsImpl extends LinkedHashSet<UUID> implements Cards, Serializabl
|
|||
@Override
|
||||
public void addAll(List<Card> cards) {
|
||||
for (Card card: cards) {
|
||||
add(card);
|
||||
add(card.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,9 +57,7 @@ public class ChoiceImpl<T extends ChoiceImpl<T>> implements Choice, Serializable
|
|||
this.chosen = choice.chosen;
|
||||
this.required = choice.required;
|
||||
this.message = choice.message;
|
||||
for (String c: choice.choices) {
|
||||
this.choices.add(c);
|
||||
}
|
||||
this.choices.addAll(choice.choices);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -67,13 +67,9 @@ public class FilterCard<T extends FilterCard<T>> extends FilterObject<Card, Filt
|
|||
|
||||
public FilterCard(FilterCard<T> filter) {
|
||||
super(filter);
|
||||
for (UUID oId: filter.ownerId) {
|
||||
this.ownerId.add(oId);
|
||||
}
|
||||
this.ownerId.addAll(filter.ownerId);
|
||||
this.notOwner = filter.notOwner;
|
||||
for (String code: filter.expansionSetCode) {
|
||||
this.expansionSetCode.add(code);
|
||||
}
|
||||
this.expansionSetCode.addAll(filter.expansionSetCode);
|
||||
this.notExpansionSetCode = filter.notExpansionSetCode;
|
||||
this.owner = filter.owner;
|
||||
}
|
||||
|
|
|
@ -91,12 +91,8 @@ public class FilterObject<E extends MageObject, T extends FilterObject<E, T>> ex
|
|||
super(filter);
|
||||
this.abilities = filter.abilities.copy();
|
||||
this.notAbilities = filter.notAbilities;
|
||||
for (CardType cType: (List<CardType>)filter.cardType) {
|
||||
this.cardType.add(cType);
|
||||
}
|
||||
for (CardType cType: (List<CardType>)filter.notCardTypeList) {
|
||||
this.notCardTypeList.add(cType);
|
||||
}
|
||||
this.cardType.addAll(filter.cardType);
|
||||
this.notCardTypeList.addAll(filter.notCardTypeList);
|
||||
this.scopeCardType = filter.scopeCardType;
|
||||
this.notCardType = filter.notCardType;
|
||||
this.notScopeCardType = filter.notScopeCardType;
|
||||
|
@ -106,18 +102,12 @@ public class FilterObject<E extends MageObject, T extends FilterObject<E, T>> ex
|
|||
this.color = filter.color.copy();
|
||||
this.scopeColor = filter.scopeColor;
|
||||
this.notColor = filter.notColor;
|
||||
for (String fName: (List<String>)filter.name) {
|
||||
this.name.add(fName);
|
||||
}
|
||||
this.name.addAll(filter.name);
|
||||
this.notName = filter.notName;
|
||||
for (String fSubtype: (List<String>)filter.subtype) {
|
||||
this.subtype.add(fSubtype);
|
||||
}
|
||||
this.subtype.addAll(filter.subtype);
|
||||
this.scopeSubtype = filter.scopeSubtype;
|
||||
this.notSubtype = filter.notSubtype;
|
||||
for (String fSupertype: (List<String>)filter.supertype) {
|
||||
this.supertype.add(fSupertype);
|
||||
}
|
||||
this.supertype.addAll(filter.supertype);
|
||||
this.scopeSupertype = filter.scopeSupertype;
|
||||
this.notSupertype = filter.notSupertype;
|
||||
this.convertedManaCost = filter.convertedManaCost;
|
||||
|
|
|
@ -61,13 +61,9 @@ public class FilterPermanent<T extends FilterPermanent<T>> extends FilterObject<
|
|||
|
||||
public FilterPermanent(final FilterPermanent<T> filter) {
|
||||
super(filter);
|
||||
for (UUID oId: filter.ownerId) {
|
||||
this.ownerId.add(oId);
|
||||
}
|
||||
this.ownerId = new ArrayList<UUID>(filter.ownerId);
|
||||
this.notOwner = filter.notOwner;
|
||||
for (UUID oId: filter.controllerId) {
|
||||
this.controllerId.add(oId);
|
||||
}
|
||||
this.controllerId = new ArrayList<UUID>(filter.controllerId);
|
||||
this.notController = filter.notController;
|
||||
this.useTapped = filter.useTapped;
|
||||
this.tapped = filter.tapped;
|
||||
|
|
|
@ -52,9 +52,7 @@ public class FilterPlayer extends FilterImpl<Player, FilterPlayer> implements Fi
|
|||
|
||||
public FilterPlayer(FilterPlayer filter) {
|
||||
super(filter);
|
||||
for (UUID pId: filter.playerId) {
|
||||
this.playerId.add(pId);
|
||||
}
|
||||
this.playerId.addAll(filter.playerId);
|
||||
this.notPlayer = filter.notPlayer;
|
||||
this.playerTarget = filter.playerTarget;
|
||||
}
|
||||
|
|
|
@ -55,9 +55,7 @@ public class FilterStackObject<T extends FilterStackObject<T>> extends FilterObj
|
|||
|
||||
public FilterStackObject(final FilterStackObject<T> filter) {
|
||||
super(filter);
|
||||
for (UUID cId: filter.controllerId) {
|
||||
this.controllerId.add(cId);
|
||||
}
|
||||
this.controllerId.addAll(filter.controllerId);
|
||||
this.notController = filter.notController;
|
||||
this.controller = filter.controller;
|
||||
}
|
||||
|
|
|
@ -145,6 +145,8 @@ public interface Game extends MageItem, Serializable {
|
|||
public void start(UUID choosingPlayerId);
|
||||
public void start(UUID choosingPlayerId, GameOptions options);
|
||||
public void resume();
|
||||
public void pause();
|
||||
public boolean isPaused();
|
||||
public void end();
|
||||
public void mulligan(UUID playerId);
|
||||
public void quit(UUID playerId);
|
||||
|
|
|
@ -77,6 +77,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
private final static transient Logger logger = Logger.getLogger(GameImpl.class);
|
||||
|
||||
private static FilterAura filterAura = new FilterAura();
|
||||
private static FilterLegendaryPermanent filterLegendary = new FilterLegendaryPermanent();
|
||||
private static FilterEquipment filterEquipment = new FilterEquipment();
|
||||
private static FilterFortification filterFortification = new FilterFortification();
|
||||
private static Random rnd = new Random();
|
||||
|
@ -125,6 +126,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
this.gameCards = game.gameCards;
|
||||
this.simulation = game.simulation;
|
||||
this.gameOptions = game.gameOptions;
|
||||
this.lki.putAll(game.lki);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -355,27 +357,44 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
|
||||
@Override
|
||||
public void resume() {
|
||||
play(state.getActivePlayerId());
|
||||
}
|
||||
|
||||
protected void play(UUID nextPlayerId) {
|
||||
PlayerList players = state.getPlayerList(nextPlayerId);
|
||||
PlayerList players = state.getPlayerList(state.getActivePlayerId());
|
||||
Player player = getPlayer(players.get());
|
||||
while (!isGameOver()) {
|
||||
state.setTurnNum(state.getTurnNum() + 1);
|
||||
state.resume();
|
||||
if (!isGameOver()) {
|
||||
if (simulation)
|
||||
logger.info("Turn " + Integer.toString(state.getTurnNum()));
|
||||
fireInformEvent("Turn " + Integer.toString(state.getTurnNum()));
|
||||
if (checkStopOnTurnOption()) return;
|
||||
state.setActivePlayerId(player.getId());
|
||||
state.getTurn().play(this, player.getId());
|
||||
if (isGameOver())
|
||||
break;
|
||||
endOfTurn();
|
||||
player = players.getNext(this);
|
||||
state.getTurn().resumePlay(this);
|
||||
if (!isPaused() && !isGameOver()) {
|
||||
endOfTurn();
|
||||
player = players.getNext(this);
|
||||
state.setTurnNum(state.getTurnNum() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
winnerId = findWinnersAndLosers();
|
||||
play(player.getId());
|
||||
}
|
||||
|
||||
protected void play(UUID nextPlayerId) {
|
||||
if (!isPaused() && !isGameOver()) {
|
||||
PlayerList players = state.getPlayerList(nextPlayerId);
|
||||
Player player = getPlayer(players.get());
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
// if (simulation)
|
||||
// logger.info("Turn " + Integer.toString(state.getTurnNum()));
|
||||
fireInformEvent("Turn " + Integer.toString(state.getTurnNum()));
|
||||
if (checkStopOnTurnOption()) return;
|
||||
state.setActivePlayerId(player.getId());
|
||||
state.getTurn().play(this, player.getId());
|
||||
if (isPaused() || isGameOver())
|
||||
break;
|
||||
endOfTurn();
|
||||
player = players.getNext(this);
|
||||
state.setTurnNum(state.getTurnNum() + 1);
|
||||
}
|
||||
}
|
||||
if (isGameOver())
|
||||
winnerId = findWinnersAndLosers();
|
||||
}
|
||||
|
||||
private boolean checkStopOnTurnOption() {
|
||||
|
@ -501,6 +520,16 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
return playerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
state.pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
return state.isPaused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
state.endGame();
|
||||
|
@ -547,25 +576,25 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
public void playPriority(UUID activePlayerId) {
|
||||
int bookmark = 0;
|
||||
try {
|
||||
while (!isGameOver()) {
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
state.getPlayers().resetPassed();
|
||||
state.getPlayerList().setCurrent(activePlayerId);
|
||||
Player player;
|
||||
while (!isGameOver()) {
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
try {
|
||||
if (bookmark == 0)
|
||||
bookmark = bookmarkState();
|
||||
player = getPlayer(state.getPlayerList().get());
|
||||
state.setPriorityPlayerId(player.getId());
|
||||
while (!player.isPassed() && !player.hasLost() && !player.hasLeft() && !isGameOver()) {
|
||||
while (!player.isPassed() && !player.hasLost() && !player.hasLeft() && !isPaused() && !isGameOver()) {
|
||||
checkStateAndTriggered();
|
||||
if (isGameOver()) return;
|
||||
if (isPaused() || isGameOver()) return;
|
||||
// resetPassed should be called if player performs any action
|
||||
player.priority(this);
|
||||
if (isGameOver()) return;
|
||||
if (isPaused() || isGameOver()) return;
|
||||
applyEffects();
|
||||
}
|
||||
if (isGameOver()) return;
|
||||
if (isPaused() || isGameOver()) return;
|
||||
if (allPassed()) {
|
||||
if (!state.getStack().isEmpty()) {
|
||||
//20091005 - 115.4
|
||||
|
@ -669,9 +698,9 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
public boolean checkStateAndTriggered() {
|
||||
boolean somethingHappened = false;
|
||||
//20091005 - 115.5
|
||||
while (!this.isGameOver()) {
|
||||
while (!isPaused() && !this.isGameOver()) {
|
||||
if (!checkStateBasedActions() ) {
|
||||
if (this.isGameOver() || !checkTriggered()) {
|
||||
if (isPaused() || this.isGameOver() || !checkTriggered()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -711,28 +740,127 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
player.lost(this);
|
||||
}
|
||||
}
|
||||
for (Permanent perm: getBattlefield().getAllActivePermanents(CardType.CREATURE)) {
|
||||
//20091005 - 704.5f
|
||||
if (perm.getToughness().getValue() == 0) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
|
||||
List<Permanent> planeswalkers = new ArrayList<Permanent>();
|
||||
List<Permanent> legendary = new ArrayList<Permanent>();
|
||||
for (Permanent perm: getBattlefield().getAllActivePermanents()) {
|
||||
if (perm.getCardType().contains(CardType.CREATURE)) {
|
||||
//20091005 - 704.5f
|
||||
if (perm.getToughness().getValue() == 0) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false)) {
|
||||
somethingHappened = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//20091005 - 704.5g/704.5h
|
||||
else if (perm.getToughness().getValue() <= perm.getDamage() || perm.isDeathtouched()) {
|
||||
if (perm.destroy(null, this, false)) {
|
||||
somethingHappened = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (perm.getCardType().contains(CardType.PLANESWALKER)) {
|
||||
//20091005 - 704.5i
|
||||
if (perm.getCounters().getCount(CounterType.LOYALTY) == 0) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false)) {
|
||||
somethingHappened = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
planeswalkers.add(perm);
|
||||
}
|
||||
if (filterAura.match(perm)) {
|
||||
//20091005 - 704.5n, 702.14c
|
||||
if (perm.getAttachedTo() == null) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
else {
|
||||
Target target = perm.getSpellAbility().getTargets().get(0);
|
||||
if (target instanceof TargetPermanent) {
|
||||
Permanent attachedTo = getPermanent(perm.getAttachedTo());
|
||||
if (attachedTo == null) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
else {
|
||||
Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter();
|
||||
if (!auraFilter.match(attachedTo) || attachedTo.hasProtectionFrom(perm)) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target instanceof TargetPlayer) {
|
||||
Player attachedTo = getPlayer(perm.getAttachedTo());
|
||||
if (attachedTo == null) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
else {
|
||||
Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter();
|
||||
if (!auraFilter.match(attachedTo) || attachedTo.hasProtectionFrom(perm)) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filterLegendary.match(perm))
|
||||
legendary.add(perm);
|
||||
if (filterEquipment.match(perm)) {
|
||||
//20091005 - 704.5p, 702.14d
|
||||
if (perm.getAttachedTo() != null) {
|
||||
Permanent creature = getPermanent(perm.getAttachedTo());
|
||||
if (creature == null) {
|
||||
perm.attachTo(null, this);
|
||||
}
|
||||
else if (!creature.getCardType().contains(CardType.CREATURE) || creature.hasProtectionFrom(perm)) {
|
||||
if (creature.removeAttachment(perm.getId(), this))
|
||||
somethingHappened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filterFortification.match(perm)) {
|
||||
if (perm.getAttachedTo() != null) {
|
||||
Permanent land = getPermanent(perm.getAttachedTo());
|
||||
if (land == null) {
|
||||
perm.attachTo(null, this);
|
||||
}
|
||||
else if (!land.getCardType().contains(CardType.LAND) || land.hasProtectionFrom(perm)) {
|
||||
if (land.removeAttachment(perm.getId(), this))
|
||||
somethingHappened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//20091005 - 704.5q
|
||||
if (perm.getAttachments().size() > 0) {
|
||||
for (UUID attachmentId: perm.getAttachments()) {
|
||||
Permanent attachment = getPermanent(attachmentId);
|
||||
if (attachment != null && !(attachment.getSubtype().contains("Aura") ||
|
||||
attachment.getSubtype().contains("Equipment") ||
|
||||
attachment.getSubtype().contains("Fortification"))) {
|
||||
if (perm.removeAttachment(attachment.getId(), this))
|
||||
somethingHappened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//20091005 - 704.5g/704.5h
|
||||
else if (perm.getToughness().getValue() <= perm.getDamage() || perm.isDeathtouched()) {
|
||||
if (perm.destroy(null, this, false))
|
||||
somethingHappened = true;
|
||||
|
||||
//20110501 - 704.5r
|
||||
if (perm.getCounters().containsKey(CounterType.P1P1) && perm.getCounters().containsKey(CounterType.M1M1)) {
|
||||
int p1p1 = perm.getCounters().getCount(CounterType.P1P1);
|
||||
int m1m1 = perm.getCounters().getCount(CounterType.M1M1);
|
||||
int min = Math.min(p1p1, m1m1);
|
||||
perm.getCounters().removeCounter(CounterType.P1P1, min);
|
||||
perm.getCounters().removeCounter(CounterType.M1M1, min);
|
||||
}
|
||||
}
|
||||
//20091005 - 704.5i
|
||||
for (Permanent perm: getBattlefield().getAllActivePermanents(CardType.PLANESWALKER)) {
|
||||
if (perm.getCounters().getCount(CounterType.LOYALTY) == 0) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//20091005 - 704.5j, 801.14
|
||||
if (getBattlefield().contains(new FilterPlaneswalkerPermanent(), 2)) { //don't bother checking if less than 2 planeswalkers in play
|
||||
for (Permanent planeswalker: getBattlefield().getAllActivePermanents(CardType.PLANESWALKER)) {
|
||||
if (planeswalkers.size() > 1) { //don't bother checking if less than 2 planeswalkers in play
|
||||
for (Permanent planeswalker: planeswalkers) {
|
||||
for (String planeswalkertype: planeswalker.getSubtype()) {
|
||||
FilterPlaneswalkerPermanent filterPlaneswalker = new FilterPlaneswalkerPermanent();
|
||||
filterPlaneswalker.getSubtype().add(planeswalkertype);
|
||||
|
@ -746,48 +874,9 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
}
|
||||
}
|
||||
//20091005 - 704.5n, 702.14c
|
||||
for (Permanent perm: getBattlefield().getAllActivePermanents(filterAura)) {
|
||||
if (perm.getAttachedTo() == null) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
else {
|
||||
Target target = perm.getSpellAbility().getTargets().get(0);
|
||||
if (target instanceof TargetPermanent) {
|
||||
Permanent attachedTo = getPermanent(perm.getAttachedTo());
|
||||
if (attachedTo == null) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
else {
|
||||
Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter();
|
||||
if (!auraFilter.match(attachedTo) || attachedTo.hasProtectionFrom(perm)) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target instanceof TargetPlayer) {
|
||||
Player attachedTo = getPlayer(perm.getAttachedTo());
|
||||
if (attachedTo == null) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
else {
|
||||
Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter();
|
||||
if (!auraFilter.match(attachedTo) || attachedTo.hasProtectionFrom(perm)) {
|
||||
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
|
||||
somethingHappened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FilterLegendaryPermanent filterLegendary = new FilterLegendaryPermanent();
|
||||
//20091005 - 704.5k, 801.12
|
||||
if (getBattlefield().contains(filterLegendary, 2)) { //don't bother checking if less than 2 legends in play
|
||||
for (Permanent legend: getBattlefield().getAllActivePermanents(filterLegendary)) {
|
||||
if (legendary.size() > 1) { //don't bother checking if less than 2 legends in play
|
||||
for (Permanent legend: legendary) {
|
||||
FilterLegendaryPermanent filterLegendName = new FilterLegendaryPermanent();
|
||||
filterLegendName.getName().add(legend.getName());
|
||||
if (getBattlefield().contains(filterLegendName, legend.getControllerId(), this, 2)) {
|
||||
|
@ -798,55 +887,6 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
}
|
||||
}
|
||||
//20091005 - 704.5p, 702.14d
|
||||
for (Permanent perm: getBattlefield().getAllActivePermanents(filterEquipment)) {
|
||||
if (perm.getAttachedTo() != null) {
|
||||
Permanent creature = getPermanent(perm.getAttachedTo());
|
||||
if (creature == null) {
|
||||
perm.attachTo(null, this);
|
||||
}
|
||||
else if (!creature.getCardType().contains(CardType.CREATURE) || creature.hasProtectionFrom(perm)) {
|
||||
if (creature.removeAttachment(perm.getId(), this))
|
||||
somethingHappened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Permanent perm: getBattlefield().getAllActivePermanents(filterFortification)) {
|
||||
if (perm.getAttachedTo() != null) {
|
||||
Permanent land = getPermanent(perm.getAttachedTo());
|
||||
if (land == null) {
|
||||
perm.attachTo(null, this);
|
||||
}
|
||||
else if (!land.getCardType().contains(CardType.LAND) || land.hasProtectionFrom(perm)) {
|
||||
if (land.removeAttachment(perm.getId(), this))
|
||||
somethingHappened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//20091005 - 704.5q
|
||||
for (Permanent perm: getBattlefield().getAllActivePermanents()) {
|
||||
if (perm.getAttachments().size() > 0) {
|
||||
for (UUID attachmentId: perm.getAttachments()) {
|
||||
Permanent attachment = getPermanent(attachmentId);
|
||||
if (attachment != null && !(attachment.getSubtype().contains("Aura") ||
|
||||
attachment.getSubtype().contains("Equipment") ||
|
||||
attachment.getSubtype().contains("Fortification"))) {
|
||||
if (perm.removeAttachment(attachment.getId(), this))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//20110501 - 704.5r
|
||||
for (Permanent perm: getBattlefield().getAllActivePermanents()) {
|
||||
if (perm.getCounters().containsKey(CounterType.P1P1) && perm.getCounters().containsKey(CounterType.M1M1)) {
|
||||
int p1p1 = perm.getCounters().getCount(CounterType.P1P1);
|
||||
int m1m1 = perm.getCounters().getCount(CounterType.M1M1);
|
||||
int min = Math.min(p1p1, m1m1);
|
||||
perm.getCounters().removeCounter(CounterType.P1P1, min);
|
||||
perm.getCounters().removeCounter(CounterType.M1M1, min);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: implement the rest
|
||||
|
||||
|
|
|
@ -85,8 +85,9 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
private Revealed revealed;
|
||||
private Map<UUID, LookedAt> lookedAt = new HashMap<UUID, LookedAt>();
|
||||
private Battlefield battlefield;
|
||||
private int turnNum;
|
||||
private int turnNum = 1;
|
||||
private boolean gameOver;
|
||||
private boolean paused;
|
||||
// private List<String> messages = new ArrayList<String>();
|
||||
private ContinuousEffects effects;
|
||||
private TriggeredAbilities triggers;
|
||||
|
@ -128,9 +129,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
this.command = state.command.copy();
|
||||
this.exile = state.exile.copy();
|
||||
this.revealed = state.revealed.copy();
|
||||
for (Map.Entry<UUID, LookedAt> entry: state.lookedAt.entrySet()) {
|
||||
lookedAt.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
this.lookedAt.putAll(state.lookedAt);
|
||||
this.battlefield = state.battlefield.copy();
|
||||
this.turnNum = state.turnNum;
|
||||
this.gameOver = state.gameOver;
|
||||
|
@ -141,13 +140,8 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
this.combat = state.combat.copy();
|
||||
this.turnMods = state.turnMods.copy();
|
||||
this.watchers = state.watchers.copy();
|
||||
for (Map.Entry<String, Object> entry : state.values.entrySet()) {
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
//TODO: might have to change value to Copyable
|
||||
}
|
||||
for (Map.Entry<UUID, Zone> entry: state.zones.entrySet()) {
|
||||
zones.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
this.values.putAll(state.values);
|
||||
this.zones.putAll(state.zones);
|
||||
for (Map.Entry<UUID, Abilities<ActivatedAbility>> entry: state.otherAbilities.entrySet()) {
|
||||
otherAbilities.put(entry.getKey(), entry.getValue().copy());
|
||||
}
|
||||
|
@ -457,4 +451,16 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
zones.clear();
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
this.paused = true;
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
this.paused = false;
|
||||
}
|
||||
|
||||
public boolean isPaused() {
|
||||
return this.paused;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,9 +66,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
for (CombatGroup group : combat.groups) {
|
||||
groups.add(group.copy());
|
||||
}
|
||||
for (UUID defenderId : combat.defenders) {
|
||||
defenders.add(defenderId);
|
||||
}
|
||||
defenders.addAll(combat.defenders);
|
||||
for (Map.Entry<UUID, CombatGroup> group : combat.blockingGroups.entrySet()) {
|
||||
blockingGroups.put(group.getKey(), group.getValue());
|
||||
}
|
||||
|
@ -128,6 +126,8 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
//20101001 - 508.1d
|
||||
checkAttackRequirements(player, game);
|
||||
player.selectAttackers(game);
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return;
|
||||
for (CombatGroup group: groups) {
|
||||
for (UUID attacker: group.getAttackers()) {
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ATTACKER_DECLARED, group.defenderId, attacker, attackerId));
|
||||
|
@ -169,6 +169,8 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
checkBlockRequirements(player, game);
|
||||
for (UUID defenderId : getPlayerDefenders(game)) {
|
||||
game.getPlayer(defenderId).selectBlockers(game);
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return;
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,21 +67,11 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
|||
this.blocked = group.blocked;
|
||||
this.defenderId = group.defenderId;
|
||||
this.defenderIsPlaneswalker = group.defenderIsPlaneswalker;
|
||||
for (UUID attackerId: group.attackers) {
|
||||
this.attackers.add(attackerId);
|
||||
}
|
||||
for (UUID blockerId: group.blockers) {
|
||||
this.blockers.add(blockerId);
|
||||
}
|
||||
for (UUID orderId: group.blockerOrder) {
|
||||
this.blockerOrder.add(orderId);
|
||||
}
|
||||
for (UUID orderId: group.attackerOrder) {
|
||||
this.attackerOrder.add(orderId);
|
||||
}
|
||||
for (Map.Entry<UUID, UUID> entry : group.players.entrySet()) {
|
||||
players.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
this.attackers.addAll(group.attackers);
|
||||
this.blockers.addAll(group.blockers);
|
||||
this.blockerOrder.addAll(group.blockerOrder);
|
||||
this.attackerOrder.addAll(group.attackerOrder);
|
||||
this.players.putAll(group.players);
|
||||
}
|
||||
|
||||
protected String getValue(Game game) {
|
||||
|
|
|
@ -157,7 +157,7 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
|
|||
|
||||
@Override
|
||||
public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) {
|
||||
Zone fromZone = game.getZone(objectId);
|
||||
Zone fromZone = game.getState().getZone(objectId);
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null && controller.removeFromBattlefield(this, game)) {
|
||||
ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, controllerId, fromZone, toZone);
|
||||
|
@ -187,7 +187,7 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
|
|||
}
|
||||
game.setZone(objectId, event.getToZone());
|
||||
game.fireEvent(event);
|
||||
return game.getZone(objectId) == toZone;
|
||||
return game.getState().getZone(objectId) == toZone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
|
|||
|
||||
@Override
|
||||
public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game) {
|
||||
Zone fromZone = game.getZone(objectId);
|
||||
Zone fromZone = game.getState().getZone(objectId);
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null && controller.removeFromBattlefield(this, game)) {
|
||||
ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, ownerId, fromZone, Zone.EXILED);
|
||||
|
|
|
@ -112,20 +112,11 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
|
|||
this.loyaltyUsed = permanent.loyaltyUsed;
|
||||
this.deathtouched = permanent.deathtouched;
|
||||
this.counters = permanent.counters.copy();
|
||||
for (UUID attachmentId : permanent.attachments) {
|
||||
this.attachments.add(attachmentId);
|
||||
}
|
||||
for (UUID imprintedId : permanent.imprinted) {
|
||||
this.imprinted.add(imprintedId);
|
||||
}
|
||||
for (UUID connectedCardId : permanent.connectedCards) {
|
||||
this.connectedCards.add(connectedCardId);
|
||||
}
|
||||
this.attachments.addAll(permanent.attachments);
|
||||
this.imprinted.addAll(permanent.imprinted);
|
||||
this.connectedCards.addAll(permanent.connectedCards);
|
||||
if (permanent.dealtDamageByThisTurn != null) {
|
||||
dealtDamageByThisTurn = new ArrayList<UUID>();
|
||||
for (UUID sourceId : permanent.dealtDamageByThisTurn) {
|
||||
this.dealtDamageByThisTurn.add(sourceId);
|
||||
}
|
||||
dealtDamageByThisTurn = new ArrayList<UUID>(permanent.dealtDamageByThisTurn);
|
||||
if (permanent.markedDamage != null) {
|
||||
markedDamage = new ArrayList<Counter>();
|
||||
for (Counter counter : permanent.markedDamage) {
|
||||
|
|
|
@ -135,16 +135,18 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
|
|||
*/
|
||||
private void updateOptionalCosts() {
|
||||
Ability abilityOrig = card.getAbilities().get(ability.getId());
|
||||
for (Object object : ability.getOptionalCosts()) {
|
||||
Cost cost = (Cost) object;
|
||||
for (Cost costOrig : abilityOrig.getOptionalCosts()) {
|
||||
if (cost.getId().equals(costOrig.getId())) {
|
||||
if (cost.isPaid()) {
|
||||
costOrig.setPaid();
|
||||
} else {
|
||||
costOrig.clearPaid();
|
||||
if (abilityOrig != null) {
|
||||
for (Object object : ability.getOptionalCosts()) {
|
||||
Cost cost = (Cost) object;
|
||||
for (Cost costOrig : abilityOrig.getOptionalCosts()) {
|
||||
if (cost.getId().equals(costOrig.getId())) {
|
||||
if (cost.isPaid()) {
|
||||
costOrig.setPaid();
|
||||
} else {
|
||||
costOrig.clearPaid();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,13 +32,12 @@ import java.util.ArrayList;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Stack;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Zone;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.ReplacementEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
|
@ -105,15 +104,9 @@ public class SpellStack extends Stack<StackObject> {
|
|||
boolean caught = false;
|
||||
Map<ReplacementEffect, Ability> rEffects = new LinkedHashMap<ReplacementEffect, Ability>();
|
||||
for (StackObject stackObject: this) {
|
||||
for (Ability ability: stackObject.getAbilities()) {
|
||||
if (ability.getZone() == Zone.STACK) {
|
||||
for (Effect effect: ability.getEffects()) {
|
||||
if (effect instanceof ReplacementEffect) {
|
||||
if (((ReplacementEffect)effect).applies(event, ability, game))
|
||||
rEffects.put((ReplacementEffect) effect, ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Entry<ReplacementEffect, Ability> entry: stackObject.getAbilities().getReplacementEffects(Zone.STACK).entrySet()) {
|
||||
if (entry.getKey().applies(event, entry.getValue(), game))
|
||||
rEffects.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
if (rEffects.size() > 0) {
|
||||
|
|
|
@ -54,16 +54,16 @@ public class EndPhase extends Phase<EndPhase> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void playStep(Game game, UUID activePlayerId) {
|
||||
protected void playStep(Game game) {
|
||||
if (currentStep.getType() == PhaseStep.CLEANUP) {
|
||||
currentStep.beginStep(game, activePlayerId);
|
||||
if (game.checkStateAndTriggered()) {
|
||||
playStep(game, activePlayerId);
|
||||
playStep(game);
|
||||
}
|
||||
currentStep.endStep(game, activePlayerId);
|
||||
}
|
||||
else
|
||||
super.playStep(game, activePlayerId);
|
||||
super.playStep(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,6 +30,7 @@ package mage.game.turn;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
|
@ -93,7 +94,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
}
|
||||
|
||||
public boolean play(Game game, UUID activePlayerId) {
|
||||
if (game.isGameOver())
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return false;
|
||||
|
||||
this.activePlayerId = activePlayerId;
|
||||
|
@ -101,12 +102,14 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
if (beginPhase(game, activePlayerId)) {
|
||||
|
||||
for (Step step: steps) {
|
||||
if (game.isGameOver())
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return false;
|
||||
currentStep = step;
|
||||
if (!game.getState().getTurnMods().skipStep(activePlayerId, currentStep.getType()))
|
||||
playStep(game, activePlayerId);
|
||||
playStep(game);
|
||||
}
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return false;
|
||||
count++;
|
||||
endPhase(game, activePlayerId);
|
||||
return true;
|
||||
|
@ -114,6 +117,34 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean resumePlay(Game game, PhaseStep stepType) {
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return false;
|
||||
|
||||
this.activePlayerId = game.getActivePlayerId();
|
||||
Iterator<Step> it = steps.iterator();
|
||||
Step step;
|
||||
do {
|
||||
step = it.next();
|
||||
currentStep = step;
|
||||
} while (step.getType() != stepType);
|
||||
resumeStep(game);
|
||||
while (it.hasNext()) {
|
||||
step = it.next();
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return false;
|
||||
currentStep = step;
|
||||
if (!game.getState().getTurnMods().skipStep(activePlayerId, currentStep.getType()))
|
||||
playStep(game);
|
||||
}
|
||||
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return false;
|
||||
count++;
|
||||
endPhase(game, activePlayerId);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean beginPhase(Game game, UUID activePlayerId) {
|
||||
if (!game.replaceEvent(new GameEvent(event, null, null, activePlayerId))) {
|
||||
game.fireEvent(new GameEvent(preEvent, null, null, activePlayerId));
|
||||
|
@ -138,21 +169,36 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
playExtraSteps(game, currentStep.getType());
|
||||
}
|
||||
|
||||
protected void playStep(Game game, UUID activePlayerId) {
|
||||
protected void playStep(Game game) {
|
||||
if (!currentStep.skipStep(game, activePlayerId)) {
|
||||
prePriority(game, activePlayerId);
|
||||
currentStep.priority(game, activePlayerId);
|
||||
postPriority(game, activePlayerId);
|
||||
if (!game.isPaused() && !game.isGameOver())
|
||||
currentStep.priority(game, activePlayerId);
|
||||
if (!game.isPaused() && !game.isGameOver())
|
||||
postPriority(game, activePlayerId);
|
||||
}
|
||||
}
|
||||
|
||||
protected void resumeStep(Game game) {
|
||||
switch (currentStep.getStepPart()) {
|
||||
case PRE:
|
||||
prePriority(game, activePlayerId);
|
||||
case PRIORITY:
|
||||
if (!game.isPaused() && !game.isGameOver())
|
||||
currentStep.priority(game, activePlayerId);
|
||||
case POST:
|
||||
if (!game.isPaused() && !game.isGameOver())
|
||||
postPriority(game, activePlayerId);
|
||||
}
|
||||
}
|
||||
|
||||
private void playExtraSteps(Game game, PhaseStep afterStep) {
|
||||
while (true) {
|
||||
Step extraStep = game.getState().getTurnMods().extraStep(activePlayerId, afterStep);
|
||||
if (extraStep == null)
|
||||
return;
|
||||
currentStep = extraStep;
|
||||
playStep(game, activePlayerId);
|
||||
playStep(game);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,11 @@ public abstract class Step<T extends Step<T>> implements Serializable {
|
|||
protected EventType stepEvent;
|
||||
protected EventType preStepEvent;
|
||||
protected EventType postStepEvent;
|
||||
protected StepPart stepPart;
|
||||
|
||||
public enum StepPart {
|
||||
PRE, PRIORITY, POST;
|
||||
}
|
||||
|
||||
public abstract T copy();
|
||||
|
||||
|
@ -60,6 +65,7 @@ public abstract class Step<T extends Step<T>> implements Serializable {
|
|||
this.stepEvent = step.stepEvent;
|
||||
this.preStepEvent = step.preStepEvent;
|
||||
this.postStepEvent = step.postStepEvent;
|
||||
this.stepPart = step.stepPart;
|
||||
}
|
||||
|
||||
public PhaseStep getType() {
|
||||
|
@ -67,15 +73,19 @@ public abstract class Step<T extends Step<T>> implements Serializable {
|
|||
}
|
||||
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
stepPart = StepPart.PRE;
|
||||
game.fireEvent(new GameEvent(preStepEvent, null, null, activePlayerId));
|
||||
}
|
||||
|
||||
public void priority(Game game, UUID activePlayerId) {
|
||||
if (hasPriority)
|
||||
if (hasPriority) {
|
||||
stepPart = StepPart.PRIORITY;
|
||||
game.playPriority(activePlayerId);
|
||||
}
|
||||
}
|
||||
|
||||
public void endStep(Game game, UUID activePlayerId) {
|
||||
stepPart = StepPart.POST;
|
||||
game.fireEvent(new GameEvent(postStepEvent, null, null, activePlayerId));
|
||||
}
|
||||
|
||||
|
@ -87,4 +97,8 @@ public abstract class Step<T extends Step<T>> implements Serializable {
|
|||
return this.hasPriority;
|
||||
}
|
||||
|
||||
public StepPart getStepPart() {
|
||||
return stepPart;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ package mage.game.turn;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
|
@ -100,8 +101,8 @@ public class Turn implements Serializable {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void play(Game game, UUID activePlayerId) {
|
||||
if (game.isGameOver())
|
||||
public void play(Game game, UUID activePlayerId) {
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return;
|
||||
|
||||
if (game.getState().getTurnMods().skipTurn(activePlayerId))
|
||||
|
@ -113,7 +114,7 @@ public class Turn implements Serializable {
|
|||
resetCounts();
|
||||
game.getPlayer(activePlayerId).beginTurn(game);
|
||||
for (Phase phase: phases) {
|
||||
if (game.isGameOver())
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return;
|
||||
currentPhase = phase;
|
||||
if (!game.getState().getTurnMods().skipPhase(activePlayerId, currentPhase.getType())) {
|
||||
|
@ -132,6 +133,44 @@ public class Turn implements Serializable {
|
|||
playExtraTurns(game);
|
||||
}
|
||||
|
||||
public void resumePlay(Game game) {
|
||||
activePlayerId = game.getActivePlayerId();
|
||||
UUID priorityPlayerId = game.getPriorityPlayerId();
|
||||
TurnPhase phaseType = game.getPhase().getType();
|
||||
PhaseStep stepType = game.getStep().getType();
|
||||
|
||||
Iterator<Phase> it = phases.iterator();
|
||||
Phase phase;
|
||||
do {
|
||||
phase = it.next();
|
||||
currentPhase = phase;
|
||||
} while (phase.type != phaseType);
|
||||
if (phase.resumePlay(game, stepType)) {
|
||||
//20091005 - 500.4/703.4n
|
||||
game.emptyManaPools();
|
||||
game.saveState();
|
||||
//20091005 - 500.8
|
||||
playExtraPhases(game, phase.getType());
|
||||
}
|
||||
while (it.hasNext()) {
|
||||
phase = it.next();
|
||||
if (game.isPaused() || game.isGameOver())
|
||||
return;
|
||||
currentPhase = phase;
|
||||
if (!game.getState().getTurnMods().skipPhase(activePlayerId, currentPhase.getType())) {
|
||||
if (phase.play(game, activePlayerId)) {
|
||||
//20091005 - 500.4/703.4n
|
||||
game.emptyManaPools();
|
||||
game.saveState();
|
||||
//20091005 - 500.8
|
||||
playExtraPhases(game, phase.getType());
|
||||
}
|
||||
}
|
||||
if (!currentPhase.equals(phase)) // phase was changed from the card
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkTurnIsControlledByOtherPlayer(Game game, UUID activePlayerId) {
|
||||
UUID newControllerId = game.getState().getTurnMods().controlsTurn(activePlayerId);
|
||||
if (newControllerId != null && !newControllerId.equals(activePlayerId)) {
|
||||
|
|
|
@ -154,9 +154,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
this.range = player.range;
|
||||
this.canGainLife = player.canGainLife;
|
||||
this.canLoseLife = player.canLoseLife;
|
||||
for (UUID id: player.inRange) {
|
||||
this.inRange.add(id);
|
||||
}
|
||||
this.attachments.addAll(player.attachments);
|
||||
this.inRange.addAll(player.inRange);
|
||||
this.userData = player.userData;
|
||||
}
|
||||
|
||||
|
@ -504,7 +503,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
if (card != null) {
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getId(), ability.getSourceId(), playerId))) {
|
||||
int bookmark = game.bookmarkState();
|
||||
Zone fromZone = game.getZone(card.getId());
|
||||
Zone fromZone = game.getState().getZone(card.getId());
|
||||
card.cast(game, fromZone, ability, playerId);
|
||||
|
||||
Ability spellAbility = game.getStack().getSpell(ability.getId()).getSpellAbility();
|
||||
|
@ -530,7 +529,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
//20091005 - 305.1
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), playerId))) {
|
||||
int bookmark = game.bookmarkState();
|
||||
Zone zone = game.getZone(card.getId());
|
||||
Zone zone = game.getState().getZone(card.getId());
|
||||
switch (zone) {
|
||||
case HAND:
|
||||
removeFromHand(card, game);
|
||||
|
@ -541,6 +540,9 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
case GRAVEYARD:
|
||||
removeFromGraveyard(card, game);
|
||||
break;
|
||||
default:
|
||||
// invalid zone for play land
|
||||
return false;
|
||||
}
|
||||
|
||||
if (card.putOntoBattlefield(game, zone, null, playerId)) {
|
||||
|
|
|
@ -76,9 +76,7 @@ public abstract class TargetImpl<T extends TargetImpl<T>> implements Target {
|
|||
this.minNumberOfTargets = target.minNumberOfTargets;
|
||||
this.required = target.required;
|
||||
this.chosen = target.chosen;
|
||||
for (Entry<UUID, Integer> entry: target.targets.entrySet()) {
|
||||
targets.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
this.targets.putAll(target.targets);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -74,7 +74,7 @@ public abstract class TargetObject<T extends TargetObject<T>> extends TargetImpl
|
|||
@Override
|
||||
public boolean canTarget(UUID id, Game game) {
|
||||
MageObject object = game.getObject(id);
|
||||
if (object != null && game.getZone(id).match(zone))
|
||||
if (object != null && game.getState().getZone(id).match(zone))
|
||||
return getFilter().match(object);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -146,7 +146,8 @@ public class TargetPermanent<T extends TargetPermanent<T>> extends TargetObject<
|
|||
int remainingTargets = this.minNumberOfTargets - targets.size();
|
||||
if (remainingTargets == 0) {
|
||||
// if we return true, then AnowonTheRuinSage will hang for AI when no targets in play
|
||||
return false;
|
||||
// TODO: retest Anowon the Ruin Sage
|
||||
return true;
|
||||
}
|
||||
int count = 0;
|
||||
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, game)) {
|
||||
|
|
|
@ -62,7 +62,7 @@ public class TargetCardInExile extends TargetCard<TargetCardInExile> {
|
|||
@Override
|
||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||
Card card = game.getCard(id);
|
||||
if (card != null && game.getZone(card.getId()) == Zone.EXILED) {
|
||||
if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
||||
ExileZone exile;
|
||||
if (zoneId != null) {
|
||||
exile = game.getExile().getExileZone(zoneId);
|
||||
|
|
|
@ -66,7 +66,7 @@ public class TargetCardInGraveyard extends TargetCard<TargetCardInGraveyard> {
|
|||
@Override
|
||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||
Card card = game.getCard(id);
|
||||
if (card != null && game.getZone(card.getId()) == Zone.GRAVEYARD)
|
||||
if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD)
|
||||
return filter.match(card);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public class TargetCardInOpponentsGraveyard extends TargetCard<TargetCardInOppon
|
|||
@Override
|
||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||
Card card = game.getCard(id);
|
||||
if (card != null && game.getZone(card.getId()) == Constants.Zone.GRAVEYARD) {
|
||||
if (card != null && game.getState().getZone(card.getId()) == Constants.Zone.GRAVEYARD) {
|
||||
if (game.getOpponents(source.getControllerId()).contains(card.getOwnerId())) {
|
||||
return filter.match(card);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ public class TargetCardInYourGraveyard extends TargetCard<TargetCardInYourGravey
|
|||
@Override
|
||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||
Card card = game.getCard(id);
|
||||
if (card != null && game.getZone(card.getId()) == Zone.GRAVEYARD)
|
||||
if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD)
|
||||
if (game.getPlayer(source.getControllerId()).getGraveyard().contains(id))
|
||||
return filter.match(card);
|
||||
return false;
|
||||
|
|
Loading…
Add table
Reference in a new issue