GameEntity: when attachment is phased out, treat as not attached

This commit is contained in:
Hans Mackowiak
2021-04-11 17:00:20 +02:00
parent 183209baa3
commit f6ee232d9e
8 changed files with 65 additions and 72 deletions

View File

@@ -41,14 +41,12 @@ import forge.game.spellability.TargetRestrictions;
import forge.game.staticability.StaticAbility;
import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
import forge.util.collect.FCollection;
public abstract class GameEntity extends GameObject implements IIdentifiable {
protected final int id;
private String name = "";
private int preventNextDamage = 0;
protected CardCollection attachedCards;
protected CardCollection attachedCards = new CardCollection();
private Map<Card, Map<String, String>> preventionShieldsWithEffects = Maps.newTreeMap();
protected Map<CounterType, Integer> counters = Maps.newHashMap();
@@ -285,43 +283,36 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
public abstract boolean hasKeyword(final Keyword keyword);
public final CardCollectionView getEnchantedBy() {
if (attachedCards == null) {
return CardCollection.EMPTY;
}
// enchanted means attached by Aura
return CardLists.filter(attachedCards, CardPredicates.Presets.AURA);
return CardLists.filter(getAttachedCards(), CardPredicates.Presets.AURA);
}
// doesn't include phased out cards
public final CardCollectionView getAttachedCards() {
return CardCollection.getView(attachedCards);
return CardLists.filter(attachedCards, CardPredicates.phasedIn());
}
// for view does include phased out cards
public final CardCollectionView getAllAttachedCards() {
return attachedCards;
}
public final void setAttachedCards(final Iterable<Card> cards) {
if (cards == null) {
attachedCards = null;
}
else {
attachedCards = new CardCollection(cards);
}
getView().updateAttachedCards(this);
attachedCards = new CardCollection(cards);
updateAttachedCards();
}
public final boolean hasCardAttachments() {
return FCollection.hasElements(attachedCards);
return !getAttachedCards().isEmpty();
}
public final boolean isEnchanted() {
if (attachedCards == null) {
return false;
}
// enchanted means attached by Aura
return Iterables.any(attachedCards, CardPredicates.Presets.AURA);
return Iterables.any(getAttachedCards(), CardPredicates.Presets.AURA);
}
public final boolean hasCardAttachment(Card c) {
return FCollection.hasElement(attachedCards, c);
return getAttachedCards().contains(c);
}
public final boolean isEnchantedBy(Card c) {
// Rule 303.4k Even if c is no Aura it still counts
@@ -329,9 +320,6 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
}
public final boolean hasCardAttachment(final String cardName) {
if (attachedCards == null) {
return false;
}
return CardLists.count(getAttachedCards(), CardPredicates.nameEquals(cardName)) > 0;
}
public final boolean isEnchantedBy(final String cardName) {
@@ -344,12 +332,8 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
* @param Card c
*/
public final void addAttachedCard(final Card c) {
if (attachedCards == null) {
attachedCards = new CardCollection();
}
if (attachedCards.add(c)) {
getView().updateAttachedCards(this);
updateAttachedCards();
getGame().fireEvent(new GameEventCardAttachment(c, null, this));
}
}
@@ -359,17 +343,16 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
* @param Card c
*/
public final void removeAttachedCard(final Card c) {
if (attachedCards == null) { return; }
if (attachedCards.remove(c)) {
if (attachedCards.isEmpty()) {
attachedCards = null;
}
getView().updateAttachedCards(this);
updateAttachedCards();
getGame().fireEvent(new GameEventCardAttachment(c, this, null));
}
}
public final void updateAttachedCards() {
getView().updateAttachedCards(this);
}
public final void unAttachAllCards() {
for (Card c : Lists.newArrayList(getAttachedCards())) {
c.unattachFromEntity(this);

View File

@@ -1,5 +1,6 @@
package forge.game;
import forge.game.card.CardCollectionView;
import forge.game.card.CardView;
import forge.trackable.TrackableCollection;
import forge.trackable.TrackableObject;
@@ -54,6 +55,12 @@ public abstract class GameEntityView extends TrackableObject {
public boolean hasCardAttachments() {
return getAttachedCards() != null;
}
public Iterable<CardView> getAllAttachedCards() {
return get(TrackableProperty.AllAttachedCards);
}
public boolean hasAnyCardAttachments() {
return getAllAttachedCards() != null;
}
protected void updateAttachedCards(GameEntity e) {
if (e.hasCardAttachments()) {
@@ -62,5 +69,11 @@ public abstract class GameEntityView extends TrackableObject {
else {
set(TrackableProperty.AttachedCards, null);
}
CardCollectionView all = e.getAllAttachedCards();
if (all.isEmpty()) {
set(TrackableProperty.AllAttachedCards, null);
} else {
set(TrackableProperty.AllAttachedCards, CardView.getCollection(all));
}
}
}

View File

@@ -3226,19 +3226,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
}
public final CardCollectionView getEquippedBy() {
if (this.attachedCards == null) {
return CardCollection.EMPTY;
}
return CardLists.filter(attachedCards, CardPredicates.Presets.EQUIPMENT);
return CardLists.filter(getAttachedCards(), CardPredicates.Presets.EQUIPMENT);
}
public final boolean isEquipped() {
if (this.attachedCards == null) {
return false;
}
return Iterables.any(attachedCards, CardPredicates.Presets.EQUIPMENT);
return Iterables.any(getAttachedCards(), CardPredicates.Presets.EQUIPMENT);
}
public final boolean isEquippedBy(Card c) {
return this.hasCardAttachment(c);
@@ -3248,19 +3240,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
}
public final CardCollectionView getFortifiedBy() {
if (this.attachedCards == null) {
return CardCollection.EMPTY;
}
return CardLists.filter(attachedCards, CardPredicates.Presets.FORTIFICATION);
return CardLists.filter(getAttachedCards(), CardPredicates.Presets.FORTIFICATION);
}
public final boolean isFortified() {
if (this.attachedCards == null) {
return false;
}
return Iterables.any(attachedCards, CardPredicates.Presets.FORTIFICATION);
return Iterables.any(getAttachedCards(), CardPredicates.Presets.FORTIFICATION);
}
public final boolean isFortifiedBy(Card c) {
// 301.5e + 301.6
@@ -4624,6 +4608,12 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
}
}
// update the game entity it was attached to
GameEntity ge = this.getEntityAttachedTo();
if (ge != null) {
ge.updateAttachedCards();
}
getGame().fireEvent(new GameEventCardPhased(this, isPhasedOut()));
}

View File

@@ -479,6 +479,16 @@ public final class CardPredicates {
};
}
public static final Predicate<Card> phasedIn() {
return new Predicate<Card>() {
@Override
public boolean apply(final Card c)
{
return !c.isPhasedOut();
}
};
}
public static class Presets {
/**

View File

@@ -3426,11 +3426,7 @@ public class Player extends GameEntity implements Comparable<Player> {
}
public final boolean isCursed() {
if (this.attachedCards == null) {
return false;
}
return CardLists.count(attachedCards, CardPredicates.Presets.CURSE) > 0;
return CardLists.count(getAttachedCards(), CardPredicates.Presets.CURSE) > 0;
}
public boolean canDiscardBy(SpellAbility sa) {

View File

@@ -14,6 +14,7 @@ public enum TrackableProperty {
Text(TrackableTypes.StringType),
PreventNextDamage(TrackableTypes.IntegerType),
AttachedCards(TrackableTypes.CardViewCollectionType),
AllAttachedCards(TrackableTypes.CardViewCollectionType),
Counters(TrackableTypes.CounterMapType),
CurrentPlane(TrackableTypes.StringType),
PlanarPlayer(TrackableTypes.PlayerViewType),

View File

@@ -688,8 +688,8 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
}
toPanel.getAttachedPanels().clear();
if (card.hasCardAttachments()) {
final Iterable<CardView> enchants = card.getAttachedCards();
if (card.hasAnyCardAttachments()) {
final Iterable<CardView> enchants = card.getAllAttachedCards();
for (final CardView e : enchants) {
final CardPanel cardE = getCardPanel(e.getId());
if (cardE != null) {

View File

@@ -286,8 +286,8 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH
attachedPanels.clear();
if (card.hasCardAttachments()) {
final Iterable<CardView> enchants = card.getAttachedCards();
if (card.hasAnyCardAttachments()) {
final Iterable<CardView> enchants = card.getAllAttachedCards();
for (final CardView e : enchants) {
final CardAreaPanel cardE = CardAreaPanel.get(e);
if (cardE != null) {