forked from External/mage
Merge branch 'master' into add-minimum-rating-option
This commit is contained in:
commit
e7d129a074
568 changed files with 21414 additions and 6453 deletions
|
|
@ -12,6 +12,9 @@ public interface Controllable {
|
|||
UUID getId();
|
||||
|
||||
default boolean isControlledBy(UUID controllerID){
|
||||
if(getControllerId() == null){
|
||||
return false;
|
||||
}
|
||||
return getControllerId().equals(controllerID);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1026,6 +1026,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
watchers.add(new BlockedAttackerWatcher());
|
||||
watchers.add(new DamageDoneWatcher());
|
||||
watchers.add(new PlanarRollWatcher());
|
||||
watchers.add(new PlayersAttackedThisTurnWatcher());
|
||||
|
||||
//20100716 - 103.5
|
||||
for (UUID playerId : state.getPlayerList(startingPlayerId)) {
|
||||
|
|
@ -1527,7 +1528,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
@Override
|
||||
public void addEffect(ContinuousEffect continuousEffect, Ability source) {
|
||||
Ability newAbility = source.copy();
|
||||
newAbility.setSourceObject(null, this); // Update the source object to the currently existing Object
|
||||
newAbility.setSourceObjectZoneChangeCounter(getState().getZoneChangeCounter(source.getSourceId()));
|
||||
ContinuousEffect newEffect = continuousEffect.copy();
|
||||
|
||||
newEffect.newId();
|
||||
|
|
@ -1698,11 +1699,17 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
if (ability instanceof TriggeredManaAbility || ability instanceof DelayedTriggeredManaAbility) {
|
||||
// 20110715 - 605.4
|
||||
Ability manaAbiltiy = ability.copy();
|
||||
if (manaAbiltiy.getSourceObjectZoneChangeCounter() == 0) {
|
||||
manaAbiltiy.setSourceObjectZoneChangeCounter(getState().getZoneChangeCounter(ability.getSourceId()));
|
||||
}
|
||||
manaAbiltiy.activate(this, false);
|
||||
manaAbiltiy.resolve(this);
|
||||
} else {
|
||||
TriggeredAbility newAbility = ability.copy();
|
||||
newAbility.newId();
|
||||
if (newAbility.getSourceObjectZoneChangeCounter() == 0) {
|
||||
newAbility.setSourceObjectZoneChangeCounter(getState().getZoneChangeCounter(ability.getSourceId()));
|
||||
}
|
||||
state.addTriggeredAbility(newAbility);
|
||||
}
|
||||
}
|
||||
|
|
@ -1711,10 +1718,10 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
public UUID addDelayedTriggeredAbility(DelayedTriggeredAbility delayedAbility, Ability source) {
|
||||
delayedAbility.setSourceId(source.getSourceId());
|
||||
delayedAbility.setControllerId(source.getControllerId());
|
||||
delayedAbility.setSourceObject(source.getSourceObject(this), this);
|
||||
// return addDelayedTriggeredAbility(delayedAbility);
|
||||
DelayedTriggeredAbility newAbility = delayedAbility.copy();
|
||||
newAbility.newId();
|
||||
newAbility.setSourceObjectZoneChangeCounter(getState().getZoneChangeCounter(source.getSourceId()));
|
||||
newAbility.initOnAdding(this);
|
||||
// ability.init is called as the ability triggeres not now.
|
||||
// If a FixedTarget pointer is already set from the effect setting up this delayed ability
|
||||
|
|
@ -2594,7 +2601,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
boolean addPlaneAgain = false;
|
||||
for (Iterator<CommandObject> it = this.getState().getCommand().iterator(); it.hasNext();) {
|
||||
CommandObject obj = it.next();
|
||||
if (obj.getControllerId().equals(playerId)) {
|
||||
if (obj.isControlledBy(playerId)) {
|
||||
if (obj instanceof Emblem) {
|
||||
((Emblem) obj).discardEffects();// This may not be the best fix but it works
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.game.combat;
|
||||
|
||||
import mage.MageObject;
|
||||
|
|
@ -6,6 +5,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.effects.RequirementEffect;
|
||||
import mage.abilities.effects.RestrictionEffect;
|
||||
import mage.abilities.keyword.BandingAbility;
|
||||
import mage.abilities.keyword.BandsWithOtherAbility;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.abilities.keyword.special.JohanVigilanceAbility;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -14,8 +14,12 @@ import mage.filter.StaticFilters;
|
|||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterCreatureForCombatBlock;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.AbilityPredicate;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.filter.predicate.mageobject.SupertypePredicate;
|
||||
import mage.filter.predicate.permanent.AttackingSameNotBandedPredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
|
|
@ -103,8 +107,8 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get all possible defender (players and plainwalkers) That does not mean
|
||||
* neccessarly mean that they are really attacked
|
||||
* Get all possible defender (players and planeswalkers) That does not mean
|
||||
* necessarily mean that they are really attacked
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -246,11 +250,14 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
game.getCombat().checkAttackRequirements(player, game);
|
||||
boolean firstTime = true;
|
||||
do {
|
||||
if (!firstTime || !game.getPlayer(game.getActivePlayerId()).getAvailableAttackers(game).isEmpty()) {
|
||||
if (!firstTime
|
||||
|| !game.getPlayer(game.getActivePlayerId()).getAvailableAttackers(game).isEmpty()) {
|
||||
player.selectAttackers(game, attackingPlayerId);
|
||||
}
|
||||
firstTime = false;
|
||||
if (game.isPaused() || game.checkIfGameIsOver() || game.executingRollback()) {
|
||||
if (game.isPaused()
|
||||
|| game.checkIfGameIsOver()
|
||||
|| game.executingRollback()) {
|
||||
return;
|
||||
}
|
||||
// because of possible undo during declare attackers it's neccassary to call here the methods with "game.getCombat()." to get the current combat object!!!
|
||||
|
|
@ -293,53 +300,115 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
Permanent attacker = game.getPermanent(creatureId);
|
||||
if (attacker != null && player != null) {
|
||||
CombatGroup combatGroup = findGroup(attacker.getId());
|
||||
if (combatGroup != null && attacker.getAbilities().containsKey(BandingAbility.getInstance().getId()) && attacker.getBandedCards().isEmpty() && getAttackers().size() > 1) {
|
||||
boolean isBanded = false;
|
||||
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("attacking creature to band with " + attacker.getLogName());
|
||||
filter.add(Predicates.not(new PermanentIdPredicate(creatureId)));
|
||||
filter.add(new AttackingSameNotBandedPredicate(combatGroup.getDefenderId())); // creature that isn't already banded, and is attacking the same player or planeswalker
|
||||
while (player.canRespond()) {
|
||||
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true);
|
||||
target.setRequired(false);
|
||||
if (!target.canChoose(attackingPlayerId, game)
|
||||
|| game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, attackingPlayerId, attackingPlayerId))
|
||||
|| !player.chooseUse(Outcome.Benefit, "Do you wish to " + (isBanded ? "band " + attacker.getLogName() + " with another " : "form a band with " + attacker.getLogName() + " and an ") + "attacking creature?", null, game)) {
|
||||
break;
|
||||
}
|
||||
if (target.choose(Outcome.Benefit, attackingPlayerId, null, game)) {
|
||||
isBanded = true;
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
|
||||
for (UUID bandedId : attacker.getBandedCards()) {
|
||||
permanent.addBandedCard(bandedId);
|
||||
Permanent banded = game.getPermanent(bandedId);
|
||||
if (banded != null) {
|
||||
banded.addBandedCard(targetId);
|
||||
}
|
||||
}
|
||||
permanent.addBandedCard(creatureId);
|
||||
attacker.addBandedCard(targetId);
|
||||
if (!permanent.getAbilities().containsKey(BandingAbility.getInstance().getId())) {
|
||||
filter.add(new AbilityPredicate(BandingAbility.class));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (combatGroup != null && attacker.getBandedCards().isEmpty() && getAttackers().size() > 1) {
|
||||
boolean canBand = attacker.getAbilities().containsKey(BandingAbility.getInstance().getId());
|
||||
List<Ability> bandsWithOther = new ArrayList<>();
|
||||
for (Ability ability : attacker.getAbilities()) {
|
||||
if (ability.getClass().equals(BandsWithOtherAbility.class)) {
|
||||
bandsWithOther.add(ability);
|
||||
}
|
||||
}
|
||||
if (isBanded) {
|
||||
StringBuilder sb = new StringBuilder(player.getLogName()).append(" formed a band with ").append((attacker.getBandedCards().size() + 1) + " creatures: ");
|
||||
sb.append(attacker.getLogName());
|
||||
for (UUID id : attacker.getBandedCards()) {
|
||||
sb.append(", ");
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
if (permanent != null) {
|
||||
sb.append(permanent.getLogName());
|
||||
boolean canBandWithOther = !bandsWithOther.isEmpty();
|
||||
if (canBand || canBandWithOther) {
|
||||
boolean isBanded = false;
|
||||
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("attacking creature to band with " + attacker.getLogName());
|
||||
filter.add(Predicates.not(new PermanentIdPredicate(creatureId)));
|
||||
filter.add(new AttackingSameNotBandedPredicate(combatGroup.getDefenderId())); // creature that isn't already banded, and is attacking the same player or planeswalker
|
||||
List<Predicate<MageObject>> predicates = new ArrayList<>();
|
||||
if (!canBand && canBandWithOther) {
|
||||
for (Ability ab : bandsWithOther) {
|
||||
BandsWithOtherAbility ability = (BandsWithOtherAbility) ab;
|
||||
if (ability.getSubtype() != null) {
|
||||
predicates.add(new SubtypePredicate(ability.getSubtype()));
|
||||
}
|
||||
if (ability.getSupertype() != null) {
|
||||
predicates.add(new SupertypePredicate(ability.getSupertype()));
|
||||
}
|
||||
if (ability.getName() != null) {
|
||||
predicates.add(new NamePredicate(ability.getName()));
|
||||
}
|
||||
}
|
||||
filter.add(Predicates.or(predicates));
|
||||
}
|
||||
while (player.canRespond()) {
|
||||
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true);
|
||||
target.setRequired(false);
|
||||
canBand &= target.canChoose(attackingPlayerId, game);
|
||||
canBandWithOther &= target.canChoose(attackingPlayerId, game);
|
||||
if (game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, attackingPlayerId, attackingPlayerId))
|
||||
|| (!canBand && !canBandWithOther)
|
||||
|| !player.chooseUse(Outcome.Benefit, "Do you wish to " + (isBanded ? "band " + attacker.getLogName() + " with another " : "form a band with " + attacker.getLogName() + " and an ") + "attacking creature?", null, game)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (canBand && canBandWithOther) {
|
||||
if (player.chooseUse(Outcome.Detriment, "Choose type of banding ability to apply:", attacker.getLogName(), "Banding", "Bands with other", null, game)) {
|
||||
canBandWithOther = false;
|
||||
} else {
|
||||
canBand = false;
|
||||
for (Ability ab : bandsWithOther) {
|
||||
BandsWithOtherAbility ability = (BandsWithOtherAbility) ab;
|
||||
if (ability.getSubtype() != null) {
|
||||
predicates.add(new SubtypePredicate(ability.getSubtype()));
|
||||
}
|
||||
if (ability.getSupertype() != null) {
|
||||
predicates.add(new SupertypePredicate(ability.getSupertype()));
|
||||
}
|
||||
if (ability.getName() != null) {
|
||||
predicates.add(new NamePredicate(ability.getName()));
|
||||
}
|
||||
}
|
||||
filter.add(Predicates.or(predicates));
|
||||
}
|
||||
}
|
||||
|
||||
if (target.choose(Outcome.Benefit, attackingPlayerId, null, game)) {
|
||||
isBanded = true;
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
|
||||
for (UUID bandedId : attacker.getBandedCards()) {
|
||||
permanent.addBandedCard(bandedId);
|
||||
Permanent banded = game.getPermanent(bandedId);
|
||||
if (banded != null) {
|
||||
banded.addBandedCard(targetId);
|
||||
}
|
||||
}
|
||||
permanent.addBandedCard(creatureId);
|
||||
attacker.addBandedCard(targetId);
|
||||
if (canBand) {
|
||||
if (!permanent.getAbilities().containsKey(BandingAbility.getInstance().getId())) {
|
||||
filter.add(new AbilityPredicate(BandingAbility.class));
|
||||
canBandWithOther = false;
|
||||
}
|
||||
} else if (canBandWithOther) {
|
||||
List<Predicate<MageObject>> newPredicates = new ArrayList<>();
|
||||
for (Predicate<MageObject> predicate : predicates) {
|
||||
if (predicate.apply(permanent, game)) {
|
||||
newPredicates.add(predicate);
|
||||
}
|
||||
}
|
||||
filter.add(Predicates.or(newPredicates));
|
||||
canBand = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
game.informPlayers(sb.toString());
|
||||
if (isBanded) {
|
||||
StringBuilder sb = new StringBuilder(player.getLogName()).append(" formed a band with ").append((attacker.getBandedCards().size() + 1) + " creatures: ");
|
||||
sb.append(attacker.getLogName());
|
||||
for (UUID id : attacker.getBandedCards()) {
|
||||
sb.append(", ");
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
if (permanent != null) {
|
||||
sb.append(permanent.getLogName());
|
||||
}
|
||||
}
|
||||
game.informPlayers(sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -387,11 +456,16 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
if (defenders.size() == 1) {
|
||||
player.declareAttacker(creature.getId(), defenders.iterator().next(), game, false);
|
||||
} else {
|
||||
TargetDefender target = new TargetDefender(defenders, creature.getId());
|
||||
target.setRequired(true);
|
||||
target.setTargetName("planeswalker or player for " + creature.getLogName() + " to attack");
|
||||
if (player.chooseTarget(Outcome.Damage, target, null, game)) {
|
||||
player.declareAttacker(creature.getId(), target.getFirstTarget(), game, false);
|
||||
if (!player.isHuman()) { // computer only for multiple defenders
|
||||
player.declareAttacker(creature.getId(), defenders.iterator().next(), game, false);
|
||||
} else { // human players only for multiple defenders
|
||||
TargetDefender target = new TargetDefender(defenders, creature.getId());
|
||||
target.setRequired(true);
|
||||
target.setTargetName("planeswalker or player for " + creature.getLogName() + " to attack");
|
||||
if (player.chooseTarget(Outcome.Damage, target, null, game)) {
|
||||
System.out.println("The player " + player.getName() + " declares an attacker here. " + creature.getName());
|
||||
player.declareAttacker(creature.getId(), target.getFirstTarget(), game, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -483,7 +557,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
* Handle the blocker selection process
|
||||
*
|
||||
* @param blockController player that controlls how to block, if null the
|
||||
* defender is the controller
|
||||
* defender is the controller
|
||||
* @param game
|
||||
*/
|
||||
public void selectBlockers(Player blockController, Game game) {
|
||||
|
|
@ -1275,10 +1349,10 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
if (defenderAttackedBy.size() >= defendingPlayer.getMaxAttackedBy()) {
|
||||
Player attackingPlayer = game.getPlayer(game.getControllerId(attackerId));
|
||||
if (attackingPlayer != null && !game.isSimulation()) {
|
||||
game.informPlayer(attackingPlayer, "No more than " +
|
||||
CardUtil.numberToText(defendingPlayer.getMaxAttackedBy()) +
|
||||
" creatures can attack " +
|
||||
defendingPlayer.getLogName());
|
||||
game.informPlayer(attackingPlayer, "No more than "
|
||||
+ CardUtil.numberToText(defendingPlayer.getMaxAttackedBy())
|
||||
+ " creatures can attack "
|
||||
+ defendingPlayer.getLogName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1308,7 +1382,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
* @param playerId
|
||||
* @param game
|
||||
* @param solveBanding check whether also add creatures banded with
|
||||
* attackerId
|
||||
* attackerId
|
||||
*/
|
||||
public void addBlockingGroup(UUID blockerId, UUID attackerId, UUID playerId, Game game, boolean solveBanding) {
|
||||
Permanent blocker = game.getPermanent(blockerId);
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ import java.io.Serializable;
|
|||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ControllerAssignCombatDamageToBlockersAbility;
|
||||
import mage.abilities.common.ControllerDivideCombatDamageAbility;
|
||||
import mage.abilities.common.DamageAsThoughNotBlockedAbility;
|
||||
import mage.abilities.keyword.BandingAbility;
|
||||
import mage.abilities.keyword.BandsWithOtherAbility;
|
||||
import mage.abilities.keyword.CantBlockAloneAbility;
|
||||
import mage.abilities.keyword.DeathtouchAbility;
|
||||
import mage.abilities.keyword.DoubleStrikeAbility;
|
||||
|
|
@ -110,6 +112,56 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
|||
return perm.getAbilities().containsKey(BandingAbility.getInstance().getId());
|
||||
}
|
||||
|
||||
private boolean appliesBandsWithOther(List<UUID> creatureIds, Game game) {
|
||||
for (UUID creatureId : creatureIds) {
|
||||
Permanent perm = game.getPermanent(creatureId);
|
||||
if (perm != null && perm.getBandedCards() != null) {
|
||||
for (Ability ab : perm.getAbilities()) {
|
||||
if (ab.getClass().equals(BandsWithOtherAbility.class)) {
|
||||
BandsWithOtherAbility ability = (BandsWithOtherAbility) ab;
|
||||
if (ability.getSubtype() != null) {
|
||||
if (perm.hasSubtype(ability.getSubtype(), game)) {
|
||||
for (UUID bandedId : creatureIds) {
|
||||
if (!bandedId.equals(creatureId)) {
|
||||
Permanent banded = game.getPermanent(bandedId);
|
||||
if (banded != null && banded.hasSubtype(ability.getSubtype(), game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ability.getSupertype() != null) {
|
||||
if (perm.getSuperType().contains(ability.getSupertype())) {
|
||||
for (UUID bandedId : creatureIds) {
|
||||
if (!bandedId.equals(creatureId)) {
|
||||
Permanent banded = game.getPermanent(bandedId);
|
||||
if (banded != null && banded.getSuperType().contains(ability.getSupertype())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ability.getName() != null) {
|
||||
if (perm.getName().equals(ability.getName())) {
|
||||
for (UUID bandedId : creatureIds) {
|
||||
if (!bandedId.equals(creatureId)) {
|
||||
Permanent banded = game.getPermanent(bandedId);
|
||||
if (banded != null && banded.getName().equals(ability.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void assignDamageToBlockers(boolean first, Game game) {
|
||||
if (!attackers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) {
|
||||
Permanent attacker = game.getPermanent(attackers.get(0));
|
||||
|
|
@ -837,6 +889,9 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (appliesBandsWithOther(attackers, game)) { // 702.21k - both a [quality] creature with “bands with other [quality]” and another [quality] creature (...)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -855,6 +910,9 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (appliesBandsWithOther(blockers, game)) { // 702.21j - both a [quality] creature with “bands with other [quality]” and another [quality] creature (...)
|
||||
return true;
|
||||
}
|
||||
for (Permanent defensiveFormation : game.getBattlefield().getAllActivePermanents(defendingPlayerId)) {
|
||||
if (defensiveFormation.getAbilities().containsKey(ControllerAssignCombatDamageToBlockersAbility.getInstance().getId())) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -3,17 +3,16 @@ package mage.game.command;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.game.Controllable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Viserion, nantuko
|
||||
*/
|
||||
public interface CommandObject extends MageObject {
|
||||
public interface CommandObject extends MageObject, Controllable {
|
||||
|
||||
UUID getSourceId();
|
||||
|
||||
UUID getControllerId();
|
||||
|
||||
void assignNewId();
|
||||
|
||||
MageObject getSourceObject();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.game.command;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.game.command;
|
||||
|
||||
import static java.lang.Math.log;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
|
@ -289,7 +287,7 @@ public class Plane implements CommandObject {
|
|||
if (plane instanceof Plane) {
|
||||
return (Plane) plane;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ package mage.game.command.emblems;
|
|||
import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility;
|
||||
import mage.abilities.effects.common.LoseGameTargetPlayerEffect;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.command.Emblem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class VraskaGolgariQueenEmblem extends Emblem {
|
||||
|
|
@ -17,9 +17,9 @@ public final class VraskaGolgariQueenEmblem extends Emblem {
|
|||
this.setName("Emblem Vraska");
|
||||
this.setExpansionSetCodeForImage("GRN");
|
||||
this.getAbilities().add(new DealsDamageToAPlayerAllTriggeredAbility(
|
||||
new LoseGameTargetPlayerEffect(),
|
||||
Zone.COMMAND, new LoseGameTargetPlayerEffect(),
|
||||
StaticFilters.FILTER_CONTROLLED_A_CREATURE,
|
||||
false, SetTargetPointer.PLAYER, true
|
||||
false, SetTargetPointer.NONE, true, true
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,7 +147,8 @@ public abstract class DraftImpl implements Draft {
|
|||
|
||||
@Override
|
||||
public void autoPick(UUID playerId) {
|
||||
this.addPick(playerId, players.get(playerId).getBooster().get(0).getId(), null);
|
||||
List<Card> booster = players.get(playerId).getBooster();
|
||||
this.addPick(playerId, booster.get(booster.size()-1).getId(), null);
|
||||
}
|
||||
|
||||
protected void passLeft() {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
package mage.game.permanent.token;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class ElfKnightToken extends TokenImpl {
|
||||
|
||||
public ElfKnightToken() {
|
||||
super("Knight Ally", "2/2 green and white Elf Knight creature token with vigilance");
|
||||
super("Elf Knight", "2/2 green and white Elf Knight creature token with vigilance");
|
||||
this.setExpansionSetCodeForImage("GRN");
|
||||
cardType.add(CardType.CREATURE);
|
||||
color.setGreen(true);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
package mage.game.permanent.token;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.MageInt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class ExpansionSymbolToken extends TokenImpl {
|
||||
|
||||
public ExpansionSymbolToken() {
|
||||
super("Expansion-Symbol", "1/1 colorless Expansion-Symbol creature token");
|
||||
cardType.add(CardType.CREATURE);
|
||||
subtype.add(SubType.EXPANSION_SYMBOL);
|
||||
power = new MageInt(1);
|
||||
toughness = new MageInt(1);
|
||||
}
|
||||
|
||||
public ExpansionSymbolToken(final ExpansionSymbolToken token) {
|
||||
super(token);
|
||||
}
|
||||
|
||||
public ExpansionSymbolToken copy() {
|
||||
return new ExpansionSymbolToken(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ public final class GoblinToken extends TokenImpl {
|
|||
static {
|
||||
tokenImageSets.addAll(Arrays.asList("10E", "ALA", "SOM", "M10", "NPH", "M13", "RTR",
|
||||
"MMA", "M15", "C14", "KTK", "EVG", "DTK", "ORI", "DDG", "DDN", "DD3EVG", "MM2",
|
||||
"MM3", "EMA", "C16", "DOM"));
|
||||
"MM3", "EMA", "C16", "DOM", "ANA"));
|
||||
}
|
||||
|
||||
public GoblinToken(boolean withHaste) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import mage.constants.SubType;
|
|||
import mage.target.TargetPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class MaskToken extends TokenImpl {
|
||||
|
|
@ -18,8 +17,8 @@ public final class MaskToken extends TokenImpl {
|
|||
public MaskToken() {
|
||||
super(
|
||||
"Mask", "white Aura enchantment token named Mask "
|
||||
+ "attached to another target permanent. "
|
||||
+ "The token has enchant permanent and totem armor."
|
||||
+ "attached to another target permanent. "
|
||||
+ "The token has enchant permanent and totem armor."
|
||||
);
|
||||
cardType.add(CardType.ENCHANTMENT);
|
||||
color.setWhite(true);
|
||||
|
|
@ -31,6 +30,7 @@ public final class MaskToken extends TokenImpl {
|
|||
ability.addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||
this.addAbility(ability);
|
||||
|
||||
// Totem armor
|
||||
this.addAbility(new TotemArmorAbility());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
package mage.game.permanent.token;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.MageInt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class RabidSheepToken extends TokenImpl {
|
||||
|
||||
public RabidSheepToken() {
|
||||
super("Rabid Sheep", "2/2 green Sheep creature token named Rabid Sheep");
|
||||
cardType.add(CardType.CREATURE);
|
||||
subtype.add(SubType.SHEEP);
|
||||
color.setGreen(true);
|
||||
power = new MageInt(2);
|
||||
toughness = new MageInt(2);
|
||||
}
|
||||
|
||||
public RabidSheepToken(final RabidSheepToken token) {
|
||||
super(token);
|
||||
}
|
||||
|
||||
public RabidSheepToken copy() {
|
||||
return new RabidSheepToken(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ public final class SpiritWhiteToken extends TokenImpl {
|
|||
final static private List<String> tokenImageSets = new ArrayList<>();
|
||||
|
||||
static {
|
||||
tokenImageSets.addAll(Arrays.asList("AVR", "C14", "CNS", "DDC", "DDK", "FRF", "ISD", "KTK", "M15", "MM2", "SHM", "SOI", "EMA", "C16", "MM3", "CMA", "E01"));
|
||||
tokenImageSets.addAll(Arrays.asList("AVR", "C14", "CNS", "DDC", "DDK", "FRF", "ISD", "KTK", "M15", "MM2", "SHM", "SOI", "EMA", "C16", "MM3", "CMA", "E01", "ANA"));
|
||||
}
|
||||
|
||||
public SpiritWhiteToken() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
package mage.game.permanent.token;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.MageInt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class UktabiKongApeToken extends TokenImpl {
|
||||
|
||||
public UktabiKongApeToken() {
|
||||
super("Ape", "1/1 green Ape creature token");
|
||||
cardType.add(CardType.CREATURE);
|
||||
subtype.add(SubType.APE);
|
||||
color.setGreen(true);
|
||||
power = new MageInt(1);
|
||||
toughness = new MageInt(1);
|
||||
}
|
||||
|
||||
public UktabiKongApeToken(final UktabiKongApeToken token) {
|
||||
super(token);
|
||||
}
|
||||
|
||||
public UktabiKongApeToken copy() {
|
||||
return new UktabiKongApeToken(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
package mage.game.permanent.token;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.keyword.BandsWithOtherAbility;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class WolvesOfTheHuntToken extends TokenImpl {
|
||||
|
||||
public WolvesOfTheHuntToken() {
|
||||
super("Wolves of the Hunt", "1/1 green Wolf creature token named Wolves of the Hunt");
|
||||
cardType.add(CardType.CREATURE);
|
||||
subtype.add(SubType.WOLF);
|
||||
color.setGreen(true);
|
||||
power = new MageInt(1);
|
||||
toughness = new MageInt(1);
|
||||
this.addAbility(new BandsWithOtherAbility("Wolves of the Hunt"));
|
||||
}
|
||||
|
||||
public WolvesOfTheHuntToken(final WolvesOfTheHuntToken token) {
|
||||
super(token);
|
||||
}
|
||||
|
||||
public WolvesOfTheHuntToken copy() {
|
||||
return new WolvesOfTheHuntToken(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -518,14 +518,19 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
return this.ability.getSourcePermanentIfItStillExists(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceObjectZoneChangeCounter(int zoneChangeCounter) {
|
||||
ability.setSourceObjectZoneChangeCounter(zoneChangeCounter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceObjectZoneChangeCounter() {
|
||||
return ability.getSourceObjectZoneChangeCounter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceObject(MageObject sourceObject, Game game) {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
public Permanent getSourcePermanentOrLKI(Game game) {
|
||||
return ability.getSourcePermanentOrLKI(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue