diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddTrigger.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddTrigger.java index ffdd3d8db..4183a781c 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddTrigger.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddTrigger.java @@ -6,6 +6,7 @@ import com.gempukku.lotro.cards.build.field.effect.EffectAppender; import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer; import com.gempukku.lotro.cards.build.field.effect.appender.resolver.TimeResolver; import com.gempukku.lotro.cards.build.field.effect.trigger.TriggerChecker; +import com.gempukku.lotro.game.AbstractActionProxy; import com.gempukku.lotro.game.ActionProxy; import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.logic.actions.AbstractCostToEffectAction; @@ -56,7 +57,7 @@ public class AddTrigger implements EffectAppenderProducer { } private ActionProxy createActionProxy(CostToEffectAction action, ActionContext actionContext, boolean optional, TriggerChecker trigger, Requirement[] requirements, EffectAppender[] costs, EffectAppender[] effects) { - return new ActionProxy() { + return new AbstractActionProxy() { private boolean checkRequirements(ActionContext actionContext) { for (Requirement requirement : requirements) { if (!requirement.accepts(actionContext)) diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/AbstractActionProxy.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/AbstractActionProxy.java index b57cc4e0f..98024583d 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/AbstractActionProxy.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/AbstractActionProxy.java @@ -3,12 +3,23 @@ package com.gempukku.lotro.game; import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.logic.actions.OptionalTriggerAction; import com.gempukku.lotro.logic.actions.RequiredTriggerAction; +import com.gempukku.lotro.logic.timing.Action; import com.gempukku.lotro.logic.timing.Effect; import com.gempukku.lotro.logic.timing.EffectResult; import java.util.List; public abstract class AbstractActionProxy implements ActionProxy { + @Override + public List getOptionalBeforeActions(String playerId, LotroGame game, Effect effect) { + return null; + } + + @Override + public List getOptionalAfterActions(String playerId, LotroGame game, EffectResult effectResult) { + return null; + } + @Override public List getRequiredBeforeTriggers(LotroGame game, Effect effect) { return null; diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/ActionProxy.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/ActionProxy.java index 99e89f4d0..a2332fb14 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/ActionProxy.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/ActionProxy.java @@ -3,17 +3,22 @@ package com.gempukku.lotro.game; import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.logic.actions.OptionalTriggerAction; import com.gempukku.lotro.logic.actions.RequiredTriggerAction; +import com.gempukku.lotro.logic.timing.Action; import com.gempukku.lotro.logic.timing.Effect; import com.gempukku.lotro.logic.timing.EffectResult; import java.util.List; public interface ActionProxy { - public List getRequiredBeforeTriggers(LotroGame lotroGame, Effect effect); + public List getOptionalBeforeActions(String playerId, LotroGame game, Effect effect); - public List getOptionalBeforeTriggers(String playerId, LotroGame lotroGame, Effect effect); + public List getRequiredBeforeTriggers(LotroGame game, Effect effect); - public List getRequiredAfterTriggers(LotroGame lotroGame, EffectResult effectResult); + public List getOptionalBeforeTriggers(String playerId, LotroGame game, Effect effect); - public List getOptionalAfterTriggers(String playerId, LotroGame lotroGame, EffectResult effectResult); + public List getOptionalAfterActions(String playerId, LotroGame game, EffectResult effectResult); + + public List getRequiredAfterTriggers(LotroGame game, EffectResult effectResult); + + public List getOptionalAfterTriggers(String playerId, LotroGame game, EffectResult effectResult); } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/actions/DefaultActionsEnvironment.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/actions/DefaultActionsEnvironment.java index 677ceb1e1..c71e6bbe3 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/actions/DefaultActionsEnvironment.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/actions/DefaultActionsEnvironment.java @@ -3,14 +3,12 @@ package com.gempukku.lotro.game.state.actions; import com.gempukku.lotro.common.Phase; import com.gempukku.lotro.common.Side; import com.gempukku.lotro.common.Zone; -import com.gempukku.lotro.filters.Filters; import com.gempukku.lotro.game.ActionProxy; import com.gempukku.lotro.game.ActionsEnvironment; import com.gempukku.lotro.game.CompletePhysicalCardVisitor; import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.logic.GameUtils; -import com.gempukku.lotro.logic.PlayUtils; import com.gempukku.lotro.logic.actions.OptionalTriggerAction; import com.gempukku.lotro.logic.actions.RequiredTriggerAction; import com.gempukku.lotro.logic.timing.Action; @@ -164,16 +162,17 @@ public class DefaultActionsEnvironment implements ActionsEnvironment { @Override public List getOptionalBeforeActions(String playerId, Effect effect) { - GatherOptionalBeforeActions gatherActions = new GatherOptionalBeforeActions(playerId, effect); + List result = new LinkedList<>(); - _lotroGame.getGameState().iterateActivableCards(playerId, gatherActions); - - List result = new LinkedList(); - - for (Action action : gatherActions.getActions()) { - action.setPerformingPlayer(playerId); - if (_lotroGame.getModifiersQuerying().canPlayAction(_lotroGame, playerId, action)) - result.add(action); + for (ActionProxy actionProxy : _actionProxies) { + List actions = actionProxy.getOptionalBeforeActions(playerId, _lotroGame, effect); + if (actions != null) { + for (Action action : actions) { + action.setPerformingPlayer(playerId); + if (_lotroGame.getModifiersQuerying().canPlayAction(_lotroGame, playerId, action)) + result.add(action); + } + } } return result; @@ -247,16 +246,19 @@ public class DefaultActionsEnvironment implements ActionsEnvironment { @Override public List getOptionalAfterActions(String playerId, Collection effectResults) { - GatherOptionalAfterActions gatherAfterActions = new GatherOptionalAfterActions(playerId, effectResults); + List result = new LinkedList<>(); - _lotroGame.getGameState().iterateActivableCards(playerId, gatherAfterActions); - - List result = new LinkedList(); - - for (Action action : gatherAfterActions.getActions()) { - action.setPerformingPlayer(playerId); - if (_lotroGame.getModifiersQuerying().canPlayAction(_lotroGame, playerId, action)) - result.add(action); + for (ActionProxy actionProxy : _actionProxies) { + for (EffectResult effectResult : effectResults) { + List actions = actionProxy.getOptionalAfterActions(playerId, _lotroGame, effectResult); + if (actions != null) { + for (Action action : actions) { + action.setPerformingPlayer(playerId); + if (_lotroGame.getModifiersQuerying().canPlayAction(_lotroGame, playerId, action)) + result.add(action); + } + } + } } return result; @@ -356,37 +358,6 @@ public class DefaultActionsEnvironment implements ActionsEnvironment { } } - private class GatherOptionalBeforeActions extends CompletePhysicalCardVisitor { - private String _playerId; - private Effect _effect; - private List _actions = new LinkedList(); - - private GatherOptionalBeforeActions(String playerId, Effect effect) { - _playerId = playerId; - _effect = effect; - } - - @Override - public void doVisitPhysicalCard(PhysicalCard physicalCard) { - if (!_lotroGame.getModifiersQuerying().hasTextRemoved(_lotroGame, physicalCard)) { - if (physicalCard.getZone().isInPlay()) { - List actions = physicalCard.getBlueprint().getOptionalInPlayBeforeActions(_playerId, _lotroGame, _effect, physicalCard); - if (actions != null) - _actions.addAll(actions); - } else if (physicalCard.getZone() == Zone.HAND - && PlayUtils.checkPlayRequirements(_lotroGame, physicalCard, Filters.any, 0, 0, false, false)) { - List actions = physicalCard.getBlueprint().getPlayResponseEventBeforeActions(_playerId, _lotroGame, _effect, physicalCard); - if (actions != null) - _actions.addAll(actions); - } - } - } - - public List getActions() { - return _actions; - } - } - private class GatherOptionalAfterTriggers extends CompletePhysicalCardVisitor { private String _playerId; private Collection _effectResults; @@ -441,40 +412,6 @@ public class DefaultActionsEnvironment implements ActionsEnvironment { } } - private class GatherOptionalAfterActions extends CompletePhysicalCardVisitor { - private String _playerId; - private Collection _effectResults; - private List _actions = new LinkedList(); - - private GatherOptionalAfterActions(String playerId, Collection effectResults) { - _playerId = playerId; - _effectResults = effectResults; - } - - @Override - protected void doVisitPhysicalCard(PhysicalCard physicalCard) { - if (!_lotroGame.getModifiersQuerying().hasTextRemoved(_lotroGame, physicalCard)) { - if (_effectResults != null) - for (EffectResult effectResult : _effectResults) { - if (physicalCard.getZone().isInPlay()) { - List actions = physicalCard.getBlueprint().getOptionalInPlayAfterActions(_playerId, _lotroGame, effectResult, physicalCard); - if (actions != null) - _actions.addAll(actions); - } else if (physicalCard.getZone() == Zone.HAND - && PlayUtils.checkPlayRequirements(_lotroGame, physicalCard, Filters.any, 0, 0, false, false)) { - List actions = physicalCard.getBlueprint().getPlayResponseEventAfterActions(_playerId, _lotroGame, effectResult, physicalCard); - if (actions != null) - _actions.addAll(actions); - } - } - } - } - - public List getActions() { - return _actions; - } - } - private class GatherPhaseActionsVisitor extends CompletePhysicalCardVisitor { private LotroGame _game; private String _playerId; diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/RuleSet.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/RuleSet.java index b6e172e85..8899ce150 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/RuleSet.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/RuleSet.java @@ -52,8 +52,10 @@ public class RuleSet { new FollowerRule(_actionsEnvironment).applyRule(); new PlayPermanentRule(_modifiersLogic).applyRule(); - new PlayEventRule(_modifiersLogic).applyRule(); + new PlayResponseEventRule(_actionsEnvironment).applyRule(); + + new ActivateResponseAbilitiesRule(_actionsEnvironment).applyRule(); new TakeOffRingRule(_actionsEnvironment).applyRule(); } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/ActivateResponseAbilitiesRule.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/ActivateResponseAbilitiesRule.java new file mode 100644 index 000000000..4fbfbb735 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/ActivateResponseAbilitiesRule.java @@ -0,0 +1,68 @@ +package com.gempukku.lotro.logic.timing.rules; + +import com.gempukku.lotro.common.CardType; +import com.gempukku.lotro.common.Phase; +import com.gempukku.lotro.filters.Filter; +import com.gempukku.lotro.filters.Filters; +import com.gempukku.lotro.game.AbstractActionProxy; +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.game.state.actions.DefaultActionsEnvironment; +import com.gempukku.lotro.logic.actions.ActivateCardAction; +import com.gempukku.lotro.logic.modifiers.condition.OrCondition; +import com.gempukku.lotro.logic.modifiers.condition.PhaseCondition; +import com.gempukku.lotro.logic.timing.Action; +import com.gempukku.lotro.logic.timing.Effect; +import com.gempukku.lotro.logic.timing.EffectResult; + +import java.util.LinkedList; +import java.util.List; + +public class ActivateResponseAbilitiesRule { + private DefaultActionsEnvironment actionsEnvironment; + + public ActivateResponseAbilitiesRule(DefaultActionsEnvironment actionsEnvironment) { + this.actionsEnvironment = actionsEnvironment; + } + + public void applyRule() { + actionsEnvironment.addAlwaysOnActionProxy( + new AbstractActionProxy() { + @Override + public List getOptionalBeforeActions(String playerId, LotroGame game, Effect effect) { + List result = new LinkedList<>(); + for (PhysicalCard activableCard : Filters.filterActive(game, getActivatableCardsFilter(playerId))) { + if (!game.getModifiersQuerying().hasTextRemoved(game, activableCard)) { + final List actions = activableCard.getBlueprint().getOptionalInPlayBeforeActions(playerId, game, effect, activableCard); + if (actions != null) + result.addAll(actions); + } + } + + return result; + } + + @Override + public List getOptionalAfterActions(String playerId, LotroGame game, EffectResult effectResult) { + List result = new LinkedList<>(); + for (PhysicalCard activableCard : Filters.filterActive(game, getActivatableCardsFilter(playerId))) { + if (!game.getModifiersQuerying().hasTextRemoved(game, activableCard)) { + final List actions = activableCard.getBlueprint().getOptionalInPlayAfterActions(playerId, game, effectResult, activableCard); + if (actions != null) + result.addAll(actions); + } + } + + return result; + } + } + ); + } + + private Filter getActivatableCardsFilter(String playerId) { + return Filters.conditionFilter( + Filters.or(Filters.currentSite, Filters.and(Filters.not(CardType.SITE), Filters.owner(playerId))), + new OrCondition(new PhaseCondition(Phase.PUT_RING_BEARER), new PhaseCondition(Phase.PLAY_STARTING_FELLOWSHIP)), + Filters.and(Filters.not(CardType.SITE), Filters.owner(playerId))); + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/PlayResponseEventRule.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/PlayResponseEventRule.java new file mode 100644 index 000000000..912e069a8 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/PlayResponseEventRule.java @@ -0,0 +1,61 @@ +package com.gempukku.lotro.logic.timing.rules; + +import com.gempukku.lotro.common.CardType; +import com.gempukku.lotro.common.Keyword; +import com.gempukku.lotro.common.Side; +import com.gempukku.lotro.filters.Filters; +import com.gempukku.lotro.game.AbstractActionProxy; +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.game.state.actions.DefaultActionsEnvironment; +import com.gempukku.lotro.logic.GameUtils; +import com.gempukku.lotro.logic.PlayUtils; +import com.gempukku.lotro.logic.actions.PlayEventAction; +import com.gempukku.lotro.logic.timing.Action; +import com.gempukku.lotro.logic.timing.Effect; +import com.gempukku.lotro.logic.timing.EffectResult; + +import java.util.LinkedList; +import java.util.List; + +public class PlayResponseEventRule { + private DefaultActionsEnvironment actionsEnvironment; + + public PlayResponseEventRule(DefaultActionsEnvironment actionsEnvironment) { + this.actionsEnvironment = actionsEnvironment; + } + + public void applyRule() { + actionsEnvironment.addAlwaysOnActionProxy( + new AbstractActionProxy() { + @Override + public List getOptionalAfterActions(String playerId, LotroGame game, EffectResult effectResult) { + List result = new LinkedList<>(); + final Side side = GameUtils.getSide(game, playerId); + for (PhysicalCard responseEvent : Filters.filter(game.getGameState().getHand(playerId), game, side, CardType.EVENT, Keyword.RESPONSE)) { + if (PlayUtils.checkPlayRequirements(game, responseEvent, Filters.any, 0, 0, false, false)) { + final List actions = responseEvent.getBlueprint().getPlayResponseEventAfterActions(playerId, game, effectResult, responseEvent); + if (actions != null) + result.addAll(actions); + } + } + return result; + } + + @Override + public List getOptionalBeforeActions(String playerId, LotroGame game, Effect effect) { + List result = new LinkedList<>(); + final Side side = GameUtils.getSide(game, playerId); + for (PhysicalCard responseEvent : Filters.filter(game.getGameState().getHand(playerId), game, side, CardType.EVENT, Keyword.RESPONSE)) { + if (PlayUtils.checkPlayRequirements(game, responseEvent, Filters.any, 0, 0, false, false)) { + final List actions = responseEvent.getBlueprint().getPlayResponseEventBeforeActions(playerId, game, effect, responseEvent); + if (actions != null) + result.addAll(actions); + } + } + return result; + } + } + ); + } +}