mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
GameEntity: when attachment is phased out, treat as not attached
This commit is contained in:
@@ -41,14 +41,12 @@ import forge.game.spellability.TargetRestrictions;
|
|||||||
import forge.game.staticability.StaticAbility;
|
import forge.game.staticability.StaticAbility;
|
||||||
import forge.game.trigger.TriggerType;
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.collect.FCollection;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class GameEntity extends GameObject implements IIdentifiable {
|
public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||||
protected final int id;
|
protected final int id;
|
||||||
private String name = "";
|
private String name = "";
|
||||||
private int preventNextDamage = 0;
|
private int preventNextDamage = 0;
|
||||||
protected CardCollection attachedCards;
|
protected CardCollection attachedCards = new CardCollection();
|
||||||
private Map<Card, Map<String, String>> preventionShieldsWithEffects = Maps.newTreeMap();
|
private Map<Card, Map<String, String>> preventionShieldsWithEffects = Maps.newTreeMap();
|
||||||
protected Map<CounterType, Integer> counters = Maps.newHashMap();
|
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 abstract boolean hasKeyword(final Keyword keyword);
|
||||||
|
|
||||||
public final CardCollectionView getEnchantedBy() {
|
public final CardCollectionView getEnchantedBy() {
|
||||||
if (attachedCards == null) {
|
|
||||||
return CardCollection.EMPTY;
|
|
||||||
}
|
|
||||||
// enchanted means attached by Aura
|
// 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() {
|
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) {
|
public final void setAttachedCards(final Iterable<Card> cards) {
|
||||||
if (cards == null) {
|
|
||||||
attachedCards = null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
attachedCards = new CardCollection(cards);
|
attachedCards = new CardCollection(cards);
|
||||||
}
|
updateAttachedCards();
|
||||||
|
|
||||||
getView().updateAttachedCards(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasCardAttachments() {
|
public final boolean hasCardAttachments() {
|
||||||
return FCollection.hasElements(attachedCards);
|
return !getAttachedCards().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isEnchanted() {
|
public final boolean isEnchanted() {
|
||||||
if (attachedCards == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// enchanted means attached by Aura
|
// 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) {
|
public final boolean hasCardAttachment(Card c) {
|
||||||
return FCollection.hasElement(attachedCards, c);
|
return getAttachedCards().contains(c);
|
||||||
}
|
}
|
||||||
public final boolean isEnchantedBy(Card c) {
|
public final boolean isEnchantedBy(Card c) {
|
||||||
// Rule 303.4k Even if c is no Aura it still counts
|
// 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) {
|
public final boolean hasCardAttachment(final String cardName) {
|
||||||
if (attachedCards == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return CardLists.count(getAttachedCards(), CardPredicates.nameEquals(cardName)) > 0;
|
return CardLists.count(getAttachedCards(), CardPredicates.nameEquals(cardName)) > 0;
|
||||||
}
|
}
|
||||||
public final boolean isEnchantedBy(final String cardName) {
|
public final boolean isEnchantedBy(final String cardName) {
|
||||||
@@ -344,12 +332,8 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
|||||||
* @param Card c
|
* @param Card c
|
||||||
*/
|
*/
|
||||||
public final void addAttachedCard(final Card c) {
|
public final void addAttachedCard(final Card c) {
|
||||||
if (attachedCards == null) {
|
|
||||||
attachedCards = new CardCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attachedCards.add(c)) {
|
if (attachedCards.add(c)) {
|
||||||
getView().updateAttachedCards(this);
|
updateAttachedCards();
|
||||||
getGame().fireEvent(new GameEventCardAttachment(c, null, this));
|
getGame().fireEvent(new GameEventCardAttachment(c, null, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -359,17 +343,16 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
|||||||
* @param Card c
|
* @param Card c
|
||||||
*/
|
*/
|
||||||
public final void removeAttachedCard(final Card c) {
|
public final void removeAttachedCard(final Card c) {
|
||||||
if (attachedCards == null) { return; }
|
|
||||||
|
|
||||||
if (attachedCards.remove(c)) {
|
if (attachedCards.remove(c)) {
|
||||||
if (attachedCards.isEmpty()) {
|
updateAttachedCards();
|
||||||
attachedCards = null;
|
|
||||||
}
|
|
||||||
getView().updateAttachedCards(this);
|
|
||||||
getGame().fireEvent(new GameEventCardAttachment(c, this, null));
|
getGame().fireEvent(new GameEventCardAttachment(c, this, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void updateAttachedCards() {
|
||||||
|
getView().updateAttachedCards(this);
|
||||||
|
}
|
||||||
|
|
||||||
public final void unAttachAllCards() {
|
public final void unAttachAllCards() {
|
||||||
for (Card c : Lists.newArrayList(getAttachedCards())) {
|
for (Card c : Lists.newArrayList(getAttachedCards())) {
|
||||||
c.unattachFromEntity(this);
|
c.unattachFromEntity(this);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game;
|
package forge.game;
|
||||||
|
|
||||||
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.trackable.TrackableCollection;
|
import forge.trackable.TrackableCollection;
|
||||||
import forge.trackable.TrackableObject;
|
import forge.trackable.TrackableObject;
|
||||||
@@ -54,6 +55,12 @@ public abstract class GameEntityView extends TrackableObject {
|
|||||||
public boolean hasCardAttachments() {
|
public boolean hasCardAttachments() {
|
||||||
return getAttachedCards() != null;
|
return getAttachedCards() != null;
|
||||||
}
|
}
|
||||||
|
public Iterable<CardView> getAllAttachedCards() {
|
||||||
|
return get(TrackableProperty.AllAttachedCards);
|
||||||
|
}
|
||||||
|
public boolean hasAnyCardAttachments() {
|
||||||
|
return getAllAttachedCards() != null;
|
||||||
|
}
|
||||||
|
|
||||||
protected void updateAttachedCards(GameEntity e) {
|
protected void updateAttachedCards(GameEntity e) {
|
||||||
if (e.hasCardAttachments()) {
|
if (e.hasCardAttachments()) {
|
||||||
@@ -62,5 +69,11 @@ public abstract class GameEntityView extends TrackableObject {
|
|||||||
else {
|
else {
|
||||||
set(TrackableProperty.AttachedCards, null);
|
set(TrackableProperty.AttachedCards, null);
|
||||||
}
|
}
|
||||||
|
CardCollectionView all = e.getAllAttachedCards();
|
||||||
|
if (all.isEmpty()) {
|
||||||
|
set(TrackableProperty.AllAttachedCards, null);
|
||||||
|
} else {
|
||||||
|
set(TrackableProperty.AllAttachedCards, CardView.getCollection(all));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3226,19 +3226,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final CardCollectionView getEquippedBy() {
|
public final CardCollectionView getEquippedBy() {
|
||||||
if (this.attachedCards == null) {
|
return CardLists.filter(getAttachedCards(), CardPredicates.Presets.EQUIPMENT);
|
||||||
return CardCollection.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardLists.filter(attachedCards, CardPredicates.Presets.EQUIPMENT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isEquipped() {
|
public final boolean isEquipped() {
|
||||||
if (this.attachedCards == null) {
|
return Iterables.any(getAttachedCards(), CardPredicates.Presets.EQUIPMENT);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Iterables.any(attachedCards, CardPredicates.Presets.EQUIPMENT);
|
|
||||||
}
|
}
|
||||||
public final boolean isEquippedBy(Card c) {
|
public final boolean isEquippedBy(Card c) {
|
||||||
return this.hasCardAttachment(c);
|
return this.hasCardAttachment(c);
|
||||||
@@ -3248,19 +3240,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final CardCollectionView getFortifiedBy() {
|
public final CardCollectionView getFortifiedBy() {
|
||||||
if (this.attachedCards == null) {
|
return CardLists.filter(getAttachedCards(), CardPredicates.Presets.FORTIFICATION);
|
||||||
return CardCollection.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardLists.filter(attachedCards, CardPredicates.Presets.FORTIFICATION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isFortified() {
|
public final boolean isFortified() {
|
||||||
if (this.attachedCards == null) {
|
return Iterables.any(getAttachedCards(), CardPredicates.Presets.FORTIFICATION);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Iterables.any(attachedCards, CardPredicates.Presets.FORTIFICATION);
|
|
||||||
}
|
}
|
||||||
public final boolean isFortifiedBy(Card c) {
|
public final boolean isFortifiedBy(Card c) {
|
||||||
// 301.5e + 301.6
|
// 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()));
|
getGame().fireEvent(new GameEventCardPhased(this, isPhasedOut()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
public static class Presets {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3426,11 +3426,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isCursed() {
|
public final boolean isCursed() {
|
||||||
if (this.attachedCards == null) {
|
return CardLists.count(getAttachedCards(), CardPredicates.Presets.CURSE) > 0;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardLists.count(attachedCards, CardPredicates.Presets.CURSE) > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canDiscardBy(SpellAbility sa) {
|
public boolean canDiscardBy(SpellAbility sa) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public enum TrackableProperty {
|
|||||||
Text(TrackableTypes.StringType),
|
Text(TrackableTypes.StringType),
|
||||||
PreventNextDamage(TrackableTypes.IntegerType),
|
PreventNextDamage(TrackableTypes.IntegerType),
|
||||||
AttachedCards(TrackableTypes.CardViewCollectionType),
|
AttachedCards(TrackableTypes.CardViewCollectionType),
|
||||||
|
AllAttachedCards(TrackableTypes.CardViewCollectionType),
|
||||||
Counters(TrackableTypes.CounterMapType),
|
Counters(TrackableTypes.CounterMapType),
|
||||||
CurrentPlane(TrackableTypes.StringType),
|
CurrentPlane(TrackableTypes.StringType),
|
||||||
PlanarPlayer(TrackableTypes.PlayerViewType),
|
PlanarPlayer(TrackableTypes.PlayerViewType),
|
||||||
|
|||||||
@@ -688,8 +688,8 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
|||||||
}
|
}
|
||||||
toPanel.getAttachedPanels().clear();
|
toPanel.getAttachedPanels().clear();
|
||||||
|
|
||||||
if (card.hasCardAttachments()) {
|
if (card.hasAnyCardAttachments()) {
|
||||||
final Iterable<CardView> enchants = card.getAttachedCards();
|
final Iterable<CardView> enchants = card.getAllAttachedCards();
|
||||||
for (final CardView e : enchants) {
|
for (final CardView e : enchants) {
|
||||||
final CardPanel cardE = getCardPanel(e.getId());
|
final CardPanel cardE = getCardPanel(e.getId());
|
||||||
if (cardE != null) {
|
if (cardE != null) {
|
||||||
|
|||||||
@@ -286,8 +286,8 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH
|
|||||||
|
|
||||||
attachedPanels.clear();
|
attachedPanels.clear();
|
||||||
|
|
||||||
if (card.hasCardAttachments()) {
|
if (card.hasAnyCardAttachments()) {
|
||||||
final Iterable<CardView> enchants = card.getAttachedCards();
|
final Iterable<CardView> enchants = card.getAllAttachedCards();
|
||||||
for (final CardView e : enchants) {
|
for (final CardView e : enchants) {
|
||||||
final CardAreaPanel cardE = CardAreaPanel.get(e);
|
final CardAreaPanel cardE = CardAreaPanel.get(e);
|
||||||
if (cardE != null) {
|
if (cardE != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user