mirror of
https://github.com/correl/mage.git
synced 2024-12-25 03:00:15 +00:00
...
This commit is contained in:
parent
805f20264e
commit
69e219c7c6
107 changed files with 3238 additions and 616 deletions
|
@ -214,6 +214,7 @@ public final class Constants {
|
|||
DrawCard(true),
|
||||
Discard(false),
|
||||
Sacrifice(false),
|
||||
ReturnToHand(false),
|
||||
Exile(false),
|
||||
Protect(true),
|
||||
PutManaInPool(true),
|
||||
|
|
|
@ -61,7 +61,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
public List<ActivatedAbility> getActivatedAbilities(Zone zone) {
|
||||
List<ActivatedAbility> zonedAbilities = new ArrayList<ActivatedAbility>();
|
||||
for (Ability ability: this) {
|
||||
if (ability.isEnabled() && ability instanceof ActivatedAbility && ability.getZone().match(zone)) {
|
||||
if (ability instanceof ActivatedAbility && ability.getZone().match(zone)) {
|
||||
zonedAbilities.add((ActivatedAbility)ability);
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
public List<ManaAbility> getManaAbilities(Zone zone) {
|
||||
List<ManaAbility> abilities = new ArrayList<ManaAbility>();
|
||||
for (Ability ability: this) {
|
||||
if (ability.isEnabled() && ability instanceof ManaAbility && ability.getZone().match(zone)) {
|
||||
if (ability instanceof ManaAbility && ability.getZone().match(zone)) {
|
||||
abilities.add((ManaAbility)ability);
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
public List<EvasionAbility> getEvasionAbilities() {
|
||||
List<EvasionAbility> abilities = new ArrayList<EvasionAbility>();
|
||||
for (Ability ability: this) {
|
||||
if (ability.isEnabled() && ability instanceof EvasionAbility) {
|
||||
if (ability instanceof EvasionAbility) {
|
||||
abilities.add((EvasionAbility)ability);
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
public List<StaticAbility> getStaticAbilities(Zone zone) {
|
||||
List<StaticAbility> zonedAbilities = new ArrayList<StaticAbility>();
|
||||
for (Ability ability: this) {
|
||||
if (ability.isEnabled() && ability instanceof StaticAbility && ability.getZone().match(zone)) {
|
||||
if (ability instanceof StaticAbility && ability.getZone().match(zone)) {
|
||||
zonedAbilities.add((StaticAbility)ability);
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
public List<TriggeredAbility> getTriggeredAbilities(Zone zone) {
|
||||
List<TriggeredAbility> zonedAbilities = new ArrayList<TriggeredAbility>();
|
||||
for (Ability ability: this) {
|
||||
if (ability.isEnabled() && ability instanceof TriggeredAbility && ability.getZone().match(zone)) {
|
||||
if (ability instanceof TriggeredAbility && ability.getZone().match(zone)) {
|
||||
zonedAbilities.add((TriggeredAbility)ability);
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
public List<ProtectionAbility> getProtectionAbilities() {
|
||||
List<ProtectionAbility> abilities = new ArrayList<ProtectionAbility>();
|
||||
for (Ability ability: this) {
|
||||
if (ability.isEnabled() && ability instanceof ProtectionAbility) {
|
||||
if (ability instanceof ProtectionAbility) {
|
||||
abilities.add((ProtectionAbility)ability);
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
public List<KickerAbility> getKickerAbilities() {
|
||||
List<KickerAbility> abilities = new ArrayList<KickerAbility>();
|
||||
for (Ability ability: this) {
|
||||
if (ability.isEnabled() && ability instanceof KickerAbility) {
|
||||
if (ability instanceof KickerAbility) {
|
||||
abilities.add((KickerAbility)ability);
|
||||
}
|
||||
}
|
||||
|
@ -153,6 +153,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Abilities abilities) {
|
||||
if (this.size() < abilities.size())
|
||||
return false;
|
||||
|
@ -170,6 +171,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(UUID abilityId) {
|
||||
for (Ability ability: this) {
|
||||
if (ability.getId().equals(abilityId))
|
||||
|
@ -178,6 +180,7 @@ public class AbilitiesImpl extends ArrayList<Ability> implements Abilities, Seri
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ability get(UUID abilityId) {
|
||||
for (Ability ability: this) {
|
||||
if (ability.getId().equals(abilityId))
|
||||
|
|
|
@ -66,10 +66,9 @@ public interface Ability extends Serializable {
|
|||
public Zone getZone();
|
||||
public String getRule();
|
||||
public String getName();
|
||||
public boolean isEnabled();
|
||||
public void setEnabled(boolean enabled);
|
||||
public boolean activate(Game game, boolean noMana);
|
||||
public boolean resolve(Game game);
|
||||
public void reset(Game game);
|
||||
|
||||
public void setControllerId(UUID controllerId);
|
||||
public void setSourceId(UUID sourceID);
|
||||
|
|
|
@ -113,6 +113,9 @@ public abstract class AbilityImpl implements Ability, Serializable {
|
|||
return costs.pay(game, noMana);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(Game game) {}
|
||||
|
||||
protected boolean useAlternativeCost(Game game) {
|
||||
for (AlternativeCost cost: alternativeCosts) {
|
||||
if (cost.isAvailable(game)) {
|
||||
|
@ -197,6 +200,13 @@ public abstract class AbilityImpl implements Ability, Serializable {
|
|||
sbRule.append(cost.getText()).append("\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (Cost cost: this.costs) {
|
||||
if (!(cost instanceof ManaCost)) {
|
||||
sbRule.append("As an additional cost to cast {this}, ").append(cost.getText()).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sbRule.append(effects.getText());
|
||||
|
||||
|
@ -208,16 +218,6 @@ public abstract class AbilityImpl implements Ability, Serializable {
|
|||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCost(Cost cost) {
|
||||
if (cost != null) {
|
||||
|
@ -273,9 +273,7 @@ public abstract class AbilityImpl implements Ability, Serializable {
|
|||
|
||||
@Override
|
||||
public UUID getFirstTarget() {
|
||||
if (this.targets.size() > 0)
|
||||
return this.targets.get(0).getFirstTarget();
|
||||
return null;
|
||||
return targets.getFirstTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.util.UUID;
|
|||
import mage.Constants.CardType;
|
||||
import mage.Constants.Zone;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.keyword.FlashAbility;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
|
@ -48,8 +49,10 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean canActivate(UUID playerId, Game game) {
|
||||
if ((game.getObject(sourceId).getCardType().contains(CardType.INSTANT) || game.canPlaySorcery(playerId)) &&
|
||||
costs.canPay(playerId, game) && targets.canChoose(sourceId, playerId, game)) {
|
||||
if ((game.getObject(sourceId).getCardType().contains(CardType.INSTANT) ||
|
||||
game.getObject(sourceId).getAbilities().containsKey(FlashAbility.getInstance().getId()) ||
|
||||
game.canPlaySorcery(playerId)) &&
|
||||
costs.canPay(playerId, game) && targets.canChoose(sourceId, playerId, game)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -42,19 +42,34 @@ import mage.game.Game;
|
|||
*/
|
||||
public class ActivateOncePerTurnActivatedAbility extends ActivatedAbilityImpl {
|
||||
|
||||
protected UUID effectId;
|
||||
|
||||
public ActivateOncePerTurnActivatedAbility(Zone zone, Effect effect, Cost cost) {
|
||||
super(zone, effect, cost);
|
||||
effectId = effect.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canActivate(UUID playerId, Game game) {
|
||||
//assumes that ability creates a continuous effect
|
||||
if (game.getContinuousEffects().effectExists(this.id))
|
||||
return false;
|
||||
return super.canActivate(playerId, game);
|
||||
Boolean activated = (Boolean)game.getState().getValue(this.id.toString() + "activated");
|
||||
if (activated == null)
|
||||
return true;
|
||||
else
|
||||
return !activated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean activate(Game game, boolean noMana) {
|
||||
if (canActivate(this.controllerId, game)) {
|
||||
if (super.activate(game, noMana)) {
|
||||
game.getState().setValue(this.id.toString() + "activated", Boolean.TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(Game game) {
|
||||
game.getState().setValue(this.id.toString() + "activated", Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
///*
|
||||
//* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
//*
|
||||
//* Redistribution and use in source and binary forms, with or without modification, are
|
||||
//* permitted provided that the following conditions are met:
|
||||
//*
|
||||
//* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
//* conditions and the following disclaimer.
|
||||
//*
|
||||
//* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
//* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
//* provided with the distribution.
|
||||
//*
|
||||
//* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
//* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
//* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
//* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
//* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
//* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
//* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
//* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//*
|
||||
//* The views and conclusions contained in the software and documentation are those of the
|
||||
//* authors and should not be interpreted as representing official policies, either expressed
|
||||
//* or implied, of BetaSteward_at_googlemail.com.
|
||||
//*/
|
||||
//
|
||||
//package mage.abilities.common;
|
||||
//
|
||||
//import mage.abilities.TriggeredAbilityImpl;
|
||||
//import mage.abilities.effects.Effect;
|
||||
//import mage.game.Game;
|
||||
//import mage.game.events.GameEvent;
|
||||
//
|
||||
///**
|
||||
// *
|
||||
// * @author BetaSteward_at_googlemail.com
|
||||
// */
|
||||
//public class AsRequiredTriggeredAbility extends TriggeredAbilityImpl {
|
||||
//
|
||||
// public AsRequiredTriggeredAbility(Effect effect) {
|
||||
// super(null, effect);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void handleEvent(GameEvent event, Game game) {
|
||||
// }
|
||||
//}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.common;
|
||||
|
||||
import mage.Constants.Duration;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.Constants.Zone;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.RequirementAttackEffect;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetDefender;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class AttacksEachTurnStaticAbility extends StaticAbility {
|
||||
|
||||
public AttacksEachTurnStaticAbility() {
|
||||
super(Zone.BATTLEFIELD, new AttacksEachTurnEffect());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AttacksEachTurnEffect extends RequirementAttackEffect {
|
||||
|
||||
public AttacksEachTurnEffect() {
|
||||
super(Duration.WhileOnBattlefield);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
Permanent creature = game.getPermanent(this.source.getSourceId());
|
||||
if (creature != null) {
|
||||
if (creature.canAttack(game)) {
|
||||
TargetDefender target = new TargetDefender(game.getCombat().getDefenders(), creature.getControllerId());
|
||||
Player controller = game.getPlayer(creature.getControllerId());
|
||||
while (!target.isChosen())
|
||||
controller.chooseTarget(Outcome.Damage, target, game);
|
||||
game.getCombat().declareAttacker(creature.getId(), target.getFirstTarget(), game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "{this} attacks each turn if able.";
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ import java.io.Serializable;
|
|||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.target.Targets;
|
||||
|
||||
public interface Cost extends Serializable {
|
||||
|
||||
|
@ -41,7 +42,8 @@ public interface Cost extends Serializable {
|
|||
public boolean isPaid();
|
||||
public void clearPaid();
|
||||
public void setPaid();
|
||||
|
||||
public Targets getTargets();
|
||||
|
||||
public Ability getAbility();
|
||||
public void setAbility(Ability ability);
|
||||
|
||||
|
|
|
@ -29,16 +29,15 @@
|
|||
package mage.abilities.costs;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.target.Target;
|
||||
import mage.target.Targets;
|
||||
|
||||
public abstract class CostImpl implements Cost {
|
||||
|
||||
protected String text;
|
||||
protected Ability ability;
|
||||
protected boolean paid = false;
|
||||
|
||||
// public CostImpl(Ability ability) {
|
||||
// this.ability = ability;
|
||||
// }
|
||||
protected Targets targets = new Targets(null);
|
||||
|
||||
public CostImpl() {
|
||||
}
|
||||
|
@ -56,6 +55,19 @@ public abstract class CostImpl implements Cost {
|
|||
@Override
|
||||
public void setAbility(Ability ability) {
|
||||
this.ability = ability;
|
||||
targets.setSource(ability);
|
||||
}
|
||||
|
||||
public void addTarget(Target target) {
|
||||
if (target != null) {
|
||||
target.setAbility(ability);
|
||||
this.targets.add(target);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Targets getTargets() {
|
||||
return this.targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.UUID;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.game.Game;
|
||||
import mage.target.Targets;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -142,4 +143,13 @@ public class CostsImpl<T extends Cost> extends ArrayList<T> implements Costs<T>
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Targets getTargets() {
|
||||
Targets targets = new Targets(ability);
|
||||
for (Cost cost: this) {
|
||||
targets.addAll(cost.getTargets());
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.costs.common;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.Constants.Zone;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class ReturnToHandTargetCost extends CostImpl {
|
||||
|
||||
public ReturnToHandTargetCost(TargetControlledPermanent target) {
|
||||
this.addTarget(target);
|
||||
this.text = "return " + target.getTargetName() + " you control to it's owner's hand";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Game game, boolean noMana) {
|
||||
if (targets.choose(Outcome.ReturnToHand, game)) {
|
||||
Permanent source = game.getPermanent(targets.getFirstTarget());
|
||||
if (source != null) {
|
||||
paid = source.moveToZone(Zone.HAND, game, false);
|
||||
}
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(UUID playerId, Game game) {
|
||||
return targets.canChoose(playerId, playerId, game);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -30,10 +30,11 @@ package mage.abilities.costs.common;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetSacrificePermanent;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -41,18 +42,15 @@ import mage.target.common.TargetSacrificePermanent;
|
|||
*/
|
||||
public class SacrificeTargetCost extends CostImpl {
|
||||
|
||||
public TargetSacrificePermanent target;
|
||||
|
||||
public SacrificeTargetCost(TargetSacrificePermanent target) {
|
||||
this.target = target;
|
||||
public SacrificeTargetCost(TargetControlledPermanent target) {
|
||||
this.addTarget(target);
|
||||
this.text = "Sacrifice " + target.getTargetName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Game game, boolean noMana) {
|
||||
target.setAbility(ability);
|
||||
if (target.choose(Outcome.Sacrifice, game)) {
|
||||
Permanent source = game.getPermanent(target.getFirstTarget());
|
||||
if (targets.choose(Outcome.Sacrifice, game)) {
|
||||
Permanent source = game.getPermanent(targets.getFirstTarget());
|
||||
if (source != null) {
|
||||
paid = source.sacrifice(this.ability.getSourceId(), game);
|
||||
}
|
||||
|
@ -62,7 +60,11 @@ public class SacrificeTargetCost extends CostImpl {
|
|||
|
||||
@Override
|
||||
public boolean canPay(UUID playerId, Game game) {
|
||||
return target.canChoose(playerId, playerId, game);
|
||||
return targets.canChoose(playerId, playerId, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAbility(Ability ability) {
|
||||
super.setAbility(ability);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,12 @@ public abstract class ManaCostImpl extends CostImpl implements ManaCost {
|
|||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPaid() {
|
||||
payment.clear();
|
||||
super.clearPaid();
|
||||
}
|
||||
|
||||
protected boolean assignColored(ManaPool pool, ColoredManaSymbol mana) {
|
||||
switch (mana) {
|
||||
case B:
|
||||
|
|
|
@ -76,6 +76,7 @@ public class MonoHybridManaCost extends ManaCostImpl implements ManaCost {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testPay(Mana testMana) {
|
||||
switch (mana) {
|
||||
case B:
|
||||
|
|
61
Mage/src/mage/abilities/effects/RequirementAttackEffect.java
Normal file
61
Mage/src/mage/abilities/effects/RequirementAttackEffect.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects;
|
||||
|
||||
import mage.Constants.Duration;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public abstract class RequirementAttackEffect extends ReplacementEffectImpl {
|
||||
|
||||
public RequirementAttackEffect(Duration duration) {
|
||||
super(duration, Outcome.Detriment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Game game) {
|
||||
apply(game);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Game game) {
|
||||
if (event.getType().equals(EventType.DECLARE_ATTACKERS_STEP_PRE))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
61
Mage/src/mage/abilities/effects/RequirementBlockEffect.java
Normal file
61
Mage/src/mage/abilities/effects/RequirementBlockEffect.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects;
|
||||
|
||||
import mage.Constants.Duration;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public abstract class RequirementBlockEffect extends ReplacementEffectImpl {
|
||||
|
||||
public RequirementBlockEffect(Duration duration) {
|
||||
super(duration, Outcome.Detriment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Game game) {
|
||||
apply(game);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Game game) {
|
||||
if (event.getType().equals(EventType.DECLARE_BLOCKERS_STEP_PRE))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.Constants.Duration;
|
||||
import mage.Constants.Layer;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.Constants.SubLayer;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.counters.Counter;
|
||||
import mage.counters.PlusOneCounter;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class AddPlusOneCountersControlledEffect extends OneShotEffect {
|
||||
|
||||
private int amount;
|
||||
private FilterPermanent filter;
|
||||
|
||||
public AddPlusOneCountersControlledEffect(int amount) {
|
||||
this(amount, new FilterCreaturePermanent());
|
||||
}
|
||||
|
||||
public AddPlusOneCountersControlledEffect(int amount, FilterPermanent filter) {
|
||||
super(Outcome.Benefit);
|
||||
this.amount = amount;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, this.source.getControllerId())) {
|
||||
perm.getCounters().addCounter(new PlusOneCounter(amount)); }
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Put ").append(amount).append(" +1/+1 counter");
|
||||
if (amount > 1)
|
||||
sb.append("s");
|
||||
sb.append(" on each ").append(filter.getName()).append(" you control");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -37,12 +37,13 @@ import mage.game.permanent.Permanent;
|
|||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class EquipEffect extends OneShotEffect {
|
||||
public class AttachEffect extends OneShotEffect {
|
||||
|
||||
public EquipEffect(Outcome outcome) {
|
||||
public AttachEffect(Outcome outcome) {
|
||||
super(outcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
|
@ -51,8 +52,4 @@ public class EquipEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Equip";
|
||||
}
|
||||
}
|
|
@ -46,10 +46,12 @@ import mage.game.permanent.token.Token;
|
|||
public class BecomesCreatureSourceEOTEffect extends ContinuousEffectImpl {
|
||||
|
||||
protected Token token;
|
||||
protected String type;
|
||||
|
||||
public BecomesCreatureSourceEOTEffect(Token token) {
|
||||
public BecomesCreatureSourceEOTEffect(Token token, String type) {
|
||||
super(Duration.EndOfTurn, Outcome.BecomeCreature);
|
||||
this.token = token;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -97,7 +99,7 @@ public class BecomesCreatureSourceEOTEffect extends ContinuousEffectImpl {
|
|||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Until end of turn {this} becomes a " + token.getDescription() + ". It's still a land";
|
||||
return "Until end of turn {this} becomes a " + token.getDescription() + " that's still a " + this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -51,14 +51,17 @@ public class CantCounterControlledEffect extends ReplacementEffectImpl {
|
|||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Game game) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Game game) {
|
||||
if (event.getType() == EventType.COUNTER) {
|
||||
filter.getControllerId().clear();
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetAmount;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class DamageMultiEffect extends OneShotEffect {
|
||||
|
||||
protected int amount;
|
||||
|
||||
public DamageMultiEffect(int amount) {
|
||||
super(Outcome.Damage);
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
Target multiTarget = this.source.getTargets().get(0);
|
||||
for (UUID target: multiTarget.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(target);
|
||||
if (permanent != null) {
|
||||
permanent.damage(multiTarget.getTargetAmount(target), this.source.getSourceId(), game);
|
||||
}
|
||||
else {
|
||||
Player player = game.getPlayer(target);
|
||||
if (player != null) {
|
||||
player.damage(multiTarget.getTargetAmount(target), this.source.getSourceId(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{source} deals ").append(Integer.toString(amount));
|
||||
sb.append(" damage divided as you choose among any number of target ").append(this.source.getTargets().get(0).getTargetName());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -50,6 +50,7 @@ public class DestroyTargetEffect extends OneShotEffect {
|
|||
this.noRegen = noRegen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
Permanent permanent = game.getPermanent(this.source.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.Constants.Outcome;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class DrawCardControllerEffect extends OneShotEffect {
|
||||
|
||||
protected int amount;
|
||||
|
||||
public DrawCardControllerEffect(int amount) {
|
||||
super(Outcome.DrawCard);
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
Player player = game.getPlayer(this.source.getControllerId());
|
||||
if (player != null) {
|
||||
player.drawCards(amount, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("draw ").append(Integer.toString(amount)).append(" card").append((amount == 1?"":"s"));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -58,7 +58,9 @@ public class DrawCardTargetEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Target player draws " + Integer.toString(amount) + " card" + (amount == 1?"":"s");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Target player draws ").append(Integer.toString(amount)).append(" card").append((amount == 1?"":"s"));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,11 +41,11 @@ import mage.game.permanent.Permanent;
|
|||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class GainAbilityEquippedEffect extends ContinuousEffectImpl {
|
||||
public class GainAbilityAttachedEffect extends ContinuousEffectImpl {
|
||||
|
||||
protected Ability ability;
|
||||
|
||||
public GainAbilityEquippedEffect(Ability ability) {
|
||||
public GainAbilityAttachedEffect(Ability ability) {
|
||||
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
||||
this.ability = ability;
|
||||
}
|
|
@ -55,8 +55,11 @@ public class GainProtectionFromColorTargetEOTEffect extends GainAbilityTargetEff
|
|||
protectionFilter.setColor(choice.getColor());
|
||||
protectionFilter.setMessage(choice.getChoice());
|
||||
Permanent creature = game.getPermanent(source.getFirstTarget());
|
||||
creature.addAbility(ability);
|
||||
return true;
|
||||
if (creature != null) {
|
||||
creature.addAbility(ability);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.Constants.Outcome;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class LoseLifeTargetEffect extends OneShotEffect {
|
||||
|
||||
protected int amount;
|
||||
|
||||
public LoseLifeTargetEffect(int amount) {
|
||||
super(Outcome.Damage);
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
Player player = game.getPlayer(this.source.getFirstTarget());
|
||||
if (player != null) {
|
||||
player.loseLife(amount, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Target " + this.source.getTargets().get(0).getTargetName() + " loses " + Integer.toString(amount) + " life";
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -48,7 +48,7 @@ public class PlayTargetWithoutPayingManaEffect extends OneShotEffect {
|
|||
public boolean apply(Game game) {
|
||||
Player controller = game.getPlayer(this.source.getControllerId());
|
||||
Card target = (Card) game.getObject(this.source.getFirstTarget());
|
||||
return controller.cast(target, game, true);
|
||||
return controller.cast(target.getSpellAbility(), game, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -57,7 +57,7 @@ public class PreventAllCombatDamageEffect extends PreventionEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Game game) {
|
||||
if (game.getTurn().getStep() == PhaseStep.COMBAT_DAMAGE)
|
||||
if (game.getTurn().getStepType() == PhaseStep.COMBAT_DAMAGE)
|
||||
return super.applies(event, game);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.Constants.Duration;
|
||||
import mage.abilities.effects.PreventionEffectImpl;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class PreventAllDamageSourceEffect extends PreventionEffectImpl {
|
||||
|
||||
public PreventAllDamageSourceEffect(Duration duration) {
|
||||
super(duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Game game) {
|
||||
event.setAmount(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Game game) {
|
||||
if (super.applies(event, game)) {
|
||||
if (event.getTargetId().equals(this.source.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Prevent all damage that would be dealt to {this} " + duration.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.Constants.Outcome;
|
||||
import mage.Constants.Zone;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class ReturnToHandTargetEffect extends OneShotEffect {
|
||||
|
||||
public ReturnToHandTargetEffect() {
|
||||
super(Outcome.ReturnToHand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
Permanent permanent = game.getPermanent(this.source.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
return permanent.moveToZone(Zone.HAND, game, false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Return target " + this.source.getTargets().get(0).getTargetName() + " to it's owner's hand";
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LokiX
|
||||
*/
|
||||
public class SearchLibraryPutInHandEffect extends OneShotEffect {
|
||||
|
||||
private TargetCardInLibrary target;
|
||||
|
||||
public SearchLibraryPutInHandEffect(TargetCardInLibrary target) {
|
||||
super(Outcome.DrawCard);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
Player player = game.getPlayer(this.source.getControllerId());
|
||||
player.searchLibrary(target, game);
|
||||
if (target.getTargets().size() > 0) {
|
||||
for (UUID cardId: target.getTargets()) {
|
||||
Card card = player.getLibrary().remove(cardId);
|
||||
if (card != null){
|
||||
player.putInHand(card, game);
|
||||
}
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Search your library for ");
|
||||
if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) {
|
||||
sb.append("up to ").append(target.getMaxNumberOfTargets()).append(" ");
|
||||
sb.append(target.getTargetName()).append(" and put them into your hand");
|
||||
}
|
||||
else {
|
||||
sb.append("a ").append(target.getTargetName()).append(" and put that card into your hand");
|
||||
}
|
||||
sb.append(". Then shuffle your library");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(Ability ability) {
|
||||
super.setSource(ability);
|
||||
target.setAbility(ability);
|
||||
}
|
||||
}
|
|
@ -64,23 +64,25 @@ public class SearchLibraryPutInPlayEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game) {
|
||||
Player player = game.getPlayer(this.source.getControllerId());
|
||||
player.searchLibrary(target, game);
|
||||
if (target.getTargets().size() > 0) {
|
||||
for (UUID cardId: target.getTargets()) {
|
||||
Card card = player.getLibrary().remove(cardId);
|
||||
if (card != null) {
|
||||
if (player.putOntoBattlefield(card, game)) {
|
||||
if (tapped) {
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null)
|
||||
permanent.setTapped(true);
|
||||
if (player.searchLibrary(target, game)) {
|
||||
if (target.getTargets().size() > 0) {
|
||||
for (UUID cardId: target.getTargets()) {
|
||||
Card card = player.getLibrary().remove(cardId);
|
||||
if (card != null) {
|
||||
if (player.putOntoBattlefield(card, game)) {
|
||||
if (tapped) {
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null)
|
||||
permanent.setTapped(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -63,6 +63,7 @@ public class SearchLibraryRevealPutInHandEffect extends OneShotEffect {
|
|||
Card card = player.getLibrary().remove(cardId);
|
||||
if (card != null) {
|
||||
player.putInHand(card, game);
|
||||
revealed.add(card);
|
||||
}
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
|
|
|
@ -59,7 +59,7 @@ public class SkipNextUntapTargetEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Game game) {
|
||||
if (game.getTurn().getStep() == PhaseStep.UNTAP &&
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP &&
|
||||
event.getType() == EventType.UNTAP &&
|
||||
event.getTargetId().equals(source.getFirstTarget())) {
|
||||
return true;
|
||||
|
|
71
Mage/src/mage/abilities/effects/common/TapTargetEffect.java
Normal file
71
Mage/src/mage/abilities/effects/common/TapTargetEffect.java
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class TapTargetEffect extends OneShotEffect {
|
||||
|
||||
public TapTargetEffect() {
|
||||
super(Outcome.Tap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game) {
|
||||
for (UUID target: this.source.getTargets().get(0).getTargets()) {
|
||||
Permanent permanent = game.getPermanent(target);
|
||||
if (permanent != null) {
|
||||
permanent.setTapped(true);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
Target target = this.source.getTargets().get(0);
|
||||
if (target.getNumberOfTargets() > 1)
|
||||
return "tap " + target.getNumberOfTargets() + " target " + this.source.getTargets().get(0).getTargetName() + "s";
|
||||
else
|
||||
return "tap target " + this.source.getTargets().get(0).getTargetName();
|
||||
}
|
||||
|
||||
}
|
|
@ -87,7 +87,7 @@ class CascadeEffect extends OneShotEffect {
|
|||
|
||||
if (card != null) {
|
||||
if (player.chooseUse(outcome, "Use cascade effect on " + card.getName() + "?", game)) {
|
||||
player.cast(card, game, true);
|
||||
player.cast(card.getSpellAbility(), game, true);
|
||||
exile.remove(card.getId());
|
||||
}
|
||||
}
|
||||
|
|
54
Mage/src/mage/abilities/keyword/EnchantAbility.java
Normal file
54
Mage/src/mage/abilities/keyword/EnchantAbility.java
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import mage.Constants.Outcome;
|
||||
import mage.Constants.Zone;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class EnchantAbility extends StaticAbility {
|
||||
|
||||
public EnchantAbility(Outcome outcome, TargetPermanent target) {
|
||||
super(Zone.BATTLEFIELD, new AttachEffect(outcome));
|
||||
this.addTarget(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Enchant " + this.getTargets().get(0).getTargetName();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -34,7 +34,7 @@ import mage.Constants.TimingRule;
|
|||
import mage.Constants.Zone;
|
||||
import mage.abilities.ActivatedAbilityImpl;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.effects.common.EquipEffect;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
|
@ -44,9 +44,14 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public class EquipAbility extends ActivatedAbilityImpl {
|
||||
|
||||
public EquipAbility(Outcome outcome, Cost cost) {
|
||||
super(Zone.BATTLEFIELD, new EquipEffect(outcome), cost);
|
||||
this.targets.add(new TargetCreaturePermanent(1, TargetController.YOU));
|
||||
super(Zone.BATTLEFIELD, new AttachEffect(outcome), cost);
|
||||
this.addTarget(new TargetCreaturePermanent(1, TargetController.YOU));
|
||||
this.timing = TimingRule.SORCERY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Equip" + super.getRule();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,8 +51,9 @@ public class ExaltedAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == EventType.DECLARED_ATTACKERS && game.getActivePlayerId().equals(this.controllerId) ) {
|
||||
if (game.getCombat().attacksAlone()) {
|
||||
this.targets.add(new TargetCreaturePermanent());
|
||||
this.targets.get(0).getTargets().add(game.getCombat().getAttackers().get(0));
|
||||
TargetCreaturePermanent target = new TargetCreaturePermanent();
|
||||
this.addTarget(target);
|
||||
this.getTargets().get(0).addTarget(game.getCombat().getAttackers().get(0), game);
|
||||
trigger(game, event.getPlayerId());
|
||||
return true;
|
||||
}
|
||||
|
|
60
Mage/src/mage/abilities/keyword/FlashAbility.java
Normal file
60
Mage/src/mage/abilities/keyword/FlashAbility.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import mage.Constants.Zone;
|
||||
import mage.abilities.StaticAbility;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class FlashAbility extends StaticAbility {
|
||||
|
||||
private static final FlashAbility fINSTANCE = new FlashAbility();
|
||||
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
return fINSTANCE;
|
||||
}
|
||||
|
||||
public static FlashAbility getInstance() {
|
||||
return fINSTANCE;
|
||||
}
|
||||
|
||||
private FlashAbility() {
|
||||
super(Zone.BATTLEFIELD, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Flash";
|
||||
}
|
||||
|
||||
}
|
|
@ -33,7 +33,7 @@ import mage.Constants.TimingRule;
|
|||
import mage.Constants.Zone;
|
||||
import mage.abilities.ActivatedAbilityImpl;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.effects.common.EquipEffect;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.target.common.TargetLandPermanent;
|
||||
|
||||
/**
|
||||
|
@ -43,9 +43,9 @@ import mage.target.common.TargetLandPermanent;
|
|||
public class FortifyAbility extends ActivatedAbilityImpl {
|
||||
//20091005 - 702.64
|
||||
|
||||
public FortifyAbility(Zone zone, EquipEffect effect, Cost cost) {
|
||||
public FortifyAbility(Zone zone, AttachEffect effect, Cost cost) {
|
||||
super(zone, effect, cost);
|
||||
targets.add(new TargetLandPermanent(1, TargetController.YOU));
|
||||
this.addTarget(new TargetLandPermanent(1, TargetController.YOU));
|
||||
timing = TimingRule.SORCERY;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,16 @@ public class KickerAbility extends StaticAbility {
|
|||
public boolean activate(Game game, boolean noMana) {
|
||||
Player player = game.getPlayer(this.getControllerId());
|
||||
if (player.chooseUse(this.effects.get(0).getOutcome(), "Use kicker " + this.effects.get(0).getText() + "?", game)) {
|
||||
kicked = super.activate(game, noMana);
|
||||
game.saveState();
|
||||
game.bookmarkState();
|
||||
if (super.activate(game, noMana)) {
|
||||
game.removeLastBookmark();
|
||||
kicked = true;
|
||||
}
|
||||
else {
|
||||
game.restoreState();
|
||||
kicked = false;
|
||||
}
|
||||
return kicked;
|
||||
}
|
||||
return false;
|
||||
|
|
60
Mage/src/mage/abilities/keyword/LandwalkAbility.java
Normal file
60
Mage/src/mage/abilities/keyword/LandwalkAbility.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import mage.abilities.EvasionAbilityImpl;
|
||||
import mage.filter.common.FilterLandCard;
|
||||
import mage.filter.common.FilterLandPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class LandwalkAbility extends EvasionAbilityImpl {
|
||||
|
||||
FilterLandPermanent filter;
|
||||
|
||||
public LandwalkAbility(FilterLandPermanent filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBlock(Permanent permanent, Game game) {
|
||||
return game.getBattlefield().countAll(filter, permanent.getControllerId()) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return filter.getMessage() + "walk";
|
||||
}
|
||||
|
||||
}
|
86
Mage/src/mage/abilities/keyword/MultikickerAbility.java
Normal file
86
Mage/src/mage/abilities/keyword/MultikickerAbility.java
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class MultikickerAbility extends KickerAbility {
|
||||
|
||||
int activateCount = 0;
|
||||
|
||||
public MultikickerAbility(Effect effect, boolean replaces) {
|
||||
super(effect, replaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean activate(Game game, boolean noMana) {
|
||||
activateCount = 0;
|
||||
while (true) {
|
||||
this.costs.clearPaid();
|
||||
this.manaCosts.clearPaid();
|
||||
if (!super.activate(game, noMana))
|
||||
break;
|
||||
activateCount++;
|
||||
}
|
||||
kicked = activateCount > 0;
|
||||
return kicked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resolve(Game game) {
|
||||
boolean result = false;
|
||||
for (int i = 0; i < activateCount; i++) {
|
||||
result |= super.resolve(game);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Multikicker");
|
||||
if (manaCosts.size() > 0) {
|
||||
sb.append(manaCosts.getText());
|
||||
if (costs.size() > 0)
|
||||
sb.append(",");
|
||||
}
|
||||
if (costs.size() > 0)
|
||||
sb.append(costs.getText());
|
||||
sb.append(":").append(effects.getText());
|
||||
if (replaces)
|
||||
sb.append(" instead");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -59,9 +59,9 @@ public class UnearthAbility extends ActivatedAbilityImpl {
|
|||
public UnearthAbility(ManaCosts costs) {
|
||||
super(Zone.GRAVEYARD, new UnearthEffect(), costs);
|
||||
this.timing = TimingRule.SORCERY;
|
||||
this.effects.add(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield));
|
||||
this.effects.add(new CreateDelayedTriggeredAbilityEffect(new UnearthDelayedTriggeredAbility()));
|
||||
this.effects.add(new UnearthLeavesBattlefieldEffect());
|
||||
this.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield));
|
||||
this.addEffect(new CreateDelayedTriggeredAbilityEffect(new UnearthDelayedTriggeredAbility()));
|
||||
this.addEffect(new UnearthLeavesBattlefieldEffect());
|
||||
}
|
||||
|
||||
public boolean isUnearthed() {
|
||||
|
|
|
@ -33,7 +33,6 @@ import mage.Constants.Zone;
|
|||
import mage.Mana;
|
||||
import mage.abilities.ActivatedAbilityImpl;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.game.Game;
|
||||
|
||||
|
@ -57,7 +56,7 @@ public abstract class ManaAbility extends ActivatedAbilityImpl {
|
|||
return costs.canPay(playerId, game);
|
||||
}
|
||||
|
||||
public Mana getNetMana() {
|
||||
public Mana getNetMana(Game game) {
|
||||
return netMana;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ package mage.abilities.mana;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import mage.Mana;
|
||||
import mage.game.Game;
|
||||
import mage.util.Copier;
|
||||
|
||||
/**
|
||||
|
@ -44,13 +45,13 @@ import mage.util.Copier;
|
|||
*/
|
||||
public class ManaOptions extends ArrayList<Mana> {
|
||||
|
||||
public void addMana(List<ManaAbility> abilities) {
|
||||
public void addMana(List<ManaAbility> abilities, Game game) {
|
||||
if (isEmpty())
|
||||
this.add(new Mana());
|
||||
if (!abilities.isEmpty()) {
|
||||
if (abilities.size() == 1) {
|
||||
//if there is only one mana option available add it to all the existing options
|
||||
addMana(abilities.get(0).getNetMana());
|
||||
addMana(abilities.get(0).getNetMana(game));
|
||||
}
|
||||
else if (abilities.size() > 1) {
|
||||
//perform a union of all existing options and the new options
|
||||
|
@ -61,7 +62,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
for (Mana mana: copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(ability.getNetMana());
|
||||
newMana.add(ability.getNetMana(game));
|
||||
this.add(newMana);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
package mage.cards;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
@ -43,6 +44,7 @@ public interface Cards extends Map<UUID, Card>, Serializable {
|
|||
public void setOwner(UUID ownerId);
|
||||
public void addAll(List<Card> createCards);
|
||||
public List<Card> getCards(FilterCard filter);
|
||||
public Collection<Card> getUniqueCards();
|
||||
public Card getRandom();
|
||||
public int count(FilterCard filter);
|
||||
|
||||
|
|
|
@ -30,8 +30,11 @@ package mage.cards;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Zone;
|
||||
|
@ -119,4 +122,15 @@ public class CardsImpl extends LinkedHashMap<UUID, Card> implements Cards, Seria
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Card> getUniqueCards() {
|
||||
Map<String, Card> cards = new HashMap<String, Card>();
|
||||
for(Card card: this.values()) {
|
||||
if (!cards.containsKey(card.getName())) {
|
||||
cards.put(card.getName(), card);
|
||||
}
|
||||
}
|
||||
return cards.values();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
|
||||
package mage.filter.common;
|
||||
|
||||
import mage.abilities.keyword.DefenderAbility;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
@ -46,6 +49,15 @@ public class FilterCreatureForAttack extends FilterCreaturePermanent {
|
|||
this.useBlocking = true;
|
||||
this.tapped = false;
|
||||
this.useTapped = true;
|
||||
this.abilities.add(DefenderAbility.getInstance());
|
||||
this.notAbilities = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(Permanent permanent) {
|
||||
if (!super.match(permanent))
|
||||
return false;
|
||||
|
||||
return permanent.canTap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.Collection;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.cards.Card;
|
||||
import mage.game.events.GameEvent;
|
||||
|
||||
/**
|
||||
|
@ -73,9 +74,19 @@ public class Exile implements Serializable {
|
|||
return exileZones.get(id);
|
||||
}
|
||||
|
||||
void checkTriggers(GameEvent event, Game game) {
|
||||
public void checkTriggers(GameEvent event, Game game) {
|
||||
for (ExileZone exile: exileZones.values()) {
|
||||
exile.checkTriggers(event, game);
|
||||
}
|
||||
}
|
||||
|
||||
public Card getCard(UUID cardId) {
|
||||
Card card;
|
||||
for (ExileZone exile: exileZones.values()) {
|
||||
card = exile.get(cardId);
|
||||
if (card != null)
|
||||
return card;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
package mage.game;
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.game.stack.SpellStack;
|
||||
import mage.MageObject;
|
||||
import java.io.Serializable;
|
||||
|
@ -65,13 +66,16 @@ public interface Game extends MageItem, Serializable {
|
|||
public MultiplayerAttackOption getAttackOption();
|
||||
|
||||
//game data methods
|
||||
public Object getCustomData();
|
||||
public void setCustomData(Object data);
|
||||
public MageObject getObject(UUID objectId);
|
||||
public Permanent getPermanent(UUID permanentId);
|
||||
public Card getCard(UUID cardId);
|
||||
public void addPlayer(Player player) throws GameException;
|
||||
public Player getPlayer(UUID playerId);
|
||||
public Players getPlayers();
|
||||
public PlayerList getPlayerList(UUID playerId);
|
||||
public Set<UUID> getOpponents(UUID controllerId);
|
||||
public PlayerList getPlayerList();
|
||||
public Set<UUID> getOpponents(UUID playerId);
|
||||
public Turn getTurn();
|
||||
public int getTurnNum();
|
||||
public boolean isMainPhase();
|
||||
|
@ -98,6 +102,7 @@ public interface Game extends MageItem, Serializable {
|
|||
public void fireSelectTargetEvent(UUID playerId, String message, TriggeredAbilities abilities, boolean required);
|
||||
public void fireRevealCardsEvent(String message, Cards cards);
|
||||
public void fireSelectEvent(UUID playerId, String message);
|
||||
public void fireLookAtCardsEvent(UUID playerId, String message, Cards cards);
|
||||
public void firePriorityEvent(UUID playerId);
|
||||
public void firePlayManaEvent(UUID playerId, String message);
|
||||
public void firePlayXManaEvent(UUID playerId, String message);
|
||||
|
@ -112,6 +117,7 @@ public interface Game extends MageItem, Serializable {
|
|||
public boolean replaceEvent(GameEvent event);
|
||||
|
||||
//game play methods
|
||||
public void init();
|
||||
public void start();
|
||||
public void end();
|
||||
public void mulligan(UUID playerId);
|
||||
|
@ -121,21 +127,8 @@ public interface Game extends MageItem, Serializable {
|
|||
public void addEffect(ContinuousEffect continuousEffect);
|
||||
public void addTriggeredAbility(TriggeredAbility ability);
|
||||
public void applyEffects();
|
||||
// public boolean checkStateAndTriggered();
|
||||
// public boolean checkStateBasedActions();
|
||||
public boolean checkStateAndTriggered();
|
||||
public void playPriority(UUID activePlayerId);
|
||||
public boolean playUntapStep(UUID activePlayerId);
|
||||
public boolean playUpkeepStep(UUID activePlayerId);
|
||||
public boolean playDrawStep(UUID activePlayerId);
|
||||
public boolean playPreCombatMainStep(UUID activePlayerId);
|
||||
public boolean playBeginCombatStep(UUID activePlayerId);
|
||||
public boolean playDeclareAttackersStep(UUID activePlayerId);
|
||||
public boolean playDeclareBlockersStep(UUID activePlayerId);
|
||||
public boolean playCombatDamageStep(UUID activePlayerId, boolean first);
|
||||
public boolean playEndCombatStep(UUID activePlayerId);
|
||||
public boolean playPostMainStep(UUID activePlayerId);
|
||||
public boolean playEndStep(UUID activePlayerId);
|
||||
public boolean playCleanupStep(UUID activePlayerId);
|
||||
|
||||
//game transaction methods
|
||||
public void saveState();
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
|
||||
package mage.game;
|
||||
|
||||
import java.io.IOException;
|
||||
import mage.game.stack.SpellStack;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Stack;
|
||||
import java.util.UUID;
|
||||
|
@ -47,6 +47,7 @@ import mage.abilities.TriggeredAbilities;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffects;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.choices.Choice;
|
||||
import mage.filter.Filter.ComparisonScope;
|
||||
|
@ -55,7 +56,6 @@ import mage.filter.common.FilterFortification;
|
|||
import mage.filter.common.FilterLegendaryPermanent;
|
||||
import mage.filter.common.FilterPlaneswalkerPermanent;
|
||||
import mage.game.combat.Combat;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.game.events.Listener;
|
||||
|
@ -73,18 +73,19 @@ import mage.target.TargetPlayer;
|
|||
|
||||
public abstract class GameImpl implements Game, Serializable {
|
||||
|
||||
private Stack<Integer> savedStates = new Stack<Integer>();
|
||||
private transient Stack<Integer> savedStates = new Stack<Integer>();
|
||||
private Object customData;
|
||||
|
||||
protected UUID id;
|
||||
protected boolean ready = false;
|
||||
protected TableEventSource tableEventSource = new TableEventSource();
|
||||
protected PlayerQueryEventSource playerQueryEventSource = new PlayerQueryEventSource();
|
||||
protected transient TableEventSource tableEventSource = new TableEventSource();
|
||||
protected transient PlayerQueryEventSource playerQueryEventSource = new PlayerQueryEventSource();
|
||||
|
||||
protected GameState state;
|
||||
protected UUID startingPlayerId;
|
||||
protected UUID choosingPlayerId;
|
||||
protected Player winner;
|
||||
protected GameStates gameStates;
|
||||
protected transient GameStates gameStates = new GameStates();
|
||||
protected RangeOfInfluence range;
|
||||
protected MultiplayerAttackOption attackOption;
|
||||
|
||||
|
@ -93,7 +94,6 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
this.range = range;
|
||||
this.attackOption = attackOption;
|
||||
state = new GameState();
|
||||
gameStates = new GameStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -101,6 +101,16 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCustomData() {
|
||||
return customData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomData(Object data) {
|
||||
this.customData = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlayer(Player player) throws GameException {
|
||||
state.addPlayer(player);
|
||||
|
@ -131,6 +141,11 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
return state.getPermanent(permanentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Card getCard(UUID cardId) {
|
||||
return state.getCard(cardId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameStates getGameStates() {
|
||||
return gameStates;
|
||||
|
@ -138,7 +153,8 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
|
||||
@Override
|
||||
public void saveState() {
|
||||
gameStates.save(state);
|
||||
if (gameStates != null)
|
||||
gameStates.save(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -179,7 +195,9 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
|
||||
@Override
|
||||
public void restoreState() {
|
||||
state.restore(gameStates.rollback(savedStates.pop()));
|
||||
GameState restore = gameStates.rollback(savedStates.pop());
|
||||
if (restore != null)
|
||||
state.restore(restore);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -189,6 +207,29 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
|
||||
@Override
|
||||
public void start() {
|
||||
init();
|
||||
PlayerList players = state.getPlayerList(startingPlayerId);
|
||||
Player player = getPlayer(players.get());
|
||||
while (!isGameOver()) {
|
||||
if (player.getId().equals(startingPlayerId)) {
|
||||
state.setTurnNum(state.getTurnNum() + 1);
|
||||
fireInformEvent("Turn " + Integer.toString(state.getTurnNum()));
|
||||
}
|
||||
state.setActivePlayerId(player.getId());
|
||||
state.getTurn().play(this, player.getId());
|
||||
if (isGameOver())
|
||||
break;
|
||||
endOfTurn();
|
||||
player = players.getNext(this);
|
||||
}
|
||||
|
||||
winner = findWinner();
|
||||
|
||||
saveState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
for (Player player: state.getPlayers().values()) {
|
||||
player.init(this);
|
||||
}
|
||||
|
@ -204,6 +245,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
if (startingPlayerId == null) {
|
||||
TargetPlayer targetPlayer = new TargetPlayer();
|
||||
targetPlayer.setRequired(true);
|
||||
targetPlayer.setTargetName("starting player");
|
||||
Player choosingPlayer = getPlayer(pickChoosingPlayer());
|
||||
if (choosingPlayer.chooseTarget(Outcome.Benefit, targetPlayer, this)) {
|
||||
startingPlayerId = targetPlayer.getTargets().get(0);
|
||||
|
@ -216,13 +258,15 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
saveState();
|
||||
|
||||
//20091005 - 103.3
|
||||
for (Player player: state.getPlayerList(startingPlayerId)) {
|
||||
for (UUID playerId: state.getPlayerList(startingPlayerId)) {
|
||||
Player player = getPlayer(playerId);
|
||||
player.setLife(this.getLife(), this);
|
||||
player.drawCards(7, this);
|
||||
}
|
||||
|
||||
//20091005 - 103.4
|
||||
for (Player player: state.getPlayerList(startingPlayerId)) {
|
||||
for (UUID playerId: state.getPlayerList(startingPlayerId)) {
|
||||
Player player = getPlayer(playerId);
|
||||
while (player.getHand().size() > 0 && player.chooseMulligan(this)) {
|
||||
mulligan(player.getId());
|
||||
}
|
||||
|
@ -230,21 +274,6 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
saveState();
|
||||
}
|
||||
|
||||
while (!isGameOver()) {
|
||||
state.setTurnNum(state.getTurnNum() + 1);
|
||||
fireInformEvent("Turn " + Integer.toString(state.getTurnNum()));
|
||||
for (Player player: state.getPlayerList(startingPlayerId)) {
|
||||
state.setActivePlayerId(player.getId());
|
||||
state.getTurn().play(this, player.getId());
|
||||
if (isGameOver())
|
||||
break;
|
||||
endOfTurn();
|
||||
}
|
||||
}
|
||||
|
||||
winner = findWinner();
|
||||
|
||||
saveState();
|
||||
}
|
||||
|
||||
protected Player findWinner() {
|
||||
|
@ -314,9 +343,12 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
|
||||
@Override
|
||||
public void playPriority(UUID activePlayerId) {
|
||||
state.getPlayers().resetPassed();
|
||||
while (!isGameOver()) {
|
||||
for (Player player: getPlayerList(activePlayerId)) {
|
||||
state.getPlayers().resetPassed();
|
||||
state.getPlayerList().setCurrent(activePlayerId);
|
||||
Player player;
|
||||
while (!isGameOver()) {
|
||||
player = getPlayer(state.getPlayerList().get());
|
||||
state.setPriorityPlayerId(player.getId());
|
||||
while (!player.isPassed() && !player.hasLost() && !player.hasLeft()&& !isGameOver()) {
|
||||
checkStateAndTriggered();
|
||||
|
@ -338,8 +370,10 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
saveState();
|
||||
break;
|
||||
}
|
||||
return;
|
||||
else
|
||||
return;
|
||||
}
|
||||
state.getPlayerList().getNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,7 +410,8 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
state.addTriggeredAbility((TriggeredAbility) ability.copy());
|
||||
}
|
||||
|
||||
protected boolean checkStateAndTriggered() {
|
||||
@Override
|
||||
public boolean checkStateAndTriggered() {
|
||||
boolean somethingHappened = false;
|
||||
//20091005 - 115.5
|
||||
while (true) {
|
||||
|
@ -392,7 +427,8 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
|
||||
public boolean checkTriggered() {
|
||||
boolean played = false;
|
||||
for (Player player: getPlayerList(state.getActivePlayerId())) {
|
||||
for (UUID playerId: state.getPlayerList(state.getActivePlayerId())) {
|
||||
Player player = getPlayer(playerId);
|
||||
while (true) {
|
||||
TriggeredAbilities abilities = state.getTriggered().getControlledBy(player.getId());
|
||||
if (abilities.size() == 0)
|
||||
|
@ -516,173 +552,14 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
return somethingHappened;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playUntapStep(UUID activePlayerId) {
|
||||
fireEvent(new GameEvent(GameEvent.EventType.BEGINNING_PHASE_PRE, null, null, activePlayerId));
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.UNTAP_STEP, null, null, activePlayerId))) {
|
||||
//20091005 - 502.1/703.4a
|
||||
getPlayer(activePlayerId).phasing(this);
|
||||
//20091005 - 502.2/703.4b
|
||||
getPlayer(activePlayerId).untap(this);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.UNTAP_STEP_PRE, null, null, activePlayerId));
|
||||
fireEvent(new GameEvent(GameEvent.EventType.UNTAP_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playUpkeepStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.UPKEEP_STEP, null, null, activePlayerId))) {
|
||||
fireEvent(new GameEvent(GameEvent.EventType.UPKEEP_STEP_PRE, null, null, activePlayerId));
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.UPKEEP_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playDrawStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.DRAW_STEP, null, null, activePlayerId))) {
|
||||
//20091005 - 504.1/703.4c
|
||||
getPlayer(activePlayerId).drawCards(1, this);
|
||||
saveState();
|
||||
fireEvent(new GameEvent(GameEvent.EventType.DRAW_STEP_PRE, null, null, activePlayerId));
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.DRAW_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playPreCombatMainStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.PRECOMBAT_MAIN_STEP, null, null, activePlayerId))) {
|
||||
fireEvent(new GameEvent(GameEvent.EventType.PRECOMBAT_MAIN_STEP_PRE, null, null, activePlayerId));
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.PRECOMBAT_MAIN_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playBeginCombatStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.BEGIN_COMBAT_STEP, null, null, activePlayerId))) {
|
||||
//20091005 - 507.1
|
||||
state.getCombat().clear();
|
||||
state.getCombat().setAttacker(activePlayerId);
|
||||
state.getCombat().setDefenders(this);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.BEGIN_COMBAT_STEP_PRE, null, null, activePlayerId));
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.PRECOMBAT_MAIN_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playDeclareAttackersStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP, null, null, activePlayerId))) {
|
||||
state.getCombat().selectAttackers(this);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE, null, null, activePlayerId));
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playDeclareBlockersStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP, null, null, activePlayerId))) {
|
||||
state.getCombat().selectBlockers(this);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_PRE, null, null, activePlayerId));
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playCombatDamageStep(UUID activePlayerId, boolean first) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.COMBAT_DAMAGE_STEP, null, null, activePlayerId))) {
|
||||
fireEvent(new GameEvent(GameEvent.EventType.COMBAT_DAMAGE_STEP_PRE, null, null, activePlayerId));
|
||||
for (CombatGroup group: getCombat().getGroups()) {
|
||||
group.assignDamage(first, this);
|
||||
}
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.COMBAT_DAMAGE_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playEndCombatStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.END_COMBAT_STEP, null, null, activePlayerId))) {
|
||||
fireEvent(new GameEvent(GameEvent.EventType.END_COMBAT_STEP_PRE, null, null, activePlayerId));
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.END_COMBAT_STEP_POST, null, null, activePlayerId));
|
||||
removeCreaturesFromCombat();
|
||||
saveState();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playPostMainStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.POSTCOMBAT_MAIN_STEP, null, null, activePlayerId))) {
|
||||
fireEvent(new GameEvent(GameEvent.EventType.POSTCOMBAT_MAIN_STEP_PRE, null, null, activePlayerId));
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.POSTCOMBAT_MAIN_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playEndStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.END_TURN_STEP, null, null, activePlayerId))) {
|
||||
fireEvent(new GameEvent(GameEvent.EventType.END_TURN_STEP_PRE, null, null, activePlayerId));
|
||||
playPriority(activePlayerId);
|
||||
fireEvent(new GameEvent(GameEvent.EventType.END_TURN_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playCleanupStep(UUID activePlayerId) {
|
||||
if (!replaceEvent(new GameEvent(GameEvent.EventType.CLEANUP_STEP, null, null, activePlayerId))) {
|
||||
fireEvent(new GameEvent(GameEvent.EventType.CLEANUP_STEP_PRE, null, null, activePlayerId));
|
||||
//20091005 - 514.1
|
||||
Player player = getPlayer(activePlayerId);
|
||||
if (!player.hasLeft() && !player.hasLost())
|
||||
player.discardToMax(this);
|
||||
state.getBattlefield().endOfTurn(activePlayerId, this);
|
||||
state.removeEotEffects(this);
|
||||
if (checkStateAndTriggered()) {
|
||||
playPriority(activePlayerId);
|
||||
playCleanupStep(activePlayerId);
|
||||
}
|
||||
fireEvent(new GameEvent(GameEvent.EventType.CLEANUP_STEP_POST, null, null, activePlayerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlayerQueryEventListener(Listener<PlayerQueryEvent> listener) {
|
||||
playerQueryEventSource.addListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void firePriorityEvent(UUID playerId) {
|
||||
String message = this.state.getTurn().getStep().toString();
|
||||
public synchronized void firePriorityEvent(UUID playerId) {
|
||||
String message = this.state.getTurn().getStepType().toString();
|
||||
if (this.canPlaySorcery(playerId))
|
||||
message += " - play spells and sorceries.";
|
||||
else
|
||||
|
@ -692,7 +569,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void fireSelectEvent(UUID playerId, String message) {
|
||||
public synchronized void fireSelectEvent(UUID playerId, String message) {
|
||||
playerQueryEventSource.select(playerId, message);
|
||||
}
|
||||
|
||||
|
@ -736,6 +613,11 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
tableEventSource.fireTableEvent(EventType.REVEAL, message, cards, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireLookAtCardsEvent(UUID playerId, String message, Cards cards) {
|
||||
playerQueryEventSource.target(playerId, message, cards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireGetAmountEvent(UUID playerId, String message, int min, int max) {
|
||||
playerQueryEventSource.amount(playerId, message, min, max);
|
||||
|
@ -768,8 +650,8 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public PlayerList getPlayerList(UUID playerId) {
|
||||
return state.getPlayerList(playerId);
|
||||
public PlayerList getPlayerList() {
|
||||
return state.getPlayerList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -814,7 +696,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean isMainPhase() {
|
||||
return state.getTurn().getStep() == PhaseStep.PRECOMBAT_MAIN || state.getTurn().getStep() == PhaseStep.POSTCOMBAT_MAIN;
|
||||
return state.getTurn().getStepType() == PhaseStep.PRECOMBAT_MAIN || state.getTurn().getStepType() == PhaseStep.POSTCOMBAT_MAIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -854,4 +736,12 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
return state.getContinuousEffects();
|
||||
}
|
||||
|
||||
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
savedStates = new Stack<Integer>();
|
||||
tableEventSource = new TableEventSource();
|
||||
playerQueryEventSource = new PlayerQueryEventSource();
|
||||
gameStates = new GameStates();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,12 +29,15 @@
|
|||
package mage.game;
|
||||
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.stack.SpellStack;
|
||||
import mage.game.stack.StackObject;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Zone;
|
||||
import mage.MageObject;
|
||||
|
@ -67,6 +70,7 @@ import mage.watchers.Watchers;
|
|||
public class GameState implements Serializable {
|
||||
|
||||
private Players players = new Players();
|
||||
private PlayerList playerList = new PlayerList();
|
||||
private UUID activePlayerId;
|
||||
private UUID priorityPlayerId;
|
||||
private Turn turn = new Turn();
|
||||
|
@ -83,9 +87,11 @@ public class GameState implements Serializable {
|
|||
private Combat combat = new Combat();
|
||||
private TurnMods turnMods = new TurnMods();
|
||||
private Watchers watchers = new Watchers();
|
||||
private Map<String, Object> values = new HashMap<String, Object>();
|
||||
|
||||
public void addPlayer(Player player) {
|
||||
players.put(player.getId(), player);
|
||||
playerList.add(player.getId());
|
||||
}
|
||||
|
||||
public Players getPlayers() {
|
||||
|
@ -181,14 +187,18 @@ public class GameState implements Serializable {
|
|||
this.messages.add(message);
|
||||
}
|
||||
|
||||
public PlayerList getPlayerList() {
|
||||
return playerList;
|
||||
}
|
||||
|
||||
public PlayerList getPlayerList(UUID playerId) {
|
||||
PlayerList playerList = new PlayerList();
|
||||
PlayerList newPlayerList = new PlayerList();
|
||||
for (Player player: players.values()) {
|
||||
if (!player.hasLeft() && !player.hasLost())
|
||||
playerList.add(player);
|
||||
newPlayerList.add(player.getId());
|
||||
}
|
||||
playerList.setCurrent(playerId);
|
||||
return playerList;
|
||||
newPlayerList.setCurrent(playerId);
|
||||
return newPlayerList;
|
||||
}
|
||||
|
||||
public MageObject getObject(UUID objectId) {
|
||||
|
@ -198,28 +208,9 @@ public class GameState implements Serializable {
|
|||
object.setZone(Zone.BATTLEFIELD);
|
||||
return object;
|
||||
}
|
||||
for(Player player: players.values()) {
|
||||
if (player.getHand().containsKey(objectId)) {
|
||||
object = player.getHand().get(objectId);
|
||||
object.setZone(Zone.HAND);
|
||||
return object;
|
||||
}
|
||||
if (player.getGraveyard().containsKey(objectId)) {
|
||||
object = player.getGraveyard().get(objectId);
|
||||
object.setZone(Zone.GRAVEYARD);
|
||||
return object;
|
||||
}
|
||||
// if (player.getLibrary().containsKey(objectId)) {
|
||||
// return player.getLibrary().get(objectId);
|
||||
// }
|
||||
// for (Cards cards: player..values()) {
|
||||
// if (cards.containsKey(id))
|
||||
// return cards.get(id);
|
||||
// }
|
||||
// if (player.getSideboard().containsKey(id)) {
|
||||
// return player.getSideboard().get(id);
|
||||
// }
|
||||
}
|
||||
object = getCard(objectId);
|
||||
if (object != null)
|
||||
return object;
|
||||
for (StackObject item: stack) {
|
||||
if (item.getId().equals(objectId)) {
|
||||
item.setZone(Zone.STACK);
|
||||
|
@ -230,6 +221,23 @@ public class GameState implements Serializable {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Card getCard(UUID cardId) {
|
||||
Card card;
|
||||
for(Player player: players.values()) {
|
||||
if (player.getHand().containsKey(cardId)) {
|
||||
card = player.getHand().get(cardId);
|
||||
card.setZone(Zone.HAND);
|
||||
return card;
|
||||
}
|
||||
if (player.getGraveyard().containsKey(cardId)) {
|
||||
card = player.getGraveyard().get(cardId);
|
||||
card.setZone(Zone.GRAVEYARD);
|
||||
return card;
|
||||
}
|
||||
}
|
||||
return this.exile.getCard(cardId);
|
||||
}
|
||||
|
||||
public Permanent getPermanent(UUID permanentId) {
|
||||
Permanent permanent;
|
||||
if (battlefield.containsPermanent(permanentId)) {
|
||||
|
@ -296,4 +304,11 @@ public class GameState implements Serializable {
|
|||
return effects;
|
||||
}
|
||||
|
||||
public Object getValue(String valueId) {
|
||||
return values.get(valueId);
|
||||
}
|
||||
|
||||
public void setValue(String valueId, Object value) {
|
||||
values.put(valueId, value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,10 +50,13 @@ public class GameStates implements Serializable {
|
|||
}
|
||||
|
||||
public GameState rollback(int index) {
|
||||
while (states.size() > index) {
|
||||
states.remove(index);
|
||||
if (index < states.size()) {
|
||||
while (states.size() > index) {
|
||||
states.remove(index);
|
||||
}
|
||||
return new Copier<GameState>().uncompressCopy(states.get(index - 1));
|
||||
}
|
||||
return new Copier<GameState>().uncompressCopy(states.get(index - 1));
|
||||
return null;
|
||||
}
|
||||
|
||||
public GameState get(int index) {
|
||||
|
|
|
@ -111,9 +111,9 @@ public class Combat implements Serializable {
|
|||
PlayerList players;
|
||||
switch (game.getAttackOption()) {
|
||||
case LEFT:
|
||||
players = game.getPlayerList(attackerId);
|
||||
players = game.getState().getPlayerList(attackerId);
|
||||
while (true) {
|
||||
Player opponent = players.getNext();
|
||||
Player opponent = players.getNext(game);
|
||||
if (opponents.contains(opponent.getId())) {
|
||||
defenders.add(opponent.getId());
|
||||
break;
|
||||
|
@ -121,9 +121,9 @@ public class Combat implements Serializable {
|
|||
}
|
||||
break;
|
||||
case RIGHT:
|
||||
players = game.getPlayerList(attackerId);
|
||||
players = game.getState().getPlayerList(attackerId);
|
||||
while (true) {
|
||||
Player opponent = players.getPrevious();
|
||||
Player opponent = players.getPrevious(game);
|
||||
if (opponents.contains(opponent.getId())) {
|
||||
defenders.add(opponent.getId());
|
||||
break;
|
||||
|
@ -217,7 +217,7 @@ public class Combat implements Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected boolean isAttacked(UUID defenderId, Game game) {
|
||||
public boolean isAttacked(UUID defenderId, Game game) {
|
||||
for (CombatGroup group: groups) {
|
||||
if (group.getDefenderId().equals(defenderId))
|
||||
return true;
|
||||
|
|
|
@ -44,7 +44,7 @@ import mage.cards.Cards;
|
|||
public class PlayerQueryEvent extends EventObject implements ExternalEvent, Serializable {
|
||||
|
||||
public enum QueryType {
|
||||
ASK, CHOOSE, CHOOSE_ABILITY, PICK_TARGET, PICK_ABILITY, SELECT, PLAY_MANA, PLAY_X_MANA, AMOUNT
|
||||
ASK, CHOOSE, CHOOSE_ABILITY, PICK_TARGET, PICK_ABILITY, SELECT, PLAY_MANA, PLAY_X_MANA, AMOUNT, LOOK
|
||||
}
|
||||
|
||||
private String message;
|
||||
|
@ -109,6 +109,10 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
|
|||
return new PlayerQueryEvent(playerId, message, null, null, null, QueryType.AMOUNT, min, max, false);
|
||||
}
|
||||
|
||||
public static PlayerQueryEvent lookEvent(UUID playerId, String message, Cards cards) {
|
||||
return new PlayerQueryEvent(playerId, message, null, null, cards, QueryType.LOOK, 0, 0, false);
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,10 @@ public class PlayerQueryEventSource implements EventSource<PlayerQueryEvent>, Se
|
|||
dispatcher.fireEvent(PlayerQueryEvent.targetEvent(playerId, message, cards, required));
|
||||
}
|
||||
|
||||
public void target(UUID playerId, String message, Cards cards) {
|
||||
dispatcher.fireEvent(PlayerQueryEvent.lookEvent(playerId, message, cards));
|
||||
}
|
||||
|
||||
public void target(UUID playerId, String message, TriggeredAbilities abilities, boolean required) {
|
||||
dispatcher.fireEvent(PlayerQueryEvent.targetEvent(playerId, message, abilities, required));
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ import mage.game.Game;
|
|||
public class TableEvent extends EventObject implements ExternalEvent, Serializable {
|
||||
|
||||
public enum EventType {
|
||||
UPDATE, INFO, REVEAL
|
||||
UPDATE, INFO, REVEAL, LOOK
|
||||
}
|
||||
|
||||
private Game game;
|
||||
|
|
|
@ -137,8 +137,7 @@ public class Battlefield implements Serializable {
|
|||
|
||||
public void endOfTurn(UUID controllerId, Game game) {
|
||||
for (Permanent perm: field.values()) {
|
||||
if (perm.getControllerId().equals(controllerId))
|
||||
perm.endOfTurn(game);
|
||||
perm.endOfTurn(game);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,15 +145,6 @@ public class Battlefield implements Serializable {
|
|||
return field.values();
|
||||
}
|
||||
|
||||
public Collection<Permanent> getAllPermanents(UUID controllerId) {
|
||||
List<Permanent> perms = new ArrayList<Permanent>();
|
||||
for (Permanent perm: field.values()) {
|
||||
if (perm.getControllerId().equals(controllerId))
|
||||
perms.add(perm);
|
||||
}
|
||||
return perms;
|
||||
}
|
||||
|
||||
public List<Permanent> getAllActivePermanents() {
|
||||
List<Permanent> active = new ArrayList<Permanent>();
|
||||
for (Permanent perm: field.values()) {
|
||||
|
@ -164,6 +154,14 @@ public class Battlefield implements Serializable {
|
|||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Permanents 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
|
||||
* @see Permanent
|
||||
*/
|
||||
public List<Permanent> getAllActivePermanents(UUID controllerId) {
|
||||
List<Permanent> active = new ArrayList<Permanent>();
|
||||
for (Permanent perm: field.values()) {
|
||||
|
@ -173,6 +171,14 @@ public class Battlefield implements Serializable {
|
|||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Permanents on the battlefield that match the specified CardType.
|
||||
* This method ignores the range of influence.
|
||||
*
|
||||
* @param type
|
||||
* @return a list of Permanent
|
||||
* @see Permanent
|
||||
*/
|
||||
public List<Permanent> getAllActivePermanents(CardType type) {
|
||||
List<Permanent> active = new ArrayList<Permanent>();
|
||||
for (Permanent perm: field.values()) {
|
||||
|
@ -182,6 +188,14 @@ public class Battlefield implements Serializable {
|
|||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Permanents on the battlefield that match the supplied filter.
|
||||
* This method ignores the range of influence.
|
||||
*
|
||||
* @param filter
|
||||
* @return a list of Permanent
|
||||
* @see Permanent
|
||||
*/
|
||||
public List<Permanent> getAllActivePermanents(FilterPermanent filter) {
|
||||
List<Permanent> active = new ArrayList<Permanent>();
|
||||
for (Permanent perm: field.values()) {
|
||||
|
@ -191,6 +205,15 @@ public class Battlefield implements Serializable {
|
|||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Permanents 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
|
||||
* @see Permanent
|
||||
*/
|
||||
public List<Permanent> getAllActivePermanents(FilterPermanent filter, UUID controllerId) {
|
||||
List<Permanent> active = new ArrayList<Permanent>();
|
||||
for (Permanent perm: field.values()) {
|
||||
|
@ -200,6 +223,16 @@ public class Battlefield implements Serializable {
|
|||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Permanents 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
|
||||
* @see Permanent
|
||||
*/
|
||||
public List<Permanent> getActivePermanents(FilterPermanent filter, UUID sourcePlayerId, Game game) {
|
||||
if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) {
|
||||
return getAllActivePermanents(filter);
|
||||
|
@ -215,6 +248,14 @@ public class Battlefield implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Permanents that are within the range of influence of the specified player id.
|
||||
*
|
||||
* @param sourcePlayerId
|
||||
* @param game
|
||||
* @return a list of Permanent
|
||||
* @see Permanent
|
||||
*/
|
||||
public List<Permanent> getActivePermanents(UUID sourcePlayerId, Game game) {
|
||||
if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) {
|
||||
return getAllActivePermanents();
|
||||
|
@ -248,13 +289,4 @@ public class Battlefield implements Serializable {
|
|||
return phasedOut;
|
||||
}
|
||||
|
||||
// public List<Permanent> getMatches(FilterPermanent filter) {
|
||||
// List<Permanent> matches = new ArrayList<Permanent>();
|
||||
// for (Permanent perm: field.values()) {
|
||||
// if (filter.match(perm))
|
||||
// matches.add(perm);
|
||||
// }
|
||||
// return matches;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -110,6 +110,9 @@ public abstract class PermanentImpl extends CardImpl implements Permanent
|
|||
this.damage = 0;
|
||||
this.loyaltyUsed = false;
|
||||
this.turnsOnBattlefield++;
|
||||
for (Ability ability: this.abilities) {
|
||||
ability.reset(game);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
49
Mage/src/mage/game/permanent/token/InsectToken.java
Normal file
49
Mage/src/mage/game/permanent/token/InsectToken.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.permanent.token;
|
||||
|
||||
import mage.Constants.CardType;
|
||||
import mage.MageInt;
|
||||
import mage.ObjectColor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class InsectToken extends Token {
|
||||
|
||||
public InsectToken() {
|
||||
super("Insect", "1/1 green Insect creature token");
|
||||
cardType.add(CardType.CREATURE);
|
||||
color = ObjectColor.GREEN;
|
||||
subtype.add("Insect");
|
||||
power = new MageInt(1);
|
||||
toughness = new MageInt(1);
|
||||
}
|
||||
}
|
|
@ -56,10 +56,12 @@ public class Spell implements StackObject, Card {
|
|||
// private static final transient Copier<Spell> copier = new Copier<Spell>();
|
||||
|
||||
private Card card;
|
||||
private SpellAbility ability;
|
||||
private UUID controllerId;
|
||||
|
||||
public Spell(Card card, UUID controllerId) {
|
||||
public Spell(Card card, SpellAbility ability, UUID controllerId) {
|
||||
this.card = card;
|
||||
this.ability = ability;
|
||||
this.controllerId = controllerId;
|
||||
}
|
||||
|
||||
|
@ -67,19 +69,12 @@ public class Spell implements StackObject, Card {
|
|||
public boolean resolve(Game game) {
|
||||
boolean result = false;
|
||||
if (card.getCardType().contains(CardType.INSTANT) || card.getCardType().contains(CardType.SORCERY)) {
|
||||
SpellAbility ability = card.getSpellAbility();
|
||||
if (ability.getTargets().stillLegal(game)) {
|
||||
boolean replaced = false;
|
||||
for (KickerAbility kicker: card.getAbilities().getKickerAbilities()) {
|
||||
if (kicker.isKicked()) {
|
||||
if (kicker.isReplaces()) {
|
||||
replaced = true;
|
||||
}
|
||||
kicker.resolve(game);
|
||||
}
|
||||
}
|
||||
boolean replaced = resolveKicker(game);
|
||||
if (!replaced)
|
||||
result = ability.resolve(game);
|
||||
else
|
||||
result = true;
|
||||
|
||||
if (ability.getEffects().contains(ExileSpellEffect.getInstance()))
|
||||
game.getExile().getPermanentExile().add(card);
|
||||
|
@ -91,12 +86,39 @@ public class Spell implements StackObject, Card {
|
|||
counter(game);
|
||||
return false;
|
||||
}
|
||||
else if (card.getCardType().contains(CardType.ENCHANTMENT) && card.getSubtype().contains("Aura")) {
|
||||
if (ability.getTargets().stillLegal(game)) {
|
||||
Player controller = game.getPlayers().get(controllerId);
|
||||
if (controller.putOntoBattlefield(card, game)) {
|
||||
return ability.resolve(game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//20091005 - 608.2b
|
||||
counter(game);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
Player controller = game.getPlayers().get(controllerId);
|
||||
return controller.putOntoBattlefield(card, game);
|
||||
result = controller.putOntoBattlefield(card, game);
|
||||
resolveKicker(game);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean resolveKicker(Game game) {
|
||||
boolean replaced = false;
|
||||
for (KickerAbility kicker: card.getAbilities().getKickerAbilities()) {
|
||||
if (kicker.isKicked()) {
|
||||
if (kicker.isReplaces()) {
|
||||
replaced = true;
|
||||
}
|
||||
kicker.resolve(game);
|
||||
}
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void counter(Game game) {
|
||||
game.getPlayers().get(controllerId).putInGraveyard(card, game, false);
|
||||
|
|
|
@ -83,6 +83,9 @@ public class StackAbility implements StackObject, Ability {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(Game game) { }
|
||||
|
||||
@Override
|
||||
public void counter(Game game) {
|
||||
|
||||
|
@ -176,14 +179,6 @@ public class StackAbility implements StackObject, Ability {
|
|||
return ability.getRule();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return ability.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {}
|
||||
|
||||
@Override
|
||||
public void setControllerId(UUID controllerId) {
|
||||
this.controllerId = controllerId;
|
||||
|
|
58
Mage/src/mage/game/turn/BeginCombatStep.java
Normal file
58
Mage/src/mage/game/turn/BeginCombatStep.java
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class BeginCombatStep extends Step {
|
||||
|
||||
public BeginCombatStep() {
|
||||
super(PhaseStep.BEGIN_COMBAT, true);
|
||||
this.stepEvent = EventType.BEGIN_COMBAT_STEP;
|
||||
this.preStepEvent = EventType.BEGIN_COMBAT_STEP_PRE;
|
||||
this.postStepEvent = EventType.BEGIN_COMBAT_STEP_POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
//20091005 - 507.1
|
||||
game.getCombat().clear();
|
||||
game.getCombat().setAttacker(activePlayerId);
|
||||
game.getCombat().setDefenders(game);
|
||||
super.beginStep(game, activePlayerId);
|
||||
}
|
||||
|
||||
}
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
package mage.game.turn;
|
||||
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.Constants.TurnPhase;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
|
@ -43,9 +42,9 @@ public class BeginningPhase extends Phase {
|
|||
this.event = EventType.BEGINNING_PHASE;
|
||||
this.preEvent = EventType.BEGINNING_PHASE_PRE;
|
||||
this.postEvent = EventType.BEGINNING_PHASE_POST;
|
||||
this.steps.add(new Step(PhaseStep.UNTAP));
|
||||
this.steps.add(new Step(PhaseStep.UPKEEP));
|
||||
this.steps.add(new Step(PhaseStep.DRAW));
|
||||
this.steps.add(new UntapStep());
|
||||
this.steps.add(new UpkeepStep());
|
||||
this.steps.add(new DrawStep());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
63
Mage/src/mage/game/turn/CleanupStep.java
Normal file
63
Mage/src/mage/game/turn/CleanupStep.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class CleanupStep extends Step {
|
||||
|
||||
public CleanupStep() {
|
||||
super(PhaseStep.CLEANUP, true);
|
||||
this.stepEvent = EventType.CLEANUP_STEP;
|
||||
this.preStepEvent = EventType.CLEANUP_STEP_PRE;
|
||||
this.postStepEvent = EventType.CLEANUP_STEP_POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
super.beginStep(game, activePlayerId);
|
||||
Player activePlayer = game.getPlayer(activePlayerId);
|
||||
//20091005 - 514.1
|
||||
if (!activePlayer.hasLeft() && !activePlayer.hasLost())
|
||||
activePlayer.discardToMax(game);
|
||||
//20100423 - 514.2
|
||||
game.getBattlefield().endOfTurn(activePlayerId, game);
|
||||
game.getState().removeEotEffects(game);
|
||||
|
||||
}
|
||||
|
||||
}
|
74
Mage/src/mage/game/turn/CombatDamageStep.java
Normal file
74
Mage/src/mage/game/turn/CombatDamageStep.java
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class CombatDamageStep extends Step {
|
||||
|
||||
private boolean first;
|
||||
|
||||
public CombatDamageStep(boolean first) {
|
||||
super(PhaseStep.COMBAT_DAMAGE, true);
|
||||
this.first = first;
|
||||
this.stepEvent = EventType.COMBAT_DAMAGE_STEP;
|
||||
this.preStepEvent = EventType.COMBAT_DAMAGE_STEP_PRE;
|
||||
this.postStepEvent = EventType.COMBAT_DAMAGE_STEP_POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean skipStep(Game game, UUID activePlayerId) {
|
||||
if (game.getCombat().noAttackers())
|
||||
return true;
|
||||
if (first && !game.getCombat().hasFirstOrDoubleStrike(game))
|
||||
return true;
|
||||
return super.skipStep(game, activePlayerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
super.beginStep(game, activePlayerId);
|
||||
for (CombatGroup group: game.getCombat().getGroups()) {
|
||||
group.assignDamage(first, game);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
}
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
package mage.game.turn;
|
||||
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.Constants.TurnPhase;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
|
@ -43,12 +42,12 @@ public class CombatPhase extends Phase {
|
|||
this.event = EventType.COMBAT_PHASE;
|
||||
this.preEvent = EventType.COMBAT_PHASE_PRE;
|
||||
this.postEvent = EventType.COMBAT_PHASE_POST;
|
||||
this.steps.add(new Step(PhaseStep.BEGIN_COMBAT));
|
||||
this.steps.add(new Step(PhaseStep.DECLARE_ATTACKERS));
|
||||
this.steps.add(new Step(PhaseStep.DECLARE_BLOCKERS));
|
||||
this.steps.add(new Step(PhaseStep.FIRST_COMBAT_DAMAGE));
|
||||
this.steps.add(new Step(PhaseStep.COMBAT_DAMAGE));
|
||||
this.steps.add(new Step(PhaseStep.END_COMBAT));
|
||||
this.steps.add(new BeginCombatStep());
|
||||
this.steps.add(new DeclareAttackersStep());
|
||||
this.steps.add(new DeclareBlockersStep());
|
||||
this.steps.add(new CombatDamageStep(true));
|
||||
this.steps.add(new CombatDamageStep(false));
|
||||
this.steps.add(new EndOfCombatStep());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
62
Mage/src/mage/game/turn/DeclareAttackersStep.java
Normal file
62
Mage/src/mage/game/turn/DeclareAttackersStep.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class DeclareAttackersStep extends Step {
|
||||
|
||||
public DeclareAttackersStep() {
|
||||
super(PhaseStep.DECLARE_ATTACKERS, true);
|
||||
this.stepEvent = EventType.DECLARE_ATTACKERS_STEP;
|
||||
this.preStepEvent = EventType.DECLARE_ATTACKERS_STEP_PRE;
|
||||
this.postStepEvent = EventType.DECLARE_ATTACKERS_STEP_POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean skipStep(Game game, UUID activePlayerId) {
|
||||
if (!game.getPlayer(activePlayerId).hasAvailableAttackers(game))
|
||||
return true;
|
||||
return super.skipStep(game, activePlayerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
super.beginStep(game, activePlayerId);
|
||||
game.getCombat().selectAttackers(game);
|
||||
}
|
||||
|
||||
}
|
62
Mage/src/mage/game/turn/DeclareBlockersStep.java
Normal file
62
Mage/src/mage/game/turn/DeclareBlockersStep.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class DeclareBlockersStep extends Step {
|
||||
|
||||
public DeclareBlockersStep() {
|
||||
super(PhaseStep.DECLARE_BLOCKERS, true);
|
||||
this.stepEvent = EventType.DECLARE_BLOCKERS_STEP;
|
||||
this.preStepEvent = EventType.DECLARE_BLOCKERS_STEP_PRE;
|
||||
this.postStepEvent = EventType.DECLARE_BLOCKERS_STEP_POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean skipStep(Game game, UUID activePlayerId) {
|
||||
if (game.getCombat().noAttackers())
|
||||
return true;
|
||||
return super.skipStep(game, activePlayerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
super.beginStep(game, activePlayerId);
|
||||
game.getCombat().selectBlockers(game);
|
||||
}
|
||||
|
||||
}
|
60
Mage/src/mage/game/turn/DrawStep.java
Normal file
60
Mage/src/mage/game/turn/DrawStep.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class DrawStep extends Step {
|
||||
|
||||
public DrawStep() {
|
||||
super(PhaseStep.DRAW, true);
|
||||
this.stepEvent = EventType.DRAW_STEP;
|
||||
this.preStepEvent = EventType.DRAW_STEP_PRE;
|
||||
this.postStepEvent = EventType.DRAW_STEP_POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
Player activePlayer = game.getPlayer(activePlayerId);
|
||||
//20091005 - 504.1/703.4c
|
||||
activePlayer.drawCards(1, game);
|
||||
game.saveState();
|
||||
super.beginStep(game, activePlayerId);
|
||||
}
|
||||
|
||||
|
||||
}
|
57
Mage/src/mage/game/turn/EndOfCombatStep.java
Normal file
57
Mage/src/mage/game/turn/EndOfCombatStep.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class EndOfCombatStep extends Step {
|
||||
|
||||
public EndOfCombatStep() {
|
||||
super(PhaseStep.END_COMBAT, true);
|
||||
this.stepEvent = EventType.END_COMBAT_STEP;
|
||||
this.preStepEvent = EventType.END_COMBAT_STEP_PRE;
|
||||
this.postStepEvent = EventType.END_COMBAT_STEP_POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endStep(Game game, UUID activePlayerId) {
|
||||
super.endStep(game, activePlayerId);
|
||||
//20091005 - 511.3
|
||||
game.getCombat().endCombat(game);
|
||||
game.saveState();
|
||||
}
|
||||
|
||||
}
|
|
@ -28,8 +28,10 @@
|
|||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.Constants.TurnPhase;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
|
@ -43,8 +45,21 @@ public class EndPhase extends Phase {
|
|||
this.event = EventType.END_PHASE;
|
||||
this.preEvent = EventType.END_PHASE_PRE;
|
||||
this.postEvent = EventType.END_PHASE_POST;
|
||||
this.steps.add(new Step(PhaseStep.END_TURN));
|
||||
this.steps.add(new Step(PhaseStep.CLEANUP));
|
||||
this.steps.add(new EndStep());
|
||||
this.steps.add(new CleanupStep());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void playStep(Game game, UUID activePlayerId) {
|
||||
if (currentStep.getType() == PhaseStep.CLEANUP) {
|
||||
currentStep.beginStep(game, activePlayerId);
|
||||
if (game.checkStateAndTriggered()) {
|
||||
playStep(game, activePlayerId);
|
||||
}
|
||||
currentStep.endStep(game, activePlayerId);
|
||||
}
|
||||
else
|
||||
super.playStep(game, activePlayerId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
47
Mage/src/mage/game/turn/EndStep.java
Normal file
47
Mage/src/mage/game/turn/EndStep.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class EndStep extends Step {
|
||||
|
||||
public EndStep() {
|
||||
super(PhaseStep.END_TURN, true);
|
||||
this.stepEvent = EventType.END_TURN_STEP;
|
||||
this.preStepEvent = EventType.END_TURN_STEP_PRE;
|
||||
this.postStepEvent = EventType.END_TURN_STEP_POST;
|
||||
}
|
||||
|
||||
}
|
|
@ -58,10 +58,12 @@ public abstract class Phase implements Serializable {
|
|||
return type;
|
||||
}
|
||||
|
||||
public PhaseStep getStep() {
|
||||
if (currentStep != null)
|
||||
return currentStep.getType();
|
||||
return null;
|
||||
public Step getStep() {
|
||||
return currentStep;
|
||||
}
|
||||
|
||||
public void setStep(Step step) {
|
||||
this.currentStep = step;
|
||||
}
|
||||
|
||||
public void resetCount() {
|
||||
|
@ -85,13 +87,8 @@ public abstract class Phase implements Serializable {
|
|||
if (game.isGameOver())
|
||||
return false;
|
||||
currentStep = step;
|
||||
if (step.play(game, activePlayerId)) {
|
||||
//20091005 - 500.4/703.4n
|
||||
game.emptyManaPools();
|
||||
game.saveState();
|
||||
//20091005 - 500.9
|
||||
playExtraSteps(game, step.getType());
|
||||
}
|
||||
if (!game.getState().getTurnMods().skipStep(activePlayerId, currentStep.getType()))
|
||||
playStep(game, activePlayerId);
|
||||
}
|
||||
count++;
|
||||
game.fireEvent(new GameEvent(postEvent, null, null, activePlayerId));
|
||||
|
@ -100,14 +97,34 @@ public abstract class Phase implements Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void prePriority(Game game, UUID activePlayerId) {
|
||||
currentStep.beginStep(game, activePlayerId);
|
||||
}
|
||||
|
||||
public void postPriority(Game game, UUID activePlayerId) {
|
||||
currentStep.endStep(game, activePlayerId);
|
||||
//20091005 - 500.4/703.4n
|
||||
game.emptyManaPools();
|
||||
game.saveState();
|
||||
//20091005 - 500.9
|
||||
playExtraSteps(game, currentStep.getType());
|
||||
}
|
||||
|
||||
protected void playStep(Game game, UUID activePlayerId) {
|
||||
if (!currentStep.skipStep(game, activePlayerId)) {
|
||||
prePriority(game, activePlayerId);
|
||||
currentStep.priority(game, activePlayerId);
|
||||
postPriority(game, activePlayerId);
|
||||
}
|
||||
}
|
||||
|
||||
private void playExtraSteps(Game game, PhaseStep afterStep) {
|
||||
while (true) {
|
||||
PhaseStep extraStep = game.getState().getTurnMods().extraStep(activePlayerId, afterStep);
|
||||
Step extraStep = game.getState().getTurnMods().extraStep(activePlayerId, afterStep);
|
||||
if (extraStep == null)
|
||||
return;
|
||||
Step step = new Step(extraStep);
|
||||
currentStep = step;
|
||||
step.play(game, activePlayerId);
|
||||
currentStep = extraStep;
|
||||
playStep(game, activePlayerId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public class PostCombatMainPhase extends Phase {
|
|||
this.event = EventType.POSTCOMBAT_MAIN_PHASE;
|
||||
this.preEvent = EventType.POSTCOMBAT_MAIN_PHASE_PRE;
|
||||
this.postEvent = EventType.POSTCOMBAT_MAIN_STEP_POST;
|
||||
this.steps.add(new Step(PhaseStep.POSTCOMBAT_MAIN));
|
||||
this.steps.add(new PostCombatMainStep());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
47
Mage/src/mage/game/turn/PostCombatMainStep.java
Normal file
47
Mage/src/mage/game/turn/PostCombatMainStep.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class PostCombatMainStep extends Step {
|
||||
|
||||
public PostCombatMainStep() {
|
||||
super(PhaseStep.POSTCOMBAT_MAIN, true);
|
||||
this.stepEvent = EventType.POSTCOMBAT_MAIN_STEP;
|
||||
this.preStepEvent = EventType.POSTCOMBAT_MAIN_STEP_PRE;
|
||||
this.postStepEvent = EventType.POSTCOMBAT_MAIN_STEP_POST;
|
||||
}
|
||||
|
||||
}
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
package mage.game.turn;
|
||||
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.Constants.TurnPhase;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
|
@ -43,7 +42,7 @@ public class PreCombatMainPhase extends Phase {
|
|||
this.event = EventType.PRECOMBAT_MAIN_PHASE;
|
||||
this.preEvent = EventType.PRECOMBAT_MAIN_PHASE_PRE;
|
||||
this.postEvent = EventType.PRECOMBAT_MAIN_PHASE_POST;
|
||||
this.steps.add(new Step(PhaseStep.PRECOMBAT_MAIN));
|
||||
this.steps.add(new PreCombatMainStep());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
47
Mage/src/mage/game/turn/PreCombatMainStep.java
Normal file
47
Mage/src/mage/game/turn/PreCombatMainStep.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class PreCombatMainStep extends Step {
|
||||
|
||||
public PreCombatMainStep() {
|
||||
super(PhaseStep.PRECOMBAT_MAIN, true);
|
||||
this.stepEvent = EventType.PRECOMBAT_MAIN_STEP;
|
||||
this.preStepEvent = EventType.PRECOMBAT_MAIN_STEP_PRE;
|
||||
this.postStepEvent = EventType.PRECOMBAT_MAIN_STEP_POST;
|
||||
}
|
||||
|
||||
}
|
|
@ -32,61 +32,49 @@ import java.io.Serializable;
|
|||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class Step implements Serializable {
|
||||
public abstract class Step implements Serializable {
|
||||
|
||||
private PhaseStep type;
|
||||
private boolean hasPriority;
|
||||
protected EventType stepEvent;
|
||||
protected EventType preStepEvent;
|
||||
protected EventType postStepEvent;
|
||||
|
||||
public Step(PhaseStep type) {
|
||||
public Step(PhaseStep type, boolean hasPriority) {
|
||||
this.type = type;
|
||||
this.hasPriority = hasPriority;
|
||||
}
|
||||
|
||||
public PhaseStep getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean play(Game game, UUID activePlayerId) {
|
||||
switch(type) {
|
||||
case UNTAP:
|
||||
return game.playUntapStep(activePlayerId);
|
||||
case UPKEEP:
|
||||
return game.playUpkeepStep(activePlayerId);
|
||||
case DRAW:
|
||||
return game.playDrawStep(activePlayerId);
|
||||
case PRECOMBAT_MAIN:
|
||||
return game.playPreCombatMainStep(activePlayerId);
|
||||
case BEGIN_COMBAT:
|
||||
return game.playBeginCombatStep(activePlayerId);
|
||||
case DECLARE_ATTACKERS:
|
||||
if (game.getPlayer(activePlayerId).hasAvailableAttackers(game))
|
||||
return game.playDeclareAttackersStep(activePlayerId);
|
||||
return false;
|
||||
case DECLARE_BLOCKERS:
|
||||
if (!game.getCombat().noAttackers())
|
||||
return game.playDeclareBlockersStep(activePlayerId);
|
||||
return false;
|
||||
case FIRST_COMBAT_DAMAGE:
|
||||
if (!game.getCombat().noAttackers() && game.getCombat().hasFirstOrDoubleStrike(game))
|
||||
return game.playCombatDamageStep(activePlayerId, true);
|
||||
return false;
|
||||
case COMBAT_DAMAGE:
|
||||
if (!game.getCombat().noAttackers())
|
||||
return game.playCombatDamageStep(activePlayerId, false);
|
||||
return false;
|
||||
case END_COMBAT:
|
||||
return game.playEndCombatStep(activePlayerId);
|
||||
case POSTCOMBAT_MAIN:
|
||||
return game.playPostMainStep(activePlayerId);
|
||||
case END_TURN:
|
||||
return game.playEndStep(activePlayerId);
|
||||
case CLEANUP:
|
||||
return game.playCleanupStep(activePlayerId);
|
||||
}
|
||||
return false;
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
game.fireEvent(new GameEvent(preStepEvent, null, null, activePlayerId));
|
||||
}
|
||||
|
||||
public void priority(Game game, UUID activePlayerId) {
|
||||
if (hasPriority)
|
||||
game.playPriority(activePlayerId);
|
||||
}
|
||||
|
||||
public void endStep(Game game, UUID activePlayerId) {
|
||||
game.fireEvent(new GameEvent(postStepEvent, null, null, activePlayerId));
|
||||
}
|
||||
|
||||
public boolean skipStep(Game game, UUID activePlayerId) {
|
||||
return game.replaceEvent(new GameEvent(stepEvent, null, null, activePlayerId));
|
||||
}
|
||||
|
||||
public boolean getHasPriority() {
|
||||
return this.hasPriority;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,12 +54,16 @@ public class Turn implements Serializable {
|
|||
phases.add(new EndPhase());
|
||||
}
|
||||
|
||||
public TurnPhase getPhase() {
|
||||
public TurnPhase getPhaseType() {
|
||||
if (currentPhase != null)
|
||||
return currentPhase.getType();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Phase getPhase() {
|
||||
return currentPhase;
|
||||
}
|
||||
|
||||
public Phase getPhase(TurnPhase turnPhase) {
|
||||
for (Phase phase: phases) {
|
||||
if (phase.getType() == turnPhase) {
|
||||
|
@ -69,16 +73,29 @@ public class Turn implements Serializable {
|
|||
return null;
|
||||
}
|
||||
|
||||
public PhaseStep getStep() {
|
||||
public void setPhase(Phase phase) {
|
||||
this.currentPhase = phase;
|
||||
}
|
||||
|
||||
public Step getStep() {
|
||||
if (currentPhase != null)
|
||||
return currentPhase.getStep();
|
||||
return null;
|
||||
}
|
||||
|
||||
public PhaseStep getStepType() {
|
||||
if (currentPhase != null && currentPhase.getStep() != null)
|
||||
return currentPhase.getStep().getType();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void play(Game game, UUID activePlayerId) {
|
||||
if (game.isGameOver())
|
||||
return;
|
||||
|
||||
if (game.getState().getTurnMods().skipTurn(activePlayerId))
|
||||
return;
|
||||
|
||||
this.activePlayerId = activePlayerId;
|
||||
resetCounts();
|
||||
game.getPlayer(activePlayerId).beginTurn(game);
|
||||
|
@ -86,12 +103,14 @@ public class Turn implements Serializable {
|
|||
if (game.isGameOver())
|
||||
return;
|
||||
currentPhase = phase;
|
||||
if (phase.play(game, activePlayerId)) {
|
||||
//20091005 - 500.4/703.4n
|
||||
game.emptyManaPools();
|
||||
game.saveState();
|
||||
//20091005 - 500.8
|
||||
playExtraPhases(game, phase.getType());
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
//20091005 - 500.7
|
||||
|
|
|
@ -42,14 +42,20 @@ public class TurnMod implements Serializable {
|
|||
|
||||
private UUID playerId;
|
||||
private boolean extraTurn;
|
||||
private boolean skipTurn;
|
||||
private TurnPhase extraPhase;
|
||||
private PhaseStep extraStep;
|
||||
private TurnPhase skipPhase;
|
||||
private Step extraStep;
|
||||
private PhaseStep skipStep;
|
||||
private TurnPhase afterPhase;
|
||||
private PhaseStep afterStep;
|
||||
|
||||
public TurnMod(UUID playerId) {
|
||||
public TurnMod(UUID playerId, boolean skip) {
|
||||
this.playerId = playerId;
|
||||
this.extraTurn = true;
|
||||
if (skip)
|
||||
this.skipTurn = true;
|
||||
else
|
||||
this.extraTurn = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,9 +64,12 @@ public class TurnMod implements Serializable {
|
|||
* @param extraPhase
|
||||
* @param afterPhase - set to null if extraPhase is after the next phase
|
||||
*/
|
||||
public TurnMod(UUID playerId, TurnPhase extraPhase, TurnPhase afterPhase) {
|
||||
public TurnMod(UUID playerId, TurnPhase phase, TurnPhase afterPhase, boolean skip) {
|
||||
this.playerId = playerId;
|
||||
this.extraPhase = extraPhase;
|
||||
if (skip)
|
||||
this.skipPhase = phase;
|
||||
else
|
||||
this.extraPhase = phase;
|
||||
this.afterPhase = afterPhase;
|
||||
}
|
||||
|
||||
|
@ -70,12 +79,17 @@ public class TurnMod implements Serializable {
|
|||
* @param extraStep
|
||||
* @param afterStep - set to null if extraStep is after the next step
|
||||
*/
|
||||
public TurnMod(UUID playerId, PhaseStep extraStep, PhaseStep afterStep) {
|
||||
public TurnMod(UUID playerId, Step step, PhaseStep afterStep) {
|
||||
this.playerId = playerId;
|
||||
this.extraStep = extraStep;
|
||||
this.extraStep = step;
|
||||
this.afterStep = afterStep;
|
||||
}
|
||||
|
||||
public TurnMod(UUID playerId, PhaseStep step) {
|
||||
this.playerId = playerId;
|
||||
this.skipStep = step;
|
||||
}
|
||||
|
||||
public UUID getPlayerId() {
|
||||
return playerId;
|
||||
}
|
||||
|
@ -84,14 +98,26 @@ public class TurnMod implements Serializable {
|
|||
return extraTurn;
|
||||
}
|
||||
|
||||
public boolean isSkipTurn() {
|
||||
return skipTurn;
|
||||
}
|
||||
|
||||
public TurnPhase getExtraPhase() {
|
||||
return extraPhase;
|
||||
}
|
||||
|
||||
public PhaseStep getExtraStep() {
|
||||
public Step getExtraStep() {
|
||||
return extraStep;
|
||||
}
|
||||
|
||||
public TurnPhase getSkipPhase() {
|
||||
return skipPhase;
|
||||
}
|
||||
|
||||
public PhaseStep getSkipStep() {
|
||||
return skipStep;
|
||||
}
|
||||
|
||||
public TurnPhase getAfterPhase() {
|
||||
return afterPhase;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,19 @@ public class TurnMods extends ArrayList<TurnMod> {
|
|||
return false;
|
||||
}
|
||||
|
||||
public PhaseStep extraStep(UUID playerId, PhaseStep afterStep) {
|
||||
public boolean skipTurn(UUID playerId) {
|
||||
ListIterator<TurnMod> it = this.listIterator(this.size());
|
||||
while (it.hasPrevious()) {
|
||||
TurnMod turnMod = it.previous();
|
||||
if (turnMod.isSkipTurn() == true && turnMod.getPlayerId().equals(playerId)) {
|
||||
it.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Step extraStep(UUID playerId, PhaseStep afterStep) {
|
||||
ListIterator<TurnMod> it = this.listIterator(this.size());
|
||||
while (it.hasPrevious()) {
|
||||
TurnMod turnMod = it.previous();
|
||||
|
@ -64,6 +76,18 @@ public class TurnMods extends ArrayList<TurnMod> {
|
|||
return null;
|
||||
}
|
||||
|
||||
public boolean skipStep(UUID playerId, PhaseStep step) {
|
||||
ListIterator<TurnMod> it = this.listIterator(this.size());
|
||||
while (it.hasPrevious()) {
|
||||
TurnMod turnMod = it.previous();
|
||||
if (turnMod.getSkipStep() != null && turnMod.getPlayerId().equals(playerId) && turnMod.getSkipStep() == step) {
|
||||
it.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public TurnPhase extraPhase(UUID playerId, TurnPhase afterPhase) {
|
||||
ListIterator<TurnMod> it = this.listIterator(this.size());
|
||||
while (it.hasPrevious()) {
|
||||
|
@ -76,4 +100,16 @@ public class TurnMods extends ArrayList<TurnMod> {
|
|||
return null;
|
||||
}
|
||||
|
||||
public boolean skipPhase(UUID playerId, TurnPhase phase) {
|
||||
ListIterator<TurnMod> it = this.listIterator(this.size());
|
||||
while (it.hasPrevious()) {
|
||||
TurnMod turnMod = it.previous();
|
||||
if (turnMod.getSkipPhase() != null && turnMod.getPlayerId().equals(playerId) && turnMod.getSkipPhase() == phase) {
|
||||
it.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
61
Mage/src/mage/game/turn/UntapStep.java
Normal file
61
Mage/src/mage/game/turn/UntapStep.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class UntapStep extends Step {
|
||||
|
||||
public UntapStep() {
|
||||
super(PhaseStep.UNTAP, false);
|
||||
this.stepEvent = EventType.UNTAP_STEP;
|
||||
this.preStepEvent = EventType.UNTAP_STEP_PRE;
|
||||
this.postStepEvent = EventType.UNTAP_STEP_POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
super.beginStep(game, activePlayerId);
|
||||
Player activePlayer = game.getPlayer(activePlayerId);
|
||||
//20091005 - 502.1/703.4a
|
||||
activePlayer.phasing(game);
|
||||
//20091005 - 502.2/703.4b
|
||||
activePlayer.untap(game);
|
||||
}
|
||||
|
||||
|
||||
}
|
47
Mage/src/mage/game/turn/UpkeepStep.java
Normal file
47
Mage/src/mage/game/turn/UpkeepStep.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class UpkeepStep extends Step {
|
||||
|
||||
public UpkeepStep() {
|
||||
super(PhaseStep.UPKEEP, true);
|
||||
this.stepEvent = EventType.UPKEEP_STEP;
|
||||
this.preStepEvent = EventType.UPKEEP_STEP_PRE;
|
||||
this.postStepEvent = EventType.UPKEEP_STEP_POST;
|
||||
}
|
||||
|
||||
}
|
|
@ -74,6 +74,13 @@ public class Library implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the top card of the Library and returns it
|
||||
*
|
||||
* @param game
|
||||
* @return Card
|
||||
* @see Card
|
||||
*/
|
||||
public Card removeFromTop(Game game) {
|
||||
Card card = library.pollFirst();
|
||||
if (card == null) {
|
||||
|
@ -82,6 +89,13 @@ public class Library implements Serializable {
|
|||
return card;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the top card of the Library without removing it
|
||||
*
|
||||
* @param game
|
||||
* @return Card
|
||||
* @see Card
|
||||
*/
|
||||
public Card getFromTop(Game game) {
|
||||
return library.peekFirst();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,9 @@ import mage.Constants.Outcome;
|
|||
import mage.MageItem;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.ActivatedAbility;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.TriggeredAbilities;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
|
@ -50,6 +52,7 @@ import mage.game.Game;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetAmount;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
||||
|
@ -71,8 +74,10 @@ public interface Player extends MageItem {
|
|||
public void gainLife(int amount, Game game);
|
||||
public int damage(int damage, UUID sourceId, Game game);
|
||||
public Cards getHand();
|
||||
public int getLandsPlayed();
|
||||
public boolean isPassed();
|
||||
public boolean isEmptyDraw();
|
||||
public void pass();
|
||||
public void resetPassed();
|
||||
public boolean hasLost();
|
||||
public boolean hasWon();
|
||||
|
@ -84,7 +89,7 @@ public interface Player extends MageItem {
|
|||
public void reset();
|
||||
public void shuffleLibrary(Game game);
|
||||
public int drawCards(int num, Game game);
|
||||
public boolean cast(Card card, Game game, boolean noMana);
|
||||
public boolean cast(SpellAbility ability, Game game, boolean noMana);
|
||||
public boolean putInHand(Card card, Game game);
|
||||
public boolean removeFromHand(Card card, Game game);
|
||||
public boolean putOntoBattlefield(Card card, Game game);
|
||||
|
@ -97,7 +102,7 @@ public interface Player extends MageItem {
|
|||
public boolean playLand(Card card, Game game);
|
||||
public boolean activateAbility(ActivatedAbility ability, Game game);
|
||||
public boolean triggerAbility(TriggeredAbility ability, Game game);
|
||||
public boolean canTarget(MageObject source);
|
||||
public boolean canBeTargetedBy(MageObject source);
|
||||
public void checkTriggers(GameEvent event, Game game);
|
||||
public void discard(int amount, Game game);
|
||||
public void discardToMax(Game game);
|
||||
|
@ -109,7 +114,8 @@ public interface Player extends MageItem {
|
|||
public void abort();
|
||||
|
||||
public void revealCards(Cards cards, Game game);
|
||||
|
||||
public void lookAtCards(Cards cards, Game game);
|
||||
|
||||
public Player copy();
|
||||
public void restore(Player player);
|
||||
|
||||
|
@ -120,12 +126,13 @@ public interface Player extends MageItem {
|
|||
|
||||
public abstract void priority(Game game);
|
||||
public abstract boolean chooseTarget(Outcome outcome, Target target, Game game);
|
||||
public abstract boolean chooseTarget(Cards cards, TargetCard target, Game game);
|
||||
public abstract boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Game game);
|
||||
public abstract boolean chooseMulligan(Game game);
|
||||
public abstract boolean chooseUse(Outcome outcome, String message, Game game);
|
||||
public abstract boolean choose(Outcome outcome, Choice choice, Game game);
|
||||
public abstract boolean playMana(ManaCost unpaid, Game game);
|
||||
public abstract boolean playXMana(VariableManaCost cost, Game game);
|
||||
public abstract boolean searchCards(Cards cards, TargetCard target, Game game);
|
||||
public abstract int chooseEffect(List<ReplacementEffect> rEffects, Game game);
|
||||
public abstract TriggeredAbility chooseTriggeredAbility(TriggeredAbilities abilities, Game game);
|
||||
public abstract void selectAttackers(Game game);
|
||||
|
@ -142,4 +149,7 @@ public interface Player extends MageItem {
|
|||
public void phasing(Game game);
|
||||
public void untap(Game game);
|
||||
|
||||
public List<Ability> getPlayable(Game game, boolean hidden);
|
||||
public List<Ability> getPlayableOptions(Ability ability, Game game);
|
||||
|
||||
}
|
||||
|
|
|
@ -41,8 +41,10 @@ import mage.Constants.Outcome;
|
|||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.Constants.Zone;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.AbilitiesImpl;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.ActivatedAbility;
|
||||
import mage.abilities.PlayLandAbility;
|
||||
import mage.abilities.SpecialAction;
|
||||
|
@ -52,6 +54,7 @@ import mage.abilities.keyword.KickerAbility;
|
|||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.abilities.keyword.ShroudAbility;
|
||||
import mage.abilities.mana.ManaAbility;
|
||||
import mage.abilities.mana.ManaOptions;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
|
@ -106,6 +109,10 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
library.addAll(deck.getCards());
|
||||
}
|
||||
|
||||
protected PlayerImpl(UUID id) {
|
||||
this.playerId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Game game) {
|
||||
this.hand.clear();
|
||||
|
@ -161,18 +168,18 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
else {
|
||||
inRange.add(playerId);
|
||||
PlayerList players = game.getPlayerList(playerId);
|
||||
PlayerList players = game.getState().getPlayerList(playerId);
|
||||
for (int i = 0; i < range.getRange(); i++) {
|
||||
Player player = players.getNext();
|
||||
Player player = players.getNext(game);
|
||||
while (player.hasLeft())
|
||||
player = players.getNext();
|
||||
player = players.getNext(game);
|
||||
inRange.add(player.getId());
|
||||
}
|
||||
players = game.getPlayerList(playerId);
|
||||
players = game.getState().getPlayerList(playerId);
|
||||
for (int i = 0; i < range.getRange(); i++) {
|
||||
Player player = players.getPrevious();
|
||||
Player player = players.getPrevious(game);
|
||||
while (player.hasLeft())
|
||||
player = players.getPrevious();
|
||||
player = players.getPrevious(game);
|
||||
inRange.add(player.getId());
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +203,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(MageObject source) {
|
||||
public boolean canBeTargetedBy(MageObject source) {
|
||||
if (this.hasLost() || this.hasLeft())
|
||||
return false;
|
||||
if (source != null) {
|
||||
|
@ -251,6 +258,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
public boolean putInHand(Card card, Game game) {
|
||||
if (card.getOwnerId().equals(playerId)) {
|
||||
this.hand.add(card);
|
||||
if (card.getSpellAbility() != null)
|
||||
card.getSpellAbility().clear();
|
||||
} else {
|
||||
return game.getPlayer(card.getOwnerId()).putInHand(card, game);
|
||||
}
|
||||
|
@ -337,24 +346,25 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean cast(Card card, Game game, boolean noMana) {
|
||||
public boolean cast(SpellAbility ability, Game game, boolean noMana) {
|
||||
//20091005 - 601.2a
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, card.getId(), playerId))) {
|
||||
game.bookmarkState();
|
||||
removeFromHand(card, game);
|
||||
|
||||
game.getStack().push(new Spell(card, playerId));
|
||||
card.getSpellAbility().clear();
|
||||
if (card.getSpellAbility().activate(game, noMana)) {
|
||||
for (KickerAbility ability: card.getAbilities().getKickerAbilities()) {
|
||||
ability.copy().activate(game, false);
|
||||
Card card = game.getCard(ability.getSourceId());
|
||||
if (card != null) {
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, card.getId(), playerId))) {
|
||||
game.bookmarkState();
|
||||
removeFromHand(card, game);
|
||||
game.getStack().push(new Spell(card, ability, playerId));
|
||||
if (ability.activate(game, noMana)) {
|
||||
for (KickerAbility kicker: card.getAbilities().getKickerAbilities()) {
|
||||
kicker.activate(game, false);
|
||||
}
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.SPELL_CAST, card.getId(), playerId));
|
||||
game.fireInformEvent(name + " casts " + card.getName());
|
||||
game.removeLastBookmark();
|
||||
return true;
|
||||
}
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.SPELL_CAST, card.getId(), playerId));
|
||||
game.fireInformEvent(name + " casts " + card.getName());
|
||||
game.removeLastBookmark();
|
||||
return true;
|
||||
game.restoreState();
|
||||
}
|
||||
game.restoreState();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -437,7 +447,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
result = playManaAbility((ManaAbility)ability.copy(), game);
|
||||
}
|
||||
else if (ability instanceof SpellAbility) {
|
||||
result = cast(hand.get(ability.getSourceId()), game, false);
|
||||
result = cast((SpellAbility)ability, game, false);
|
||||
}
|
||||
else {
|
||||
result = playAbility((ActivatedAbility)ability.copy(), game);
|
||||
|
@ -455,10 +465,12 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
game.saveState();
|
||||
game.bookmarkState();
|
||||
TriggeredAbility ability = (TriggeredAbility) source.copy();
|
||||
game.getStack().push(new StackAbility(ability, playerId));
|
||||
if (ability.activate(game, false)) {
|
||||
game.removeLastBookmark();
|
||||
return true;
|
||||
if (ability.getTargets().canChoose(ability.getSourceId(), playerId, game)) {
|
||||
game.getStack().push(new StackAbility(ability, playerId));
|
||||
if (ability.activate(game, false)) {
|
||||
game.removeLastBookmark();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
game.restoreState();
|
||||
return false;
|
||||
|
@ -473,6 +485,11 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return useable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLandsPlayed() {
|
||||
return landsPlayed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayLand() {
|
||||
//20091005 - 114.2a
|
||||
|
@ -493,6 +510,11 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
game.fireRevealCardsEvent(this.name + " revealed", cards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lookAtCards(Cards cards, Game game) {
|
||||
game.fireLookAtCardsEvent(playerId, this.name + " looking at", cards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void phasing(Game game) {
|
||||
//20091005 - 502.1
|
||||
|
@ -630,6 +652,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
this.manaPool = player.getManaPool();
|
||||
this.life = player.getLife();
|
||||
this.counters = player.getCounters();
|
||||
this.inRange = player.getInRange();
|
||||
this.landsPlayed = player.getLandsPlayed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -637,6 +661,11 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return passed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pass() {
|
||||
this.passed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmptyDraw() {
|
||||
return library.isEmtpyDraw();
|
||||
|
@ -645,9 +674,9 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
@Override
|
||||
public void resetPassed() {
|
||||
if (!this.loses && !this.left)
|
||||
passed = false;
|
||||
this.passed = false;
|
||||
else
|
||||
passed = true;
|
||||
this.passed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -668,6 +697,11 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
for (Iterator<Permanent> it = game.getBattlefield().getAllPermanents().iterator(); it.hasNext();) {
|
||||
Permanent perm = it.next();
|
||||
if (perm.getOwnerId().equals(playerId)) {
|
||||
if (perm.getAttachedTo() != null) {
|
||||
Permanent attachedTo = game.getPermanent(perm.getAttachedTo());
|
||||
if (attachedTo != null)
|
||||
attachedTo.removeAttachment(perm.getId(), game);
|
||||
}
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
@ -756,15 +790,15 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
public boolean searchLibrary(TargetCardInLibrary target, Game game) {
|
||||
//20091005 - 701.14c
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.SEARCH_LIBRARY, playerId, playerId))) {
|
||||
if (library.count(target.getFilter()) < target.getNumberOfTargets()) {
|
||||
TargetCardInLibrary newTarget = new TargetCardInLibrary(library.count(target.getFilter()), target.getMaxNumberOfTargets(), target.getFilter());
|
||||
searchCards(new CardsImpl(Zone.LIBRARY, getLibrary().getCards()), newTarget, game);
|
||||
TargetCardInLibrary newTarget;
|
||||
if (library.count(target.getFilter()) < target.getNumberOfTargets())
|
||||
newTarget = new TargetCardInLibrary(library.count(target.getFilter()), target.getMaxNumberOfTargets(), target.getFilter());
|
||||
else
|
||||
newTarget = target;
|
||||
if (chooseTarget(new CardsImpl(Zone.LIBRARY, getLibrary().getCards()), newTarget, game)) {
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SEARCHED, playerId, playerId));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
searchCards(new CardsImpl(Zone.LIBRARY, getLibrary().getCards()), target, game);
|
||||
}
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SEARCHED, playerId, playerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -781,4 +815,138 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return attackers;
|
||||
}
|
||||
|
||||
protected ManaOptions getManaAvailable(Game game) {
|
||||
List<Permanent> manaPerms = this.getAvailableManaProducers(game);
|
||||
|
||||
ManaOptions available = new ManaOptions();
|
||||
for (Permanent perm: manaPerms) {
|
||||
available.addMana(perm.getAbilities().getManaAbilities(Zone.BATTLEFIELD), game);
|
||||
}
|
||||
return available;
|
||||
}
|
||||
|
||||
protected List<Permanent> getAvailableManaProducers(Game game) {
|
||||
List<Permanent> result = new ArrayList<Permanent>();
|
||||
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(playerId)) {
|
||||
for (ManaAbility ability: permanent.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||
if (ability.canActivate(playerId, game)) {
|
||||
result.add(permanent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected boolean canPlay(ActivatedAbility ability, ManaOptions available, Game game) {
|
||||
if (!(ability instanceof ManaAbility) && ability.canActivate(playerId, game)) {
|
||||
ManaOptions abilityOptions = ability.getManaCosts().getOptions();
|
||||
if (abilityOptions.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
for (Mana mana: abilityOptions) {
|
||||
for (Mana avail: available) {
|
||||
if (mana.enough(avail)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Ability> getPlayable(Game game, boolean hidden) {
|
||||
List<Ability> playable = new ArrayList<Ability>();
|
||||
|
||||
ManaOptions available = getManaAvailable(game);
|
||||
available.addMana(manaPool.getMana());
|
||||
|
||||
if (hidden) {
|
||||
for (Card card: hand.getUniqueCards()) {
|
||||
for (ActivatedAbility ability: card.getAbilities().getActivatedAbilities(Zone.HAND)) {
|
||||
if (canPlay(ability, available, game))
|
||||
playable.add(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Card card: graveyard.getUniqueCards()) {
|
||||
for (ActivatedAbility ability: card.getAbilities().getActivatedAbilities(Zone.GRAVEYARD)) {
|
||||
if (canPlay(ability, available, game))
|
||||
playable.add(ability);
|
||||
}
|
||||
}
|
||||
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(playerId)) {
|
||||
for (ActivatedAbility ability: permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
|
||||
if (canPlay(ability, available, game))
|
||||
playable.add(ability);
|
||||
}
|
||||
}
|
||||
return playable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Ability> getPlayableOptions(Ability ability, Game game) {
|
||||
List<Ability> options = new ArrayList<Ability>();
|
||||
|
||||
if (ability.getTargets().size() > 0)
|
||||
addTargetOptions(options, ability, 0, game);
|
||||
else if (ability.getChoices().size() > 0)
|
||||
addChoiceOptions(options, ability, 0, game);
|
||||
else if (ability.getCosts().getTargets().size() > 0)
|
||||
addCostTargetOptions(options, ability, 0, game);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private void addTargetOptions(List<Ability> options, Ability option, int targetNum, Game game) {
|
||||
for (UUID targetId: option.getTargets().get(targetNum).possibleTargets(option.getSourceId(), playerId, game)) {
|
||||
Ability newOption = option.copy();
|
||||
newOption.getTargets().get(targetNum).addTarget(targetId, game);
|
||||
if (targetNum < option.getTargets().size() - 1) {
|
||||
addTargetOptions(options, newOption, targetNum + 1, game);
|
||||
}
|
||||
else {
|
||||
if (option.getChoices().size() > 0)
|
||||
addChoiceOptions(options, newOption, 0, game);
|
||||
else if (option.getCosts().getTargets().size() > 0)
|
||||
addCostTargetOptions(options, newOption, 0, game);
|
||||
else
|
||||
options.add(newOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addChoiceOptions(List<Ability> options, Ability option, int choiceNum, Game game) {
|
||||
for (String choice: option.getChoices().get(choiceNum).getChoices()) {
|
||||
Ability newOption = option.copy();
|
||||
newOption.getChoices().get(choiceNum).setChoice(choice);
|
||||
if (choiceNum < option.getChoices().size() - 1) {
|
||||
addChoiceOptions(options, newOption, choiceNum + 1, game);
|
||||
}
|
||||
else {
|
||||
if (option.getCosts().getTargets().size() > 0)
|
||||
addCostTargetOptions(options, newOption, 0, game);
|
||||
else
|
||||
options.add(newOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addCostTargetOptions(List<Ability> options, Ability option, int targetNum, Game game) {
|
||||
for (UUID targetId: option.getCosts().getTargets().get(targetNum).possibleTargets(option.getSourceId(), playerId, game)) {
|
||||
Ability newOption = option.copy();
|
||||
newOption.getCosts().getTargets().get(targetNum).addTarget(targetId, game);
|
||||
if (targetNum < option.getCosts().getTargets().size() - 1) {
|
||||
addCostTargetOptions(options, newOption, targetNum + 1, game);
|
||||
}
|
||||
else {
|
||||
options.add(newOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,22 +29,39 @@
|
|||
package mage.players;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.game.Game;
|
||||
import mage.util.CircularList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class PlayerList extends CircularList<Player> {
|
||||
public class PlayerList extends CircularList<UUID> {
|
||||
|
||||
public boolean setCurrent(UUID playerId) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list.get(i).getId().equals(playerId)) {
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
public Player getNext(Game game) {
|
||||
Player player;
|
||||
UUID start = this.get();
|
||||
while (true) {
|
||||
player = game.getPlayer(super.getNext());
|
||||
if (!player.hasLeft() && !player.hasLost())
|
||||
break;
|
||||
if (player.getId().equals(start))
|
||||
return null;
|
||||
}
|
||||
return false;
|
||||
return player;
|
||||
}
|
||||
|
||||
public Player getPrevious(Game game) {
|
||||
Player player;
|
||||
UUID start = this.get();
|
||||
while (true) {
|
||||
player = game.getPlayer(super.getPrevious());
|
||||
if (!player.hasLeft() && !player.hasLost())
|
||||
break;
|
||||
if (player.getId().equals(start))
|
||||
return null;
|
||||
}
|
||||
return player;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,15 +47,19 @@ public interface Target extends Serializable {
|
|||
public boolean doneChosing();
|
||||
public void clearChosen();
|
||||
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game);
|
||||
public List<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game);
|
||||
public boolean choose(Outcome outcome, Game game);
|
||||
public String getMessage();
|
||||
public String getTargetName();
|
||||
public void setTargetName(String name);
|
||||
public String getTargetedName(Game game);
|
||||
public Zone getZone();
|
||||
public boolean isLegal(Game game);
|
||||
public boolean canTarget(UUID id, Game game);
|
||||
public void addTarget(UUID id, Game game);
|
||||
public void addTarget(UUID id, int amount, Game game);
|
||||
|
||||
public int getTargetAmount(UUID targetId);
|
||||
public int getNumberOfTargets();
|
||||
public int getMaxNumberOfTargets();
|
||||
public List<UUID> getTargets();
|
||||
|
@ -66,6 +70,6 @@ public interface Target extends Serializable {
|
|||
public boolean isRequired();
|
||||
public void setRequired(boolean required);
|
||||
|
||||
public UUID getLastTarget();
|
||||
// public UUID getLastTarget();
|
||||
public UUID getFirstTarget();
|
||||
}
|
||||
|
|
87
Mage/src/mage/target/TargetAmount.java
Normal file
87
Mage/src/mage/target/TargetAmount.java
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.target;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public abstract class TargetAmount extends TargetImpl {
|
||||
|
||||
int amount;
|
||||
int remainingAmount;
|
||||
|
||||
public TargetAmount(int amount) {
|
||||
this.amount = amount;
|
||||
this.remainingAmount = amount;
|
||||
this.required = true;
|
||||
}
|
||||
|
||||
public int getAmountRemaining() {
|
||||
return remainingAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doneChosing() {
|
||||
return remainingAmount == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearChosen() {
|
||||
super.clearChosen();
|
||||
remainingAmount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTarget(UUID id, int amount, Game game) {
|
||||
if (amount <= remainingAmount) {
|
||||
super.addTarget(id, amount, game);
|
||||
remainingAmount -= amount;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean choose(Outcome outcome, Game game) {
|
||||
Player player = game.getPlayer(this.source.getControllerId());
|
||||
chosen = remainingAmount == 0;
|
||||
while (remainingAmount > 0) {
|
||||
if (!player.chooseTargetAmount(outcome, this, game)) {
|
||||
return chosen;
|
||||
}
|
||||
chosen = remainingAmount == 0;
|
||||
}
|
||||
return chosen = true;
|
||||
}
|
||||
|
||||
}
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
package mage.target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Zone;
|
||||
import mage.cards.Card;
|
||||
|
@ -69,6 +71,23 @@ public class TargetCard extends TargetObject {
|
|||
return this.filter;
|
||||
}
|
||||
|
||||
public boolean choose(Cards cards, Game game) {
|
||||
Player player = game.getPlayer(this.source.getControllerId());
|
||||
while (!isChosen() && !doneChosing()) {
|
||||
chosen = targets.size() >= minNumberOfTargets;
|
||||
if (!player.chooseTarget(cards, this, game)) {
|
||||
return chosen;
|
||||
}
|
||||
chosen = targets.size() >= minNumberOfTargets;
|
||||
}
|
||||
while (!doneChosing()) {
|
||||
if (!player.chooseTarget(cards, this, game)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return chosen = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) {
|
||||
|
@ -77,11 +96,15 @@ public class TargetCard extends TargetObject {
|
|||
if (player != null) {
|
||||
switch (zone) {
|
||||
case HAND:
|
||||
if (player.getHand().getCards(filter).size() > this.minNumberOfTargets)
|
||||
if (player.getHand().count(filter) >= this.minNumberOfTargets)
|
||||
return true;
|
||||
break;
|
||||
case GRAVEYARD:
|
||||
if (player.getGraveyard().getCards(filter).size() > this.minNumberOfTargets)
|
||||
if (player.getGraveyard().count(filter) >= this.minNumberOfTargets)
|
||||
return true;
|
||||
break;
|
||||
case LIBRARY:
|
||||
if (player.getLibrary().count(filter) >= this.minNumberOfTargets)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
@ -91,6 +114,32 @@ public class TargetCard extends TargetObject {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
List<UUID> possibleTargets = new ArrayList<UUID>();
|
||||
for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) {
|
||||
if (filter.matchOwner(playerId)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
switch (zone) {
|
||||
case HAND:
|
||||
for (Card card: player.getHand().getCards(filter)) {
|
||||
possibleTargets.add(card.getId());
|
||||
}
|
||||
break;
|
||||
case GRAVEYARD:
|
||||
for (Card card: player.getGraveyard().getCards(filter)) {
|
||||
possibleTargets.add(card.getId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return possibleTargets;
|
||||
|
||||
}
|
||||
|
||||
public boolean canTarget(UUID id, Cards cards, Game game) {
|
||||
Card card = cards.get(id);
|
||||
if (card != null)
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
package mage.target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.Constants.Zone;
|
||||
|
@ -45,7 +47,7 @@ import mage.players.Player;
|
|||
*/
|
||||
public abstract class TargetImpl implements Target {
|
||||
|
||||
protected List<UUID> targets = new ArrayList<UUID>();
|
||||
protected Map<UUID, Integer> targets = new HashMap<UUID, Integer>();
|
||||
|
||||
protected String targetName;
|
||||
protected Zone zone;
|
||||
|
@ -75,6 +77,11 @@ public abstract class TargetImpl implements Target {
|
|||
return targetName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetName(String name) {
|
||||
this.targetName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Zone getZone() {
|
||||
return zone;
|
||||
|
@ -114,14 +121,33 @@ public abstract class TargetImpl implements Target {
|
|||
*/
|
||||
@Override
|
||||
public void addTarget(UUID id, Game game) {
|
||||
//20100423 - 113.3
|
||||
if (!targets.containsKey(id)) {
|
||||
if (source != null) {
|
||||
if (!game.replaceEvent(GameEvent.getEvent(EventType.TARGET, id, source.getSourceId(), source.getControllerId()))) {
|
||||
targets.put(id, 0);
|
||||
game.fireEvent(GameEvent.getEvent(EventType.TARGETED, id, source.getSourceId(), source.getControllerId()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
targets.put(id, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTarget(UUID id, int amount, Game game) {
|
||||
if (targets.containsKey(id)) {
|
||||
amount += targets.get(id);
|
||||
}
|
||||
if (source != null) {
|
||||
if (!game.replaceEvent(GameEvent.getEvent(EventType.TARGET, id, source.getSourceId(), source.getControllerId()))) {
|
||||
targets.add(id);
|
||||
targets.put(id, amount);
|
||||
game.fireEvent(GameEvent.getEvent(EventType.TARGETED, id, source.getSourceId(), source.getControllerId()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
targets.add(id);
|
||||
targets.put(id, amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +172,7 @@ public abstract class TargetImpl implements Target {
|
|||
|
||||
@Override
|
||||
public boolean isLegal(Game game) {
|
||||
for (UUID targetId: targets) {
|
||||
for (UUID targetId: targets.keySet()) {
|
||||
if (!canTarget(targetId, game))
|
||||
return false;
|
||||
}
|
||||
|
@ -155,20 +181,27 @@ public abstract class TargetImpl implements Target {
|
|||
|
||||
@Override
|
||||
public List<UUID> getTargets() {
|
||||
return targets;
|
||||
return new ArrayList(targets.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getLastTarget() {
|
||||
if (targets.size() > 0)
|
||||
return targets.get(targets.size() - 1);
|
||||
return null;
|
||||
public int getTargetAmount(UUID targetId) {
|
||||
if (targets.containsKey(targetId))
|
||||
return targets.get(targetId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public UUID getLastTarget() {
|
||||
// if (targets.size() > 0)
|
||||
// return targets.keySet().iterator().next();
|
||||
// return null;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public UUID getFirstTarget() {
|
||||
if (targets.size() > 0)
|
||||
return targets.get(0);
|
||||
return targets.keySet().iterator().next();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,11 +28,13 @@
|
|||
|
||||
package mage.target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.TargetController;
|
||||
import mage.Constants.Zone;
|
||||
import mage.MageObject;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
@ -116,17 +118,28 @@ public class TargetPermanent extends TargetObject {
|
|||
|
||||
@Override
|
||||
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, sourceControllerId, game);
|
||||
Iterator<Permanent> it = permanents.iterator();
|
||||
while(it.hasNext()) {
|
||||
Permanent permanent = it.next();
|
||||
if (!permanent.canBeTargetedBy(game.getObject(sourceId))) {
|
||||
it.remove();
|
||||
int count = 0;
|
||||
MageObject targetSource = game.getObject(sourceId);
|
||||
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, game)) {
|
||||
if (permanent.canBeTargetedBy(targetSource)) {
|
||||
count++;
|
||||
if (count >= this.minNumberOfTargets)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (permanents.size() >= this.minNumberOfTargets)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
List<UUID> possibleTargets = new ArrayList<UUID>();
|
||||
MageObject targetSource = game.getObject(sourceId);
|
||||
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, game)) {
|
||||
if (permanent.canBeTargetedBy(targetSource)) {
|
||||
possibleTargets.add(permanent.getId());
|
||||
}
|
||||
}
|
||||
return possibleTargets;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,8 +28,11 @@
|
|||
|
||||
package mage.target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Zone;
|
||||
import mage.MageObject;
|
||||
import mage.filter.FilterPlayer;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
@ -65,21 +68,37 @@ public class TargetPlayer extends TargetImpl {
|
|||
@Override
|
||||
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
int count = 0;
|
||||
MageObject targetSource = game.getObject(sourceId);
|
||||
for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null && !player.hasLeft() && filter.match(player)) {
|
||||
if (player.canTarget(game.getObject(sourceId)))
|
||||
if (player.canBeTargetedBy(targetSource)) {
|
||||
count++;
|
||||
if (count >= this.minNumberOfTargets)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count >= this.minNumberOfTargets)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
List<UUID> possibleTargets = new ArrayList<UUID>();
|
||||
MageObject targetSource = game.getObject(sourceId);
|
||||
for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null && !player.hasLeft() && filter.match(player)) {
|
||||
if (player.canBeTargetedBy(targetSource))
|
||||
possibleTargets.add(playerId);
|
||||
}
|
||||
}
|
||||
return possibleTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLegal(Game game) {
|
||||
for (UUID playerId: targets) {
|
||||
for (UUID playerId: targets.keySet()) {
|
||||
if (!canTarget(playerId, game))
|
||||
return false;
|
||||
}
|
||||
|
@ -91,7 +110,7 @@ public class TargetPlayer extends TargetImpl {
|
|||
Player player = game.getPlayer(id);
|
||||
if (player != null) {
|
||||
if (source != null)
|
||||
return player.canTarget(game.getObject(this.source.getSourceId())) && filter.match(player);
|
||||
return player.canBeTargetedBy(game.getObject(this.source.getSourceId())) && filter.match(player);
|
||||
else
|
||||
return filter.match(player);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
package mage.target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.Zone;
|
||||
import mage.filter.FilterSpell;
|
||||
|
@ -83,9 +85,22 @@ public class TargetSpell extends TargetObject {
|
|||
for (StackObject stackObject: game.getStack()) {
|
||||
if (stackObject instanceof Spell && game.getPlayer(sourceControllerId).getInRange().contains(stackObject.getControllerId()) && filter.match((Spell)stackObject)) {
|
||||
count++;
|
||||
if (count >= this.minNumberOfTargets)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return count >= this.minNumberOfTargets;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
List<UUID> possibleTargets = new ArrayList<UUID>();
|
||||
for (StackObject stackObject: game.getStack()) {
|
||||
if (stackObject instanceof Spell && game.getPlayer(sourceControllerId).getInRange().contains(stackObject.getControllerId()) && filter.match((Spell)stackObject)) {
|
||||
possibleTargets.add(stackObject.getId());
|
||||
}
|
||||
}
|
||||
return possibleTargets;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ import java.util.UUID;
|
|||
import mage.Constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -50,6 +49,9 @@ public class Targets extends ArrayList<Target> {
|
|||
|
||||
public void setSource(Ability ability) {
|
||||
this.source = ability;
|
||||
for (Target target: this) {
|
||||
target.setAbility(ability);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -108,4 +110,11 @@ public class Targets extends ArrayList<Target> {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public UUID getFirstTarget() {
|
||||
if (this.size() > 0)
|
||||
return this.get(0).getFirstTarget();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue