mirror of
https://github.com/magefree/mage.git
synced 2025-12-28 14:32:06 -08:00
moved faceDown property from Card to CardState
This commit is contained in:
parent
d7b9a4a979
commit
9ad8530dee
61 changed files with 378 additions and 224 deletions
|
|
@ -860,7 +860,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
return false;
|
||||
}
|
||||
} else if (object instanceof PermanentCard) {
|
||||
if (((PermanentCard)object).isFaceDown()&& !this.getWorksFaceDown()) {
|
||||
if (((PermanentCard)object).isFaceDown(game)&& !this.getWorksFaceDown()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,28 +95,6 @@ public class TriggeredAbilities extends ConcurrentHashMap<String, TriggeredAbili
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkAbilityStillExists(TriggeredAbility ability, GameEvent event, MageObject object) {
|
||||
boolean exists = true;
|
||||
|
||||
if (!object.getAbilities().contains(ability)) {
|
||||
exists = false;
|
||||
if (object instanceof PermanentCard) {
|
||||
PermanentCard permanent = (PermanentCard)object;
|
||||
if (permanent.canTransform() && event.getType() == GameEvent.EventType.TRANSFORMED) {
|
||||
exists = permanent.getCard().getAbilities().contains(ability);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (object instanceof PermanentCard) {
|
||||
PermanentCard permanent = (PermanentCard)object;
|
||||
if (permanent.isFaceDown()) {
|
||||
exists = ability.getWorksFaceDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
private MageObject getMageObject(GameEvent event, Game game, TriggeredAbility ability) {
|
||||
MageObject object = game.getPermanent(ability.getSourceId());
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public class TurnedFaceUpAllTriggeredAbility extends TriggeredAbilityImpl {
|
|||
if (!event.getTargetId().equals(getSourceId())) {
|
||||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(getSourceId());
|
||||
if (sourcePermanent != null) {
|
||||
if (sourcePermanent.isFaceDown()) {
|
||||
if (sourcePermanent.isFaceDown(game)) {
|
||||
// if face down and it's not itself that is turned face up, it does not trigger
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,10 +52,10 @@ public class FaceDownSourceCondition implements Condition {
|
|||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
if (mageObject != null) {
|
||||
if (mageObject instanceof Permanent) {
|
||||
return ((Permanent)mageObject).isFaceDown();
|
||||
return ((Permanent)mageObject).isFaceDown(game);
|
||||
}
|
||||
if (mageObject instanceof Card) {
|
||||
return ((Card)mageObject).isFaceDown();
|
||||
return ((Card)mageObject).isFaceDown(game);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
|
|||
UUID controllerId = event.getPlayerId();
|
||||
|
||||
// Aura cards that go to battlefield face down (Manifest) don't have to select targets
|
||||
if (card.isFaceDown()) {
|
||||
if (card.isFaceDown(game)) {
|
||||
return false;
|
||||
}
|
||||
// Aura enters the battlefield attached
|
||||
|
|
|
|||
|
|
@ -416,12 +416,12 @@ public class ContinuousEffects implements Serializable {
|
|||
} else {
|
||||
if (object instanceof PermanentCard) {
|
||||
PermanentCard permanent = (PermanentCard)object;
|
||||
if (permanent.isFaceDown() && !ability.getWorksFaceDown()) {
|
||||
if (permanent.isFaceDown(game) && !ability.getWorksFaceDown()) {
|
||||
return false;
|
||||
}
|
||||
} else if (object instanceof Spell) {
|
||||
Spell spell = (Spell)object;
|
||||
if (spell.isFaceDown() && !ability.getWorksFaceDown()) {
|
||||
if (spell.isFaceDown(game) && !ability.getWorksFaceDown()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public class HideawayPlayEffect extends OneShotEffect {
|
|||
// If the revealed card is a land, you can play it only if it's your turn and you haven't yet played a land this turn.
|
||||
if (game.getActivePlayerId().equals(source.getControllerId()) && controller.canPlayLand()) {
|
||||
if (controller.chooseUse(Outcome.Benefit, new StringBuilder("Play ").append(card.getName()).append(" from Exile?").toString(), game)) {
|
||||
card.setFaceDown(false);
|
||||
card.setFaceDown(false, game);
|
||||
return controller.playLand(card, game);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -83,7 +83,7 @@ public class HideawayPlayEffect extends OneShotEffect {
|
|||
// Timing restrictions based on the card's type are ignored (for instance, if it's a creature or sorcery).
|
||||
// Other play restrictions are not (such as "Play [this card] only during combat").
|
||||
if (controller.chooseUse(Outcome.Benefit, new StringBuilder("Cast ").append(card.getName()).append(" without paying it's mana cost?").toString(), game)) {
|
||||
card.setFaceDown(false);
|
||||
card.setFaceDown(false, game);
|
||||
return controller.cast(card.getSpellAbility(), game, true);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -85,9 +85,9 @@ public class BecomesFaceDownCreatureAllEffect extends ContinuousEffectImpl imple
|
|||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
||||
if (!perm.isFaceDown() && !perm.canTransform()) {
|
||||
if (!perm.isFaceDown(game) && !perm.canTransform()) {
|
||||
affectedObjectList.add(new MageObjectReference(perm));
|
||||
perm.setFaceDown(true);
|
||||
perm.setFaceDown(true, game);
|
||||
// check for Morph
|
||||
Card card = game.getCard(perm.getId());
|
||||
if (card != null) {
|
||||
|
|
@ -106,7 +106,7 @@ public class BecomesFaceDownCreatureAllEffect extends ContinuousEffectImpl imple
|
|||
boolean targetExists = false;
|
||||
for (MageObjectReference mor: affectedObjectList) {
|
||||
Permanent permanent = mor.getPermanent(game);
|
||||
if (permanent != null && permanent.isFaceDown()) {
|
||||
if (permanent != null && permanent.isFaceDown(game)) {
|
||||
targetExists = true;
|
||||
switch (layer) {
|
||||
case TypeChangingEffects_4:
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl implemen
|
|||
permanent = game.getPermanent(source.getSourceId());
|
||||
}
|
||||
|
||||
if (permanent != null && permanent.isFaceDown()) {
|
||||
if (permanent != null && permanent.isFaceDown(game)) {
|
||||
if (!foundPermanent) {
|
||||
foundPermanent = true;
|
||||
switch(faceDownType) {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ public class ManifestEffect extends OneShotEffect {
|
|||
newSource.setWorksFaceDown(true);
|
||||
List<Card> cards = controller.getLibrary().getTopCards(game, amount);
|
||||
for (Card card: cards) {
|
||||
card.setFaceDown(true);
|
||||
ManaCosts manaCosts = null;
|
||||
if (card.getCardType().contains(CardType.CREATURE)) {
|
||||
manaCosts = card.getSpellAbility().getManaCosts();
|
||||
|
|
@ -89,7 +88,7 @@ public class ManifestEffect extends OneShotEffect {
|
|||
}
|
||||
MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter() +1, game);
|
||||
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource);
|
||||
controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId());
|
||||
controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true);
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
permanent.setManifested(true);
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ public class ManifestTargetPlayerEffect extends OneShotEffect {
|
|||
newSource.setWorksFaceDown(true);
|
||||
List<Card> cards = targetPlayer.getLibrary().getTopCards(game, amount);
|
||||
for (Card card: cards) {
|
||||
card.setFaceDown(true);
|
||||
ManaCosts manaCosts = null;
|
||||
if (card.getCardType().contains(CardType.CREATURE)) {
|
||||
manaCosts = card.getSpellAbility().getManaCosts();
|
||||
|
|
@ -93,7 +92,7 @@ public class ManifestTargetPlayerEffect extends OneShotEffect {
|
|||
}
|
||||
MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter() +1, game);
|
||||
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource);
|
||||
targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId());
|
||||
targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true);
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
permanent.setManifested(true);
|
||||
|
|
|
|||
|
|
@ -130,10 +130,10 @@ class HideawayExileEffect extends OneShotEffect {
|
|||
Card card = cards.get(target1.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
cards.remove(card);
|
||||
card.setFaceDown(true);
|
||||
card.moveToExile(CardUtil.getCardExileZoneId(game, source),
|
||||
new StringBuilder("Hideaway (").append(hideawaySource.getName()).append(")").toString(),
|
||||
source.getSourceId(), game);
|
||||
card.setFaceDown(true, game);
|
||||
}
|
||||
target1.clearChosen();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,6 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
super(Zone.HAND, null);
|
||||
this.morphCosts = morphCosts;
|
||||
this.megamorph = megamorph;
|
||||
card.setMorphCard(true);
|
||||
this.setWorksFaceDown(true);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (megamorph) {
|
||||
|
|
@ -203,7 +202,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
Spell spell = game.getStack().getSpell(ability.getId());
|
||||
if (player != null && spell != null) {
|
||||
this.resetMorph();
|
||||
spell.setFaceDown(true); // so only the back is visible
|
||||
spell.setFaceDown(true, game); // so only the back is visible
|
||||
if (alternateCosts.canPay(ability, sourceId, controllerId, game)) {
|
||||
if (player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(getCosts().getText()).append(" ?").toString(), game)) {
|
||||
activateMorph(game);
|
||||
|
|
@ -226,7 +225,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
spellColor.setWhite(false);
|
||||
spellColor.setBlue(false);
|
||||
} else {
|
||||
spell.setFaceDown(false);
|
||||
spell.setFaceDown(false, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ public interface Card extends MageObject {
|
|||
List<String> getRules(Game game); // gets card rules + in game modifications
|
||||
String getExpansionSetCode();
|
||||
String getTokenSetCode();
|
||||
void setFaceDown(boolean value);
|
||||
boolean isFaceDown();
|
||||
void setFaceDown(boolean value, Game game);
|
||||
boolean isFaceDown(Game game);
|
||||
boolean turnFaceUp(Game game, UUID playerId);
|
||||
boolean turnFaceDown(Game game, UUID playerId);
|
||||
boolean isFlipCard();
|
||||
|
|
@ -106,12 +106,12 @@ public interface Card extends MageObject {
|
|||
boolean cast(Game game, Zone fromZone, SpellAbility ability, UUID controllerId);
|
||||
boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId);
|
||||
boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped);
|
||||
boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, ArrayList<UUID> appliedEffects);
|
||||
boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown);
|
||||
boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown, ArrayList<UUID> appliedEffects);
|
||||
List<Mana> getMana();
|
||||
|
||||
void build();
|
||||
|
||||
void setUsesVariousArt(boolean usesVariousArt);
|
||||
/**
|
||||
*
|
||||
* @return true if there exists various art images for this card
|
||||
|
|
@ -127,9 +127,6 @@ public interface Card extends MageObject {
|
|||
void removeCounters(String name, int amount, Game game);
|
||||
void removeCounters(Counter counter, Game game);
|
||||
|
||||
void setMorphCard(boolean morphCard);
|
||||
boolean isMorphCard();
|
||||
|
||||
@Override
|
||||
Card copy();
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import mage.Mana;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.PlayLandAbility;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.keyword.MorphAbility;
|
||||
import mage.abilities.mana.ManaAbility;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
|
|
@ -78,7 +79,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
protected String expansionSetCode;
|
||||
protected String tokenSetCode;
|
||||
protected Rarity rarity;
|
||||
protected boolean faceDown;
|
||||
protected boolean canTransform;
|
||||
protected Card secondSideCard;
|
||||
protected boolean nightCard;
|
||||
|
|
@ -143,7 +143,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
cardNumber = card.cardNumber;
|
||||
expansionSetCode = card.expansionSetCode;
|
||||
rarity = card.rarity;
|
||||
faceDown = card.faceDown;
|
||||
|
||||
canTransform = card.canTransform;
|
||||
if (canTransform) {
|
||||
|
|
@ -155,7 +154,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
flipCardName = card.flipCardName;
|
||||
splitCard = card.splitCard;
|
||||
usesVariousArt = card.usesVariousArt;
|
||||
morphCard = card.isMorphCard();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -341,10 +339,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
game.rememberLKI(objectId, event.getFromZone(), this);
|
||||
}
|
||||
|
||||
if (isFaceDown() && !event.getToZone().equals(Zone.BATTLEFIELD)) { // to battlefield is possible because of Morph
|
||||
setFaceDown(false);
|
||||
game.getCard(this.getId()).setFaceDown(false);
|
||||
}
|
||||
setFaceDown(false, game);
|
||||
updateZoneChangeCounter();
|
||||
switch (event.getToZone()) {
|
||||
case GRAVEYARD:
|
||||
|
|
@ -477,6 +472,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
} else {
|
||||
game.getExile().createZone(exileId, name).add(this);
|
||||
}
|
||||
setFaceDown(false, game);
|
||||
updateZoneChangeCounter();
|
||||
game.setZone(objectId, event.getToZone());
|
||||
game.addSimultaneousEvent(event);
|
||||
|
|
@ -487,17 +483,21 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
|
||||
@Override
|
||||
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId) {
|
||||
return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, false);
|
||||
return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, false, false, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped){
|
||||
return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, tapped, null);
|
||||
return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, tapped, false, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown){
|
||||
return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, tapped, facedown, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, ArrayList<UUID> appliedEffects){
|
||||
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown, ArrayList<UUID> appliedEffects){
|
||||
ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, sourceId, controllerId, fromZone, Zone.BATTLEFIELD, appliedEffects, tapped);
|
||||
if (!game.replaceEvent(event)) {
|
||||
if (fromZone != null) {
|
||||
|
|
@ -514,10 +514,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
break;
|
||||
case EXILED:
|
||||
game.getExile().removeCard(this, game);
|
||||
if (isFaceDown()) {
|
||||
// 110.6b Permanents enter the battlefield untapped, unflipped, face up, and phased in unless a spell or ability says otherwise.
|
||||
this.setFaceDown(false);
|
||||
}
|
||||
removed = true;
|
||||
break;
|
||||
case COMMAND:
|
||||
|
|
@ -543,6 +539,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
setZone(Zone.BATTLEFIELD, game);
|
||||
game.setScopeRelevant(true);
|
||||
permanent.setTapped(tapped);
|
||||
permanent.setFaceDown(facedown, game);
|
||||
permanent.entersBattlefield(sourceId, game, event.getFromZone(), true);
|
||||
game.setScopeRelevant(false);
|
||||
game.applyEffects();
|
||||
|
|
@ -553,21 +550,20 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setFaceDown(boolean value) {
|
||||
faceDown = value;
|
||||
public void setFaceDown(boolean value, Game game) {
|
||||
game.getState().getCardState(objectId).setFaceDown(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFaceDown() {
|
||||
return faceDown;
|
||||
public boolean isFaceDown(Game game) {
|
||||
return game.getState().getCardState(objectId).isFaceDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean turnFaceUp(Game game, UUID playerId) {
|
||||
GameEvent event = GameEvent.getEvent(GameEvent.EventType.TURNFACEUP, getId(), playerId);
|
||||
if (!game.replaceEvent(event)) {
|
||||
setFaceDown(false);
|
||||
game.getCard(objectId).setFaceDown(false); // Another instance?
|
||||
setFaceDown(false, game);
|
||||
for (Ability ability :abilities) { // abilities that were set to not visible face down must be set to visible again
|
||||
if (ability.getWorksFaceDown() && !ability.getRuleVisible()) {
|
||||
ability.setRuleVisible(true);
|
||||
|
|
@ -583,8 +579,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
public boolean turnFaceDown(Game game, UUID playerId) {
|
||||
GameEvent event = GameEvent.getEvent(GameEvent.EventType.TURNFACEDOWN, getId(), playerId);
|
||||
if (!game.replaceEvent(event)) {
|
||||
setFaceDown(true);
|
||||
game.getCard(objectId).setFaceDown(true); // Another instance?
|
||||
setFaceDown(true, game);
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.TURNEDFACEDOWN, getId(), playerId));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -638,11 +633,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
@Override
|
||||
public void build() {}
|
||||
|
||||
@Override
|
||||
public void setUsesVariousArt(boolean usesVariousArt) {
|
||||
this.usesVariousArt = usesVariousArt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getUsesVariousArt() {
|
||||
return usesVariousArt;
|
||||
|
|
@ -713,21 +703,11 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
removeCounters(counter.getName(), counter.getCount(), game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMorphCard(boolean morphCard) {
|
||||
this.morphCard = morphCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMorphCard() {
|
||||
return morphCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogName() {
|
||||
if (this.isFaceDown()) {
|
||||
return "facedown card";
|
||||
}
|
||||
// if (this.isFaceDown()) {
|
||||
// return "facedown card";
|
||||
// }
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public class FaceDownPredicate implements Predicate<Card> {
|
|||
|
||||
@Override
|
||||
public boolean apply(Card input, Game game) {
|
||||
return input.isFaceDown();
|
||||
return input.isFaceDown(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import mage.counters.Counters;
|
|||
*/
|
||||
public class CardState {
|
||||
|
||||
protected boolean faceDown;
|
||||
protected Map<String, String> info;
|
||||
protected Counters counters;
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ public class CardState {
|
|||
}
|
||||
|
||||
public CardState(final CardState state) {
|
||||
this.faceDown = state.faceDown;
|
||||
if (state.info != null) {
|
||||
info = new HashMap<>();
|
||||
info.putAll(state.info);
|
||||
|
|
@ -30,6 +32,14 @@ public class CardState {
|
|||
return new CardState(this);
|
||||
}
|
||||
|
||||
public void setFaceDown(boolean value) {
|
||||
faceDown = value;
|
||||
}
|
||||
|
||||
public boolean isFaceDown() {
|
||||
return faceDown;
|
||||
}
|
||||
|
||||
public Counters getCounters() {
|
||||
return counters;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ public abstract class GameCommanderImpl extends GameImpl {
|
|||
if(!mulliganedCards.containsKey(playerId)){
|
||||
mulliganedCards.put(playerId, new CardsImpl());
|
||||
}
|
||||
card.setFaceDown(true);
|
||||
card.moveToExile(null, "", null, this);
|
||||
card.setFaceDown(true, this);
|
||||
mulliganedCards.get(playerId).add(card);
|
||||
}
|
||||
}
|
||||
|
|
@ -165,8 +165,8 @@ public abstract class GameCommanderImpl extends GameImpl {
|
|||
if(player != null && mulliganedCards.containsKey(playerId)){
|
||||
for(Card card : mulliganedCards.get(playerId).getCards(this)){
|
||||
if(card != null){
|
||||
card.setFaceDown(false);
|
||||
card.moveToZone(Zone.LIBRARY, null, this, false);
|
||||
card.setFaceDown(false, this);
|
||||
}
|
||||
}
|
||||
if(mulliganedCards.get(playerId).size() > 0){
|
||||
|
|
|
|||
|
|
@ -277,7 +277,6 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
card = ((PermanentCard)card).getCard();
|
||||
}
|
||||
card.setOwnerId(ownerId);
|
||||
card.setFaceDown(false); // can be set face down from previous game
|
||||
gameCards.put(card.getId(), card);
|
||||
state.addCard(card);
|
||||
if (card.isSplitCard()) {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,16 @@ public class PermanentCard extends PermanentImpl {
|
|||
protected void copyFromCard(Card card) {
|
||||
this.name = card.getName();
|
||||
this.abilities.clear();
|
||||
this.abilities.addAll(card.getAbilities().copy());
|
||||
if (this.faceDown) {
|
||||
for (Ability ability: card.getAbilities()) {
|
||||
if (ability.getWorksFaceDown()) {
|
||||
this.abilities.add(ability.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.abilities = card.getAbilities().copy();
|
||||
}
|
||||
this.abilities.setControllerId(this.controllerId);
|
||||
this.cardType.clear();
|
||||
this.cardType.addAll(card.getCardType());
|
||||
|
|
@ -116,8 +125,6 @@ public class PermanentCard extends PermanentImpl {
|
|||
}
|
||||
this.flipCard = card.isFlipCard();
|
||||
this.flipCardName = card.getFlipCardName();
|
||||
this.faceDown = card.isFaceDown();
|
||||
this.morphCard = card.isMorphCard();
|
||||
}
|
||||
|
||||
public Card getCard() {
|
||||
|
|
@ -134,12 +141,6 @@ public class PermanentCard extends PermanentImpl {
|
|||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null && controller.removeFromBattlefield(this, game)) {
|
||||
Card originalCard = game.getCard(this.getId());
|
||||
if (isFaceDown()) {
|
||||
setFaceDown(false);
|
||||
if (originalCard != null) {
|
||||
originalCard.setFaceDown(false); //TODO: Do this in a better way
|
||||
}
|
||||
}
|
||||
ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, controllerId, fromZone, toZone, appliedEffects);
|
||||
if (!game.replaceEvent(event)) {
|
||||
Player owner = game.getPlayer(ownerId);
|
||||
|
|
@ -190,10 +191,6 @@ public class PermanentCard extends PermanentImpl {
|
|||
@Override
|
||||
public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList<UUID> appliedEffects) {
|
||||
Zone fromZone = game.getState().getZone(objectId);
|
||||
if (isFaceDown() && fromZone.equals(Zone.BATTLEFIELD) && (isMorphed() || isManifested())) {
|
||||
setFaceDown(false);
|
||||
game.getCard(this.getId()).setFaceDown(false); //TODO: Do this in a better way
|
||||
}
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null && controller.removeFromBattlefield(this, game)) {
|
||||
ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, ownerId, fromZone, Zone.EXILED, appliedEffects);
|
||||
|
|
@ -228,16 +225,6 @@ public class PermanentCard extends PermanentImpl {
|
|||
if (super.turnFaceUp(game, playerId)) {
|
||||
setManifested(false);
|
||||
setMorphed(false);
|
||||
card.setFaceDown(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean turnFaceDown(Game game, UUID playerId) {
|
||||
if (super.turnFaceDown(game, playerId)) {
|
||||
card.setFaceDown(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -258,17 +245,9 @@ public class PermanentCard extends PermanentImpl {
|
|||
card.adjustChoices(ability, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFaceDown(boolean value) {
|
||||
super.setFaceDown(value);
|
||||
if (card != null) {
|
||||
card.setFaceDown(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManaCosts<ManaCost> getManaCost() {
|
||||
if (isFaceDown()) { // face down permanent has always {0} mana costs
|
||||
if (faceDown) { // face down permanent has always {0} mana costs
|
||||
manaCost.clear();
|
||||
return manaCost;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
protected boolean controlledFromStartOfControllerTurn;
|
||||
protected int turnsOnBattlefield;
|
||||
protected boolean phasedIn = true;
|
||||
protected boolean faceDown;
|
||||
protected boolean attacking;
|
||||
protected int blocking;
|
||||
// number of creatures the permanent can block
|
||||
|
|
@ -139,6 +140,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
this.controlledFromStartOfControllerTurn = permanent.controlledFromStartOfControllerTurn;
|
||||
this.turnsOnBattlefield = permanent.turnsOnBattlefield;
|
||||
this.phasedIn = permanent.phasedIn;
|
||||
this.faceDown = permanent.faceDown;
|
||||
this.attacking = permanent.attacking;
|
||||
this.blocking = permanent.blocking;
|
||||
this.maxBlocks = permanent.maxBlocks;
|
||||
|
|
@ -431,6 +433,16 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFaceDown(boolean value, Game game) {
|
||||
this.faceDown = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFaceDown(Game game) {
|
||||
return faceDown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlipped() {
|
||||
return flipped;
|
||||
|
|
@ -838,7 +850,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
@Override
|
||||
public void entersBattlefield(UUID sourceId, Game game, Zone fromZone, boolean fireEvent) {
|
||||
controlledFromStartOfControllerTurn = false;
|
||||
if (this.isFaceDown()) {
|
||||
if (this.isFaceDown(game)) {
|
||||
// remove some attributes here, bceause first apply effects comes later otherwise abilities (e.g. color related) will unintended trigger
|
||||
MorphAbility.setPermanentToFaceDownCreature(this);
|
||||
}
|
||||
|
|
@ -1226,7 +1238,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
@Override
|
||||
public String getLogName() {
|
||||
if (name.isEmpty()) {
|
||||
if (isFaceDown()) {
|
||||
if (faceDown) {
|
||||
return "face down creature";
|
||||
} else {
|
||||
return "a creature without name";
|
||||
|
|
|
|||
|
|
@ -267,10 +267,7 @@ public class Spell implements StackObject, Card {
|
|||
}
|
||||
} else {
|
||||
updateOptionalCosts(0);
|
||||
if (isFaceDown()) {
|
||||
card.setFaceDown(true);
|
||||
}
|
||||
result = card.putOntoBattlefield(game, fromZone, ability.getSourceId(), controllerId);
|
||||
result = card.putOntoBattlefield(game, fromZone, ability.getSourceId(), controllerId, false, faceDown);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -628,7 +625,7 @@ public class Spell implements StackObject, Card {
|
|||
@Override
|
||||
public int getConvertedManaCost() {
|
||||
int cmc = 0;
|
||||
if (this.isMorphCard() && this.isFaceDown()) {
|
||||
if (faceDown) {
|
||||
return 0;
|
||||
}
|
||||
for (Ability spellAbility: spellAbilities) {
|
||||
|
|
@ -717,24 +714,24 @@ public class Spell implements StackObject, Card {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setFaceDown(boolean value) {
|
||||
public void setFaceDown(boolean value, Game game) {
|
||||
faceDown = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean turnFaceUp(Game game, UUID playerId) {
|
||||
setFaceDown(false);
|
||||
setFaceDown(false, game);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean turnFaceDown(Game game, UUID playerId) {
|
||||
setFaceDown(true);
|
||||
setFaceDown(true, game);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFaceDown() {
|
||||
public boolean isFaceDown(Game game) {
|
||||
return faceDown;
|
||||
}
|
||||
|
||||
|
|
@ -855,7 +852,12 @@ public class Spell implements StackObject, Card {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, ArrayList<UUID> appliedEffects) {
|
||||
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown, ArrayList<UUID> appliedEffects) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
|
|
@ -869,11 +871,6 @@ public class Spell implements StackObject, Card {
|
|||
return card.getUsesVariousArt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsesVariousArt(boolean usesVariousArt) {
|
||||
card.setUsesVariousArt(usesVariousArt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getMana() {
|
||||
return card.getMana();
|
||||
|
|
@ -973,16 +970,6 @@ public class Spell implements StackObject, Card {
|
|||
return card;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMorphCard(boolean morphCard) {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMorphCard() {
|
||||
return card.isMorphCard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Card getMainCard() {
|
||||
return card.getMainCard();
|
||||
|
|
|
|||
|
|
@ -498,6 +498,19 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
* @return
|
||||
*/
|
||||
boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped);
|
||||
|
||||
/**
|
||||
* Uses putOntoBattlefield and posts also a info message about in the game log
|
||||
*
|
||||
* @param card
|
||||
* @param game
|
||||
* @param fromZone
|
||||
* @param sourceId
|
||||
* @param tapped the card enters the battlefield tapped
|
||||
* @param facedown the card enters the battlefield facedown
|
||||
* @return
|
||||
*/
|
||||
boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown);
|
||||
|
||||
/**
|
||||
* Checks if the playerToCheckId is from an opponent in range
|
||||
|
|
|
|||
|
|
@ -2835,13 +2835,18 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId) {
|
||||
return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, false);
|
||||
return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) {
|
||||
return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, tapped, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown) {
|
||||
boolean result = false;
|
||||
if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped)) {
|
||||
if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped, facedown)) {
|
||||
game.informPlayers(new StringBuilder(this.getName())
|
||||
.append(" puts ").append(card.getLogName())
|
||||
.append(" from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue