diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/effects/LiberateASiteEffect.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/effects/LiberateASiteEffect.java new file mode 100644 index 000000000..c27887bf2 --- /dev/null +++ b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/effects/LiberateASiteEffect.java @@ -0,0 +1,66 @@ +package com.gempukku.lotro.cards.effects; + +import com.gempukku.lotro.common.Zone; +import com.gempukku.lotro.filters.Filters; +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.timing.AbstractEffect; +import com.gempukku.lotro.logic.timing.EffectResult; + +import java.util.List; + +public class LiberateASiteEffect extends AbstractEffect { + private PhysicalCard _source; + + public LiberateASiteEffect(PhysicalCard source) { + _source = source; + } + + @Override + public boolean isPlayableInFull(LotroGame game) { + return Filters.countActive(game.getGameState(), game.getModifiersQuerying(), Filters.siteControlledByShadowPlayer(game.getGameState().getCurrentPlayerId())) > 0; + } + + @Override + public String getText(LotroGame game) { + return "Liberate a site"; + } + + @Override + public EffectResult.Type getType() { + return null; + } + + private PhysicalCard getSiteToLiberate(LotroGame game) { + int maxUnoccupiedSite = Integer.MAX_VALUE; + for (String playerId : game.getGameState().getPlayerOrder().getAllPlayers()) + maxUnoccupiedSite = Math.min(maxUnoccupiedSite, game.getGameState().getPlayerPosition(playerId) - 1); + + for (int i = maxUnoccupiedSite; i >= 1; i++) { + PhysicalCard site = game.getGameState().getSite(i); + if (site.getCardController() != null + && !site.getCardController().equals(game.getGameState().getCurrentPlayerId())) + return site; + } + + return null; + } + + @Override + protected FullEffectResult playEffectReturningResult(LotroGame game) { + PhysicalCard siteToLiberate = getSiteToLiberate(game); + if (siteToLiberate != null) { + + List stackedCards = game.getGameState().getStackedCards(siteToLiberate); + for (PhysicalCard stackedCard : stackedCards) { + game.getGameState().removeCardFromZone(stackedCard); + game.getGameState().addCardToZone(stackedCard, Zone.DISCARD); + } + + game.getGameState().loseControlOfCard(siteToLiberate, Zone.ADVENTURE_PATH); + + return new FullEffectResult(null, true, true); + } + return new FullEffectResult(null, false, false); + } +} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set4/elven/Card4_071.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set4/elven/Card4_071.java new file mode 100644 index 000000000..ca8930eb3 --- /dev/null +++ b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set4/elven/Card4_071.java @@ -0,0 +1,74 @@ +package com.gempukku.lotro.cards.set4.elven; + +import com.gempukku.lotro.cards.AbstractCompanion; +import com.gempukku.lotro.cards.PlayConditions; +import com.gempukku.lotro.cards.effects.ChooseAndExertCharactersEffect; +import com.gempukku.lotro.cards.effects.ExertCharactersEffect; +import com.gempukku.lotro.cards.effects.LiberateASiteEffect; +import com.gempukku.lotro.cards.modifiers.StrengthModifier; +import com.gempukku.lotro.common.Culture; +import com.gempukku.lotro.common.Keyword; +import com.gempukku.lotro.common.Phase; +import com.gempukku.lotro.common.Race; +import com.gempukku.lotro.filters.Filters; +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.GameState; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.actions.ActivateCardAction; +import com.gempukku.lotro.logic.modifiers.Condition; +import com.gempukku.lotro.logic.modifiers.Modifier; +import com.gempukku.lotro.logic.modifiers.ModifiersQuerying; +import com.gempukku.lotro.logic.timing.Action; + +import java.util.Collections; +import java.util.List; + +/** + * Set: The Two Towers + * Side: Free + * Culture: Elven + * Twilight Cost: 2 + * Type: Companion • Elf + * Strength: 5 + * Vitality: 3 + * Resistance: 6 + * Game Text: While no opponent controls a site, Haldir is strength +2. + * Regroup: Exert Haldir at a battleground and exert another Elf to liberate a site. + */ +public class Card4_071 extends AbstractCompanion { + public Card4_071() { + super(2, 5, 3, Culture.ELVEN, Race.ELF, null, "Haldir", true); + } + + @Override + public List getAlwaysOnModifiers(final PhysicalCard self) { + return Collections.singletonList( + new StrengthModifier(self, Filters.sameCard(self), + new Condition() { + @Override + public boolean isFullfilled(GameState gameState, ModifiersQuerying modifiersQuerying) { + return Filters.countActive(gameState, modifiersQuerying, Filters.siteControlledByShadowPlayer(self.getOwner())) == 0; + } + }, 2)); + } + + @Override + protected List getExtraInPlayPhaseActions(String playerId, LotroGame game, PhysicalCard self) { + if (PlayConditions.canUseFPCardDuringPhase(game.getGameState(), Phase.REGROUP, self) + && PlayConditions.canExert(self, game.getGameState(), game.getModifiersQuerying(), self) + && game.getModifiersQuerying().hasKeyword(game.getGameState(), game.getGameState().getCurrentSite(), Keyword.BATTLEGROUND) + && PlayConditions.canExert(self, game.getGameState(), game.getModifiersQuerying(), Filters.not(Filters.sameCard(self)), Filters.race(Race.ELF))) { + ActivateCardAction action = new ActivateCardAction(self, Keyword.REGROUP); + action.appendCost( + new ExertCharactersEffect(self, self)); + action.appendCost( + new ChooseAndExertCharactersEffect(action, playerId, 1, 1, Filters.not(Filters.sameCard(self)), Filters.race(Race.ELF))); + + action.appendEffect( + new LiberateASiteEffect(self)); + + return Collections.singletonList(action); + } + return null; + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/filters/Filters.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/filters/Filters.java index 6c939212d..6609e7069 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/filters/Filters.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/filters/Filters.java @@ -378,6 +378,15 @@ public class Filters { }; } + public static Filter siteControlledByShadowPlayer(final String fellowshipPlayer) { + return new Filter() { + @Override + public boolean accepts(GameState gameState, ModifiersQuerying modifiersQuerying, PhysicalCard physicalCard) { + return physicalCard.getBlueprint().getCardType() == CardType.SITE && physicalCard.getCardController() != null && !physicalCard.getCardController().equals(fellowshipPlayer); + } + }; + } + public static Filter siteControlled(final String playerId) { return new Filter() { @Override diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java index aea772a11..6b8dfb633 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java @@ -224,6 +224,13 @@ public class GameState { listener.cardMoved(card); } + public void loseControlOfCard(PhysicalCard card, Zone zone) { + ((PhysicalCardImpl) card).setCardController(null); + ((PhysicalCardImpl) card).setZone(zone); + for (GameStateListener listener : getAllGameStateListeners()) + listener.cardMoved(card); + } + public void attachCard(PhysicalCard card, PhysicalCard attachTo) { ((PhysicalCardImpl) card).attachTo((PhysicalCardImpl) attachTo); addCardToZone(card, Zone.ATTACHED);