mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38: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.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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -37,7 +37,7 @@ import forge.util.collect.FCollectionView;
|
||||
* <p>
|
||||
* Predicate<Card> interface.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
@@ -288,7 +288,7 @@ public final class CardPredicates {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static final Predicate<Card> greaterCMC(final int cmc) {
|
||||
return new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -354,7 +354,7 @@ public final class CardPredicates {
|
||||
public static final Predicate<Card> hasCounter(final CounterEnumType type, final int n) {
|
||||
return hasCounter(CounterType.get(type), n);
|
||||
}
|
||||
|
||||
|
||||
public static final Predicate<Card> hasLessCounter(final CounterType type, final int n) {
|
||||
return new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
@@ -497,7 +507,7 @@ public final class CardPredicates {
|
||||
return c.isFaceDown();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* a Predicate<Card> to get all cards that are untapped.
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user